下面由golang教程栏目给大家介绍GoLang实现基于gin+jaeger的opentracing中间件的方法,希望对需要的朋友有所帮助!
完整源码:https://github.com/why444216978/gin-api jaeger下载地址:https://www.jaegertracing.io/download/
运行jaeger:
./jaeger-all-in-one
gin注册中间件:
server := gin.New() server.Use(trace.OpenTracing("gin-api"))
中间件定义:
package trace import ( "github.com/gin-gonic/gin" opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" ) const defaultComponentName = "net/http" const JaegerOpen = 1 const AppName = "gin-api" const JaegerHostPort = "127.0.0.1:6831" func OpenTracing(serviceName string) gin.HandlerFunc { return func(c *gin.Context) { if JaegerOpen == 1 { var parentSpan opentracing.Span tracer, closer := NewJaegerTracer(AppName, JaegerHostPort) defer closer.Close() spCtx, err := opentracing.GlobalTracer().Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(c.Request.Header)) if err != nil { parentSpan = tracer.StartSpan(c.Request.URL.Path) defer parentSpan.Finish() } else { parentSpan = opentracing.StartSpan( c.Request.URL.Path, opentracing.ChildOf(spCtx), opentracing.Tag{Key: string(ext.Component), Value: "HTTP"}, ext.SpanKindRPCServer, ) defer parentSpan.Finish() } c.Set("Tracer", tracer) c.Set("ParentSpanContext", parentSpan.Context()) } c.Next() } }
http请求实现:
package http import ( "bytes" "encoding/json" "io/ioutil" "net/http" "strconv" "gin-frame/libraries/util" simplejson "github.com/bitly/go-simplejson" "github.com/gin-gonic/gin" "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" opentracingLog "github.com/opentracing/opentracing-go/log" ) func HttpSend(c *gin.Context, method, url, logId string, data map[string]interface{}) map[string]interface{} { var ( err error ret = make(map[string]interface{}) req *http.Request ) client := &http.Client{} //请求数据 byteDates, err := json.Marshal(data) util.Must(err) reader := bytes.NewReader(byteDates) //url url = url + "?logid=" + logId //构建req req, err = http.NewRequest(method, url, reader) util.Must(err) //设置请求header req.Header.Add("content-type", "application/json") tracer, _ := c.Get("Tracer") parentSpanContext, _ := c.Get("ParentSpanContext") span := opentracing.StartSpan( "httpDo", opentracing.ChildOf(parentSpanContext.(opentracing.SpanContext)), opentracing.Tag{Key: string(ext.Component), Value: "HTTP"}, ext.SpanKindRPCClient, ) defer span.Finish() injectErr := tracer.(opentracing.Tracer).Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header)) if injectErr != nil { span.LogFields(opentracingLog.String("inject-error", err.Error())) } //发送请求 resp, err := client.Do(req) util.Must(err) defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) util.Must(err) ret["code"] = resp.StatusCode ret["msg"] = "success" ret["data"] = make(map[string]interface{}) if resp.StatusCode != http.StatusOK { ret["msg"] = "http code:" + strconv.Itoa(resp.StatusCode) return ret } if b != nil { res, err := simplejson.NewJson(b) util.Must(err) ret["data"] = res } return ret }
调用代码:
package test import ( "net/http" "github.com/gin-gonic/gin" "gin-frame/libraries/config" rpc_http "gin-frame/libraries/http" ) func Rpc(c *gin.Context) { postData := make(map[string]interface{}) logId := c.Writer.Header().Get(config.GetHeaderLogIdField()) sendUrl := "https://www.baidu.com" //urlMap := strings.Split(sendUrl, "?") //urlQueryMap := url.ParseUriQueryToMap(sendUrl) ret := rpc_http.HttpSend(c, "POST", sendUrl, logId, postData) c.JSON(http.StatusOK, gin.H{ "errno": 0, "errmsg": "success", "data": ret, }) c.Done() }
查看调用链路: