从 opentelemetry 的请求 Headers 中提取跟踪器的正确方法
Proper way of extracting tracer from request Headers for opentelemetry
我有 krakend apigateway,它使用 opentracing 并发送请求 headers 作为 X-B3-... 进行跟踪,我的服务使用 opentelemetry。
这就是我现在在 jaeger 上看到的内容。
enter image description here
enter image description here
我希望服务跨度在 apigateways 下。
我做过的解决方法:
这是使用 chi 路由器的请求的确切处理程序。
func (env *Env) getCommentForBlogRouter(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
keys := []string{"X-B3-Traceid", "X-B3-Spanid", "X-B3-Sampled"}
var carrier propagation.HeaderCarrier = propagation.HeaderCarrier{}
for _, k := range keys {
carrier.Set(strings.ToLower(k), r.Header[k][0])
}
var propagator propagation.TextMapPropagator = otel.GetTextMapPropagator()
ctx = propagator.Extract(ctx, carrier)
// fmt.Println(ctx)
tr := otel.Tracer("Handler: blog-comments")
ctx, span := tr.Start(ctx, "handler span")
defer span.End()
blogId := r.URL.Query().Get("blog-id")
span.SetAttributes(attribute.Key("blog-id").String(fmt.Sprint(blogId)))
var spanDB trace.Span
ctx, spanDB = tr.Start(ctx, "Select row")
comments, err := env.comments.GetForBlog(blogId)
spanDB.End()
var spanRes trace.Span
_, spanRes = tr.Start(ctx, "Sending Response")
defer spanRes.End()
if err != nil {
fmt.Println(err)
SendError(w, http.StatusInternalServerError, "Something went wrong")
return
}
if comments == nil {
comments = []models.Comment{}
}
SendResponse(w, http.StatusOK, map[string]interface{}{
"data": comments,
})
}
好的,我想出了如何让它发挥作用。
我添加了这个中间件,它将请求上下文与 headers traceID、spanID 和 traceFlags 同步。
在此之后,我们可以根据需要创建跟踪器和跨度。
func Tracing(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
traceID, _ := trace.TraceIDFromHex(r.Header["X-B3-Traceid"][0])
spanID, _ := trace.SpanIDFromHex(r.Header["X-B3-Spanid"][0])
var traceFlags trace.TraceFlags
if r.Header["X-B3-Sampled"][0] == "1" {
traceFlags = trace.FlagsSampled
}
spanContext := trace.NewSpanContext(trace.SpanContextConfig{
TraceID: traceID,
SpanID: spanID,
TraceFlags: traceFlags,
})
ctx := trace.ContextWithSpanContext(r.Context(), spanContext)
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
我有 krakend apigateway,它使用 opentracing 并发送请求 headers 作为 X-B3-... 进行跟踪,我的服务使用 opentelemetry。
这就是我现在在 jaeger 上看到的内容。
enter image description here
enter image description here
我希望服务跨度在 apigateways 下。
我做过的解决方法:
这是使用 chi 路由器的请求的确切处理程序。
func (env *Env) getCommentForBlogRouter(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
keys := []string{"X-B3-Traceid", "X-B3-Spanid", "X-B3-Sampled"}
var carrier propagation.HeaderCarrier = propagation.HeaderCarrier{}
for _, k := range keys {
carrier.Set(strings.ToLower(k), r.Header[k][0])
}
var propagator propagation.TextMapPropagator = otel.GetTextMapPropagator()
ctx = propagator.Extract(ctx, carrier)
// fmt.Println(ctx)
tr := otel.Tracer("Handler: blog-comments")
ctx, span := tr.Start(ctx, "handler span")
defer span.End()
blogId := r.URL.Query().Get("blog-id")
span.SetAttributes(attribute.Key("blog-id").String(fmt.Sprint(blogId)))
var spanDB trace.Span
ctx, spanDB = tr.Start(ctx, "Select row")
comments, err := env.comments.GetForBlog(blogId)
spanDB.End()
var spanRes trace.Span
_, spanRes = tr.Start(ctx, "Sending Response")
defer spanRes.End()
if err != nil {
fmt.Println(err)
SendError(w, http.StatusInternalServerError, "Something went wrong")
return
}
if comments == nil {
comments = []models.Comment{}
}
SendResponse(w, http.StatusOK, map[string]interface{}{
"data": comments,
})
}
好的,我想出了如何让它发挥作用。 我添加了这个中间件,它将请求上下文与 headers traceID、spanID 和 traceFlags 同步。 在此之后,我们可以根据需要创建跟踪器和跨度。
func Tracing(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
traceID, _ := trace.TraceIDFromHex(r.Header["X-B3-Traceid"][0])
spanID, _ := trace.SpanIDFromHex(r.Header["X-B3-Spanid"][0])
var traceFlags trace.TraceFlags
if r.Header["X-B3-Sampled"][0] == "1" {
traceFlags = trace.FlagsSampled
}
spanContext := trace.NewSpanContext(trace.SpanContextConfig{
TraceID: traceID,
SpanID: spanID,
TraceFlags: traceFlags,
})
ctx := trace.ContextWithSpanContext(r.Context(), spanContext)
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}