ホームページ  >  記事  >  バックエンド開発  >  gin+jaeger をベースにした GoLang の opentracing ミドルウェア実装の詳細な説明

gin+jaeger をベースにした GoLang の opentracing ミドルウェア実装の詳細な説明

藏色散人
藏色散人転載
2021-01-12 16:03:434687ブラウズ

golang の次のチュートリアル コラムでは、GoLang が gin jaeger に基づいて opentracing ミドルウェアを実装する方法を紹介します。

gin+jaeger をベースにした GoLang の 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()
}

呼び出しリンクの表示:


その他の関連技術記事については、

go language 列をご覧ください。 rree

以上がgin+jaeger をベースにした GoLang の opentracing ミドルウェア実装の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。