您现在的位置是:群英 > 开发技术 > 编程语言
opentracing中间件如何实现,在GoLang里有什么好方法
Admin发表于 2022-05-26 17:49:16939 次浏览
这篇文章主要给大家介绍“opentracing中间件如何实现,在GoLang里有什么好方法”的相关知识,下文通过实际案例向大家展示操作过程,内容简单清晰,易于学习,有这方面学习需要的朋友可以参考,希望这篇“opentracing中间件如何实现,在GoLang里有什么好方法”文章能对大家有所帮助。

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

查看调用链路:



通过以上内容的阐述,相信大家对“opentracing中间件如何实现,在GoLang里有什么好方法”已经有了进一步的了解,更多相关的问题,欢迎关注群英网络或到群英官网咨询客服。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

标签: Golang
相关信息推荐
2022-06-27 17:16:01 
摘要:本章给大家介绍html5实现把上传的图片转成base64编码在显示(代码实例)。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。
2022-06-16 09:25:40 
摘要:有2个转换函数:1、implode(),语法为“implode($glue,$arr)”,会返回一个由数组元素和“$glue”字符组合成的字符串。2、join(),语法为“join($glue,$arr)”,可以将一个一维数组转化为字符串。
2022-05-06 18:01:48 
摘要:在PHP中,and用于逻辑判断,语法为“数值1 and 数值2”,若and两边的操作数都是true,则返回true,否则返回false;and是一个逻辑运算符,与“&&”运算符一样都表示逻辑“与”,并且“&&”运算符的优先级比and要高。
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部