generated from liuzhaomax/go-maxms
/
tracing.go
79 lines (73 loc) · 2.51 KB
/
tracing.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package tracing
import (
"github.com/gin-gonic/gin"
"github.com/google/wire"
"github.com/liuzhaomax/maxblog-user/internal/core"
"github.com/opentracing/opentracing-go"
"github.com/uber/jaeger-client-go"
jConfig "github.com/uber/jaeger-client-go/config"
"io"
"net/http"
)
var TracingSet = wire.NewSet(wire.Struct(new(Tracing), "*"))
type Tracing struct {
Logger core.ILogger
TracerConfig *jConfig.Configuration
}
// Trace 通过header传递traceID给下游服务来实现嵌套链路
func (t *Tracing) Trace() gin.HandlerFunc {
return func(c *gin.Context) {
// 生成tracer
tracer, closer, err := t.TracerConfig.NewTracer(jConfig.Logger(jaeger.StdLogger))
defer func(closer io.Closer) {
_ = closer.Close()
}(closer)
if err != nil {
c.AbortWithStatusJSON(http.StatusUnauthorized, t.GenErrMsg(c, "tracer生成失败", err))
return
}
// 创建span
var span opentracing.Span
parent := c.Request.Header.Get(core.ParentId)
if parent != core.EmptyString {
// 有父级span的时候提取父级span的traceID
carrier := opentracing.HTTPHeadersCarrier(c.Request.Header)
ctx, err := tracer.Extract(opentracing.HTTPHeaders, carrier)
if err != nil {
c.AbortWithStatusJSON(http.StatusUnauthorized, t.GenErrMsg(c, "tracer提取失败", err))
return
}
span = tracer.StartSpan(c.Request.URL.Path, opentracing.ChildOf(ctx))
} else {
span = tracer.StartSpan(c.Request.URL.Path)
}
defer span.Finish()
// 从 Span 上下文中获取 Trace ID 和 Span ID,并设置到header中
spanContext := span.Context()
traceID := spanContext.(jaeger.SpanContext).TraceID().String()
spanID := spanContext.(jaeger.SpanContext).SpanID().String()
if parent != core.EmptyString {
c.Request.Header.Set(core.ParentId, c.Request.Header.Get(core.SpanId))
} else {
c.Request.Header.Set(core.ParentId, spanID)
}
c.Request.Header.Set(core.TraceId, traceID)
c.Request.Header.Set(core.SpanId, spanID)
// 生成carrier
carrier := opentracing.HTTPHeadersCarrier(c.Request.Header)
err = tracer.Inject(span.Context(), opentracing.HTTPHeaders, carrier)
if err != nil {
c.AbortWithStatusJSON(http.StatusUnauthorized, t.GenErrMsg(c, "tracer注入失败", err))
return
}
c.Next()
}
}
func (t *Tracing) GenOkMsg(c *gin.Context, desc string) string {
t.Logger.SucceedWithField(c, desc)
return core.FormatInfo(desc)
}
func (t *Tracing) GenErrMsg(c *gin.Context, desc string, err error) error {
t.Logger.FailWithField(c, core.Unknown, desc, err)
return core.FormatError(core.Unknown, desc, err)
}