Maison > développement back-end > Golang > Explication détaillée de l'implémentation par GoLang du middleware opentracing basé sur gin+jaeger

Explication détaillée de l'implémentation par GoLang du middleware opentracing basé sur gin+jaeger

藏色散人
Libérer: 2021-01-12 16:04:41
avant
4691 Les gens l'ont consulté

La colonne tutorielle suivante de golang vous présentera comment GoLang implémente un middleware opentracing basé sur gin+jaeger. J'espère que cela sera utile aux amis dans le besoin !

Explication détaillée de l'implémentation par GoLang du middleware opentracing basé sur gin+jaeger

完整源码:https://github.com/why444216978/gin-api
jaeger下载地址:https://www.jaegertracing.io/download/
Copier après la connexion

Exécutez Jaeger :

./jaeger-all-in-one
Copier après la connexion

gin middleware d'enregistrement :

server := gin.New()

server.Use(trace.OpenTracing("gin-api"))
Copier après la connexion

Définition du middleware :

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()
	}
}
Copier après la connexion

Implémentation de la requête 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
}
Copier après la connexion

Code d'appel :

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()
}
Copier après la connexion

Afficher le lien d'appel :

Pour plus d'articles techniques connexes, veuillez visiter la colonne go langage  !

附原文地址: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
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:csdn.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal