当前位置: 首页 > 知识库问答 >
问题:

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

郭博涉
2023-03-14

我知道我们将使用上下文传播来获取作为彼此的子级创建的父跟踪和跨度,但我的发布者正在使用标头(nats不是超文本传输协议

我的message broker使用标头,我正在将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在订阅者端构建上下文/span?

我相信我可以在通道内做这样的事情:

    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个答案

宋臻
2023-03-14

拿到了!

btw类型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
}

然后你称之为传递包含痕迹和跨度标识的东西

然后使用函数返回的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
 类似资料:
  • 问题内容: 我正在尝试将String传递给我的。如何通过针对读者的“测试” 而不是来自读者的输入? 问题答案: 您可以如下修改代码

  • 问题内容: 我正在遵循指南,它为我提供了以下代码: 我想知道的是如何仍然可以创建一个,但是不要读取文件的内容,而要使用一个已有的变量。 问题答案: 使用而不是。 请参阅StringReader的文档 例:

  • 问题内容: 我不习惯在Java中使用流-如何从中创建流? 问题答案: 干得好: 更新 对于多字节支持使用(感谢 Aaron Waibel 的评论): 请参阅ByteArrayInputStream手册。 在上面的String#getBytes(charset)方法中使用charset参数是安全的。 在JDK 7+之后,您可以使用 而不是硬编码的编码字符串:

  • 本文向大家介绍如何从Java ArrayList创建字符串?,包括了如何从Java ArrayList创建字符串?的使用技巧和注意事项,需要的朋友参考一下 要将ArrayList的内容转换为String,创建一个StringBuffer对象,将ArrayList的内容附加到该对象,最后使用toString()方法将StringBuffer对象转换为String 。 示例 输出结果

  • 问题内容: 我有一个字符串形式: 依此类推(长度会有所不同)。由此创建字典的最简单方法是什么? 我知道我可以拆分,但是我无法获得正确的语法。如果我分开,那么我如何将这两个部分结合在一起? 对此进行迭代似乎很痛苦。 问题答案: 编辑:下一个解决方案是当您想要将值作为整数,我认为这是您想要的。

  • 问题内容: 这是一个非常基本的问题。但是我无法在Java文档中找到答案,也无法对其进行测试,因为我不知道这种方法是否存在。 我可能会收到一个URL字符串,可能是 要么 然后我会得到可能以开头的资源路径,或者就像 我正在看课,可以处理第一部分,即获取hostURL使其成为HTTPS或HTTP请求。问题是附加资源路径。我必须手动检查它的第一个字母是否存在。我想知道此功能是否已经在某个类中。 问题答案: