本文介绍通过OpenTelemetry Java SDK将Java应用的Trace数据接入到日志服务的操作步骤。
前提条件
已创建Trace实例。更多信息,请参见创建Trace实例。
已安装Java 8及以上版本的开发环境。
说明建议使用JDK 8u252及以上版本。
(推荐)方案一:通过Java Agent自动上传Trace数据
目前有数十种Java框架支持通过Java Agent自动上传Trace数据到日志服务,详细的Java框架列表请参见SupportedLibraries。
Java Agent上传方式不支持和其他类似的方案(例如SkyWalking Agent、Zipkin Agent等)同时使用,可能会产生未定义行为。
下载最新版本Java Agent。更多信息,请参见OpenTelemetry Release列表。
集成Java Agent。
此处以JVM的-javaagent为例,配置相关的环境变量。更多信息,请参见opentelemetry-java-instrumentation。其中,代码中的变量(例如${endpoint}、${project}等)需根据实际情况替换。
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc export OTEL_EXPORTER_OTLP_ENDPOINT=https://${endpoint} export OTEL_EXPORTER_OTLP_COMPRESSION=gzip export OTEL_EXPORTER_OTLP_HEADERS=x-sls-otel-project=${project},x-sls-otel-instance-id=${instance},x-sls-otel-ak-id=${access-key-id},x-sls-otel-ak-secret=${access-key-secret} java -javaagent:/path/to/opentelemetry-javaagent-all.jar -Dotel.resource.attributes=service.namespace=${service.namespace},service.name=${service},service.version=${version},host.name=${host},deployment.environment=${environment} -jar /path/to/your/app.jar
表 1. 变量说明
变量
说明
示例
${endpoint}
日志服务Project的接入地址,格式为${project}.${region-endpoint}:Port,其中:
${project}:日志服务Project名称。
${region-endpoint}:日志服务Project所在地域的访问域名,支持公网和阿里云内网(经典网络、VPC)。更多信息,请参见服务入口。
Port:网络端口,固定为10010。
test-project.cn-hangzhou.log.aliyuncs.com:10010
${project}
日志服务Project名称。
test-project
${instance}
Trace服务实例ID。更多信息,请参见创建Trace实例。
test-traces
${access-key-id}
阿里云账号AccessKey ID。
建议您使用只具备日志服务Project写入权限的RAM用户的AccessKey(包括AccessKey ID和AccessKey Secret)。授予RAM用户向指定Project写入数据权限的具体操作,请参见授权。如何获取AccessKey的具体操作,请参见访问密钥。
无
${access-key-secret}
阿里云账号AccessKey Secret。
建议您使用只具备日志服务Project写入权限的RAM用户的AccessKey。
无
${service.namespace}
服务归属的命名空间。
order
${service}
服务名。根据您的实际场景配置。
payment
${version}
服务版本号。建议按照va.b.c格式定义。
v0.1.2
${host}
主机名。
localhost
${environment}
部署环境。例如测试环境、生产环境。根据您的实际场景配置。
pre
方案二:手动构造Trace数据并上传
当您使用自建框架或有其他需求时,可以手动构造Trace数据并上传到日志服务。此处以Maven方式为例,更多信息,请参见Manual Instrumentation。示例代码,请参见OpenTelemetry Manual API Demo。
添加Maven依赖。
<dependencies> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-api</artifactId> </dependency> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-sdk</artifactId> </dependency> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-exporter-otlp</artifactId> </dependency> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-semconv</artifactId> <version>1.20.1-alpha</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-bom</artifactId> <version>1.20.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
添加初始化代码。
代码中的变量(例如${endpoint}、${project}等)需根据实际情况替换。关于变量的详细说明,请参见变量说明。
Resource resource = Resource.getDefault() .merge(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, "service-name"))) .merge(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAMESPACE, "namespace"))) .merge(Resource.create(Attributes.of(ResourceAttributes.SERVICE_VERSION, "1.0.0"))) .merge(Resource.create(Attributes.of(ResourceAttributes.HOST_NAME, "host-name"))); SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() .addSpanProcessor( BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder().setEndpoint("https://${endpoint}") // 配置.setEndpoint参数时,必须添加https://,例如https://test-project.cn-hangzhou.log.aliyuncs.com:10010。 .addHeader("x-sls-otel-project", "${project}") .addHeader("x-sls-otel-instance-id", "${instance}") .addHeader("x-sls-otel-ak-id", "${access-key-id}") .addHeader("x-sls-otel-ak-secret", "${access-key-secret}").build()).build()) .setResource(resource).build(); OpenTelemetry openTelemetry = OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider) .buildAndRegisterGlobal(); Tracer tracer = openTelemetry.getTracer("instrumentation-library-name", "1.0.0"); Span parentSpan = tracer.spanBuilder("parent").startSpan(); try { Span childSpan = tracer.spanBuilder("child").setParent(Context.current().with(parentSpan)).startSpan(); childSpan.setAttribute("test", "vllelel"); childSpan.end(); } finally { parentSpan.end(); }
常见问题
当您使用JDK 8u252之前版本时,Java Agent中可能出现Could not find TLS ALPN provider错误,如何处理?
您可以参见如下步骤解决:
执行如下命令添加相关的.jar包。
${youpath}为各个.jar包所在路径,请根据实际情况替换。
java -Xbootclasspath/p:${youpath}/netty-tcnative-boringssl-static-2.0.25.Final.jar -javaagent:${youpath}/opentelemetry-javaagent-all.jar -jar ${youpath}/demo2-0.0.1-SNAPSHOT.jar