英文:
How to create opentelemetry span from a string traceid
问题
我理解我们需要使用上下文传播来获取父追踪ID和创建的相互子级的跨度,但是我的发布者正在使用头部(而不是HTTP)。
我的消息代理使用头部,我在出站请求中设置了追踪ID和跨度ID作为头部,发送消息,然后订阅者应该能够创建一个新的跨度,将父追踪ID设置为请求中的追踪ID。将它们链接起来。
我的出站请求如下所示:
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的头部值。
在订阅者端如何使用追踪ID构建上下文/跨度?
我认为我可以在通道内做类似于这样的操作:
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
英文:
I understand that we're to use context propagation to get the parent traceids and spans created as children of each other, but my publisher is using headers (nats not http)
My message broker uses headers, which i'm setting a traceid and spanid as headers in the outbound request, sending the message, then the subscriber SHOULD be able to create a new span, setting the parent traceid to the traceid from the request. Linking them
My outbound request looks like:
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))
This works and on the subscriber side I can get the header values for the trace and span id
How do I construct a context/span on the subscriber side using the traceid?
I believed I could do something like this inside a channel:
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
得分: 7
明白!以下是翻译好的内容:
顺便说一下,输入 "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
}
然后你调用该函数,传入包含跟踪和 span ID 的内容。
然后你使用函数返回的 spanContext 来丰富上下文:
spanContext, err := constructNewSpanContext(request)
if err != nil {
fmt.Println("ERROR: ", err)
}
fmt.Println("IS VALID? ", spanContext.IsValid()) // 检查是否有效
requestContext := context.Background()
requestContext = trace.ContextWithSpanContext(requestContext, spanContext)
var requestInLoopSpan trace.Span
childContext, requestInLoopSpan := otel.Tracer("inboundmessage").Start(requestContext, "requestInLoopSpan")
requestInLoopSpan.AddEvent("processing....") // WORKING
英文:
GOT IT!
btw type NewRequest:
type NewRequest struct {
Requestid string `json: "requestid"`
TraceID string
SpanID string
}
You need to wrap the code that constructs the spanContext inside a function:
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
}
Then you call that passing in something that contains the trace and span ids
Then you use the returned spanContext from the function to enrich a context:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论