如何从字符串 traceid 创建 opentelemetry span?

huangapple go评论75阅读模式
英文:

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

huangapple
  • 本文由 发表于 2021年12月16日 19:13:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/70378025.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定