当前位置 博文首页 > 文章内容

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

    作者:shunshunshun18 栏目:未分类 时间:2021-01-16 10:47:35

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    下面由教程栏目给大家介绍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()
    }

    查看调用链路:

    更多相关技术文章,请访问栏目!

    附原文地址:https://success.blog.csdn.net/article/details/104100597?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2.control