Skip to content

Commit

Permalink
[AzureMonitorExporter] Remove "sampleRate" tag from SamplingResult (#…
Browse files Browse the repository at this point in the history
…37765)

* remove sampling tag

* remove tag

* pr feedback: if != 100

* add extra check for SampleRate != 100f

* remove nullable from method paramaters. update tests.
  • Loading branch information
TimothyMothra authored Jul 25, 2023
1 parent b430b2d commit 484f51f
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@ internal sealed class AzureMonitorTraceExporter : BaseExporter<Activity>
{
private readonly ITransmitter _transmitter;
private readonly string _instrumentationKey;
private readonly float _sampleRate; // This value is recorded on TelemetryItem.SampleRate.
private AzureMonitorResource? _resource;
private bool _disposed;

public AzureMonitorTraceExporter(AzureMonitorExporterOptions options) : this(TransmitterFactory.Instance.Get(options))
public AzureMonitorTraceExporter(AzureMonitorExporterOptions options) : this(options, TransmitterFactory.Instance.Get(options))
{
}

internal AzureMonitorTraceExporter(ITransmitter transmitter)
internal AzureMonitorTraceExporter(AzureMonitorExporterOptions options, ITransmitter transmitter)
{
_sampleRate = (float)Math.Round(options.SamplingRatio * 100);
_transmitter = transmitter;
_instrumentationKey = transmitter.InstrumentationKey;
}
Expand All @@ -40,7 +42,7 @@ public override ExportResult Export(in Batch<Activity> batch)

try
{
var telemetryItems = TraceHelper.OtelToAzureMonitorTrace(batch, TraceResource, _instrumentationKey);
var telemetryItems = TraceHelper.OtelToAzureMonitorTrace(batch, TraceResource, _instrumentationKey, _sampleRate);
if (telemetryItems.Count > 0)
{
exportResult = _transmitter.TrackAsync(telemetryItems, TelemetryItemOrigin.AzureMonitorTraceExporter, false, CancellationToken.None).EnsureCompleted();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Azure.Monitor.OpenTelemetry.Exporter.Models
{
internal partial class TelemetryItem
{
public TelemetryItem(Activity activity, ref ActivityTagsProcessor activityTagsProcessor, AzureMonitorResource? resource, string instrumentationKey) :
public TelemetryItem(Activity activity, ref ActivityTagsProcessor activityTagsProcessor, AzureMonitorResource? resource, string instrumentationKey, float sampleRate) :
this(activity.GetTelemetryType() == TelemetryType.Request ? "Request" : "RemoteDependency", FormatUtcTimestamp(activity.StartTimeUtc))
{
if (activity.ParentSpanId != default)
Expand Down Expand Up @@ -60,7 +60,8 @@ public TelemetryItem(Activity activity, ref ActivityTagsProcessor activityTagsPr

SetAuthenticatedUserId(ref activityTagsProcessor);
SetResourceSdkVersionAndIkey(resource, instrumentationKey);
if (AzMonList.GetTagValue(ref activityTagsProcessor.MappedTags, "sampleRate") is float sampleRate)

if (sampleRate != 100f)
{
SampleRate = sampleRate;
}
Expand All @@ -82,7 +83,11 @@ public TelemetryItem(string name, TelemetryItem telemetryItem, ActivitySpanId ac
Tags[ContextTagKeys.AiCloudRoleInstance.ToString()] = telemetryItem.Tags[ContextTagKeys.AiCloudRoleInstance.ToString()];
Tags[ContextTagKeys.AiInternalSdkVersion.ToString()] = SdkVersionUtils.s_sdkVersion;
InstrumentationKey = telemetryItem.InstrumentationKey;
SampleRate = telemetryItem.SampleRate;

if (telemetryItem.SampleRate != 100f)
{
SampleRate = telemetryItem.SampleRate;
}
}

public TelemetryItem (LogRecord logRecord, AzureMonitorResource? resource, string instrumentationKey) :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ internal struct ActivityTagsProcessor
SemanticConventions.AttributeNetHostName,
SemanticConventions.AttributeComponent,
"otel.status_code",
"sampleRate",

SemanticConventions.AttributeRpcService,
// required - RPC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Azure.Monitor.OpenTelemetry.Exporter.Internals;
internal sealed class ApplicationInsightsSampler : Sampler
{
private static readonly SamplingResult RecordOnlySamplingResult = new(SamplingDecision.RecordOnly);
private readonly SamplingResult recordAndSampleSamplingResult;
private static readonly SamplingResult RecordAndSampleSamplingResult = new(SamplingDecision.RecordAndSample);
private readonly float samplingRatio;

/// <summary>
Expand All @@ -34,13 +34,6 @@ public ApplicationInsightsSampler(float samplingRatio)

this.samplingRatio = samplingRatio;
Description = "ApplicationInsightsSampler{" + samplingRatio + "}";
var sampleRate = (float)Math.Round(samplingRatio * 100);
recordAndSampleSamplingResult = new SamplingResult(
SamplingDecision.RecordAndSample,
new Dictionary<string, object>
{
{ "sampleRate", sampleRate },
});
}

/// <summary>
Expand All @@ -51,21 +44,21 @@ public ApplicationInsightsSampler(float samplingRatio)
/// <returns>Returns whether or not we should sample telemetry in the form of a <see cref="SamplingResult"/> class.</returns>
public override SamplingResult ShouldSample(in SamplingParameters samplingParameters)
{
if (samplingRatio == 0)
if (samplingRatio == 1)
{
return RecordOnlySamplingResult;
return RecordAndSampleSamplingResult;
}

if (samplingRatio == 1)
if (samplingRatio == 0)
{
return recordAndSampleSamplingResult;
return RecordOnlySamplingResult;
}

double sampleScore = DJB2SampleScore(samplingParameters.TraceId.ToHexString().ToUpperInvariant());

if (sampleScore < samplingRatio)
{
return recordAndSampleSamplingResult;
return RecordAndSampleSamplingResult;
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal static class TraceHelper
private const int Version = 2;
private const int MaxlinksAllowed = 100;

internal static List<TelemetryItem> OtelToAzureMonitorTrace(Batch<Activity> batchActivity, AzureMonitorResource? azureMonitorResource, string instrumentationKey)
internal static List<TelemetryItem> OtelToAzureMonitorTrace(Batch<Activity> batchActivity, AzureMonitorResource? azureMonitorResource, string instrumentationKey, float sampleRate)
{
List<TelemetryItem> telemetryItems = new List<TelemetryItem>();
TelemetryItem telemetryItem;
Expand All @@ -34,7 +34,7 @@ internal static List<TelemetryItem> OtelToAzureMonitorTrace(Batch<Activity> batc
try
{
var activityTagsProcessor = EnumerateActivityTags(activity);
telemetryItem = new TelemetryItem(activity, ref activityTagsProcessor, azureMonitorResource, instrumentationKey);
telemetryItem = new TelemetryItem(activity, ref activityTagsProcessor, azureMonitorResource, instrumentationKey, sampleRate);

// Check for Exceptions events
if (activity.Events.Any())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using Azure.Monitor.OpenTelemetry.Exporter.Internals;
using Azure.Monitor.OpenTelemetry.Exporter.Models;
using OpenTelemetry;
using OpenTelemetry.Logs;
Expand Down Expand Up @@ -69,7 +70,7 @@ internal static MeterProviderBuilder AddAzureMonitorMetricExporterForTest(this M
/// <summary>
/// Extension methods to simplify registering of <see cref="AzureMonitorTraceExporter"/> with <see cref="MockTransmitter"/> for unit tests.
/// </summary>
internal static TracerProviderBuilder AddAzureMonitorTraceExporterForTest(this TracerProviderBuilder builder, out List<TelemetryItem> telemetryItems)
internal static TracerProviderBuilder AddAzureMonitorTraceExporterForTest(this TracerProviderBuilder builder, out List<TelemetryItem> telemetryItems, Action<AzureMonitorExporterOptions>? configure = null)
{
if (builder == null)
{
Expand All @@ -78,7 +79,12 @@ internal static TracerProviderBuilder AddAzureMonitorTraceExporterForTest(this T

telemetryItems = new List<TelemetryItem>();

return builder.AddProcessor(new SimpleActivityExportProcessor(new AzureMonitorTraceExporter(new MockTransmitter(telemetryItems))));
var options = new AzureMonitorExporterOptions();
configure?.Invoke(options);

builder.SetSampler(new ApplicationInsightsSampler(options.SamplingRatio));

return builder.AddProcessor(new SimpleActivityExportProcessor(new AzureMonitorTraceExporter(options, new MockTransmitter(telemetryItems))));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ private static Activity CreateActivity(string activityName)
private static TelemetryItem CreateTelemetryItem(Activity activity)
{
var activityTagsProcessor = TraceHelper.EnumerateActivityTags(activity);
return new TelemetryItem(activity, ref activityTagsProcessor, null, string.Empty);
return new TelemetryItem(activity, ref activityTagsProcessor, null, string.Empty, 1.0f);
}

private class MockFileProvider : PersistentBlobProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,65 +35,40 @@ static SampleRateTests()

[Theory]
[InlineData(50.0F)]
[InlineData("somestring")]
[InlineData(null)]
[InlineData("")]
public void ValidateSampleRateForEventException(object SampleRate)
public void ValidateSampleRateForEventException(float sampleRate)
{
using ActivitySource activitySource = new ActivitySource(ActivitySourceName);

// Valid SampleRate.
using var activity = activitySource.StartActivity(
ActivityName,
ActivityKind.Client,
parentContext: default,
startTime: DateTime.UtcNow,
tags: new Dictionary<string, object?>() { ["sampleRate"] = SampleRate });
startTime: DateTime.UtcNow);

Assert.NotNull(activity);
var activityTagsProcessor = TraceHelper.EnumerateActivityTags(activity);
var telemetryItem = new TelemetryItem(activity, ref activityTagsProcessor, null, "00000000-0000-0000-0000-000000000000");
var telemetryItem = new TelemetryItem(activity, ref activityTagsProcessor, null, "00000000-0000-0000-0000-000000000000", sampleRate);
var expTelemetryItem = new TelemetryItem("Exception", telemetryItem, default, default, default);

if (SampleRate is float)
{
Assert.Equal(SampleRate, expTelemetryItem.SampleRate);
}
else
{
Assert.Null(expTelemetryItem.SampleRate);
}
Assert.Equal(sampleRate, expTelemetryItem.SampleRate);
}

[Theory]
[InlineData(50.0F)]
[InlineData("somestring")]
[InlineData(null)]
[InlineData("")]
public void ValidateSampleRateInTelemetry(object SampleRate)
public void ValidateSampleRateInTelemetry(float sampleRate)
{
using ActivitySource activitySource = new ActivitySource(ActivitySourceName);

// Valid SampleRate.
using var activity = activitySource.StartActivity(
ActivityName,
ActivityKind.Client,
parentContext: default,
startTime: DateTime.UtcNow,
tags: new Dictionary<string, object?>() { ["sampleRate"] = SampleRate });
startTime: DateTime.UtcNow);

Assert.NotNull(activity);
var activityTagsProcessor = TraceHelper.EnumerateActivityTags(activity);
var telemetryItem = new TelemetryItem(activity, ref activityTagsProcessor, null, "00000000-0000-0000-0000-000000000000");
var telemetryItem = new TelemetryItem(activity, ref activityTagsProcessor, null, "00000000-0000-0000-0000-000000000000", sampleRate);

if (SampleRate is float)
{
Assert.Equal(SampleRate, telemetryItem.SampleRate);
}
else
{
Assert.Null(telemetryItem.SampleRate);
}
Assert.Equal(sampleRate, telemetryItem.SampleRate);
}

[Fact]
Expand All @@ -102,8 +77,7 @@ public void SampleRateE2ETest()
using var activitySource = new ActivitySource(ActivitySourceName);
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource(ActivitySourceName)
.SetSampler(new ApplicationInsightsSampler(samplingRatio: 1.0F))
.AddAzureMonitorTraceExporterForTest(out List<TelemetryItem> telemetryItems)
.AddAzureMonitorTraceExporterForTest(out List<TelemetryItem> telemetryItems, options => options.SamplingRatio = 1.0F)
.Build();

using (var activity = activitySource.StartActivity("SayHello"))
Expand All @@ -113,7 +87,7 @@ public void SampleRateE2ETest()
tracerProvider?.ForceFlush();

Assert.NotEmpty(telemetryItems);
Assert.Equal(100F, telemetryItems.Last()!.SampleRate);
Assert.Null(telemetryItems.Last()!.SampleRate);
}

[Fact]
Expand All @@ -122,8 +96,7 @@ public void NoTelemetryCreatedOnZeroSampleRate()
using var activitySource = new ActivitySource(ActivitySourceName);
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource(ActivitySourceName)
.SetSampler(new ApplicationInsightsSampler(samplingRatio: 0.0F))
.AddAzureMonitorTraceExporterForTest(out List<TelemetryItem> telemetryItems)
.AddAzureMonitorTraceExporterForTest(out List<TelemetryItem> telemetryItems, options => options.SamplingRatio = 0.0F)
.Build();

using (var activity = activitySource.StartActivity("SayHello"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void ValidateRequestDurationMetric()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddAttributes(resourceAttributes))
.AddSource(nameof(StandardMetricTests.ValidateRequestDurationMetric))
.AddProcessor(standardMetricCustomProcessor)
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new MockTransmitter(traceTelemetryItems))))
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new AzureMonitorExporterOptions(), new MockTransmitter(traceTelemetryItems))))
.Build();

using (var activity = activitySource.StartActivity("Test", ActivityKind.Server))
Expand Down Expand Up @@ -85,7 +85,7 @@ public void ValidateRequestDurationMetricNew()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddAttributes(resourceAttributes))
.AddSource(nameof(StandardMetricTests.ValidateRequestDurationMetric))
.AddProcessor(standardMetricCustomProcessor)
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new MockTransmitter(traceTelemetryItems))))
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new AzureMonitorExporterOptions(), new MockTransmitter(traceTelemetryItems))))
.Build();

using (var activity = activitySource.StartActivity("Test", ActivityKind.Server))
Expand Down Expand Up @@ -134,7 +134,7 @@ public void ValidateDependencyDurationMetric()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddAttributes(resourceAttributes))
.AddSource(nameof(StandardMetricTests.ValidateDependencyDurationMetric))
.AddProcessor(standardMetricCustomProcessor)
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new MockTransmitter(traceTelemetryItems))))
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new AzureMonitorExporterOptions(), new MockTransmitter(traceTelemetryItems))))
.Build();

