如何从字符串traceid创建opentelemetry范围

问题描述 投票:0回答:2

我知道我们要使用上下文传播来获取作为彼此子级创建的父级 Traceid 和 Span,但我的发布者正在使用标头(nats 不是 http)

我的消息代理使用标头,我将traceid和spanid设置为出站请求中的标头,发送消息,然后订阅者应该能够创建一个新的span,将父traceid设置为请求中的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
go concurrency trace open-telemetry
2个回答
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
}

然后你调用包含跟踪和跨度 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

0
投票

这是我用来创建与另一个微服务中创建的跟踪/跨度关联的跨度的 java 函数:

import io.opentelemetry.api.trace.*;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;

private Span createSpanLinkedToParent(String traceId, String spanId) {

    SpanContext remoteContext = SpanContext.createFromRemoteParent(
            traceId,
            spanId,
            TraceFlags.getSampled(),
            TraceState.getDefault());


    Tracer t = otel.getTracer("second-service");
    SpanBuilder sb= t.spanBuilder("some-operation");
    sb.setParent(Context.current().with(Span.wrap(remoteContext)));
    return sb.startSpan();
}

(使用 OpenTelemetry 1.36 测试)

© www.soinside.com 2019 - 2024. All rights reserved.