OpenTelemetry 桥接编辑

Elastic APM OpenTelemetry 桥接允许使用 OpenTelemetry API 创建 Elastic APM TransactionsSpans。OpenTelemetry 指标也会被收集。换句话说,它将对 OpenTelemetry API 的调用转换为 Elastic APM,从而允许重用现有的检测。

虽然可以使用 OpenTelemetry API 进行手动检测以适应 Elastic APM Java 代理,但无法在 Elastic APM Java 代理的上下文中使用来自 opentelemetry-java-instrumentation 的检测。
但是,您可以使用 opentelemetry-java-instrumentation(也称为 OpenTelemetry Java 代理)并将数据发送到 APM 服务器。有关更多详细信息,请参阅 OpenTelemetry 集成文档

服务的第一个跨度将被转换为 Elastic APM Transaction,后续跨度将映射到 Elastic APM Span

入门编辑

使用 OpenTelemetry API 桥接的入门第一步是声明对 API 的依赖项

pom.xml。

<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-api</artifactId>
    <version>${version.opentelemetry}</version>
</dependency>

build.gradle。

compile "io.opentelemetry:opentelemetry-api:$openTelemetryVersion"

所需的最低 OpenTelemetry 版本为 1.4.0。

初始化跟踪器编辑

桥接本身不需要单独的依赖项。Java 代理会挂接到 GlobalOpenTelemetry 以返回其自己的 OpenTelemetry 实现,该实现连接到代理的内部跟踪器。

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Tracer;

OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
Tracer tracer = openTelemetry.getTracer("");

要禁用该行为,并依赖于 GlobalOpenTelemetry 的标准发现机制,您可以将 disable_instrumentations 设置为 opentelemetry

向跨度添加自定义元数据编辑

如果您喜欢 Elastic APM Java 代理的自动检测创建的跨度,但您想添加一个自定义标签,您可以使用 OpenTelemetry API 获取当前跨度并调用 setAttribute

Span.current().setAttribute("foo", "bar");

自定义跨度跟踪编辑

我们利用 setAttribute() API 不仅 添加自定义元数据,而且还作为通过下面列出的相应自定义属性来自定义一些特殊跟踪功能的一种方式。此类属性不会添加到跨度元数据中。例如

Span.current().setAttribute("co.elastic.discardable", false);
co.elastic.discardable编辑

默认情况下,跨度可能会被丢弃,例如,如果 span_min_duration ( [1.16.0] 在 1.16.0 中添加。 ) 已设置且跨度未超过配置的阈值。使用此属性通过将其设置为 false 来使跨度不可丢弃。

使跨度不可丢弃会隐式地使所有活动跨度的整个堆栈也不可丢弃。子跨度仍然可以被丢弃。

值类型 默认值

co.elastic.discardable

布尔值

true

创建活动跨度的子跨度编辑

这是一个向 Java 代理的自动检测创建的跨度添加自定义跨度的示例。

// if there's an active span, it will implicitly be the parent
// in case there's no parent, the custom span will become a Elastic APM transaction
Span custom = tracer.spanBuilder("my custom span").startSpan();
// making your child the current one makes the Java agent aware of this span
// if the agent creates spans in the context of myTracedMethod() (such as outgoing requests),
// they'll be added as a child of your custom span
try (Scope scope = custom.makeCurrent()) {
    myTracedMethod();
} catch (Exception e) {
    custom.recordException(e);
    throw e;
} finally {
    custom.end();
}

要详细了解 OpenTelemetry API,请访问 他们的文档

指标编辑

此功能处于技术预览阶段,可能会在将来的版本中更改或删除。Elastic 将努力解决任何问题,但技术预览中的功能不受官方 GA 功能的支持 SLA 的约束。

Elastic APM Java 代理支持收集通过 OpenTelemetry 定义的指标。您可以使用 OpenTelemetry APIOpenTelemetry SDK(如果您需要更多自定义)。

在这两种情况下,Elastic APM 代理都将遵守 OpenTelemetry 指标的 disable_metricsmetrics_interval 设置。

您可以使用 custom_metrics_histogram_boundaries 设置来自定义直方图桶边界。或者,您可以在提供自己的 MeterProvider 时使用 OpenTelemetry Views 来按指标定义直方图桶。请注意,custom_metrics_histogram_boundaries 仅适用于 API 使用。如果您带来了自己的 MeterProvider,因此也带来了自己的 OpenTelemetry SDK,则该设置仅适用于 1.32.0 之前的 SDK 版本。

API 使用编辑

您可以通过 GlobalOpenTelemetry 定义指标并报告指标数据

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;

Meter myMeter = GlobalOpenTelemetry.getMeter("my_meter");
LongCounter counter = meter.counterBuilder("my_counter").build();
counter.add(42);

我们不需要您在 GlobalOpenTelemetry 中自己设置 OpenTelemetry MeterProvider。Elastic APM Java 代理将检测是否未配置 MeterProvider,在这种情况下将自动提供自己的 MeterProvider。如果您提供了自己的 MeterProvider(请参阅 使用自定义 MeterProvider),代理将使用提供的实例。

使用自定义 MeterProvider编辑

在某些情况下,仅使用 OpenTelemetry API 用于指标 可能不够灵活。一些用例示例是

  • 使用 OpenTelemetry 视图
  • 除了 Elastic APM 之外,还将指标导出到其他工具(例如 prometheus)

对于这些用例,您只需设置 OpenTelemetry SDK MeterProvider。Elastic APM 代理将通过检测安装额外的 MetricExporter,该检测器将指标数据发送到 Elastic APM。这需要使用 OpenTelemetry 版本 1.16.0 或更高版本。

要创建自己的 MeterProvider,您需要将 OpenTelemetry Metric SDK 添加为项目的依赖项

pom.xml。

<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk-metrics</artifactId>
    <version>${version.opentelemetry}</version>
</dependency>

build.gradle。

compile "io.opentelemetry:opentelemetry-sdk-metrics:$openTelemetryVersion"

之后,您可以创建和使用自己的 MeterProvider,如下所示

import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.prometheus.PrometheusHttpServer;
import io.opentelemetry.sdk.metrics.InstrumentSelector;
import io.opentelemetry.sdk.metrics.View;

//Elastic APM MetricReader will be registered automatically by the agent
SdkMeterProvider meterProvider = SdkMeterProvider.builder()
    .registerMetricReader(PrometheusHttpServer.create())
    .registerView(
        InstrumentSelector.builder().setName("my_histogram").build(),
        View.builder().setAggregation(Aggregation.explicitBucketHistogram(List.of(1.0, 5.0))).build()
    )
    .build();

Meter testMeter = meterProvider.get("my_meter");
DoubleHistogram my_histogram = testMeter.histogramBuilder("my_histogram").build();

my_histogram.record(0.5);

注意事项编辑

并非所有 OpenTelemetry API 功能都受支持。

进程内上下文传播编辑

添加到当前上下文的条目,Context.current().with(...).makeCurrent() 无法通过 Context.current().get(...) 检索。

跨度引用编辑

跨度只能有一个父跨度 (SpanBuilder#setParent)

行李编辑

行李支持已在版本 1.41.0 中添加。从 1.43.0 开始,您可以通过 baggage_to_attach 配置选项自动将行李附加为跨度、事务和错误属性。

事件编辑

事件会被静默丢弃,例如 Span.current().addEvent("my event")

注释编辑

OpenTelemetry 检测注释1.45.0 开始支持。