From 70703939c70998eba88a5fc40fe14d0b4394bdda Mon Sep 17 00:00:00 2001 From: Sean Li Date: Thu, 17 Oct 2024 17:06:07 -0700 Subject: [PATCH 01/12] Promote overflow attribute from experimental to stable --- docs/metrics/README.md | 8 +- src/OpenTelemetry/CHANGELOG.md | 4 + src/OpenTelemetry/Metrics/AggregatorStore.cs | 41 +++----- src/OpenTelemetry/Metrics/MeterProviderSdk.cs | 10 +- src/OpenTelemetry/Metrics/Metric.cs | 2 - .../Metrics/Reader/MetricReaderExt.cs | 5 - .../Metrics/AggregatorTestsBase.cs | 29 +----- .../Metrics/MetricApiTestsBase.cs | 31 +----- .../MetricOverflowAttributeTestsBase.cs | 98 ------------------- .../Metrics/MetricPointReclaimTestsBase.cs | 17 +--- .../Metrics/MetricSnapshotTestsBase.cs | 23 +---- .../Metrics/MetricTestsBase.cs | 1 - 12 files changed, 36 insertions(+), 233 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index db91e62f529..9bd5ab2bfe9 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -398,10 +398,10 @@ the first time an overflow is detected for a given metric. > 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 + variable `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE=true`. After 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. + become stable, this feature has been turned on by default. When [Delta Aggregation Temporality](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#temporality) @@ -413,10 +413,10 @@ SDK to reclaim unused metric points. [1.7.0-alpha.1](../../src/OpenTelemetry/CHANGELOG.md#170-alpha1). It is currently an experimental feature which can be turned on by setting the environment variable - `OTEL_DOTNET_EXPERIMENTAL_METRICS_RECLAIM_UNUSED_METRIC_POINTS=true`. Once the + `OTEL_DOTNET_EXPERIMENTAL_METRICS_RECLAIM_UNUSED_METRIC_POINTS=true`. After 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. + become stable, this feature has been turned on by default. ### Memory Preallocation diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index d14170c35f1..12abc2ace6a 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* The opt-in overflow attribute feature which can be enabled by setting the + environment variable `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` + to `true` is now enabled by default and supported in stable builds. + ## 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..78133e6342c 100644 --- a/src/OpenTelemetry/Metrics/AggregatorStore.cs +++ b/src/OpenTelemetry/Metrics/AggregatorStore.cs @@ -22,13 +22,12 @@ 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 string MetricPointCapHitFixMessage = "The overflow attribute is set because the cardinality limit is reached. You could 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(); @@ -65,7 +64,6 @@ internal AggregatorStore( AggregationType aggType, AggregationTemporality temporality, int cardinalityLimit, - bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints, ExemplarFilterType? exemplarFilter = null, Func? exemplarReservoirFactory = null) @@ -105,8 +103,6 @@ internal AggregatorStore( this.tagsKeysInterestingCount = hs.Count; } - this.EmitOverflowAttribute = emitOverflowAttribute; - this.exemplarFilter = exemplarFilter ?? DefaultExemplarFilter; Debug.Assert( this.exemplarFilter == ExemplarFilterType.AlwaysOff @@ -245,17 +241,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,13 +987,9 @@ 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) + this.InitializeOverflowTagPointIfNotInitialized(); + this.metricPoints[1].Update(value); + if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) { OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); } @@ -1049,13 +1038,9 @@ 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) + this.InitializeOverflowTagPointIfNotInitialized(); + this.metricPoints[1].Update(value); + if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) { OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); } 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 def0591d0d4..0bbfaf9aa4a 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..e8eacfc189c 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; } @@ -1704,15 +1704,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 +1889,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 +1897,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..39be30b77c2 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(); @@ -333,15 +328,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; From a349acf0db1457d33e3871afdd8922525999b738 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Thu, 17 Oct 2024 18:06:10 -0700 Subject: [PATCH 02/12] update wording in markdowns --- docs/metrics/README.md | 11 +++++++---- src/OpenTelemetry/CHANGELOG.md | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index 9bd5ab2bfe9..9ae4294f6b7 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) @@ -396,12 +398,13 @@ 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 + [1.6.0-rc.1](../../src/OpenTelemetry/CHANGELOG.md#160-rc1). It was an experimental feature which can be turned on by setting the environment variable `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE=true`. After the [OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute) - become stable, this feature has been turned on by default. + become stable, the environment variable is removed and this feature is enabled + by default. When [Delta Aggregation Temporality](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#temporality) @@ -413,10 +416,10 @@ SDK to reclaim unused metric points. [1.7.0-alpha.1](../../src/OpenTelemetry/CHANGELOG.md#170-alpha1). It is currently an experimental feature which can be turned on by setting the environment variable - `OTEL_DOTNET_EXPERIMENTAL_METRICS_RECLAIM_UNUSED_METRIC_POINTS=true`. After the + `OTEL_DOTNET_EXPERIMENTAL_METRICS_RECLAIM_UNUSED_METRIC_POINTS=true`. Once the [OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute) - become stable, this feature has been turned on by default. + become stable, this feature will be turned on by default. ### Memory Preallocation diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 12abc2ace6a..0e74eb72edc 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -9,6 +9,7 @@ Notes](../../RELEASENOTES.md). * The opt-in overflow attribute feature which can be enabled by setting the environment variable `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` to `true` is now enabled by default and supported in stable builds. + ([#5909](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5909)) ## 1.10.0-beta.1 From 737c3c98e5bc8cb4049b92f10c82ed90d00adac6 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Thu, 17 Oct 2024 18:12:27 -0700 Subject: [PATCH 03/12] update readme regarding the warning the first time an overflow is detected for a given metric --- docs/metrics/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index 9ae4294f6b7..c392fd7bb78 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -392,9 +392,9 @@ 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. +(if enabled). 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 From 9e4fe9bf81893201d18935a8ef13f21534ecd731 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 22 Oct 2024 17:04:25 -0700 Subject: [PATCH 04/12] Remove MetricPointCaptHitMessage --- src/OpenTelemetry/Metrics/AggregatorStore.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/OpenTelemetry/Metrics/AggregatorStore.cs b/src/OpenTelemetry/Metrics/AggregatorStore.cs index 78133e6342c..b7d560b559f 100644 --- a/src/OpenTelemetry/Metrics/AggregatorStore.cs +++ b/src/OpenTelemetry/Metrics/AggregatorStore.cs @@ -27,7 +27,6 @@ internal sealed class AggregatorStore internal long DroppedMeasurements = 0; private const ExemplarFilterType DefaultExemplarFilter = ExemplarFilterType.AlwaysOff; - private static readonly string MetricPointCapHitFixMessage = "The overflow attribute is set because the cardinality limit is reached. You could 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(); @@ -41,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; @@ -55,7 +53,6 @@ internal sealed class AggregatorStore private int metricPointIndex = 0; private int batchSize = 0; - private int metricCapHitMessageLogged; private bool zeroTagMetricPointInitialized; private bool overflowTagMetricPointInitialized; @@ -75,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; @@ -989,10 +985,6 @@ private void UpdateLongMetricPoint(int metricPointIndex, long value, ReadOnlySpa Interlocked.Increment(ref this.DroppedMeasurements); this.InitializeOverflowTagPointIfNotInitialized(); this.metricPoints[1].Update(value); - if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) - { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); - } return; } @@ -1040,10 +1032,6 @@ private void UpdateDoubleMetricPoint(int metricPointIndex, double value, ReadOnl Interlocked.Increment(ref this.DroppedMeasurements); this.InitializeOverflowTagPointIfNotInitialized(); this.metricPoints[1].Update(value); - if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) - { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); - } return; } From bc41d1ad91325789189ccfa5e62c5e9f74e05c89 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 22 Oct 2024 17:52:48 -0700 Subject: [PATCH 05/12] Update comments related to overflow attribute being optional --- test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs | 1 - .../OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs index e8eacfc189c..9c6735f7bcb 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricApiTestsBase.cs @@ -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")) diff --git a/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs b/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs index 39be30b77c2..effe208eda3 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricPointReclaimTestsBase.cs @@ -208,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++) From 127025f46c868ce11a0399a9bc62f4512ccd92ea Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 22 Oct 2024 17:53:07 -0700 Subject: [PATCH 06/12] Update README and CHANGELOG --- docs/metrics/README.md | 21 ++++----------------- src/OpenTelemetry/CHANGELOG.md | 8 +++++--- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index c392fd7bb78..eb77ebeae6e 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -388,23 +388,10 @@ 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). 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 was an - experimental feature which can be turned on by setting the environment - variable `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE=true`. After - the [OpenTelemetry - Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute) - become stable, the environment variable is removed and this feature is enabled - by default. +Starting with version 1.10.0, 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). 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 0e74eb72edc..c8ae489b09c 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -6,9 +6,11 @@ Notes](../../RELEASENOTES.md). ## Unreleased -* The opt-in overflow attribute feature which can be enabled by setting the - environment variable `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` - to `true` is now enabled by default and supported in stable builds. +* Removed the `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` + environment variable since the feature has moved from experimental to stable. + The overflow attribute feature is now enabled by default. + No internal logs will be emitted when the limit is hit, as the + `otel.metric.overflow` attribute indicates when a cardinality cap has occurred.. ([#5909](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5909)) ## 1.10.0-beta.1 From f3d125720771211536639cf0b503dc30e85962b0 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 22 Oct 2024 18:16:50 -0700 Subject: [PATCH 07/12] The measurement won't be dropped. It will be aggregated with the overflow attribute and this behavior won't be able to be turned off. --- docs/metrics/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index eb77ebeae6e..ce5f36b8dca 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -390,7 +390,7 @@ for more information. Starting with version 1.10.0, 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 +the limit will be aggregated using the [overflow attribute](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute). When [Delta Aggregation From 0823e2d24440f16370189b48357a61f13c695195 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Tue, 22 Oct 2024 18:27:10 -0700 Subject: [PATCH 08/12] Update src/OpenTelemetry/CHANGELOG.md Co-authored-by: Reiley Yang --- src/OpenTelemetry/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index c8ae489b09c..e2ae54c0a34 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -10,7 +10,7 @@ Notes](../../RELEASENOTES.md). environment variable since the feature has moved from experimental to stable. The overflow attribute feature is now enabled by default. No internal logs will be emitted when the limit is hit, as the - `otel.metric.overflow` attribute indicates when a cardinality cap has occurred.. + `otel.metric.overflow` attribute indicates when a cardinality cap has occurred. ([#5909](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5909)) ## 1.10.0-beta.1 From aeceb18af53084cf3e89feaa7efad6f115650e2e Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 22 Oct 2024 18:47:37 -0700 Subject: [PATCH 09/12] reword --- src/OpenTelemetry/CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index e2ae54c0a34..0de526e7e6d 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -6,11 +6,11 @@ Notes](../../RELEASENOTES.md). ## Unreleased -* Removed the `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` - environment variable since the feature has moved from experimental to stable. +* Promote overflow attribute from experimental to stable and removed the + `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` environment variable. The overflow attribute feature is now enabled by default. - No internal logs will be emitted when the limit is hit, as the - `otel.metric.overflow` attribute indicates when a cardinality cap has occurred. + No internal logs will be emitted when the cardinality limit is reached, as the + `otel.metric.overflow` attribute can be used to tell that the limit is reached. ([#5909](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5909)) ## 1.10.0-beta.1 From b72090e54295779469cec8d07a275abe2111c958 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 22 Oct 2024 18:54:01 -0700 Subject: [PATCH 10/12] typo --- src/OpenTelemetry/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 0de526e7e6d..a21e43057ff 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -6,7 +6,7 @@ Notes](../../RELEASENOTES.md). ## Unreleased -* Promote overflow attribute from experimental to stable and removed the +* Promoted overflow attribute from experimental to stable and removed the `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` environment variable. The overflow attribute feature is now enabled by default. No internal logs will be emitted when the cardinality limit is reached, as the From 6c67e3fe4b07fd613c10084b65a13920c3bc3b35 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Wed, 23 Oct 2024 17:02:36 -0700 Subject: [PATCH 11/12] improve README and CHANGELOG --- docs/metrics/README.md | 13 +++++++++---- src/OpenTelemetry/CHANGELOG.md | 26 +++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index ce5f36b8dca..c6512981620 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -388,10 +388,15 @@ 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. -Starting with version 1.10.0, given a metric, once the cardinality limit is -reached, any new measurement which cannot be independently aggregated because of -the limit will be aggregated using the [overflow -attribute](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute). +Given a metric, once the cardinality limit is reached, any new measurement +cannot be independently aggregated. Previously, new measurements were dropped +unless users opt-in to experimental overflow attribute feature introduced in +version [1.6.0-rc.1](../../src/OpenTelemetry/CHANGELOG.md#160-rc1). +Starting with version 1.10.0, this experimental feature is promoted to stable +and will be the default behavior. New measurements will be aggregated using the +[overflow +attribute](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute) +when the limit is reached. 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 a21e43057ff..4b8af9b2f64 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -8,9 +8,29 @@ Notes](../../RELEASENOTES.md). * Promoted overflow attribute from experimental to stable and removed the `OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE` environment variable. - The overflow attribute feature is now enabled by default. - No internal logs will be emitted when the cardinality limit is reached, as the - `otel.metric.overflow` attribute can be used to tell that the limit is reached. + + **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 adjust this globally, + use the `SetMaxMetricPointsPerMetricStream()` API. However, we recommend + setting the limit on a per-metric basis for finer control. For details on + customizing limits per metric, refer to [changing cardinality + limit](../../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 From a11884205782f37c218690c038f5ca9c3eca633d Mon Sep 17 00:00:00 2001 From: Sean Li Date: Thu, 24 Oct 2024 13:03:46 -0700 Subject: [PATCH 12/12] update wording --- docs/metrics/README.md | 14 ++++++-------- src/OpenTelemetry/CHANGELOG.md | 8 +++----- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index c6512981620..0394f63451b 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -389,14 +389,12 @@ and the `MetricStreamConfiguration.CardinalityLimit` setting. Refer to this for more information. Given a metric, once the cardinality limit is reached, any new measurement -cannot be independently aggregated. Previously, new measurements were dropped -unless users opt-in to experimental overflow attribute feature introduced in -version [1.6.0-rc.1](../../src/OpenTelemetry/CHANGELOG.md#160-rc1). -Starting with version 1.10.0, this experimental feature is promoted to stable -and will be the default behavior. New measurements will be aggregated using the -[overflow -attribute](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#overflow-attribute) -when the limit is reached. +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 4b8af9b2f64..0f2bbd74d7c 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -24,11 +24,9 @@ Notes](../../RELEASENOTES.md). 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 adjust this globally, - use the `SetMaxMetricPointsPerMetricStream()` API. However, we recommend - setting the limit on a per-metric basis for finer control. For details on - customizing limits per metric, refer to [changing cardinality - limit](../../docs/metrics/customizing-the-sdk/README.md#changing-the-cardinality-limit-for-a-metric). + 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))