OpenTelemetry 是工具、API 和 SDK 的集合。使用它来检测、生成、收集和导出遥测数据(指标、日志和跟踪),以帮助您分析软件的性能和行为。本文将介绍如何使用 Java Agent 获得自动埋点能力的同时,使用 Java SDK 添加自定义业务埋点。
步骤一:获取接入点和 Token
进入 应用性能监控控制台 应用监控 > 应用列表页面,单击接入应用,在接入应用时选择 Java 语言与 OpenTelemetry 的数据采集方式。
在选择接入方式步骤获取您的接入点和 Token,如下图所示:
上报方式说明
内网上报:使用此上报方式,您的服务需运行在腾讯云 VPC 。通过 VPC 直接联通,在避免外网通信的安全风险同时,可以节省上报流量开销。
外网上报:当您的服务部署在本地或非腾讯云 VPC 内,可以通过此方式上报数据。请注意外网通信存在安全风险,同时也会造成一定上报流量费用。
步骤二:下载 opentelemetry-javaagent.jar
步骤三:修改上报参数
修改 Java 启动的 JVM 参数上报链路数据。
-javaagent:/path/to/opentelemetry-javaagent.jar //请将路径修改为您文件下载的实际地址。-Dotel.resource.attributes=service.name=<appName>,token=<token>-Dotel.exporter.otlp.endpoint=<接入点>
说明
如果您选择使用 OpenTelemetry Collector 转发,则需删除 -Dotel.exporter.otlp.headers=Authentication=<token> 并修改<接入点>为您本地部署的服务地址。
步骤四:引入 Maven POM 依赖
<dependencies><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-api</artifactId></dependency><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-sdk-trace</artifactId></dependency><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-exporter-otlp</artifactId></dependency><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-sdk</artifactId></dependency><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-extension-annotations</artifactId></dependency><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId><version>1.9.0-alpha</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-bom</artifactId><version>1.9.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
步骤五:获得 OpenTelemetry Tracer
OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();Tracer tracer = openTelemetry.getTracer("instrumentation-library-name", "1.0.0");
步骤六:修改埋点代码
/*** 参考文档:https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/docs/contributing*/@RestController@RequestMapping("/user")public class UserController {@Autowiredprivate UserService userService;private ExecutorService es = Executors.newFixedThreadPool(5);// 第三种:获得Tracer纯手工埋点private void biz() {Tracer tracer = OpenTelemetrySupport.getTracer();Span span = tracer.spanBuilder("biz (manual)").setParent(Context.current().with(Span.current())) // 可选,自动设置.startSpan();try (Scope scope = span.makeCurrent()) {span.setAttribute("biz-id", "111");es.submit(new Runnable() {@Overridepublic void run() {Span asyncSpan = tracer.spanBuilder("async").setParent(Context.current().with(span)).startSpan();try {Thread.sleep(1000L); // some async jobs} catch (Throwable e) {}asyncSpan.end();}});Thread.sleep(1000); // fake biz logicSystem.out.println("biz done");OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();openTelemetry.getPropagators();} catch (Throwable t) {span.setStatus(StatusCode.ERROR, "handle biz error");} finally {span.end();}}// 第二种:基于标签手工埋点@WithSpanprivate void child(@SpanAttribute("user.type") String userType) {System.out.println(userType);biz();}// 第一种:自动埋点,基于API手工添加信息@RequestMapping("/async")public String async() {System.out.println("UserController.async -- " + Thread.currentThread().getId());Span span = Span.current();span.setAttribute("user.id", "123456");userService.async();child("vip");return "async";}}