5

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 Answers1

7

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
  • 1
    We can use `propagator.Extract` right. Just like how HTTP request traces are propagated. Create a `propagation.TextMapCarrier` and set trace related keys and values received from message and `propagator.Extract`. Ref: https://github.com/open-telemetry/opentelemetry-go-contrib/blob/6feda8333ee4608534f51a0bcd3e2fe8b60ab900/instrumentation/github.com/gin-gonic/gin/otelgin/gintrace.go#L62 – Bharat Gadde May 09 '22 at 18:52