azure-monitor-opentelemetry-exporter-java

CategoryGeneral
AuthorAgentic Awesome Skills 社区
LicenseMIT
Rating4.90/5
Uses16.2K

Azure Monitor OpenTelemetry Exporter for Java

> ⚠️ DEPRECATION NOTICE: This package is deprecated. Migrate to azure-monitor-opentelemetry-autoconfigure.
>
> See Migration Guide for detailed instructions.

Export OpenTelemetry telemetry data to 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>

Recommended: Use Autoconfigure Instead

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/

Basic Setup with Autoconfigure (Recommended)

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();

With Explicit Connection String

java
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitorExporter.customize(sdkBuilder, "{connection-string}");
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();

Creating Spans

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();
}

Adding Span Attributes

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();
}

Custom Span Processor

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();

Nested Spans

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();
}
}

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();
}

Metrics (via 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"
));

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 |

Migration to Autoconfigure

The azure-monitor-opentelemetry-autoconfigure package provides:

  • Automatic instrumentation of common libraries

  • Simplified configuration

  • Better integration with OpenTelemetry SDK

Migration Steps

1. 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>

2. Update initialization code per Migration Guide

Best Practices

1. Use autoconfigure — Migrate to azure-monitor-opentelemetry-autoconfigure
2. Set meaningful span names — Use descriptive operation names
3. Add relevant attributes — Include contextual data for debugging
4. Handle exceptions — Always record exceptions on spans
5. Use semantic conventions — Follow OpenTelemetry semantic conventions
6. End spans in finally — Ensure spans are always ended
7. Use try-with-resources — Scope management with try-with-resources pattern

Reference Links

| Resource | URL |
|----------|-----|
| Maven Package | https://central.sonatype.com/artifact/com.azure/azure-monitor-opentelemetry-exporter |
| GitHub | https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/monitor/azure-monitor-opentelemetry-exporter |
| Migration Guide | https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/monitor/azure-monitor-opentelemetry-exporter/MIGRATION.md |
| Autoconfigure Package | https://central.sonatype.com/artifact/com.azure/azure-monitor-opentelemetry-autoconfigure |
| OpenTelemetry Java | https://opentelemetry.io/docs/languages/java/ |
| Application Insights | https://learn.microsoft.com/azure/azure-monitor/app/app-insights-overview |

When to Use

This skill is applicable to execute the workflow or actions described in the overview.

Limitations

  • Use this skill only when the task clearly matches the scope described above.
  • Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
  • Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
Join our Telegram