From 4765dcd7232e90a68e8ec43d85e100ae839c9c76 Mon Sep 17 00:00:00 2001 From: zhangwei Date: Fri, 20 Nov 2020 13:27:22 +0800 Subject: [PATCH 1/2] add go-restful plugin --- .github/workflows/ci.yaml | 1 + go-restful/README.md | 51 +++++++++++++++ go-restful/doc.go | 19 ++++++ go-restful/example_go_restful_test.go | 89 +++++++++++++++++++++++++++ go-restful/go.mod | 9 +++ go-restful/go_restful.go | 67 ++++++++++++++++++++ 6 files changed, 236 insertions(+) create mode 100644 go-restful/README.md create mode 100644 go-restful/doc.go create mode 100644 go-restful/example_go_restful_test.go create mode 100644 go-restful/go.mod create mode 100644 go-restful/go_restful.go diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1a648b1..4544a3e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,6 +38,7 @@ jobs: - { name: 'Gin v3', plugin_dir: 'gin/v3', go_version: '1.12'} - { name: 'Go micro', plugin_dir: 'micro', go_version: '1.13'} - { name: 'Go resty', plugin_dir: 'resty', go_version: '1.12'} + - { name: 'Go restful', plugin_dir: 'go-restful', go_version: '1.13'} steps: - name: Set up Go ${{ matrix.case.go_version }} uses: actions/setup-go@v2 diff --git a/go-restful/README.md b/go-restful/README.md new file mode 100644 index 0000000..d3602d8 --- /dev/null +++ b/go-restful/README.md @@ -0,0 +1,51 @@ +# Go2sky with [go-restful](https://github.com/emicklei/go-restful) (v3+) + +## Installation + +```bash +go get -u github.com/SkyAPM/go2sky-plugins/go-restful +``` + +## Usage +```go +package main + +import ( + "io" + "log" + + "github.com/SkyAPM/go2sky" + tracerestful "github.com/SkyAPM/go2sky-plugins/go-restful" + "github.com/SkyAPM/go2sky/reporter" + "github.com/emicklei/go-restful/v3" +) + +func main() { + // Use gRPC reporter for production + re, err := reporter.NewLogReporter() + if err != nil { + log.Fatalf("new reporter error %v \n", err) + } + + defer re.Close() + + tracer, err := go2sky.NewTracer("go-restful", go2sky.WithReporter(re)) + if err != nil { + log.Fatalf("create tracer error %v \n", err) + } + + ws := new(restful.WebService) + ws.Filter(tracerestful.NewTraceFilterFunction(tracer)) + + ws.Route(ws.GET("/hello").To(func(req *restful.Request, resp *restful.Response) { + io.WriteString(resp, "go-restful") + })) + restful.Add(ws) + go func() { + http.ListenAndServe(":8080", nil) + }() + // do something +} +``` + +[See more](example_go_restful_test.go). \ No newline at end of file diff --git a/go-restful/doc.go b/go-restful/doc.go new file mode 100644 index 0000000..d48ed8d --- /dev/null +++ b/go-restful/doc.go @@ -0,0 +1,19 @@ +// Licensed to SkyAPM org under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. SkyAPM org licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// Package restful is a plugin that can be used to trace go-restful framework. +package restful diff --git a/go-restful/example_go_restful_test.go b/go-restful/example_go_restful_test.go new file mode 100644 index 0000000..bfe318e --- /dev/null +++ b/go-restful/example_go_restful_test.go @@ -0,0 +1,89 @@ +// Licensed to SkyAPM org under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. SkyAPM org licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package restful + +import ( + "io" + "log" + "net/http" + "sync" + "time" + + "github.com/SkyAPM/go2sky" + h "github.com/SkyAPM/go2sky/plugins/http" + "github.com/SkyAPM/go2sky/reporter" + "github.com/emicklei/go-restful/v3" +) + +func ExampleFilterFunction() { + re, err := reporter.NewLogReporter() + if err != nil { + log.Fatalf("new reporter error %v \n", err) + } + + defer re.Close() + + tracer, err := go2sky.NewTracer("go-restful", go2sky.WithReporter(re)) + if err != nil { + log.Fatalf("create tracer error %v \n", err) + } + + ws := new(restful.WebService) + ws.Filter(NewTraceFilterFunction(tracer)) + + ws.Route(ws.GET("/hello").To(func(req *restful.Request, resp *restful.Response) { + _, _ = io.WriteString(resp, "go-restful") + })) + restful.Add(ws) + + go func() { + _ = http.ListenAndServe(":8080", nil) + }() + + // // Wait for the server to start + time.Sleep(time.Second) + + wg := sync.WaitGroup{} + wg.Add(1) + + go func() { + defer wg.Done() + request(tracer) + }() + wg.Wait() + // Output: +} + +func request(tracer *go2sky.Tracer) { + client, err := h.NewClient(tracer) + if err != nil { + log.Fatalf("create client error %v \n", err) + } + + request, err := http.NewRequest("GET", "http://127.0.0.1:8080/hello", nil) + if err != nil { + log.Fatalf("unable to create http request: %+v\n", err) + } + + res, err := client.Do(request) + if err != nil { + log.Fatalf("unable to do http request: %+v\n", err) + } + + _ = res.Body.Close() +} diff --git a/go-restful/go.mod b/go-restful/go.mod new file mode 100644 index 0000000..d132a6d --- /dev/null +++ b/go-restful/go.mod @@ -0,0 +1,9 @@ +module github.com/SkyAPM/go2sky-plugins/go-restful + +go 1.13 + +require ( + github.com/SkyAPM/go2sky v0.5.0 + github.com/emicklei/go-restful/v3 v3.0.0 + github.com/json-iterator/go v1.1.10 // indirect +) diff --git a/go-restful/go_restful.go b/go-restful/go_restful.go new file mode 100644 index 0000000..a821561 --- /dev/null +++ b/go-restful/go_restful.go @@ -0,0 +1,67 @@ +// Licensed to SkyAPM org under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. SkyAPM org licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package restful + +import ( + "fmt" + "strconv" + "time" + + "github.com/SkyAPM/go2sky" + "github.com/SkyAPM/go2sky/propagation" + v3 "github.com/SkyAPM/go2sky/reporter/grpc/language-agent" + "github.com/emicklei/go-restful/v3" +) + +const componentIDGOHttpServer = 5004 + +// NewTraceFilterFunction return go-restful FilterFunction with tracing. +func NewTraceFilterFunction(tracer *go2sky.Tracer) restful.FilterFunction { + if tracer == nil { + return func(request *restful.Request, response *restful.Response, chain *restful.FilterChain) { + chain.ProcessFilter(request, response) + } + } + + return func(request *restful.Request, response *restful.Response, chain *restful.FilterChain) { + span, ctx, err := tracer.CreateEntrySpan(request.Request.Context(), + fmt.Sprintf("/%s%s", request.Request.Method, request.SelectedRoutePath()), func() (string, error) { + return request.HeaderParameter(propagation.Header), nil + }) + + if err != nil { + chain.ProcessFilter(request, response) + return + } + + span.SetComponent(componentIDGOHttpServer) + span.Tag(go2sky.TagHTTPMethod, request.Request.Method) + span.Tag(go2sky.TagURL, request.Request.Host+request.Request.URL.Path) + span.SetSpanLayer(v3.SpanLayer_Http) + request.Request = request.Request.WithContext(ctx) + defer func() { + code := response.StatusCode() + if code >= 400 { + span.Error(time.Now(), "Error on handling request") + } + span.Tag(go2sky.TagStatusCode, strconv.Itoa(code)) + span.End() + }() + chain.ProcessFilter(request, response) + } +} From 8049f2019ac6cbe6ad4ec8948a85090b507b8847 Mon Sep 17 00:00:00 2001 From: zhang-wei Date: Fri, 20 Nov 2020 14:03:45 +0800 Subject: [PATCH 2/2] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5782359..735e7ce 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,5 @@ The plugins of [go2sky](https://github.com/SkyAPM/go2sky) 1. [gin](gin/README.md) 1. [gear](gear/README.md) 1. [go-resty](resty/README.md) -1. [go-micro](micro/README.md) \ No newline at end of file +1. [go-micro](micro/README.md) +1. [go-restful](go-restful/README.md)