From a5380165935752573b9a5ccc39eef99e91ce815c Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Mon, 20 Sep 2021 21:52:11 -0700 Subject: [PATCH] Disallow multiple metric streams of same name. (#2392) --- src/OpenTelemetry/Metrics/MeterProviderSdk.cs | 32 +++++++++++++------ .../Metrics/MetricAPITest.cs | 10 +++--- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index af142db482c..88957422a64 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -31,6 +31,8 @@ internal sealed class MeterProviderSdk : MeterProvider private readonly Metric[] metrics; private readonly List instrumentations = new List(); private readonly object collectLock = new object(); + private readonly object instrumentCreationLock = new object(); + private readonly Dictionary metricStreamNames = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly MeterListener listener; private readonly MetricReader reader; private int metricIndex = -1; @@ -94,16 +96,26 @@ internal MeterProviderSdk( { if (meterSourcesToSubscribe.ContainsKey(instrument.Meter.Name)) { - var index = Interlocked.Increment(ref this.metricIndex); - if (index >= MaxMetrics) + lock (this.instrumentCreationLock) { - // Log that all measurements are dropped from this instrument. - } - else - { - var metric = new Metric(instrument, temporality); - this.metrics[index] = metric; - listener.EnableMeasurementEvents(instrument, metric); + if (this.metricStreamNames.ContainsKey(instrument.Name)) + { + // log and ignore this instrument. + return; + } + + var index = Interlocked.Increment(ref this.metricIndex); + if (index >= MaxMetrics) + { + // Log that all measurements are dropped from this instrument. + } + else + { + var metric = new Metric(instrument, temporality); + this.metrics[index] = metric; + this.metricStreamNames.Add(instrument.Name, true); + listener.EnableMeasurementEvents(instrument, metric); + } } } }, @@ -173,7 +185,7 @@ internal Batch Collect() this.metrics[i].SnapShot(); } - return (target > 0) ? new Batch(this.metrics, indexSnapShot + 1) : default; + return (target > 0) ? new Batch(this.metrics, target) : default; } catch (Exception) { diff --git a/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs b/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs index e87346bc38e..668a6aa1328 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs @@ -59,7 +59,7 @@ void ProcessExport(Batch batch) PreferredAggregationTemporality = exportDelta ? AggregationTemporality.Delta : AggregationTemporality.Cumulative, }; - var meter = new Meter("TestMeter"); + using var meter = new Meter("TestMeter"); var counterLong = meter.CreateCounter("mycounter"); using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddSource("TestMeter") @@ -135,7 +135,7 @@ void ProcessExport(Batch batch) PreferredAggregationTemporality = exportDelta ? AggregationTemporality.Delta : AggregationTemporality.Cumulative, }; - var meter = new Meter(meterName); + using var meter = new Meter(meterName); int i = 1; var counterLong = meter.CreateObservableCounter( "observable-counter", @@ -204,7 +204,7 @@ void ProcessExport(Batch batch) { PreferredAggregationTemporality = temporality, }; - var meter = new Meter("TestPointCapMeter"); + using var meter = new Meter("TestPointCapMeter"); var counterLong = meter.CreateCounter("mycounterCapTest"); using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddSource("TestPointCapMeter") @@ -256,7 +256,7 @@ void ProcessExport(Batch batch) PreferredAggregationTemporality = AggregationTemporality.Cumulative, }; - var meter = new Meter("TestLongCounterMeter"); + using var meter = new Meter("TestLongCounterMeter"); var counterLong = meter.CreateCounter("mycounter"); using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddSource("TestLongCounterMeter") @@ -326,7 +326,7 @@ void ProcessExport(Batch batch) PreferredAggregationTemporality = AggregationTemporality.Cumulative, }; - var meter = new Meter("TestDoubleCounterMeter"); + using var meter = new Meter("TestDoubleCounterMeter"); var counterDouble = meter.CreateCounter("mycounter"); using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddSource("TestDoubleCounterMeter")