From 307deadb9c0b6998edf5c43b5b2ac5a5be613158 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 17 Apr 2024 11:57:31 -0700 Subject: [PATCH 1/5] Turn exemplars on by default for prerelease builds to match spec. --- .../.publicApi/Experimental/PublicAPI.Unshipped.txt | 2 +- src/OpenTelemetry/Metrics/AggregatorStore.cs | 4 ++++ .../Metrics/Builder/MeterProviderBuilderExtensions.cs | 8 ++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt index 8c1a746f041..e9666e921c2 100644 --- a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -47,7 +47,7 @@ static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.SetResourceBuilder(thi static OpenTelemetry.Logs.LoggerProviderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProvider! provider, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProvider! static OpenTelemetry.Logs.LoggerProviderExtensions.ForceFlush(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool static OpenTelemetry.Logs.LoggerProviderExtensions.Shutdown(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetExemplarFilter(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.ExemplarFilterType exemplarFilter = OpenTelemetry.Metrics.ExemplarFilterType.TraceBased) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetExemplarFilter(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.ExemplarFilterType exemplarFilter) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action? configureBuilder, System.Action? configureOptions) -> OpenTelemetry.IOpenTelemetryBuilder! diff --git a/src/OpenTelemetry/Metrics/AggregatorStore.cs b/src/OpenTelemetry/Metrics/AggregatorStore.cs index bb806a01491..deb1e8bae51 100644 --- a/src/OpenTelemetry/Metrics/AggregatorStore.cs +++ b/src/OpenTelemetry/Metrics/AggregatorStore.cs @@ -27,7 +27,11 @@ internal sealed class AggregatorStore internal readonly Func? ExemplarReservoirFactory; internal long DroppedMeasurements = 0; +#if EXPOSE_EXPERIMENTAL_FEATURES + private const ExemplarFilterType DefaultExemplarFilter = ExemplarFilterType.TraceBased; +#else private const ExemplarFilterType DefaultExemplarFilter = ExemplarFilterType.AlwaysOff; +#endif private static readonly string MetricPointCapHitFixMessage = "Consider opting in for the experimental SDK feature to emit all the throttled metrics under the overflow attribute by setting env variable OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE = true. You could also modify instrumentation to reduce the number of unique key/value pair combinations. Or use Views to drop unwanted tags. Or use MeterProviderBuilder.SetMaxMetricPointsPerMetricStream to set higher limit."; private static readonly Comparison> DimensionComparisonDelegate = (x, y) => x.Key.CompareTo(y.Key); diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs index 6a36562aa45..66b4575c326 100644 --- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs @@ -322,13 +322,13 @@ public static MeterProvider Build(this MeterProviderBuilder meterProviderBuilder /// Sets the to be used for this provider /// which controls how measurements will be offered to exemplar reservoirs. /// Default provider configuration: . + /// cref="ExemplarFilterType.TraceBased"/>. /// /// /// - /// Note: Use or to enable exemplars. + /// Note: Use to disable + /// exemplars. /// Specification: . /// @@ -347,7 +347,7 @@ public static MeterProvider Build(this MeterProviderBuilder meterProviderBuilder #endif static MeterProviderBuilder SetExemplarFilter( this MeterProviderBuilder meterProviderBuilder, - ExemplarFilterType exemplarFilter = ExemplarFilterType.TraceBased) + ExemplarFilterType exemplarFilter) { meterProviderBuilder.ConfigureBuilder((sp, builder) => { From e12014f0c1ff03007a1e14b9e73204a044ad56bf Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 17 Apr 2024 16:00:26 -0700 Subject: [PATCH 2/5] Verify default exemplar filter in tests. --- .../Metrics/MetricExemplarTests.cs | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs index 2499c825b6a..ceed85e5102 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs @@ -643,9 +643,11 @@ static void ValidateSecondPhase( } [Theory] - [InlineData(true)] - [InlineData(false)] - public void TestTraceBasedExemplarFilter(bool enableTracing) + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(true, true)] + [InlineData(false, true)] + public void TestTraceBasedExemplarFilter(bool enableTracing, bool setExemplarFilter) { var exportedItems = new List(); @@ -653,10 +655,18 @@ public void TestTraceBasedExemplarFilter(bool enableTracing) var counter = meter.CreateCounter("testCounter"); - using var container = this.BuildMeterProvider(out var meterProvider, builder => builder - .AddMeter(meter.Name) - .SetExemplarFilter(ExemplarFilterType.TraceBased) - .AddInMemoryExporter(exportedItems)); + using var container = this.BuildMeterProvider(out var meterProvider, builder => + { + builder + .AddMeter(meter.Name) + .AddInMemoryExporter(exportedItems); + + if (setExemplarFilter) + { + // Note: TraceBased is the SDK default + builder.SetExemplarFilter(ExemplarFilterType.TraceBased); + } + }); if (enableTracing) { From dc59a27263874a866f7b886c1af6673e624a93a4 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 17 Apr 2024 16:06:53 -0700 Subject: [PATCH 3/5] CHANGELOG patch. --- src/OpenTelemetry/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 556c3064379..fc4c9369613 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -12,6 +12,11 @@ function when configuring a view (applies to individual metrics). ([#5542](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5542)) +* **Experimental (pre-release builds only):** The default `ExemplarFilterType` + on `MeterProvider` is now `ExemplarFilterType.TraceBased` which will enable + `Exemplar`s automatically when tracing is used with metrics. + ([#5545](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5545)) + ## 1.8.0 Released 2024-Apr-02 From 2e6f1418cf8db165050709ceb0c3732143b5b00a Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 18 Apr 2024 10:11:20 -0700 Subject: [PATCH 4/5] Test fix for stable builds. --- test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs index ceed85e5102..de3a5577a10 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricExemplarTests.cs @@ -661,9 +661,9 @@ public void TestTraceBasedExemplarFilter(bool enableTracing, bool setExemplarFil .AddMeter(meter.Name) .AddInMemoryExporter(exportedItems); - if (setExemplarFilter) + if (!IsExemplarApiExposed() || setExemplarFilter) { - // Note: TraceBased is the SDK default + // Note: TraceBased is the SDK default for prerelease builds only builder.SetExemplarFilter(ExemplarFilterType.TraceBased); } }); From 02356224b3fb46024755331f3b00d4c94118d3c8 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 18 Apr 2024 10:18:29 -0700 Subject: [PATCH 5/5] Tweak CHANGELOG. --- src/OpenTelemetry/CHANGELOG.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 89198a2e98f..803f3842b0b 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -7,9 +7,11 @@ function when configuring a view (applies to individual metrics). ([#5542](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5542)) -* **Experimental (pre-release builds only):** The default `ExemplarFilterType` - on `MeterProvider` is now `ExemplarFilterType.TraceBased` which will enable - `Exemplar`s automatically when tracing is used with metrics. +* **Experimental (pre-release builds only):** `Exemplar`s are now enabled + automatically with the default filter type set to `TraceBased`. `Exemplar`s + will be sampled for measurements recorded under an active trace. The default + filter can be changed by calling the `SetExemplarFilter` extension on + `MeterProviderBuilder`. Use `AlwaysOff` to disable `Exemplar`s. ([#5545](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5545)) ## 1.8.1