Skip to content

Commit

Permalink
Azure Monitor Exporter - Adopt OpenTelemetry .NET beta2 changes (Azur…
Browse files Browse the repository at this point in the history
  • Loading branch information
rajkumar-rangaraj authored Aug 29, 2020
1 parent 3510dcf commit 4a678fd
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,26 @@ namespace OpenTelemetry.Exporter.AzureMonitor
/// <summary>
/// test
/// </summary>
public static class TracerProviderBuilderExtensions
public static class AzureMonitorExporterHelperExtensions
{
/// <summary>
/// Registers an Azure Monitor trace exporter that will receive <see cref="System.Diagnostics.Activity"/> instances.
/// </summary>
/// <param name="builder"><see cref="TracerProviderBuilder"/> builder to use.</param>
/// <param name="configure">Exporter configuration options.</param>
/// <param name="processorConfigure">Activity processor configuration.</param>
/// <returns>The instance of <see cref="TracerProviderBuilder"/> to chain the calls.</returns>
public static TracerProviderBuilder UseAzureMonitorTraceExporter(this TracerProviderBuilder builder, Action<AzureMonitorExporterOptions> configure = null, Action<ActivityProcessorPipelineBuilder> processorConfigure = null)
public static TracerProviderBuilder AddAzureMonitorTraceExporter(this TracerProviderBuilder builder, Action<AzureMonitorExporterOptions> configure = null)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}

return builder.AddProcessorPipeline(pipeline =>
{
var options = new AzureMonitorExporterOptions();
configure?.Invoke(options);
var options = new AzureMonitorExporterOptions();
configure?.Invoke(options);

var exporter = new AzureMonitorTraceExporter(options);
processorConfigure?.Invoke(pipeline);
pipeline.SetExporter(exporter);
});
// TODO: Pick Simple vs Batching based on AzureMonitorExporterOptions
return builder.AddProcessor(new BatchExportActivityProcessor(new AzureMonitorTraceExporter(options)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core.Pipeline;
using OpenTelemetry.Trace;

namespace OpenTelemetry.Exporter.AzureMonitor
Expand All @@ -25,22 +24,24 @@ public AzureMonitorTraceExporter(AzureMonitorExporterOptions options)
}

/// <inheritdoc/>
public override async Task<ExportResult> ExportAsync(IEnumerable<Activity> batchActivity, CancellationToken cancellationToken)
public override ExportResult Export(in Batch<Activity> batch)
{
if (batchActivity == null)
// Prevent Azure Monitor's HTTP operations from being instrumented.
using var scope = SuppressInstrumentationScope.Begin();

try
{
throw new ArgumentNullException(nameof(batchActivity));
// TODO: Handle return value, it can be converted as metrics.
// TODO: Validate CancellationToken and async pattern here.
this.AzureMonitorTransmitter.AddBatchActivityAsync(batch, false, CancellationToken.None).EnsureCompleted();
return ExportResult.Success;
}
catch (Exception ex)
{
AzureMonitorTraceExporterEventSource.Log.FailedExport(ex);
return ExportResult.Failure;
}

// Handle return value, it can be converted as metrics.
await this.AzureMonitorTransmitter.AddBatchActivityAsync(batchActivity, cancellationToken).ConfigureAwait(false);
return ExportResult.Success;
}

/// <inheritdoc/>
public override Task ShutdownAsync(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ internal sealed class AzureMonitorTraceExporterEventSource : EventSource
public static AzureMonitorTraceExporterEventSource Log = new AzureMonitorTraceExporterEventSource();

[NonEvent]
public void ConfigurationStringParseWarning(string message)
public void FailedExport(Exception ex)
{
if (this.IsEnabled(EventLevel.Warning, EventKeywords.All))
if (this.IsEnabled(EventLevel.Error, EventKeywords.All))
{
this.WarnToParseConfigurationString(message);
this.FailedExport(ex.ToInvariantString());
}
}

Expand All @@ -39,8 +39,8 @@ public void ConnectionStringError(Exception ex)
}
}

[Event(1, Message = "{0}", Level = EventLevel.Warning)]
public void WarnToParseConfigurationString(string message) => this.WriteEvent(1, message);
[Event(1, Message = "Failed to export activities: '{0}'", Level = EventLevel.Error)]
public void FailedExport(string exception) => this.WriteEvent(1, exception);

[Event(2, Message = "Error creating SdkVersion : '{0}'", Level = EventLevel.Warning)]
public void WarnSdkVersionCreateException(string message) => this.WriteEvent(2, message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public AzureMonitorTransmitter(AzureMonitorExporterOptions exporterOptions)
serviceRestClient = new ServiceRestClient(new ClientDiagnostics(options), HttpPipelineBuilder.Build(options), endpoint: ingestionEndpoint);
}

internal async ValueTask<int> AddBatchActivityAsync(IEnumerable<Activity> batchActivity, CancellationToken cancellationToken)
internal async ValueTask<int> AddBatchActivityAsync(Batch<Activity> batchActivity, bool async, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
Expand All @@ -64,8 +64,18 @@ internal async ValueTask<int> AddBatchActivityAsync(IEnumerable<Activity> batchA
telemetryItems.Add(telemetryItem);
}

Azure.Response<TrackResponse> response;

if (async)
{
response = await this.serviceRestClient.TrackAsync(telemetryItems, cancellationToken).ConfigureAwait(false);
}
else
{
response = this.serviceRestClient.TrackAsync(telemetryItems, cancellationToken).Result;
}

// TODO: Handle exception, check telemetryItems has items
var response = await this.serviceRestClient.TrackAsync(telemetryItems, cancellationToken).ConfigureAwait(false);
return response.Value.ItemsAccepted.GetValueOrDefault();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<ItemGroup>
<PackageReference Include="System.Text.Json" />
<PackageReference Include="OpenTelemetry" Version="0.4.0-beta.2" IsImplicitlyDefined="true" />
<PackageReference Include="OpenTelemetry" Version="0.5.0-beta.2" IsImplicitlyDefined="true" />
</ItemGroup>

<!-- Shared source from Azure.Core -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ public static class DemoTrace

public static void Main()
{
OpenTelemetry.Sdk.CreateTracerProvider(builder => builder
.AddActivitySource("Samples.SampleServer")
.AddActivitySource("Samples.SampleClient")
.UseAzureMonitorTraceExporter(o => {
o.ConnectionString = "ConnectionString";
}));
using var tracerProvider = OpenTelemetry.Sdk.CreateTracerProviderBuilder()
.AddSource("Samples.SampleServer")
.AddSource("Samples.SampleClient")
.AddAzureMonitorTraceExporter(o => {
o.ConnectionString = $"InstrumentationKey=Ikey;";
})
.Build();

using (var sample = new InstrumentationWithActivitySource())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ public void Start(string url)
foreach (var headerKey in headerKeys)
{
string headerValue = context.Request.Headers[headerKey];
activity?.AddTag($"http.header.{headerKey}", headerValue);
activity?.SetTag($"http.header.{headerKey}", headerValue);
}

activity?.AddTag("http.url", context.Request.Url.AbsolutePath);
activity?.SetTag("http.url", context.Request.Url.AbsolutePath);

string requestContent;
using (var childSpan = source.StartActivity("ReadStream", ActivityKind.Consumer))
Expand All @@ -73,8 +73,8 @@ public void Start(string url)
childSpan.AddEvent(new ActivityEvent("StreamReader.ReadToEnd"));
}

activity?.AddTag("request.content", requestContent);
activity?.AddTag("request.length", requestContent.Length.ToString(CultureInfo.InvariantCulture));
activity?.SetTag("request.content", requestContent);
activity?.SetTag("request.length", requestContent.Length.ToString(CultureInfo.InvariantCulture));

var echo = Encoding.UTF8.GetBytes("echo: " + requestContent);
context.Response.ContentEncoding = Encoding.UTF8;
Expand Down Expand Up @@ -126,22 +126,22 @@ public void Start(string url)
#pragma warning restore CA2234 // Pass system uri objects instead of strings
activity?.AddEvent(new ActivityEvent("PostAsync:Ended"));

activity?.AddTag("http.url", url);
activity?.AddTag("http.status_code", $"{response.StatusCode:D}");
activity?.SetTag("http.url", url);
activity?.SetTag("http.status_code", $"{response.StatusCode:D}");

var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
activity?.AddTag("response.content", responseContent);
activity?.AddTag("response.length", responseContent.Length.ToString(CultureInfo.InvariantCulture));
activity?.SetTag("response.content", responseContent);
activity?.SetTag("response.length", responseContent.Length.ToString(CultureInfo.InvariantCulture));

foreach (var header in response.Headers)
{
if (header.Value is IEnumerable<object> enumerable)
{
activity?.AddTag($"http.header.{header.Key}", string.Join(",", enumerable));
activity?.SetTag($"http.header.{header.Key}", string.Join(",", enumerable));
}
else
{
activity?.AddTag($"http.header.{header.Key}", header.Value.ToString());
activity?.SetTag($"http.header.{header.Key}", header.Value.ToString());
}
}
}
Expand Down

0 comments on commit 4a678fd

Please sign in to comment.