前言在上一篇文章中,我们介绍了OpenTelemetry的各种使用方法,然后当你真正自己访问的时候,可能会有这样的一个问题“接入调用链需要引入SDK,我们线上应用那么多,非得改成猴年”的问题,忍不住开始怀疑人生了,然后我没有像开始时那样积极访问调用链。确实,如前所述,SDK的形式对于已经在线稳定运行的应用来说,往往是一个沉重的改造负担。不仅麻烦而且后期升级也很困难。如果SDK存在BUG,后续修复也会变得困难。但是,调用链技术的发展已经比较成熟。对于Java,JavaAgent技术可以帮助实现调用链的非侵入式访问。JavaAgent什么是JavaAgentJavaAgent一般可以称为探针,是一种可以在Java应用程序启动前和运行过程中修改应用程序字节码的技术。通过在启动项中添加-javaagent:path/to/agent.jar来使用特定的Agent。JavaAgent的优点JavaAgent可以用来无侵入地修改应用程序代码,应用程序本身不需要修改。并且由于JavaAgent是基于字节码修改的,所以非常适合应用在AOP领域。具体JavaAgent的细节这里不再赘述。以后如果大家有兴趣,我可以再写一篇相关的介绍文章。OpenTelemetryJavaInstrumentation简介opentelemetry-java-instrumentation是属于OpenTelemetry系列的一个项目。本项目是官方基于JavaAgent实现非侵入式OpenTelemetry访问的Agent项目。使用方法很简单:java-javaagent:path/to/opentelemetry-javaagent.jar-jarmyapp.jar下载opentelemetry-javaagent.jar,然后使用上面的命令运行即可。启动成功后,OpenTelemetry可以直接连接成功,不需要对应用本身的代码做任何修改。虽然启动项参数配置只要连接Agent然后简单启动就成功了,但是在实际应用中是远远不够的。需要一些配置才能让我们的调用链完成访问。采集器地址首先,我们在上一篇文章中提到,客户端产生的数据最终会发送到服务端的采集器进行统一采集整理,从而处理完整的调用链信息。所以实际上我们需要在客户端配置服务器Collector的地址。Agent内部默认的采集器地址是http://localhost:4317,我们配置自己的采集器地址。Trace、Metrics、Logs的采集器地址可自行配置。这里以Trace配置为例:otel.traces.exporter用于配置数据输出的exporter。默认是otlp,但是jaeger、zipkin等在支持的范围内,大家可以根据自己的需要进行配置。otel.exporter.otlp.trace.endpoint用于配置具体的采集端点地址。请注意,此配置仅对otlp有效。如果是jaeger或者其他,需要自己使用其他配置。一般来说:gRPC协议使用4317端口,http协议使用4318端口(推荐使用gRPC)。otel.metrics.exporter是metrics的配置。这里必须特别提醒一下,这个值在旧版本中默认为none,即不开放。但是在较新的版本中,这个值默认变成了otlp,所以需要提醒的是,如果不需要metrics的能力,需要在新版本中手动将这个值设置为none。服务名使用otel.service.name配置服务名,这个名字后面会用到很多次,最好配置正确。插件开启和关闭使用otel.instrumentation.*.enabled来配置插件的开启和关闭,例如:otel.instrumentation.kafka.enabled可以用来配置kafka组件的开关。Agent中内置了很多Instrumentation(可以理解为插件或者乐器)。您不一定想要所有这些插件,因此您可以使用此配置来自定义您需要使用的插件列表。上面列出的是一些你必须关注的配置。如果需要扩展更多,启用更多功能,使用更多配置,可以参考文档instrumentation。我们可以简单的把instrumentation理解为插件。说白了,Agent调用链强大的数据采集能力,是一个又一个Instrumentation支撑的。每个不同的SDK都需要自定义Instrumentation来支持其调用链能力。OpenTelemetry丰富的Instrumentation库为完整的调用链功能提供了很好的可用性。这是目前支持的库列表LoggerMDC如果想在日志中直接绑定,看到TraceId和SpanId,可以使用Logger的MDC能力。Agent中默认开启了日志的Instrumentation组件,其中的MDC相关组件实现了传递trace信息的能力,所以可以直接使用%mdc{trace_id}%mdc{span_id}%mdc{trace_flags}输出跟踪相关信息。比如在logback中可以这样写(%mdc和%X是等价的):
