azure-monitor-opentelemetry-exporter-java
About azure-monitor-opentelemetry-exporter-java
A Java skill for exporting OpenTelemetry telemetry to Azure Monitor and Application Insights. It covers exporter setup and span and metric recording, while noting that the package is deprecated in favor of `azure-monitor-opentelemetry-autoconfigure`.
Key features
- 01Export OpenTelemetry data to Azure Monitor
- 02Configure with a connection string
- 03Create and customize spans
- 04Record metrics and exceptions
Use cases
- 01Send Java application telemetry to Application Insights
- 02Add spans and attributes for tracing
- 03Record errors during instrumented operations
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill azure-monitor-opentelemetry-exporter-javaAfter installing, type/azure-monitor-opentelemetry-exporter-javain Claude Code to confirm it loaded.
Details
From the project READMEAzure 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)
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-monitor-opentelemetry-exporter</artifactId>
<version>1.0.0-beta.x</version>
</dependency>
Recommended: Use Autoconfigure Instead
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-monitor-opentelemetry-autoconfigure</artifactId>
<version>REPLACE_WITH_REVIEWED_COMPATIBLE_VERSION</version>
</dependency>
Environment Variables
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=xxx;IngestionEndpoint=https://xxx.in.applicationinsights.azure.com/
Version and telemetry scope
Resolve an actual compatible version from the linked official migration/package docs; placeholder versions are not buildable dependencies. Configuring exporters is not proof every application library is instrumented: verify trace/metric/log export for the pinned integration and do not initialize duplicate SDKs. Redact sensitive attributes/exceptions, use an approved telemetry destination and manage SDK shutdown/flush through the application lifecycle.
Basic Setup with Autoconfigure (Recommended)
Using Environment Variable
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
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitorExporter.customize(sdkBuilder, "{connection-string}");
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();
Creating Spans
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
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
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
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
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)
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
-
Replace dependency:
<!-- 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
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
Reference Links
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.