From 9f41eadf03f3dcc5e76c686b61fb39849f046312 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 25 Oct 2024 10:58:18 -0700 Subject: [PATCH] [sdk-metrics] Promote overflow attribute from experimental to stable (#5909) Co-authored-by: Reiley Yang Co-authored-by: Mikel Blanchard --- docs/metrics/README.md | 25 ++--- src/OpenTelemetry/CHANGELOG.md | 25 +++++ src/OpenTelemetry/Metrics/AggregatorStore.cs | 47 ++------- src/OpenTelemetry/Metrics/MeterProviderSdk.cs | 10 +- src/OpenTelemetry/Metrics/Metric.cs | 2 - .../Metrics/Reader/MetricReaderExt.cs | 5 - .../Metrics/AggregatorTestsBase.cs | 29 +----- .../Metrics/MetricApiTestsBase.cs | 32 +----- .../MetricOverflowAttributeTestsBase.cs | 98 ------------------- .../Metrics/MetricPointReclaimTestsBase.cs | 20 +--- .../Metrics/MetricSnapshotTestsBase.cs | 23 +---- .../Metrics/MetricTestsBase.cs | 1 - 12 files changed, 60 insertions(+), 257 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index db91e62f529..0394f63451b 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -10,11 +10,13 @@ * [Instruments](#instruments) * [MeterProvider Management](#meterprovider-management) * [Memory Management](#memory-management) + * [Example](#example) * [Pre-Aggregation](#pre-aggregation) * [Cardinality Limits](#cardinality-limits) * [Memory Preallocation](#memory-preallocation) * [Metrics Correlation](#metrics-correlation) * [Metrics Enrichment](#metrics-enrichment) +* [Common issues that lead to missing metrics](#common-issues-that-lead-to-missing-metrics) @@ -386,22 +388,13 @@ and the `MetricStreamConfiguration.CardinalityLimit` setting. Refer to this [doc](../../docs/metrics/customizing-the-sdk/README.md#changing-the-cardinality-limit-for-a-metric) for more information. -Given a metric, once the cardinality limit is reached, any new measurement which -cannot be independently aggregated because of the limit will be dropped or -aggregated using the [overflow -attribute](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute) -(if enabled). When NOT using the overflow attribute feature a warning is written -to the [self-diagnostic log](../../src/OpenTelemetry/README.md#self-diagnostics) -the first time an overflow is detected for a given metric. - -> [!NOTE] -> Overflow attribute was introduced in OpenTelemetry .NET - [1.6.0-rc.1](../../src/OpenTelemetry/CHANGELOG.md#160-rc1). It is currently an - experimental feature which can be turned on by setting the environment - variable `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE=true`. Once - the [OpenTelemetry - Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute) - become stable, this feature will be turned on by default. +Given a metric, once the cardinality limit is reached, any new measurement +that could not be independently aggregated will be aggregated using the +[overflow attribute](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute). +In versions prior to 1.10.0, the default behavior when cardinality limit was +reached was to drop the measurement. Users had the ability to opt-in to use +overflow attribute instead, but this behavior is the default and the only +allowed behavior starting with version 1.10.0. When [Delta Aggregation Temporality](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#temporality) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index d14170c35f1..0f2bbd74d7c 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -6,6 +6,31 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* Promoted overflow attribute from experimental to stable and removed the + `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` environment variable. + + **Previous Behavior:** + By default, when the cardinality limit was reached, measurements were dropped, + and an internal log was emitted the first time this occurred. Users could + opt-in to experimental overflow attribute feature with + `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE=true`. + With this setting, the SDK would use an overflow attribute + (`otel.metric.overflow = true`) to aggregate measurements instead of dropping + measurements. No internal log was emitted in this case. + + **New Behavior:** + The SDK now always uses the overflow attribute (`otel.metric.overflow = true`) + to aggregate measurements when the cardinality limit is reached. The previous + approach of dropping measurements has been removed. No internal logs are + emitted when the limit is hit. + + The default cardinality limit remains 2000 per metric. To set the cardinality + limit for an individual metric, use the [changing cardinality limit for a + Metric](../../docs/metrics/customizing-the-sdk/README.md#changing-the-cardinality-limit-for-a-metric). + + There is NO ability to revert to old behavior. + ([#5909](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5909)) + ## 1.10.0-beta.1 Released 2024-Sep-30 diff --git a/src/OpenTelemetry/Metrics/AggregatorStore.cs b/src/OpenTelemetry/Metrics/AggregatorStore.cs index fbbd598a67a..b7d560b559f 100644 --- a/src/OpenTelemetry/Metrics/AggregatorStore.cs +++ b/src/OpenTelemetry/Metrics/AggregatorStore.cs @@ -22,13 +22,11 @@ internal sealed class AggregatorStore internal readonly bool OutputDelta; internal readonly bool OutputDeltaWithUnusedMetricPointReclaimEnabled; internal readonly int NumberOfMetricPoints; - internal readonly bool EmitOverflowAttribute; internal readonly ConcurrentDictionary? TagsToMetricPointIndexDictionaryDelta; internal readonly Func? ExemplarReservoirFactory; internal long DroppedMeasurements = 0; private const ExemplarFilterType DefaultExemplarFilter = ExemplarFilterType.AlwaysOff; - 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); private readonly Lock lockZeroTags = new(); @@ -42,7 +40,6 @@ internal sealed class AggregatorStore new(); private readonly string name; - private readonly string metricPointCapHitMessage; private readonly MetricPoint[] metricPoints; private readonly int[] currentMetricPointBatch; private readonly AggregationType aggType; @@ -56,7 +53,6 @@ internal sealed class AggregatorStore private int metricPointIndex = 0; private int batchSize = 0; - private int metricCapHitMessageLogged; private bool zeroTagMetricPointInitialized; private bool overflowTagMetricPointInitialized; @@ -65,7 +61,6 @@ internal AggregatorStore( AggregationType aggType, AggregationTemporality temporality, int cardinalityLimit, - bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints, ExemplarFilterType? exemplarFilter = null, Func? exemplarReservoirFactory = null) @@ -77,7 +72,6 @@ internal AggregatorStore( // Previously, these were included within the original cardinalityLimit, but now they are explicitly added to enhance clarity. this.NumberOfMetricPoints = cardinalityLimit + 2; - this.metricPointCapHitMessage = $"Maximum MetricPoints limit reached for this Metric stream. Configured limit: {cardinalityLimit}"; this.metricPoints = new MetricPoint[this.NumberOfMetricPoints]; this.currentMetricPointBatch = new int[this.NumberOfMetricPoints]; this.aggType = aggType; @@ -105,8 +99,6 @@ internal AggregatorStore( this.tagsKeysInterestingCount = hs.Count; } - this.EmitOverflowAttribute = emitOverflowAttribute; - this.exemplarFilter = exemplarFilter ?? DefaultExemplarFilter; Debug.Assert( this.exemplarFilter == ExemplarFilterType.AlwaysOff @@ -245,17 +237,14 @@ internal void SnapshotDeltaWithMetricPointReclaim() this.batchSize++; } - if (this.EmitOverflowAttribute) + // TakeSnapshot for the MetricPoint for overflow + ref var metricPointForOverflow = ref this.metricPoints[1]; + if (metricPointForOverflow.MetricPointStatus != MetricPointStatus.NoCollectPending) { - // TakeSnapshot for the MetricPoint for overflow - ref var metricPointForOverflow = ref this.metricPoints[1]; - if (metricPointForOverflow.MetricPointStatus != MetricPointStatus.NoCollectPending) - { - this.TakeMetricPointSnapshot(ref metricPointForOverflow, outputDelta: true); + this.TakeMetricPointSnapshot(ref metricPointForOverflow, outputDelta: true); - this.currentMetricPointBatch[this.batchSize] = 1; - this.batchSize++; - } + this.currentMetricPointBatch[this.batchSize] = 1; + this.batchSize++; } // Index 0 and 1 are reserved for no tags and overflow @@ -994,16 +983,8 @@ private void UpdateLongMetricPoint(int metricPointIndex, long value, ReadOnlySpa if (metricPointIndex < 0) { Interlocked.Increment(ref this.DroppedMeasurements); - - if (this.EmitOverflowAttribute) - { - this.InitializeOverflowTagPointIfNotInitialized(); - this.metricPoints[1].Update(value); - } - else if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) - { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); - } + this.InitializeOverflowTagPointIfNotInitialized(); + this.metricPoints[1].Update(value); return; } @@ -1049,16 +1030,8 @@ private void UpdateDoubleMetricPoint(int metricPointIndex, double value, ReadOnl if (metricPointIndex < 0) { Interlocked.Increment(ref this.DroppedMeasurements); - - if (this.EmitOverflowAttribute) - { - this.InitializeOverflowTagPointIfNotInitialized(); - this.metricPoints[1].Update(value); - } - else if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) - { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); - } + this.InitializeOverflowTagPointIfNotInitialized(); + this.metricPoints[1].Update(value); return; } diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index 0ec16a9c20a..a83666bb4c3 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -13,7 +13,6 @@ namespace OpenTelemetry.Metrics; internal sealed class MeterProviderSdk : MeterProvider { - internal const string EmitOverFlowAttributeConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE"; internal const string ReclaimUnusedMetricPointsConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_RECLAIM_UNUSED_METRIC_POINTS"; internal const string ExemplarFilterConfigKey = "OTEL_METRICS_EXEMPLAR_FILTER"; internal const string ExemplarFilterHistogramsConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_EXEMPLAR_FILTER_HISTOGRAMS"; @@ -22,7 +21,6 @@ internal sealed class MeterProviderSdk : MeterProvider internal readonly IDisposable? OwnedServiceProvider; internal int ShutdownCount; internal bool Disposed; - internal bool EmitOverflowAttribute; internal bool ReclaimUnusedMetricPoints; internal ExemplarFilterType? ExemplarFilter; internal ExemplarFilterType? ExemplarFilterForHistograms; @@ -75,7 +73,7 @@ internal MeterProviderSdk( this.viewConfigs = state.ViewConfigs; OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent( - $"MeterProvider configuration: {{MetricLimit={state.MetricLimit}, CardinalityLimit={state.CardinalityLimit}, EmitOverflowAttribute={this.EmitOverflowAttribute}, ReclaimUnusedMetricPoints={this.ReclaimUnusedMetricPoints}, ExemplarFilter={this.ExemplarFilter}, ExemplarFilterForHistograms={this.ExemplarFilterForHistograms}}}."); + $"MeterProvider configuration: {{MetricLimit={state.MetricLimit}, CardinalityLimit={state.CardinalityLimit}, ReclaimUnusedMetricPoints={this.ReclaimUnusedMetricPoints}, ExemplarFilter={this.ExemplarFilter}, ExemplarFilterForHistograms={this.ExemplarFilterForHistograms}}}."); foreach (var reader in state.Readers) { @@ -86,7 +84,6 @@ internal MeterProviderSdk( reader.ApplyParentProviderSettings( state.MetricLimit, state.CardinalityLimit, - this.EmitOverflowAttribute, this.ReclaimUnusedMetricPoints, this.ExemplarFilter, this.ExemplarFilterForHistograms); @@ -486,11 +483,6 @@ protected override void Dispose(bool disposing) private void ApplySpecificationConfigurationKeys(IConfiguration configuration) { - if (configuration.TryGetBoolValue(OpenTelemetrySdkEventSource.Log, EmitOverFlowAttributeConfigKey, out this.EmitOverflowAttribute)) - { - OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent("Overflow attribute feature enabled via configuration."); - } - if (configuration.TryGetBoolValue(OpenTelemetrySdkEventSource.Log, ReclaimUnusedMetricPointsConfigKey, out this.ReclaimUnusedMetricPoints)) { OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent("Reclaim unused metric point feature enabled via configuration."); diff --git a/src/OpenTelemetry/Metrics/Metric.cs b/src/OpenTelemetry/Metrics/Metric.cs index 7ecb10e519f..38abf4cc622 100644 --- a/src/OpenTelemetry/Metrics/Metric.cs +++ b/src/OpenTelemetry/Metrics/Metric.cs @@ -70,7 +70,6 @@ internal Metric( MetricStreamIdentity instrumentIdentity, AggregationTemporality temporality, int cardinalityLimit, - bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints, ExemplarFilterType? exemplarFilter = null, Func? exemplarReservoirFactory = null) @@ -193,7 +192,6 @@ internal Metric( aggType, temporality, cardinalityLimit, - emitOverflowAttribute, shouldReclaimUnusedMetricPoints, exemplarFilter, exemplarReservoirFactory); diff --git a/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs b/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs index f22208c8b61..194383a37a8 100644 --- a/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/Reader/MetricReaderExt.cs @@ -22,7 +22,6 @@ public abstract partial class MetricReader private Metric?[]? metrics; private Metric[]? metricsCurrentBatch; private int metricIndex = -1; - private bool emitOverflowAttribute; private bool reclaimUnusedMetricPoints; private ExemplarFilterType? exemplarFilter; private ExemplarFilterType? exemplarFilterForHistograms; @@ -82,7 +81,6 @@ internal virtual List AddMetricWithNoViews(Instrument instrument) metricStreamIdentity, this.GetAggregationTemporality(metricStreamIdentity.InstrumentType), this.cardinalityLimit, - this.emitOverflowAttribute, this.reclaimUnusedMetricPoints, exemplarFilter); } @@ -164,7 +162,6 @@ internal virtual List AddMetricWithViews(Instrument instrument, List AddMetricWithViews(Instrument instrument, List>()); @@ -525,15 +520,7 @@ public ThreadArguments(MetricPoint histogramPoint, ManualResetEvent mreToEnsureA public class AggregatorTests : AggregatorTestsBase { public AggregatorTests() - : base(emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: false) - { - } -} - -public class AggregatorTestsWithOverflowAttribute : AggregatorTestsBase -{ - public AggregatorTestsWithOverflowAttribute() - : base(emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: false) + : base(shouldReclaimUnusedMetricPoints: false) { } } @@ -541,15 +528,7 @@ public AggregatorTestsWithOverflowAttribute() public class AggregatorTestsWithReclaimAttribute : AggregatorTestsBase { public AggregatorTestsWithReclaimAttribute() - : base(emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: true) - { - } -} - -public class AggregatorTestsWithBothReclaimAndOverflowAttributes : AggregatorTestsBase -{ - public AggregatorTestsWithBothReclaimAndOverflowAttributes() - : base(emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: true) + : base(shouldReclaimUnusedMetricPoints: true) { } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs index c84b1b1ef7d..9c6735f7bcb 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs @@ -23,8 +23,8 @@ public abstract class MetricApiTestsBase : MetricTestsBase private static readonly int NumberOfMetricUpdateByEachThread = 100000; private readonly ITestOutputHelper output; - protected MetricApiTestsBase(ITestOutputHelper output, bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints) - : base(BuildConfiguration(emitOverflowAttribute, shouldReclaimUnusedMetricPoints)) + protected MetricApiTestsBase(ITestOutputHelper output, bool shouldReclaimUnusedMetricPoints) + : base(BuildConfiguration(shouldReclaimUnusedMetricPoints)) { this.output = output; } @@ -1410,7 +1410,6 @@ int MetricPointCount() enumerator.MoveNext(); // Second element reserved for overflow attribute. // Validate second element is overflow attribute. - // Overflow attribute is behind experimental flag. So, it is not guaranteed to be present. var tagEnumerator = enumerator.Current.Tags.GetEnumerator(); tagEnumerator.MoveNext(); if (!tagEnumerator.Current.Key.Contains("otel.metric.overflow")) @@ -1704,15 +1703,10 @@ public void GaugeHandlesNoNewMeasurementsCorrectlyWithTemporality(MetricReaderTe } } - internal static IConfiguration BuildConfiguration(bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints) + internal static IConfiguration BuildConfiguration(bool shouldReclaimUnusedMetricPoints) { var configurationData = new Dictionary(); - if (emitOverflowAttribute) - { - configurationData[EmitOverFlowAttributeConfigKey] = "true"; - } - if (shouldReclaimUnusedMetricPoints) { configurationData[ReclaimUnusedMetricPointsConfigKey] = "true"; @@ -1894,15 +1888,7 @@ public UpdateThreadArguments(ManualResetEvent mreToBlockUpdateThread, ManualRese public class MetricApiTest : MetricApiTestsBase { public MetricApiTest(ITestOutputHelper output) - : base(output, emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: false) - { - } -} - -public class MetricApiTestWithOverflowAttribute : MetricApiTestsBase -{ - public MetricApiTestWithOverflowAttribute(ITestOutputHelper output) - : base(output, emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: false) + : base(output, shouldReclaimUnusedMetricPoints: false) { } } @@ -1910,15 +1896,7 @@ public MetricApiTestWithOverflowAttribute(ITestOutputHelper output) public class MetricApiTestWithReclaimAttribute : MetricApiTestsBase { public MetricApiTestWithReclaimAttribute(ITestOutputHelper output) - : base(output, emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: true) - { - } -} - -public class MetricApiTestWithBothOverflowAndReclaimAttributes : MetricApiTestsBase -{ - public MetricApiTestWithBothOverflowAndReclaimAttributes(ITestOutputHelper output) - : base(output, emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: true) + : base(output, shouldReclaimUnusedMetricPoints: true) { } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs index 43d91819232..6145de4d98a 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricOverflowAttributeTestsBase.cs @@ -16,7 +16,6 @@ public abstract class MetricOverflowAttributeTestsBase private readonly bool shouldReclaimUnusedMetricPoints; private readonly Dictionary configurationData = new() { - [MetricTestsBase.EmitOverFlowAttributeConfigKey] = "true", }; private readonly IConfiguration configuration; @@ -35,103 +34,6 @@ public MetricOverflowAttributeTestsBase(bool shouldReclaimUnusedMetricPoints) .Build(); } - [Theory] - [InlineData("false", false)] - [InlineData("False", false)] - [InlineData("FALSE", false)] - [InlineData("true", true)] - [InlineData("True", true)] - [InlineData("TRUE", true)] - public void TestEmitOverflowAttributeConfigWithEnvVar(string value, bool isEmitOverflowAttributeKeySet) - { - // Clear the environment variable value first - Environment.SetEnvironmentVariable(MetricTestsBase.EmitOverFlowAttributeConfigKey, null); - - // Set the environment variable to the value provided in the test input - Environment.SetEnvironmentVariable(MetricTestsBase.EmitOverFlowAttributeConfigKey, value); - - var exportedItems = new List(); - - var meter = new Meter(Utils.GetCurrentMethodName()); - var counter = meter.CreateCounter("TestCounter"); - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter(meter.Name) - .AddInMemoryExporter(exportedItems) - .Build(); - - counter.Add(10); - - meterProvider.ForceFlush(); - - Assert.Single(exportedItems); - Assert.Equal(isEmitOverflowAttributeKeySet, exportedItems[0].AggregatorStore.EmitOverflowAttribute); - } - - [Theory] - [InlineData("false", false)] - [InlineData("False", false)] - [InlineData("FALSE", false)] - [InlineData("true", true)] - [InlineData("True", true)] - [InlineData("TRUE", true)] - public void TestEmitOverflowAttributeConfigWithOtherConfigProvider(string value, bool isEmitOverflowAttributeKeySet) - { - var exportedItems = new List(); - - var meter = new Meter(Utils.GetCurrentMethodName()); - var counter = meter.CreateCounter("TestCounter"); - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .ConfigureServices(services => - { - var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { [MetricTestsBase.EmitOverFlowAttributeConfigKey] = value }) - .Build(); - - services.AddSingleton(configuration); - }) - .AddMeter(meter.Name) - .AddInMemoryExporter(exportedItems) - .Build(); - - counter.Add(10); - - meterProvider.ForceFlush(); - - Assert.Single(exportedItems); - Assert.Equal(isEmitOverflowAttributeKeySet, exportedItems[0].AggregatorStore.EmitOverflowAttribute); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - [InlineData(10)] - public void EmitOverflowAttributeIsNotDependentOnMaxMetricPoints(int maxMetricPoints) - { - var exportedItems = new List(); - - var meter = new Meter(Utils.GetCurrentMethodName()); - var counter = meter.CreateCounter("TestCounter"); - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .ConfigureServices(services => - { - services.AddSingleton(this.configuration); - }) - .SetMaxMetricPointsPerMetricStream(maxMetricPoints) - .AddMeter(meter.Name) - .AddInMemoryExporter(exportedItems) - .Build(); - - counter.Add(10); - - meterProvider.ForceFlush(); - - Assert.Single(exportedItems); - Assert.True(exportedItems[0].AggregatorStore.EmitOverflowAttribute); - } - [Theory] [InlineData(MetricReaderTemporalityPreference.Delta)] [InlineData(MetricReaderTemporalityPreference.Cumulative)] diff --git a/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs index f455967884a..effe208eda3 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs @@ -20,13 +20,8 @@ public abstract class MetricPointReclaimTestsBase private readonly IConfiguration configuration; - protected MetricPointReclaimTestsBase(bool emitOverflowAttribute) + protected MetricPointReclaimTestsBase() { - if (emitOverflowAttribute) - { - this.configurationData[MetricTestsBase.EmitOverFlowAttributeConfigKey] = "true"; - } - this.configuration = new ConfigurationBuilder() .AddInMemoryCollection(this.configurationData) .Build(); @@ -213,8 +208,7 @@ public void MeasurementsAreAggregatedEvenAfterTheyAreDropped(bool emitMetricWith .Build(); // Add 10 distinct combinations of dimensions to surpass the max metric points limit of 10. - // Note that one MetricPoint is reserved for zero tags and one MetricPoint is optionally - // reserved for the overflow tag depending on the user's input. + // Note that one MetricPoint is reserved for zero tags and one MetricPoint is reserved for the overflow tag. // This would lead to dropping a few measurements. We want to make sure that they can still be // aggregated later on when there are free MetricPoints available. for (int i = 0; i < 10; i++) @@ -333,15 +327,7 @@ public override ExportResult Export(in Batch batch) public class MetricPointReclaimTests : MetricPointReclaimTestsBase { public MetricPointReclaimTests() - : base(emitOverflowAttribute: false) - { - } -} - -public class MetricPointReclaimTestsWithEmitOverflowAttribute : MetricPointReclaimTestsBase -{ - public MetricPointReclaimTestsWithEmitOverflowAttribute() - : base(emitOverflowAttribute: true) + : base() { } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTestsBase.cs index 08ce90ffe44..54b8ed95868 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricSnapshotTestsBase.cs @@ -16,10 +16,9 @@ public abstract class MetricSnapshotTestsBase { private readonly IConfiguration configuration; - protected MetricSnapshotTestsBase(bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints) + protected MetricSnapshotTestsBase(bool shouldReclaimUnusedMetricPoints) { this.configuration = MetricApiTestsBase.BuildConfiguration( - emitOverflowAttribute, shouldReclaimUnusedMetricPoints); } @@ -298,15 +297,7 @@ public void VerifySnapshot_ExponentialHistogram() public class MetricSnapshotTests : MetricSnapshotTestsBase { public MetricSnapshotTests() - : base(emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: false) - { - } -} - -public class MetricSnapshotTestsWithOverflowAttribute : MetricSnapshotTestsBase -{ - public MetricSnapshotTestsWithOverflowAttribute() - : base(emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: false) + : base(shouldReclaimUnusedMetricPoints: false) { } } @@ -314,15 +305,7 @@ public MetricSnapshotTestsWithOverflowAttribute() public class MetricSnapshotTestsWithReclaimAttribute : MetricSnapshotTestsBase { public MetricSnapshotTestsWithReclaimAttribute() - : base(emitOverflowAttribute: false, shouldReclaimUnusedMetricPoints: true) - { - } -} - -public class MetricSnapshotTestsWithBothAttributes : MetricSnapshotTestsBase -{ - public MetricSnapshotTestsWithBothAttributes() - : base(emitOverflowAttribute: true, shouldReclaimUnusedMetricPoints: true) + : base(shouldReclaimUnusedMetricPoints: true) { } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs index 92b65f2b97f..746c3b6aeb3 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricTestsBase.cs @@ -16,7 +16,6 @@ namespace OpenTelemetry.Metrics.Tests; public class MetricTestsBase { - public const string EmitOverFlowAttributeConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE"; public const string ReclaimUnusedMetricPointsConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_RECLAIM_UNUSED_METRIC_POINTS"; protected readonly IConfiguration? configuration;