Home > Backend Development > Golang > Detailed explanation of GoLang's implementation of opentracing middleware based on gin+jaeger

Detailed explanation of GoLang's implementation of opentracing middleware based on gin+jaeger

藏色散人
Release: 2021-01-12 16:04:41
forward
4693 people have browsed it

The following tutorial column will introduce to you how GoLang implements opentracing middleware based on gin jaeger. I hope it will be helpful to friends in need!

完整源码:https://github.com/why444216978/gin-api
jaeger下载地址:https://www.jaegertracing.io/download/
Copy after login

Run jaeger:

./jaeger-all-in-one
Copy after login
Detailed explanation of GoLang's implementation of opentracing middleware based on gin+jaegergin Register middleware:

server := gin.New()

server.Use(trace.OpenTracing("gin-api"))
Copy after login

Middleware definition:


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()
	}
}
Copy after login

http request implementation:


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
}
Copy after login

Calling code:


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()
}
Copy after login

View calling link:



For more related technical articles, please visit the

go language

column!

The above is the detailed content of Detailed explanation of GoLang's implementation of opentracing middleware based on gin+jaeger. For more information, please follow other related articles on the PHP Chinese website!

source:csdn.net
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template