如何从字符串 traceid 创建 opentelemetry span
Posted
技术标签:
【中文标题】如何从字符串 traceid 创建 opentelemetry span【英文标题】:How to create opentelemetry span from a string traceid 【发布时间】:2022-01-19 11:38:55 【问题描述】:我知道我们要使用上下文传播来获取父 traceid 和跨度创建为彼此的子级,但我的发布者使用标头(nats 不是 http)
我的消息代理使用标头,我在出站请求中设置 traceid 和 spanid 作为标头,发送消息,然后订阅者应该能够创建一个新跨度,将父 traceid 设置为来自要求。链接它们
我的出站请求如下所示:
msg := new(nats.Msg)
msg.Data = []byte("new request being sent!")
msg.Subject = subject
getTraceID := requestSpan.SpanContext().TraceID().String()
header := make(nats.Header)
msg.Header = header
header.Set("traceid", getTraceID)
getSpanID := requestSpan.SpanContext().SpanID().String(
header.Set("spanid", getSpanID)
msg.Header = header
reply, err := nc.RequestMsg(msg, time.Duration(5*time.Second))
这很有效,在订阅者端,我可以获得跟踪和跨度 ID 的标头值
如何使用 traceid 在订阅者端构建上下文/跨度?
我相信我可以在频道内做这样的事情:
var traceID trace.TraceID
traceID, err = trace.TraceIDFromHex(request.TraceID)
if err != nil
fmt.Println("error: ", err)
continue
var spanID trace.SpanID
spanID, err = trace.SpanIDFromHex(request.SpanID)
if err != nil
fmt.Println("error: ", err)
continue
spanContext := trace.NewSpanContext(trace.SpanContextConfig
TraceID: traceID,
SpanID: spanID,
TraceFlags: 01,
)
ctx := context.Background()
ctx = trace.ContextWithSpanContext(ctx, spanContext)
var requestInLoopSpan trace.Span
ctx2, requestInLoopSpan := otel.Tracer("requestInLoop").Start(ctx, "requestInLoopSpan")
requestInLoopSpan.AddEvent("processing....") // NOT WORKING
【问题讨论】:
【参考方案1】:知道了!
顺便说一句,输入 NewRequest:
type NewRequest struct
Requestid string `json: "requestid"`
TraceID string
SpanID string
您需要将构建 spanContext 的代码封装在一个函数中:
func constructNewSpanContext(request NewRequest) (spanContext trace.SpanContext, err error)
var traceID trace.TraceID
traceID, err = trace.TraceIDFromHex(request.TraceID)
if err != nil
fmt.Println("error: ", err)
return spanContext, err
var spanID trace.SpanID
spanID, err = trace.SpanIDFromHex(request.SpanID)
if err != nil
fmt.Println("error: ", err)
return spanContext, err
var spanContextConfig trace.SpanContextConfig
spanContextConfig.TraceID = traceID
spanContextConfig.SpanID = spanID
spanContextConfig.TraceFlags = 01
spanContextConfig.Remote = false
spanContext = trace.NewSpanContext(spanContextConfig)
return spanContext, nil
然后你称之为传递包含跟踪和跨度ID的东西
然后使用函数返回的 spanContext 来丰富上下文:
spanContext, err := constructNewSpanContext(request)
if err != nil
fmt.Println("ERROR: ", err)
fmt.Println("IS VALID? ", spanContext.IsValid()) // check if okay
requestContext := context.Background()
requestContext = trace.ContextWithSpanContext(requestContext, spanContext)
var requestInLoopSpan trace.Span
childContext, requestInLoopSpan := otel.Tracer("inboundmessage").Start(requestContext, "requestInLoopSpan")
requestInLoopSpan.AddEvent("processing....") // WORKING
【讨论】:
以上是关于如何从字符串 traceid 创建 opentelemetry span的主要内容,如果未能解决你的问题,请参考以下文章
OpenTelemetry Python - 如何将新跨度实例化为给定 traceid 的子跨度
如何在 Hystrix Observables 中传递 traceIds?
Spring Cloud Sleuth - 获取当前的 traceId?