英文:
Proper way of extracting tracer from request Headers for opentelemetry
问题
我有一个使用opentracing的krakend apigateway,并且将请求头作为X-B3-...发送以进行跟踪,而我的服务使用opentelemetry。这是我现在在jaeger上的情况。
我希望服务的跨度能够归属于apigateway的跨度。
我已经做了以下解决方法:
这是使用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,
})
}
英文:
I have krakend apigateway which is using opentracing and sending req headers as X-B3-... for tracing and my service is using opentelemetry.
This is what I'm having right now on jaeger.
enter image description here
I want the service spans to come under the apigateways'.
Workaround I have done:
This is the exact handler for the request using chi router.
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,
})
}
答案1
得分: 2
好的,以下是翻译好的内容:
好的,我找到了如何使其工作的方法。
我添加了这个中间件,它将使用头部的 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)
})
}
希望对你有帮助!
英文:
Ok, I figured out how to make it work.
I added this middleware and it will sync the request context with the headers traceID, spanID and traceFlags.
After this we are good to create tracer and spans as we want.
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)
})
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论