导出器

In order to visualize and analyze your telemetry, you will need to export your data to an OpenTelemetry Collector or a backend such as Jaeger, Zipkin, Prometheus or a vendor-specific one.

As part of OpenTelemetry Java you will find many exporters being available. Among them, the OpenTelemetry Protocol (OTLP) exporters provide the best experience for you as an end-user, since it is a general-purpose telemetry data delivery protocol designed in the scope of the OpenTelemetry project.

To learn more about the OTLP protocol, you can read the OTLP Specification.

Below you will find some introductions on how to set up exporters for OTLP and other common protocols in your code.

OTLP

要将跟踪数据发送到OTLP端点(如collector或Jaeger),您需要使用opentelemetry-exporter-otlp

OTLP Artifacts

有多个OTLP选项可供选择,每个选项都适用于不同的用例。对于大多数用户来说,默认的Artifact即可满足需求并且最简单:

dependencies {
    implementation 'io.opentelemetry:opentelemetry-exporter-otlp:1.31.0'
}
<project>
    <dependencies>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-exporter-otlp</artifactId>
        </dependency>
    </dependencies>
</project>

在底层,支持两种不同的协议选项,各自具有不同的“发送器”实现。

  • grpc - OTLP导出器的gRPC实现,由OtlpGrpcSpanExporterOtlpGrpcMetricExporterOtlpGrpcLogRecordExporter表示。
  • http/protobuf - 基于HTTP发送的OTLP导出器的protobuf编码实现,由OtlpHttpSpanExporterOtlpHttpMetricExporterOtlpHttpLogRecordExporter表示。

发送器是一种抽象,允许不同的gRPC / HTTP客户端实现来满足OTLP的约定。无论发送器实现如何,都会使用相同的导出器类。当检测到类路径上的发送器实现时,自动使用该发送器实现。以下详细描述了发送器实现:

  • {groupId}:{artifactId} - 发送器描述。
  • io.opentelemetry:opentelemetry-exporter-sender-okhttp - 默认发送器,与opentelemetry-exporter-otlp一起自动包含,并与OpenTelemetry Java代理捆绑在一起。这包括了基于OkHttp的实现,适用于grpchttp/protobuf版本的协议,对大多数用户来说是合适的。但是,OkHttp对于一些环境而言,具有对Kotlin的传递性依赖关系,这是有问题的。
  • io.opentelemetry:opentelemetry-exporter-sender-jdk - 该发送器包含了基于JDK 11+的HttpClient实现,适用于http/protobuf版本的协议。它不需要额外的依赖,但需要Java 11+。要使用,请包含该Artifact并显式排除默认的io.opentelemetry:opentelemetry-exporter-sender-okhttp依赖项。
  • io.opentelemetry:opentelemetry-exporter-sender-grpc-managed-channel - 该发送器包含了基于grpc-java的实现,适用于grpc版本的协议。要使用,请包含该Artifact,显式排除默认的io.opentelemetry:opentelemetry-exporter-sender-okhttp依赖项,并包含一个gRPC传输实现之一。

用法

接下来,配置导出器以指向OTLP端点。

如果您使用了SDK自动配置,您只需更新环境变量即可:

env OTEL_EXPORTER_OTLP_ENDPOINT=http://example:4317 java -jar ./build/libs/java-simple.jar

注意,在使用OTLP导出时,您不需要设置OTEL_TRACES_EXPORTEROTEL_METRICS_EXPORTEROTEL_LOGS_EXPORTER,因为它们的默认值是otlp

手动配置的情况下,您可以按照以下示例更新应用程序:

package otel;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.Banner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;

@SpringBootApplication
public class DiceApplication {
  public static void main(String[] args) {
    SpringApplication app = new SpringApplication(DiceApplication.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
  }

  @Bean
  public OpenTelemetry openTelemetry() {
    Resource resource = Resource.getDefault().toBuilder().put(SERVICE_NAME, "dice-server").put(SERVICE_VERSION, "0.1.0").build();

    SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
            .addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder().build()).build())
            .setResource(resource)
            .build();

    SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
            .registerMetricReader(PeriodicMetricReader.builder(OtlpGrpcMetricExporter.builder().build()).build())
            .setResource(resource)
            .build();

    SdkLoggerProvider sdkLoggerProvider = SdkLoggerProvider.builder()
            .addLogRecordProcessor(
                    BatchLogRecordProcessor.builder(OtlpGrpcLogRecordExporter.builder().build()).build())
            .setResource(resource)
            .build();

    OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
        .setTracerProvider(sdkTracerProvider)
        .setMeterProvider(sdkMeterProvider)
        .setLoggerProvider(sdkLoggerProvider)
        .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
        .buildAndRegisterGlobal();

    return openTelemetry;
  }
}

为了快速查看导出的跟踪信息,您可以在docker容器中启动启用了OTLP的Jaeger:

docker run -d --name jaeger \
  -e COLLECTOR_OTLP_ENABLED=true \
  -p 16686:16686 \
  -p 4317:4317 \
  -p 4318:4318 \
  jaegertracing/all-in-one:latest
最后修改 December 10, 2023: translate (a4350d6e)