站长资讯网
最全最丰富的资讯网站

详解GoLang实现基于gin+jaeger的opentracing中间件

下面由golang教程栏目给大家介绍GoLang实现基于gin+jaeger的opentracing中间件的方法,希望对需要的朋友有所帮助!

详解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() }

查看调用链路:

详解GoLang实现基于gin+jaeger的opentracing中间件

赞(0)
分享到: 更多 (0)