using (var activity = activitySource.StartActivity("Test", ActivityKind.Client))
Expand Down Expand Up @@ -189,7 +189,7 @@ public void ValidateDependencyDurationMetricNew()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddAttributes(resourceAttributes))
.AddSource(nameof(StandardMetricTests.ValidateDependencyDurationMetric))
.AddProcessor(standardMetricCustomProcessor)
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new MockTransmitter(traceTelemetryItems))))
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new AzureMonitorExporterOptions(), new MockTransmitter(traceTelemetryItems))))
.Build();

using (var activity = activitySource.StartActivity("Test", ActivityKind.Client))
Expand Down Expand Up @@ -242,7 +242,7 @@ public void ValidateNullStatusCode(ActivityKind kind)
.SetSampler(new AlwaysOnSampler())
.AddSource(nameof(StandardMetricTests.ValidateNullStatusCode))
.AddProcessor(standardMetricCustomProcessor)
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new MockTransmitter(traceTelemetryItems))))
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new AzureMonitorExporterOptions(), new MockTransmitter(traceTelemetryItems))))
.Build();

using (var activity = activitySource.StartActivity("Test", kind))
Expand Down Expand Up @@ -290,7 +290,7 @@ public void ValidateNullStatusCodeNew(ActivityKind kind)
.SetSampler(new AlwaysOnSampler())
.AddSource(nameof(StandardMetricTests.ValidateNullStatusCode))
.AddProcessor(standardMetricCustomProcessor)
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new MockTransmitter(traceTelemetryItems))))
.AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new AzureMonitorExporterOptions(), new MockTransmitter(traceTelemetryItems))))
.Build();

using (var activity = activitySource.StartActivity("Test", kind))
Expand Down
Loading

0 comments on commit 484f51f

Please sign in to comment.