azure-monitor-opentelemetry-exporter-java
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAzure Monitor OpenTelemetry Exporter for Java
适用于Java的Azure Monitor OpenTelemetry Exporter
⚠️ DEPRECATION NOTICE: This package is deprecated. Migrate to.azure-monitor-opentelemetry-autoconfigureSee Migration Guide for detailed instructions.
Export OpenTelemetry telemetry data to Azure Monitor / Application Insights.
⚠️ 弃用通知:此包已被弃用,请迁移至。azure-monitor-opentelemetry-autoconfigure如需详细说明,请查看迁移指南。
将OpenTelemetry遥测数据导出至Azure Monitor / Application Insights。
Installation (Deprecated)
安装(已弃用)
xml
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-monitor-opentelemetry-exporter</artifactId>
<version>1.0.0-beta.x</version>
</dependency>xml
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-monitor-opentelemetry-exporter</artifactId>
<version>1.0.0-beta.x</version>
</dependency>Recommended: Use Autoconfigure Instead
推荐方案:改用Autoconfigure
xml
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-monitor-opentelemetry-autoconfigure</artifactId>
<version>LATEST</version>
</dependency>xml
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-monitor-opentelemetry-autoconfigure</artifactId>
<version>LATEST</version>
</dependency>Environment Variables
环境变量
bash
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=xxx;IngestionEndpoint=https://xxx.in.applicationinsights.azure.com/bash
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=xxx;IngestionEndpoint=https://xxx.in.applicationinsights.azure.com/Basic Setup with Autoconfigure (Recommended)
基于Autoconfigure的基础配置(推荐)
Using Environment Variable
使用环境变量
java
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder;
import io.opentelemetry.api.OpenTelemetry;
import com.azure.monitor.opentelemetry.exporter.AzureMonitorExporter;
// Connection string from APPLICATIONINSIGHTS_CONNECTION_STRING env var
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitorExporter.customize(sdkBuilder);
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();java
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder;
import io.opentelemetry.api.OpenTelemetry;
import com.azure.monitor.opentelemetry.exporter.AzureMonitorExporter;
// 连接字符串来自APPLICATIONINSIGHTS_CONNECTION_STRING环境变量
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitorExporter.customize(sdkBuilder);
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();With Explicit Connection String
使用显式连接字符串
java
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitorExporter.customize(sdkBuilder, "{connection-string}");
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();java
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitorExporter.customize(sdkBuilder, "{connection-string}");
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();Creating Spans
创建Span
java
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope;
// Get tracer
Tracer tracer = openTelemetry.getTracer("com.example.myapp");
// Create span
Span span = tracer.spanBuilder("myOperation").startSpan();
try (Scope scope = span.makeCurrent()) {
// Your application logic
doWork();
} catch (Throwable t) {
span.recordException(t);
throw t;
} finally {
span.end();
}java
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope;
// 获取Tracer
Tracer tracer = openTelemetry.getTracer("com.example.myapp");
// 创建Span
Span span = tracer.spanBuilder("myOperation").startSpan();
try (Scope scope = span.makeCurrent()) {
// 你的应用逻辑
doWork();
} catch (Throwable t) {
span.recordException(t);
throw t;
} finally {
span.end();
}Adding Span Attributes
添加Span属性
java
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
Span span = tracer.spanBuilder("processOrder")
.setAttribute("order.id", "12345")
.setAttribute("customer.tier", "premium")
.startSpan();
try (Scope scope = span.makeCurrent()) {
// Add attributes during execution
span.setAttribute("items.count", 3);
span.setAttribute("total.amount", 99.99);
processOrder();
} finally {
span.end();
}java
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
Span span = tracer.spanBuilder("processOrder")
.setAttribute("order.id", "12345")
.setAttribute("customer.tier", "premium")
.startSpan();
try (Scope scope = span.makeCurrent()) {
// 执行过程中添加属性
span.setAttribute("items.count", 3);
span.setAttribute("total.amount", 99.99);
processOrder();
} finally {
span.end();
}Custom Span Processor
自定义Span处理器
java
import io.opentelemetry.sdk.trace.SpanProcessor;
import io.opentelemetry.sdk.trace.ReadWriteSpan;
import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.context.Context;
private static final AttributeKey<String> CUSTOM_ATTR = AttributeKey.stringKey("custom.attribute");
SpanProcessor customProcessor = new SpanProcessor() {
@Override
public void onStart(Context context, ReadWriteSpan span) {
// Add custom attribute to every span
span.setAttribute(CUSTOM_ATTR, "customValue");
}
@Override
public boolean isStartRequired() {
return true;
}
@Override
public void onEnd(ReadableSpan span) {
// Post-processing if needed
}
@Override
public boolean isEndRequired() {
return false;
}
};
// Register processor
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitorExporter.customize(sdkBuilder);
sdkBuilder.addTracerProviderCustomizer(
(sdkTracerProviderBuilder, configProperties) ->
sdkTracerProviderBuilder.addSpanProcessor(customProcessor)
);
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();java
import io.opentelemetry.sdk.trace.SpanProcessor;
import io.opentelemetry.sdk.trace.ReadWriteSpan;
import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.context.Context;
private static final AttributeKey<String> CUSTOM_ATTR = AttributeKey.stringKey("custom.attribute");
SpanProcessor customProcessor = new SpanProcessor() {
@Override
public void onStart(Context context, ReadWriteSpan span) {
// 为每个Span添加自定义属性
span.setAttribute(CUSTOM_ATTR, "customValue");
}
@Override
public boolean isStartRequired() {
return true;
}
@Override
public void onEnd(ReadableSpan span) {
// 如有需要可在此进行后处理
}
@Override
public boolean isEndRequired() {
return false;
}
};
// 注册处理器
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitorExporter.customize(sdkBuilder);
sdkBuilder.addTracerProviderCustomizer(
(sdkTracerProviderBuilder, configProperties) ->
sdkTracerProviderBuilder.addSpanProcessor(customProcessor)
);
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();Nested Spans
嵌套Span
java
public void parentOperation() {
Span parentSpan = tracer.spanBuilder("parentOperation").startSpan();
try (Scope scope = parentSpan.makeCurrent()) {
childOperation();
} finally {
parentSpan.end();
}
}
public void childOperation() {
// Automatically links to parent via Context
Span childSpan = tracer.spanBuilder("childOperation").startSpan();
try (Scope scope = childSpan.makeCurrent()) {
// Child work
} finally {
childSpan.end();
}
}java
public void parentOperation() {
Span parentSpan = tracer.spanBuilder("parentOperation").startSpan();
try (Scope scope = parentSpan.makeCurrent()) {
childOperation();
} finally {
parentSpan.end();
}
}
public void childOperation() {
// 通过Context自动关联父Span
Span childSpan = tracer.spanBuilder("childOperation").startSpan();
try (Scope scope = childSpan.makeCurrent()) {
// 子任务逻辑
} finally {
childSpan.end();
}
}Recording Exceptions
记录异常
java
Span span = tracer.spanBuilder("riskyOperation").startSpan();
try (Scope scope = span.makeCurrent()) {
performRiskyWork();
} catch (Exception e) {
span.recordException(e);
span.setStatus(StatusCode.ERROR, e.getMessage());
throw e;
} finally {
span.end();
}java
Span span = tracer.spanBuilder("riskyOperation").startSpan();
try (Scope scope = span.makeCurrent()) {
performRiskyWork();
} catch (Exception e) {
span.recordException(e);
span.setStatus(StatusCode.ERROR, e.getMessage());
throw e;
} finally {
span.end();
}Metrics (via OpenTelemetry)
指标(通过OpenTelemetry)
java
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.LongHistogram;
Meter meter = openTelemetry.getMeter("com.example.myapp");
// Counter
LongCounter requestCounter = meter.counterBuilder("http.requests")
.setDescription("Total HTTP requests")
.setUnit("requests")
.build();
requestCounter.add(1, Attributes.of(
AttributeKey.stringKey("http.method"), "GET",
AttributeKey.longKey("http.status_code"), 200L
));
// Histogram
LongHistogram latencyHistogram = meter.histogramBuilder("http.latency")
.setDescription("Request latency")
.setUnit("ms")
.ofLongs()
.build();
latencyHistogram.record(150, Attributes.of(
AttributeKey.stringKey("http.route"), "/api/users"
));java
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.LongHistogram;
Meter meter = openTelemetry.getMeter("com.example.myapp");
// 计数器
LongCounter requestCounter = meter.counterBuilder("http.requests")
.setDescription("HTTP请求总数")
.setUnit("requests")
.build();
requestCounter.add(1, Attributes.of(
AttributeKey.stringKey("http.method"), "GET",
AttributeKey.longKey("http.status_code"), 200L
));
// 直方图
LongHistogram latencyHistogram = meter.histogramBuilder("http.latency")
.setDescription("请求延迟")
.setUnit("ms")
.ofLongs()
.build();
latencyHistogram.record(150, Attributes.of(
AttributeKey.stringKey("http.route"), "/api/users"
));Key Concepts
核心概念
| Concept | Description |
|---|---|
| Connection String | Application Insights connection string with instrumentation key |
| Tracer | Creates spans for distributed tracing |
| Span | Represents a unit of work with timing and attributes |
| SpanProcessor | Intercepts span lifecycle for customization |
| Exporter | Sends telemetry to Azure Monitor |
| 概念 | 描述 |
|---|---|
| Connection String | 包含检测密钥的Application Insights连接字符串 |
| Tracer | 为分布式追踪创建Span |
| Span | 代表一个带有时间和属性的工作单元 |
| SpanProcessor | 拦截Span生命周期以实现自定义逻辑 |
| Exporter | 将遥测数据发送至Azure Monitor |
Migration to Autoconfigure
迁移至Autoconfigure
The package provides:
azure-monitor-opentelemetry-autoconfigure- Automatic instrumentation of common libraries
- Simplified configuration
- Better integration with OpenTelemetry SDK
azure-monitor-opentelemetry-autoconfigure- 常见库的自动检测
- 简化的配置流程
- 与OpenTelemetry SDK更好的集成
Migration Steps
迁移步骤
-
Replace dependency:xml
<!-- Remove --> <dependency> <groupId>com.azure</groupId> <artifactId>azure-monitor-opentelemetry-exporter</artifactId> </dependency> <!-- Add --> <dependency> <groupId>com.azure</groupId> <artifactId>azure-monitor-opentelemetry-autoconfigure</artifactId> </dependency> -
Update initialization code per Migration Guide
-
替换依赖:xml
<!-- 移除 --> <dependency> <groupId>com.azure</groupId> <artifactId>azure-monitor-opentelemetry-exporter</artifactId> </dependency> <!-- 添加 --> <dependency> <groupId>com.azure</groupId> <artifactId>azure-monitor-opentelemetry-autoconfigure</artifactId> </dependency> -
根据迁移指南更新初始化代码
Best Practices
最佳实践
- Use autoconfigure — Migrate to
azure-monitor-opentelemetry-autoconfigure - Set meaningful span names — Use descriptive operation names
- Add relevant attributes — Include contextual data for debugging
- Handle exceptions — Always record exceptions on spans
- Use semantic conventions — Follow OpenTelemetry semantic conventions
- End spans in finally — Ensure spans are always ended
- Use try-with-resources — Scope management with try-with-resources pattern
- 使用Autoconfigure — 迁移至
azure-monitor-opentelemetry-autoconfigure - 设置有意义的Span名称 — 使用描述性的操作名称
- 添加相关属性 — 包含用于调试的上下文数据
- 处理异常 — 始终在Span上记录异常
- 遵循语义规范 — 遵循OpenTelemetry语义规范
- 在finally块中结束Span — 确保Span始终被结束
- 使用try-with-resources — 采用try-with-resources模式管理Scope