go - 如何从字符串 traceid 创建 opentelemetry 跨度

标签 go concurrency trace open-telemetry

我知道我们要使用上下文传播来获取创建为彼此子项的父 traceid 和跨度,但我的发布者使用的是 header (nats 而不是 http)

我的消息代理使用 header ,我在出站请求中将 traceid 和 spanid 设置为 header ,发送消息,然后订阅者应该能够创建一个新的跨度,将父 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 的 header 值

如何使用 traceid 在订阅者端构建上下文/跨度?

我相信我可以在 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

最佳答案

知道了!

顺便说一句,输入 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

关于go - 如何从字符串 traceid 创建 opentelemetry 跨度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70378025/

相关文章:

html - 如何在 gin gonic 框架(golang)中通过 c.HTML() 将函数传递给模板

entity-framework - 在 Entity Framework 中处理并发

go - 为什么我需要睡两次才能看到 goroutines?

c# - 如何将 Socket 和 WinAPI 跟踪添加到 .NET Core 控制台应用程序?

azure - 从应用程序洞察中删除跟踪

arrays - 生成具有整数范围的数组

go - 为什么只使用新函数创建的相同结构的两个指针比较相等

python - 如何编写多线程函数来同时处理不同的任务?

c++ - 如何分析/跟踪已编译的 C++ 应用程序

map - 无法从 map 分配给结构成员