Skip to content

Commit

Permalink
Rework OTel exporter API and documentation (#41705)
Browse files Browse the repository at this point in the history
Rework OTel exporter API and documentation
  • Loading branch information
jeanbisutti authored Sep 20, 2024
1 parent c57332c commit d27c57c
Show file tree
Hide file tree
Showing 22 changed files with 443 additions and 281 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
<suppress checks="LineLength" files="messages.properties"/>

<!-- Identity and opentelemetry tracing are plugin packages and shouldn't be referenced -->
<suppress checks="IllegalImport" files=".*[/\\]com[/\\]azure[/\\]monitor[/\\]opentelemetry[/\\]exporter[/\\]*"/>
<suppress checks="IllegalImport" files=".*[/\\]com[/\\]azure[/\\]monitor[/\\]opentelemetry[/\\]*"/>
<suppress checks="IllegalImport" files=".*[/\\]com[/\\]azure[/\\]spring[/\\]cloud[/\\]autoconfigure[/\\]monitor[/\\]*"/>
<suppress checks="IllegalImport" files=".*[/\\]com[/\\]azure[/\\]identity[/\\]*"/>
<suppress checks="IllegalImport" files="com.azure.messaging.servicebus.IntegrationTestBase.java"/>
Expand Down Expand Up @@ -138,6 +138,9 @@ the main ServiceBusClientBuilder. -->
<suppress checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck"
files="com.azure.containers.containerregistry.ContainerRegistryContentClient.java"/>

<suppress checks="com.azure.tools.checkstyle.checks.ExternalDependencyExposedCheck"
files="com.azure.monitor.opentelemetry.AzureMonitor.java"/>

<suppress checks="com.azure.tools.checkstyle.checks.ExternalDependencyExposedCheck"
files="com.azure.monitor.opentelemetry.exporter.AzureMonitorExporterBuilder"/>

Expand Down
2 changes: 2 additions & 0 deletions eng/versioning/version_client.txt
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,8 @@ unreleased_com.azure:azure-messaging-servicebus;7.18.0-beta.2
unreleased_com.azure:azure-messaging-eventhubs;5.19.0-beta.3
unreleased_com.azure:azure-messaging-eventhubs-checkpointstore-blob;1.20.0-beta.3

unreleased_com.azure:azure-monitor-opentelemetry-exporter;1.0.0-beta.29

# Released Beta dependencies: Copy the entry from above, prepend "beta_", remove the current
# version and set the version to the released beta. Released beta dependencies are only valid
# for dependency versions. These entries are specifically for when we've released a beta for
Expand Down
2 changes: 1 addition & 1 deletion sdk/eventhubs/azure-messaging-eventhubs-stress/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-monitor-opentelemetry-exporter</artifactId>
<version>1.0.0-beta.28</version> <!-- {x-version-update;com.azure:azure-monitor-opentelemetry-exporter;dependency} -->
<version>1.0.0-beta.29</version> <!-- {x-version-update;unreleased_com.azure:azure-monitor-opentelemetry-exporter;dependency} -->
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.azure.messaging.eventhubs.EventHubClientBuilder;
import com.azure.messaging.eventhubs.models.CloseContext;
import com.azure.messaging.eventhubs.models.InitializationContext;
import com.azure.monitor.opentelemetry.exporter.AzureMonitorExporterBuilder;
import com.azure.monitor.opentelemetry.AzureMonitor;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
Expand Down Expand Up @@ -96,9 +96,7 @@ private static OpenTelemetry init() {
}
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();

new AzureMonitorExporterBuilder()
.connectionString(applicationInsightsConnectionString)
.install(sdkBuilder);
AzureMonitor.customize(sdkBuilder, applicationInsightsConnectionString);

String instanceId = System.getenv("CONTAINER_NAME");
OpenTelemetry otel = sdkBuilder
Expand Down
108 changes: 74 additions & 34 deletions sdk/monitor/azure-monitor-opentelemetry-exporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,50 +29,91 @@ In order to export telemetry data to Azure Monitor, you will need the instrument
search for your resource. On the overview page of your resource, you will find the instrumentation key in the top
right corner.

### Creating exporter builder for Azure Monitor
```java readme-sample-createExporterBuilder
AzureMonitorExporterBuilder azureMonitorExporterBuilder = new AzureMonitorExporterBuilder()
.connectionString("{connection-string}");
```

#### Exporting span data
### Setup the OpenTelemetry SDK to work with Azure Monitor exporter

The following example shows how to export a trace data to Azure Monitor through the
`AzureMonitorTraceExporter`
If you have set the Application Insights connection string with the `APPLICATIONINSIGHTS_CONNECTION_STRING` environment variable, you can configure OpenTelemetry SDK auto-configuration for Azure in the following way:

##### Setup OpenTelemetry SDK to work with Azure Monitor exporter
```java readme-sample-setupExporter
// Create Azure Monitor exporter and initialize OpenTelemetry SDK
// This should be done just once when application starts up
```java readme-sample-autoconfigure-env-variable
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();

new AzureMonitorExporterBuilder()
.connectionString("{connection-string}")
.install(sdkBuilder);

AzureMonitor.customize(sdkBuilder);
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();
```

Tracer tracer = openTelemetry.getTracer("Sample");
You can also set the connection string in the code:
```java readme-sample-autoconfigure
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitor.customize(sdkBuilder, "{connection-string}");
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();
```

##### Create spans
## Examples

The following sections provide code samples using the OpenTelemetry Azure Monitor Exporter client library and OpenTelemetry SDK.

The following example shows how create a span:

```java readme-sample-create-span
AutoConfiguredOpenTelemetrySdkBuilder otelSdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();

AzureMonitor.customize(otelSdkBuilder, "{connection-string}");

OpenTelemetry openTelemetry = otelSdkBuilder.build().getOpenTelemetrySdk();
Tracer tracer = openTelemetry.getTracer("Sample");

```java readme-sample-createSpans
// Make service calls by adding new parent spans
ConfigurationClient client = new ConfigurationClientBuilder()
.connectionString("{app-config-connection-string}")
.buildClient();
Span span = tracer.spanBuilder("spanName").startSpan();

Span span = tracer.spanBuilder("user-parent-span").startSpan();
final Scope scope = span.makeCurrent();
try {
// Thread bound (sync) calls will automatically pick up the parent span and you don't need to pass it explicitly.
client.setConfigurationSetting("hello", "text", "World");
// Make the span the current span
try (Scope scope = span.makeCurrent()) {
// Your application logic here
} catch (Throwable t) {
span.recordException(t);
throw t;
} finally {
span.end();
scope.close();
}
```
The following example demonstrates how to add a span processor to the OpenTelemetry SDK autoconfiguration.

```java readme-sample-span-processor
private static final AttributeKey<String> ATTRIBUTE_KEY = AttributeKey.stringKey("attributeKey");

public void spanProcessor() {
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();

AzureMonitor.customize(sdkBuilder);

SpanProcessor spanProcessor = new SpanProcessor() {

@Override
public void onStart(Context context, ReadWriteSpan span) {
span.setAttribute(ATTRIBUTE_KEY, "attributeValue");
}

@Override
public boolean isStartRequired() {
return true;
}

@Override
public void onEnd(ReadableSpan readableSpan) {
}

@Override
public boolean isEndRequired() {
return false;
}
};

sdkBuilder.addTracerProviderCustomizer(
(sdkTracerProviderBuilder, configProperties) -> sdkTracerProviderBuilder
.addSpanProcessor(spanProcessor));
}
```
More advanced examples with OpenTelemetry APIs:
* [Advanced examples - 1][advanced_examples_1]
* [Advanced examples - 2][advanced_examples_2]
* [Event Hubs example][event_hubs_example]

## Key concepts

Expand All @@ -94,9 +135,6 @@ Some key concepts for the Azure Monitor exporter include:

For more information on the OpenTelemetry project, please review the [OpenTelemetry Specifications][opentelemetry_specification].

## Examples

More examples can be found in [samples][samples_code].

## Troubleshooting

Expand Down Expand Up @@ -150,7 +188,9 @@ This project has adopted the [Microsoft Open Source Code of Conduct][coc]. For m
[span_processor]: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk.md#span-processor
[sampler_ref]: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk.md#sampling
[trace_concept]: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/overview.md#trace
[samples_code]: https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/monitor/azure-monitor-opentelemetry-exporter/src/samples
[advanced_examples_1]: https://github.com/Azure-Samples/ApplicationInsights-Java-Samples/tree/main/opentelemetry-api/exporter/
[advanced_examples_2]: https://github.com/open-telemetry/opentelemetry-java-examples/tree/main/sdk-usage/src/main/java/io/opentelemetry/sdk/example
[event_hubs_example]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/monitor/azure-monitor-opentelemetry-exporter/src/samples/java/com/azure/monitor/opentelemetry/exporter/EventHubsAzureMonitorExporterSample.java
[cla]: https://cla.microsoft.com
[coc]: https://opensource.microsoft.com/codeofconduct/
[coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.monitor.opentelemetry;

import com.azure.monitor.opentelemetry.exporter.AzureMonitorExporterBuilder;
import com.azure.monitor.opentelemetry.exporter.implementation.AzureMonitorExporterProviderKeys;
import com.azure.monitor.opentelemetry.exporter.implementation.AzureMonitorLogRecordExporterProvider;
import com.azure.monitor.opentelemetry.exporter.implementation.AzureMonitorMetricExporterProvider;
import com.azure.monitor.opentelemetry.exporter.implementation.AzureMonitorSpanExporterProvider;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.metrics.Aggregation;
import io.opentelemetry.sdk.metrics.InstrumentSelector;
import io.opentelemetry.sdk.metrics.View;

import java.util.HashMap;
import java.util.Map;

/**
* Class to enable Azure Monitor for OpenTelemetry autoconfiguration.
*/
public final class AzureMonitor {

private AzureMonitor() {
}

/**
* Customizes an {@link AutoConfigurationCustomizer} for Azure Monitor. The connection string to the Application Insights resource is expected to be configured with the APPLICATIONINSIGHTS_CONNECTION_STRING environment variable.
*
* @param autoConfigurationCustomizer The OpenTelemetry autoconfiguration to set up.
*/
public static void customize(AutoConfigurationCustomizer autoConfigurationCustomizer) {
AzureMonitorExporterBuilder azureMonitorExporterBuilder = new AzureMonitorExporterBuilder();
customize(autoConfigurationCustomizer, azureMonitorExporterBuilder);
}

/**
* Customizes an {@link AutoConfigurationCustomizer} for Azure Monitor.
* @param autoConfigurationCustomizer The OpenTelemetry autoconfiguration to set up.
* @param connectionString The connection string to connect to an Application Insights resource.
*/
public static void customize(AutoConfigurationCustomizer autoConfigurationCustomizer, String connectionString) {
AzureMonitorExporterBuilder azureMonitorExporterBuilder
= new AzureMonitorExporterBuilder().connectionString(connectionString);
customize(autoConfigurationCustomizer, azureMonitorExporterBuilder);
}

/**
* Customizes an {@link AutoConfigurationCustomizer} for Azure Monitor.
* @param autoConfigurationCustomizer the {@link AutoConfigurationCustomizer} object.
* @param azureMonitorExporterBuilder Advanced configuration to send the data to Azure Monitor.
*/
public static void customize(AutoConfigurationCustomizer autoConfigurationCustomizer,
AzureMonitorExporterBuilder azureMonitorExporterBuilder) {
autoConfigurationCustomizer.addPropertiesSupplier(() -> {
Map<String, String> props = new HashMap<>();
props.put("otel.traces.exporter", AzureMonitorExporterProviderKeys.EXPORTER_NAME);
props.put("otel.metrics.exporter", AzureMonitorExporterProviderKeys.EXPORTER_NAME);
props.put("otel.logs.exporter", AzureMonitorExporterProviderKeys.EXPORTER_NAME);
props.put(AzureMonitorExporterProviderKeys.INTERNAL_USING_AZURE_MONITOR_EXPORTER_BUILDER, "true");
return props;
});
autoConfigurationCustomizer.addSpanExporterCustomizer((spanExporter, configProperties) -> {
if (spanExporter instanceof AzureMonitorSpanExporterProvider.MarkerSpanExporter) {
spanExporter = azureMonitorExporterBuilder.buildSpanExporter(configProperties);
}
return spanExporter;
});
autoConfigurationCustomizer.addMetricExporterCustomizer((metricExporter, configProperties) -> {
if (metricExporter instanceof AzureMonitorMetricExporterProvider.MarkerMetricExporter) {
metricExporter = azureMonitorExporterBuilder.buildMetricExporter(configProperties);
}
return metricExporter;
});
autoConfigurationCustomizer.addLogRecordExporterCustomizer((logRecordExporter, configProperties) -> {
if (logRecordExporter instanceof AzureMonitorLogRecordExporterProvider.MarkerLogRecordExporter) {
logRecordExporter = azureMonitorExporterBuilder.buildLogRecordExporter(configProperties);
}
return logRecordExporter;
});
// TODO (trask)
// sdkBuilder.addTracerProviderCustomizer((sdkTracerProviderBuilder, configProperties) -> {
// QuickPulse quickPulse = QuickPulse.create(getHttpPipeline());
// return sdkTracerProviderBuilder.addSpanProcessor(
// ne
autoConfigurationCustomizer
.addMeterProviderCustomizer((sdkMeterProviderBuilder, config) -> sdkMeterProviderBuilder
.registerView(InstrumentSelector.builder().setMeterName("io.opentelemetry.sdk.trace").build(),
View.builder().setAggregation(Aggregation.drop()).build())
.registerView(InstrumentSelector.builder().setMeterName("io.opentelemetry.sdk.logs").build(),
View.builder().setAggregation(Aggregation.drop()).build()));
}
}
Loading

0 comments on commit d27c57c

Please sign in to comment.