From d38e9fd236185acc83fc28b7f6f81ec92439dec4 Mon Sep 17 00:00:00 2001 From: Srikanta Date: Thu, 12 Nov 2020 23:59:29 -0800 Subject: [PATCH 1/4] Add AppConfig and Event Hubs samples for using exporters --- .../pom.xml | 21 +++ ...nfigurationAzureMonitorExporterSample.java | 63 ++++++++ .../AzureMonitorExporterSample.java | 28 ---- .../EventHubsAzureMonitorExporterSample.java | 137 ++++++++++++++++++ 4 files changed, 221 insertions(+), 28 deletions(-) create mode 100644 sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java delete mode 100644 sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AzureMonitorExporterSample.java create mode 100644 sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java diff --git a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/pom.xml b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/pom.xml index 37ef03521264a..37e65079b255c 100644 --- a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/pom.xml +++ b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/pom.xml @@ -83,6 +83,27 @@ 1.5.1 test + + + com.azure + azure-data-appconfiguration + 1.1.6 + test + + + + com.azure + azure-messaging-eventhubs + 5.3.1 + test + + + + com.azure + azure-core-tracing-opentelemetry + 1.0.0-beta.6 + test + diff --git a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java new file mode 100644 index 0000000000000..30dd770745149 --- /dev/null +++ b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.opentelemetry.exporter.azuremonitor; + +import com.azure.data.appconfiguration.ConfigurationClient; +import com.azure.data.appconfiguration.ConfigurationClientBuilder; +import io.opentelemetry.context.Scope; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.trace.TracerSdkProvider; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import io.opentelemetry.trace.Span; +import io.opentelemetry.trace.Tracer; + +/** + * Sample to demonstrate using {@link AzureMonitorExporter} to export telemetry events when setting a configuration + * in App Configuration through the {@link ConfigurationClient}. + */ +public class AppConfigurationAzureMonitorExporterSample { + + private static final Tracer TRACER = configureOpenTelemetryAndLoggingExporter(); + private static final String CONNECTION_STRING = ""; + + /** + * The main method to run the application. + * @param args Ignored args. + */ + public static void main(String[] args) { + doClientWork(); + } + + /** + * Configure the OpenTelemetry {@link AzureMonitorExporter} to enable tracing. + * @return The OpenTelemetry {@link Tracer} instance. + */ + private static Tracer configureOpenTelemetryAndLoggingExporter() { + AzureMonitorExporter exporter = new AzureMonitorExporterBuilder() + .connectionString("{connection-string}") + .buildExporter(); + + TracerSdkProvider tracerSdkProvider = OpenTelemetrySdk.getTracerProvider(); + tracerSdkProvider.addSpanProcessor(SimpleSpanProcessor.newBuilder(exporter).build()); + return tracerSdkProvider.get("Sample"); + } + + /** + * Creates the {@link ConfigurationClient} and sets a configuration in Azure App Configuration with distributed + * tracing enabled and using the Azure Monitor exporter to export telemetry events to Azure Monitor. + */ + private static void doClientWork() { + ConfigurationClient client = new ConfigurationClientBuilder() + .connectionString(CONNECTION_STRING) + .buildClient(); + + Span span = TRACER.spanBuilder("user-parent-span").startSpan(); + try (final Scope scope = TRACER.withSpan(span)) { + // 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"); + } finally { + span.end(); + } + } +} diff --git a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AzureMonitorExporterSample.java b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AzureMonitorExporterSample.java deleted file mode 100644 index 4be562653a303..0000000000000 --- a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AzureMonitorExporterSample.java +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.microsoft.opentelemetry.exporter.azuremonitor; - -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.trace.data.SpanData; - -import java.util.Collections; - -/** - * Sample to demonstrate exporting OpenTelemetry {@link SpanData} to Azure Monitor through {@link AzureMonitorExporter}. - */ -public class AzureMonitorExporterSample { - - /** - * Main method to start the sample application - * @param args Ignore args. - */ - public static void main(String[] args) { - AzureMonitorExporter azureMonitorExporter = new AzureMonitorExporterBuilder() - .connectionString("{connection-string}") - .buildExporter(); - CompletableResultCode resultCode = - azureMonitorExporter.export(Collections.singleton(new AzureMonitorExporterTest.RequestSpanData())); - System.out.println("Export operation status: " + resultCode.isSuccess()); - } -} diff --git a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java new file mode 100644 index 0000000000000..0a72f74f6be00 --- /dev/null +++ b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.opentelemetry.exporter.azuremonitor; + +import com.azure.messaging.eventhubs.EventData; +import com.azure.messaging.eventhubs.EventDataBatch; +import com.azure.messaging.eventhubs.EventHubClientBuilder; +import com.azure.messaging.eventhubs.EventHubProducerAsyncClient; +import com.azure.messaging.eventhubs.models.CreateBatchOptions; +import io.opentelemetry.context.Scope; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.trace.TracerSdkProvider; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import io.opentelemetry.trace.Span; +import io.opentelemetry.trace.Tracer; +import reactor.core.Exceptions; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import static com.azure.core.util.tracing.Tracer.PARENT_SPAN_KEY; +import static com.azure.messaging.eventhubs.implementation.ClientConstants.OPERATION_TIMEOUT; +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Sample to demontrate using {@link AzureMonitorExporter} to export telemetry events when sending events to Event Hubs + * using {@link EventHubProducerAsyncClient}. + */ +public class EventHubsAzureMonitorExporterSample { + private static final Tracer TRACER = configureOpenTelemetryAndLoggingExporter(); + private static final String CONNECTION_STRING = ""; + + /** + * The main method to run the application. + * @param args Ignored args. + */ + public static void main(String[] args) { + doClientWork(); + } + + /** + * Configure the OpenTelemetry {@link AzureMonitorExporter} to enable tracing. + * @return The OpenTelemetry {@link Tracer} instance. + */ + private static Tracer configureOpenTelemetryAndLoggingExporter() { + AzureMonitorExporter exporter = new AzureMonitorExporterBuilder() + .connectionString("{connection-string}") + .buildExporter(); + + TracerSdkProvider tracerSdkProvider = OpenTelemetrySdk.getTracerProvider(); + tracerSdkProvider.addSpanProcessor(SimpleSpanProcessor.newBuilder(exporter).build()); + return tracerSdkProvider.get("Sample"); + } + + /** + * Method that creates {@link EventHubProducerAsyncClient} to send events to Event Hubs with distributed + * telemetry enabled and using Azure Monitor exporter to export telemetry events. + */ + private static void doClientWork() { + EventHubProducerAsyncClient producer = new EventHubClientBuilder() + .connectionString(CONNECTION_STRING) + .buildAsyncProducerClient(); + + Span span = TRACER.spanBuilder("user-parent-span").startSpan(); + try (final Scope scope = TRACER.withSpan(span)) { + String firstPartition = producer.getPartitionIds().blockFirst(OPERATION_TIMEOUT); + + final byte[] body = "EventData Sample 1".getBytes(UTF_8); + final byte[] body2 = "EventData Sample 2".getBytes(UTF_8); + + // We will publish three events based on simple sentences. + Flux data = Flux.just( + new EventData(body).addContext(PARENT_SPAN_KEY, TRACER.getCurrentSpan()), + new EventData(body2).addContext(PARENT_SPAN_KEY, TRACER.getCurrentSpan())); + + // Create a batch to send the events. + final CreateBatchOptions options = new CreateBatchOptions() + .setPartitionId(firstPartition) + .setMaximumSizeInBytes(256); + + final AtomicReference currentBatch = new AtomicReference<>( + producer.createBatch(options).block(OPERATION_TIMEOUT)); + + data.flatMap(event -> { + final EventDataBatch batch = currentBatch.get(); + if (batch.tryAdd(event)) { + return Mono.empty(); + } + + // The batch is full, so we create a new batch and send the batch. Mono.when completes when both + // operations + // have completed. + return Mono.when( + producer.send(batch), + producer.createBatch(options).map(newBatch -> { + currentBatch.set(newBatch); + + // Add that event that we couldn't before. + if (!newBatch.tryAdd(event)) { + throw Exceptions.propagate(new IllegalArgumentException(String.format( + "Event is too large for an empty batch. Max size: %s. Event: %s", + newBatch.getMaxSizeInBytes(), event.getBodyAsString()))); + } + + return newBatch; + })); + }).then() + .doFinally(signal -> { + final EventDataBatch batch = currentBatch.getAndSet(null); + if (batch != null) { + producer.send(batch).block(OPERATION_TIMEOUT); + } + }) + .subscribe(unused -> System.out.println("Complete"), + error -> System.out.println("Error sending events: " + error), + () -> { + System.out.println("Completed sending events."); + span.end(); + }); + + + // The .subscribe() creation and assignment is not a blocking call. For the purpose of this example, we sleep + // the thread so the program does not end before the send operation is complete. Using .block() instead of + // .subscribe() will turn this into a synchronous call. + try { + TimeUnit.SECONDS.sleep(5); + } catch (InterruptedException ignored) { + } finally { + // Disposing of our producer. + producer.close(); + } + } + } +} From 7ce94195241f942093ceaa12a3f3fa5749e3a552 Mon Sep 17 00:00:00 2001 From: Srikanta Date: Fri, 13 Nov 2020 00:38:46 -0800 Subject: [PATCH 2/4] Fix compiler warnings --- .../AppConfigurationAzureMonitorExporterSample.java | 4 +++- .../azuremonitor/EventHubsAzureMonitorExporterSample.java | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java index 30dd770745149..38e03bc9ed602 100644 --- a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java +++ b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java @@ -53,11 +53,13 @@ private static void doClientWork() { .buildClient(); Span span = TRACER.spanBuilder("user-parent-span").startSpan(); - try (final Scope scope = TRACER.withSpan(span)) { + final Scope scope = TRACER.withSpan(span); + 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"); } finally { span.end(); + scope.close(); } } } diff --git a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java index 0a72f74f6be00..5f61298c03aea 100644 --- a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java +++ b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java @@ -65,7 +65,8 @@ private static void doClientWork() { .buildAsyncProducerClient(); Span span = TRACER.spanBuilder("user-parent-span").startSpan(); - try (final Scope scope = TRACER.withSpan(span)) { + final Scope scope = TRACER.withSpan(span); + try { String firstPartition = producer.getPartitionIds().blockFirst(OPERATION_TIMEOUT); final byte[] body = "EventData Sample 1".getBytes(UTF_8); @@ -132,6 +133,8 @@ private static void doClientWork() { // Disposing of our producer. producer.close(); } + } finally { + scope.close(); } } } From 1dfb5e726e5b8d46734ab233c760b20c26ccaab0 Mon Sep 17 00:00:00 2001 From: Srikanta <51379715+srnagar@users.noreply.github.com> Date: Fri, 13 Nov 2020 10:10:48 -0800 Subject: [PATCH 3/4] Update sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/pom.xml --- .../microsoft-opentelemetry-exporter-azuremonitor/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/pom.xml b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/pom.xml index 37e65079b255c..8113a814241ab 100644 --- a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/pom.xml +++ b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/pom.xml @@ -87,7 +87,7 @@ com.azure azure-data-appconfiguration - 1.1.6 + 1.1.7 test From 4506a284687ae3b0ceb0061c646776d326ffcc41 Mon Sep 17 00:00:00 2001 From: Srikanta Date: Fri, 13 Nov 2020 10:23:32 -0800 Subject: [PATCH 4/4] Update method names --- .../AppConfigurationAzureMonitorExporterSample.java | 4 ++-- .../azuremonitor/EventHubsAzureMonitorExporterSample.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java index 38e03bc9ed602..3b4174bb6d49d 100644 --- a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java +++ b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/AppConfigurationAzureMonitorExporterSample.java @@ -18,7 +18,7 @@ */ public class AppConfigurationAzureMonitorExporterSample { - private static final Tracer TRACER = configureOpenTelemetryAndLoggingExporter(); + private static final Tracer TRACER = configureAzureMonitorExporter(); private static final String CONNECTION_STRING = ""; /** @@ -33,7 +33,7 @@ public static void main(String[] args) { * Configure the OpenTelemetry {@link AzureMonitorExporter} to enable tracing. * @return The OpenTelemetry {@link Tracer} instance. */ - private static Tracer configureOpenTelemetryAndLoggingExporter() { + private static Tracer configureAzureMonitorExporter() { AzureMonitorExporter exporter = new AzureMonitorExporterBuilder() .connectionString("{connection-string}") .buildExporter(); diff --git a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java index 5f61298c03aea..c70b34e38d754 100644 --- a/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java +++ b/sdk/monitor/microsoft-opentelemetry-exporter-azuremonitor/src/samples/java/com/microsoft/opentelemetry/exporter/azuremonitor/EventHubsAzureMonitorExporterSample.java @@ -30,7 +30,7 @@ * using {@link EventHubProducerAsyncClient}. */ public class EventHubsAzureMonitorExporterSample { - private static final Tracer TRACER = configureOpenTelemetryAndLoggingExporter(); + private static final Tracer TRACER = configureAzureMonitorExporter(); private static final String CONNECTION_STRING = ""; /** @@ -45,7 +45,7 @@ public static void main(String[] args) { * Configure the OpenTelemetry {@link AzureMonitorExporter} to enable tracing. * @return The OpenTelemetry {@link Tracer} instance. */ - private static Tracer configureOpenTelemetryAndLoggingExporter() { + private static Tracer configureAzureMonitorExporter() { AzureMonitorExporter exporter = new AzureMonitorExporterBuilder() .connectionString("{connection-string}") .buildExporter();