首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用OTEL Java代理,如何在不使用@WithSpan的情况下创建新上下文

使用OTEL Java代理,如何在不使用@WithSpan的情况下创建新上下文
EN

Stack Overflow用户
提问于 2021-03-23 02:05:32
回答 1查看 250关注 0票数 0

opentelemetry-javaagent-all代理(版本0.17.0和1.0.1)一直是向我的Java应用程序添加跟踪信息的起点。自动检测的效果很好。

我的一些应用程序不能被自动检测。对于应用程序的这一部分,我首先向代码中的有趣位置添加了@WithSpan注释。

现在,我已经达到了使用简单的@WithSpan注释所能达到的极限。然而,我的应用程序底层的框架允许我注册在某些点调用的回调--例如,我可以提供在客户端连接/断开连接时得到通知的处理程序。

我认为我需要的是在调用Foo.onConnect()时启动一个新的跨度,并将其设置为对应于每个请求的Span的父级。

代码语言:javascript
复制
public class Foo {

    void onConnect() {
        // called when a client connects to my app
        // Here I want to create a Span that will be the parent of the Span created in
        // Foo.processEachRequest().
    }

    @WithSpan
    public void processEachRequest() {
        // works, but since it is called for each request... each span is in a separate Trace
    }

    void onDisconnect() {
        // called when the client disconnects from my app
        // Here I can end the parent Span.
    }
}

其他想法--都没成功:

1-最明显的解决方案是在底层框架中添加@WithSpan注释。由于各种原因,这将不是一个实际的前进道路。

2-下一个选择可能是寻找一种方法来告诉javaagent关于我的底层框架中的方法。( New Relic代理可以做这样的事情。)无论如何,这似乎不是开放遥测代理的一个功能。

因此,我剩下的工作就是寻找一种使用回调来完成此任务的方法,如上所述。有没有办法做到这一点?

EN

回答 1

Stack Overflow用户

发布于 2021-04-28 02:48:17

这应该可以通过手动检测您的代码。您将使用OpenTelemetry的Tracer接口,如OpenTelemetry Java docs中所述。

这应该会给你一个大概的概念:

代码语言:javascript
复制
public class Foo {
    private Span parentSpan; // you might need a Map/List/Stack here

    void onConnect() {
        Tracer tracer =
                openTelemetry.getTracer("instrumentation-library-name", "1.0.0");
        Span span = tracer.spanBuilder("my span").startSpan();
        this.parentSpan = span; // might need to store span per request/client/connection-id
    }

    public void processEachRequest() {
        final Span parent = this.lookupParentSpan();
        if (parent != null) {
            try (Scope scope = span.makeCurrent()) {
              yourLogic();
            } catch (Throwable t) {
              span.setStatus(StatusCode.ERROR, "error message");
              throw t;
            }
        } else {
            yourLogic();
        }
    }

    void onDisconnect() {
        final Span parent = this.lookupParentSpan();
        if (parent != null) {
            parent.end();
        }
    }

    private Span lookupParentSpan() {
        // you probably want to lookup the span by client or connection id from a (weak) map
        return this.parentSpan;
    }
}

注意:您必须保证跨度始终是结束的并且不会泄漏。确保正确地确定您的范围,并最终调用Span#end()

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66751548

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档