From a6e5a38c5ac73a2ea385c4292b2fbdc69a951ece Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 4 Mar 2024 12:45:18 -0800 Subject: [PATCH 1/4] Remove ExemplarFilter classes. --- src/OpenTelemetry/Metrics/AggregatorStore.cs | 248 ++++++++---------- .../Builder/MeterProviderBuilderExtensions.cs | 6 +- .../Builder/MeterProviderBuilderSdk.cs | 6 +- .../Exemplar/AlwaysOffExemplarFilter.cs | 27 -- .../Exemplar/AlwaysOnExemplarFilter.cs | 27 -- .../Metrics/Exemplar/ExemplarFilter.cs | 50 ---- .../Exemplar/TraceBasedExemplarFilter.cs | 30 --- src/OpenTelemetry/Metrics/Metric.cs | 2 +- src/OpenTelemetry/Metrics/MetricReaderExt.cs | 4 +- .../Metrics/AggregatorTestsBase.cs | 2 +- 10 files changed, 113 insertions(+), 289 deletions(-) delete mode 100644 src/OpenTelemetry/Metrics/Exemplar/AlwaysOffExemplarFilter.cs delete mode 100644 src/OpenTelemetry/Metrics/Exemplar/AlwaysOnExemplarFilter.cs delete mode 100644 src/OpenTelemetry/Metrics/Exemplar/ExemplarFilter.cs delete mode 100644 src/OpenTelemetry/Metrics/Exemplar/TraceBasedExemplarFilter.cs diff --git a/src/OpenTelemetry/Metrics/AggregatorStore.cs b/src/OpenTelemetry/Metrics/AggregatorStore.cs index 525d3ba7566..2ecb30e521f 100644 --- a/src/OpenTelemetry/Metrics/AggregatorStore.cs +++ b/src/OpenTelemetry/Metrics/AggregatorStore.cs @@ -20,9 +20,9 @@ internal sealed class AggregatorStore 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 static readonly ExemplarFilter DefaultExemplarFilter = new AlwaysOffExemplarFilter(); private readonly object lockZeroTags = new(); private readonly object lockOverflowTag = new(); @@ -44,7 +44,7 @@ internal sealed class AggregatorStore private readonly int exponentialHistogramMaxScale; private readonly UpdateLongDelegate updateLongCallback; private readonly UpdateDoubleDelegate updateDoubleCallback; - private readonly ExemplarFilter exemplarFilter; + private readonly ExemplarFilterType exemplarFilter; private readonly Func[], int, int> lookupAggregatorStore; private int metricPointIndex = 0; @@ -60,7 +60,7 @@ internal AggregatorStore( int cardinalityLimit, bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints, - ExemplarFilter? exemplarFilter = null, + ExemplarFilterType? exemplarFilter = ExemplarFilterType.AlwaysOff, Func? exemplarReservoirFactory = null) { this.name = metricStreamIdentity.InstrumentName; @@ -144,17 +144,33 @@ internal bool IsExemplarEnabled() { // Using this filter to indicate On/Off // instead of another separate flag. - return this.exemplarFilter is not AlwaysOffExemplarFilter; + return this.exemplarFilter != ExemplarFilterType.AlwaysOff; } internal void Update(long value, ReadOnlySpan> tags) { - this.updateLongCallback(value, tags); + try + { + this.updateLongCallback(value, tags); + } + catch (Exception) + { + Interlocked.Increment(ref this.DroppedMeasurements); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, "SDK internal error occurred.", "Contact SDK owners."); + } } internal void Update(double value, ReadOnlySpan> tags) { - this.updateDoubleCallback(value, tags); + try + { + this.updateDoubleCallback(value, tags); + } + catch (Exception) + { + Interlocked.Increment(ref this.DroppedMeasurements); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, "SDK internal error occurred.", "Contact SDK owners."); + } } internal int Snapshot() @@ -924,177 +940,121 @@ private int RemoveStaleEntriesAndGetAvailableMetricPointRare(LookupData lookupDa private void UpdateLong(long value, ReadOnlySpan> tags) { - try - { - var index = this.FindMetricAggregatorsDefault(tags); - if (index < 0) - { - Interlocked.Increment(ref this.DroppedMeasurements); - - if (this.EmitOverflowAttribute) - { - this.InitializeOverflowTagPointIfNotInitialized(); - this.metricPoints[1].Update(value); - return; - } - else - { - if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) - { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); - } - - return; - } - } + var index = this.FindMetricAggregatorsDefault(tags); - // TODO: can special case built-in filters to be bit faster. - if (this.IsExemplarEnabled()) - { - var shouldSample = this.exemplarFilter.ShouldSample(value, tags); - this.metricPoints[index].UpdateWithExemplar(value, tags: default, shouldSample); - } - else - { - this.metricPoints[index].Update(value); - } - } - catch (Exception) - { - Interlocked.Increment(ref this.DroppedMeasurements); - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, "SDK internal error occurred.", "Contact SDK owners."); - } + this.UpdateLongMetricPoint(index, value, tags: default); } private void UpdateLongCustomTags(long value, ReadOnlySpan> tags) { - try - { - var index = this.FindMetricAggregatorsCustomTag(tags); - if (index < 0) - { - Interlocked.Increment(ref this.DroppedMeasurements); + var index = this.FindMetricAggregatorsCustomTag(tags); - if (this.EmitOverflowAttribute) - { - this.InitializeOverflowTagPointIfNotInitialized(); - this.metricPoints[1].Update(value); - return; - } - else - { - if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) - { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); - } + this.UpdateLongMetricPoint(index, value, tags); + } - return; - } - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void UpdateLongMetricPoint(int metricPointIndex, long value, ReadOnlySpan> tags) + { + if (metricPointIndex < 0) + { + Interlocked.Increment(ref this.DroppedMeasurements); - // TODO: can special case built-in filters to be bit faster. - if (this.IsExemplarEnabled()) + if (this.EmitOverflowAttribute) { - var shouldSample = this.exemplarFilter.ShouldSample(value, tags); - this.metricPoints[index].UpdateWithExemplar(value, tags, shouldSample); + this.InitializeOverflowTagPointIfNotInitialized(); + this.metricPoints[1].Update(value); } - else + else if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) { - this.metricPoints[index].Update(value); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); } + + return; } - catch (Exception) + + switch (this.exemplarFilter) { - Interlocked.Increment(ref this.DroppedMeasurements); - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, "SDK internal error occurred.", "Contact SDK owners."); + case ExemplarFilterType.AlwaysOn: + this.metricPoints[metricPointIndex].UpdateWithExemplar( + value, + tags, + isSampled: true); + break; + case ExemplarFilterType.TraceBased: + this.metricPoints[metricPointIndex].UpdateWithExemplar( + value, + tags, + isSampled: Activity.Current?.Recorded ?? false); + break; + default: +#if DEBUG + if (this.exemplarFilter != ExemplarFilterType.AlwaysOff) + { + Debug.Fail("Unexpected ExemplarFilterType"); + } +#endif + this.metricPoints[metricPointIndex].Update(value); + break; } } private void UpdateDouble(double value, ReadOnlySpan> tags) { - try - { - var index = this.FindMetricAggregatorsDefault(tags); - if (index < 0) - { - Interlocked.Increment(ref this.DroppedMeasurements); + var index = this.FindMetricAggregatorsDefault(tags); - if (this.EmitOverflowAttribute) - { - this.InitializeOverflowTagPointIfNotInitialized(); - this.metricPoints[1].Update(value); - return; - } - else - { - if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) - { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); - } - - return; - } - } - - // TODO: can special case built-in filters to be bit faster. - if (this.IsExemplarEnabled()) - { - var shouldSample = this.exemplarFilter.ShouldSample(value, tags); - this.metricPoints[index].UpdateWithExemplar(value, tags: default, shouldSample); - } - else - { - this.metricPoints[index].Update(value); - } - } - catch (Exception) - { - Interlocked.Increment(ref this.DroppedMeasurements); - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, "SDK internal error occurred.", "Contact SDK owners."); - } + this.UpdateDoubleMetricPoint(index, value, tags: default); } private void UpdateDoubleCustomTags(double value, ReadOnlySpan> tags) { - try - { - var index = this.FindMetricAggregatorsCustomTag(tags); - if (index < 0) - { - Interlocked.Increment(ref this.DroppedMeasurements); + var index = this.FindMetricAggregatorsCustomTag(tags); - if (this.EmitOverflowAttribute) - { - this.InitializeOverflowTagPointIfNotInitialized(); - this.metricPoints[1].Update(value); - return; - } - else - { - if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) - { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); - } + this.UpdateDoubleMetricPoint(index, value, tags); + } - return; - } - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void UpdateDoubleMetricPoint(int metricPointIndex, double value, ReadOnlySpan> tags) + { + if (metricPointIndex < 0) + { + Interlocked.Increment(ref this.DroppedMeasurements); - // TODO: can special case built-in filters to be bit faster. - if (this.IsExemplarEnabled()) + if (this.EmitOverflowAttribute) { - var shouldSample = this.exemplarFilter.ShouldSample(value, tags); - this.metricPoints[index].UpdateWithExemplar(value, tags, shouldSample); + this.InitializeOverflowTagPointIfNotInitialized(); + this.metricPoints[1].Update(value); } - else + else if (Interlocked.CompareExchange(ref this.metricCapHitMessageLogged, 1, 0) == 0) { - this.metricPoints[index].Update(value); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, this.metricPointCapHitMessage, MetricPointCapHitFixMessage); } + + return; } - catch (Exception) + + switch (this.exemplarFilter) { - Interlocked.Increment(ref this.DroppedMeasurements); - OpenTelemetrySdkEventSource.Log.MeasurementDropped(this.name, "SDK internal error occurred.", "Contact SDK owners."); + case ExemplarFilterType.AlwaysOn: + this.metricPoints[metricPointIndex].UpdateWithExemplar( + value, + tags, + isSampled: true); + break; + case ExemplarFilterType.TraceBased: + this.metricPoints[metricPointIndex].UpdateWithExemplar( + value, + tags, + isSampled: Activity.Current?.Recorded ?? false); + break; + default: +#if DEBUG + if (this.exemplarFilter != ExemplarFilterType.AlwaysOff) + { + Debug.Fail("Unexpected ExemplarFilterType"); + } +#endif + this.metricPoints[metricPointIndex].Update(value); + break; } } diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs index dbe132ae14b..9728af3c7dc 100644 --- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs @@ -356,13 +356,13 @@ static MeterProviderBuilder SetExemplarFilter( switch (exemplarFilter) { case ExemplarFilterType.AlwaysOn: - meterProviderBuilderSdk.SetExemplarFilter(new AlwaysOnExemplarFilter()); + meterProviderBuilderSdk.SetExemplarFilter(exemplarFilter); break; case ExemplarFilterType.AlwaysOff: - meterProviderBuilderSdk.SetExemplarFilter(new AlwaysOffExemplarFilter()); + meterProviderBuilderSdk.SetExemplarFilter(exemplarFilter); break; case ExemplarFilterType.TraceBased: - meterProviderBuilderSdk.SetExemplarFilter(new TraceBasedExemplarFilter()); + meterProviderBuilderSdk.SetExemplarFilter(exemplarFilter); break; default: throw new NotSupportedException($"SdkExemplarFilter '{exemplarFilter}' is not supported."); diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs index a3ca2a15e56..11084ec7f0d 100644 --- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs @@ -39,7 +39,7 @@ public MeterProviderBuilderSdk(IServiceProvider serviceProvider) public ResourceBuilder? ResourceBuilder { get; private set; } - public ExemplarFilter? ExemplarFilter { get; private set; } + public ExemplarFilterType? ExemplarFilter { get; private set; } public MeterProvider? Provider => this.meterProvider; @@ -145,10 +145,8 @@ public MeterProviderBuilder SetResourceBuilder(ResourceBuilder resourceBuilder) return this; } - public MeterProviderBuilder SetExemplarFilter(ExemplarFilter exemplarFilter) + public MeterProviderBuilder SetExemplarFilter(ExemplarFilterType exemplarFilter) { - Debug.Assert(exemplarFilter != null, "exemplarFilter was null"); - this.ExemplarFilter = exemplarFilter; return this; diff --git a/src/OpenTelemetry/Metrics/Exemplar/AlwaysOffExemplarFilter.cs b/src/OpenTelemetry/Metrics/Exemplar/AlwaysOffExemplarFilter.cs deleted file mode 100644 index 5f40db2de36..00000000000 --- a/src/OpenTelemetry/Metrics/Exemplar/AlwaysOffExemplarFilter.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -namespace OpenTelemetry.Metrics; - -/// -/// An implementation which makes no measurements -/// eligible for becoming an . -/// -/// -/// Specification: . -/// -internal sealed class AlwaysOffExemplarFilter : ExemplarFilter -{ - /// - public override bool ShouldSample(long value, ReadOnlySpan> tags) - { - return false; - } - - /// - public override bool ShouldSample(double value, ReadOnlySpan> tags) - { - return false; - } -} diff --git a/src/OpenTelemetry/Metrics/Exemplar/AlwaysOnExemplarFilter.cs b/src/OpenTelemetry/Metrics/Exemplar/AlwaysOnExemplarFilter.cs deleted file mode 100644 index 67f2e4ced5a..00000000000 --- a/src/OpenTelemetry/Metrics/Exemplar/AlwaysOnExemplarFilter.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -namespace OpenTelemetry.Metrics; - -/// -/// An implementation which makes all measurements -/// eligible for becoming an . -/// -/// -/// Specification: . -/// -internal sealed class AlwaysOnExemplarFilter : ExemplarFilter -{ - /// - public override bool ShouldSample(long value, ReadOnlySpan> tags) - { - return true; - } - - /// - public override bool ShouldSample(double value, ReadOnlySpan> tags) - { - return true; - } -} diff --git a/src/OpenTelemetry/Metrics/Exemplar/ExemplarFilter.cs b/src/OpenTelemetry/Metrics/Exemplar/ExemplarFilter.cs deleted file mode 100644 index 20296b5540d..00000000000 --- a/src/OpenTelemetry/Metrics/Exemplar/ExemplarFilter.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -namespace OpenTelemetry.Metrics; - -/// -/// ExemplarFilter base implementation and contract. -/// -/// -/// Specification: . -/// -internal abstract class ExemplarFilter -{ - /// - /// Determines if a given measurement is eligible for being - /// considered for becoming Exemplar. - /// - /// The value of the measurement. - /// The complete set of tags provided with the measurement. - /// - /// Returns - /// true to indicate this measurement is eligible to become Exemplar - /// and will be given to an ExemplarReservoir. - /// Reservoir may further sample, so a true here does not mean that this - /// measurement will become an exemplar, it just means it'll be - /// eligible for being Exemplar. - /// false to indicate this measurement is not eligible to become Exemplar - /// and will not be given to the ExemplarReservoir. - /// - public abstract bool ShouldSample(long value, ReadOnlySpan> tags); - - /// - /// Determines if a given measurement is eligible for being - /// considered for becoming Exemplar. - /// - /// The value of the measurement. - /// The complete set of tags provided with the measurement. - /// - /// Returns - /// true to indicate this measurement is eligible to become Exemplar - /// and will be given to an ExemplarReservoir. - /// Reservoir may further sample, so a true here does not mean that this - /// measurement will become an exemplar, it just means it'll be - /// eligible for being Exemplar. - /// false to indicate this measurement is not eligible to become Exemplar - /// and will not be given to the ExemplarReservoir. - /// - public abstract bool ShouldSample(double value, ReadOnlySpan> tags); -} diff --git a/src/OpenTelemetry/Metrics/Exemplar/TraceBasedExemplarFilter.cs b/src/OpenTelemetry/Metrics/Exemplar/TraceBasedExemplarFilter.cs deleted file mode 100644 index db1b16a0b15..00000000000 --- a/src/OpenTelemetry/Metrics/Exemplar/TraceBasedExemplarFilter.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Diagnostics; - -namespace OpenTelemetry.Metrics; - -/// -/// An implementation which makes measurements -/// recorded in the context of a sampled (span) eligible -/// for becoming an . -/// -/// -/// Specification: . -/// -internal sealed class TraceBasedExemplarFilter : ExemplarFilter -{ - /// - public override bool ShouldSample(long value, ReadOnlySpan> tags) - { - return Activity.Current?.Recorded ?? false; - } - - /// - public override bool ShouldSample(double value, ReadOnlySpan> tags) - { - return Activity.Current?.Recorded ?? false; - } -} diff --git a/src/OpenTelemetry/Metrics/Metric.cs b/src/OpenTelemetry/Metrics/Metric.cs index ca82f8d4eaa..32b107c5b2f 100644 --- a/src/OpenTelemetry/Metrics/Metric.cs +++ b/src/OpenTelemetry/Metrics/Metric.cs @@ -49,7 +49,7 @@ internal Metric( int cardinalityLimit, bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints, - ExemplarFilter? exemplarFilter = null, + ExemplarFilterType? exemplarFilter = null, Func? exemplarReservoirFactory = null) { this.InstrumentIdentity = instrumentIdentity; diff --git a/src/OpenTelemetry/Metrics/MetricReaderExt.cs b/src/OpenTelemetry/Metrics/MetricReaderExt.cs index 6b78958e6a5..629ef4c33a6 100644 --- a/src/OpenTelemetry/Metrics/MetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/MetricReaderExt.cs @@ -24,7 +24,7 @@ public abstract partial class MetricReader private int metricIndex = -1; private bool emitOverflowAttribute; - private ExemplarFilter? exemplarFilter; + private ExemplarFilterType? exemplarFilter; internal static void DeactivateMetric(Metric metric) { @@ -171,7 +171,7 @@ internal virtual List AddMetricWithViews(Instrument instrument, List Date: Mon, 4 Mar 2024 12:47:11 -0800 Subject: [PATCH 2/4] Tweak. --- src/OpenTelemetry/Metrics/AggregatorStore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry/Metrics/AggregatorStore.cs b/src/OpenTelemetry/Metrics/AggregatorStore.cs index 2ecb30e521f..72e779bc4dd 100644 --- a/src/OpenTelemetry/Metrics/AggregatorStore.cs +++ b/src/OpenTelemetry/Metrics/AggregatorStore.cs @@ -60,7 +60,7 @@ internal AggregatorStore( int cardinalityLimit, bool emitOverflowAttribute, bool shouldReclaimUnusedMetricPoints, - ExemplarFilterType? exemplarFilter = ExemplarFilterType.AlwaysOff, + ExemplarFilterType? exemplarFilter = null, Func? exemplarReservoirFactory = null) { this.name = metricStreamIdentity.InstrumentName; From 8f9d5f0cf81e627f1d3565489940bae022f1cc80 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 4 Mar 2024 14:41:10 -0800 Subject: [PATCH 3/4] Code review. --- .../Metrics/Builder/MeterProviderBuilderExtensions.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs index 9728af3c7dc..6a36562aa45 100644 --- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs @@ -356,11 +356,7 @@ static MeterProviderBuilder SetExemplarFilter( switch (exemplarFilter) { case ExemplarFilterType.AlwaysOn: - meterProviderBuilderSdk.SetExemplarFilter(exemplarFilter); - break; case ExemplarFilterType.AlwaysOff: - meterProviderBuilderSdk.SetExemplarFilter(exemplarFilter); - break; case ExemplarFilterType.TraceBased: meterProviderBuilderSdk.SetExemplarFilter(exemplarFilter); break; From 08a51f8f5d176097fdd9ae0d862876e40227db04 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 4 Mar 2024 15:54:46 -0800 Subject: [PATCH 4/4] Tweaks. --- src/OpenTelemetry/Metrics/AggregatorStore.cs | 86 ++++++++++---------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/src/OpenTelemetry/Metrics/AggregatorStore.cs b/src/OpenTelemetry/Metrics/AggregatorStore.cs index 72e779bc4dd..547d7c61964 100644 --- a/src/OpenTelemetry/Metrics/AggregatorStore.cs +++ b/src/OpenTelemetry/Metrics/AggregatorStore.cs @@ -75,7 +75,6 @@ internal AggregatorStore( this.exponentialHistogramMaxSize = metricStreamIdentity.ExponentialHistogramMaxSize; this.exponentialHistogramMaxScale = metricStreamIdentity.ExponentialHistogramMaxScale; this.StartTimeExclusive = DateTimeOffset.UtcNow; - this.exemplarFilter = exemplarFilter ?? DefaultExemplarFilter; this.ExemplarReservoirFactory = exemplarReservoirFactory; if (metricStreamIdentity.TagKeys == null) { @@ -93,6 +92,13 @@ internal AggregatorStore( this.EmitOverflowAttribute = emitOverflowAttribute; + this.exemplarFilter = exemplarFilter ?? DefaultExemplarFilter; + Debug.Assert( + this.exemplarFilter == ExemplarFilterType.AlwaysOff + || this.exemplarFilter == ExemplarFilterType.AlwaysOn + || this.exemplarFilter == ExemplarFilterType.TraceBased, + "this.exemplarFilter had an unexpected value"); + var reservedMetricPointsCount = 1; if (emitOverflowAttribute) @@ -972,29 +978,24 @@ private void UpdateLongMetricPoint(int metricPointIndex, long value, ReadOnlySpa return; } - switch (this.exemplarFilter) + var exemplarFilterType = this.exemplarFilter; + if (exemplarFilterType == ExemplarFilterType.AlwaysOff) { - case ExemplarFilterType.AlwaysOn: - this.metricPoints[metricPointIndex].UpdateWithExemplar( - value, - tags, - isSampled: true); - break; - case ExemplarFilterType.TraceBased: - this.metricPoints[metricPointIndex].UpdateWithExemplar( - value, - tags, - isSampled: Activity.Current?.Recorded ?? false); - break; - default: -#if DEBUG - if (this.exemplarFilter != ExemplarFilterType.AlwaysOff) - { - Debug.Fail("Unexpected ExemplarFilterType"); - } -#endif - this.metricPoints[metricPointIndex].Update(value); - break; + this.metricPoints[metricPointIndex].Update(value); + } + else if (exemplarFilterType == ExemplarFilterType.AlwaysOn) + { + this.metricPoints[metricPointIndex].UpdateWithExemplar( + value, + tags, + isSampled: true); + } + else + { + this.metricPoints[metricPointIndex].UpdateWithExemplar( + value, + tags, + isSampled: Activity.Current?.Recorded ?? false); } } @@ -1032,29 +1033,24 @@ private void UpdateDoubleMetricPoint(int metricPointIndex, double value, ReadOnl return; } - switch (this.exemplarFilter) + var exemplarFilterType = this.exemplarFilter; + if (exemplarFilterType == ExemplarFilterType.AlwaysOff) { - case ExemplarFilterType.AlwaysOn: - this.metricPoints[metricPointIndex].UpdateWithExemplar( - value, - tags, - isSampled: true); - break; - case ExemplarFilterType.TraceBased: - this.metricPoints[metricPointIndex].UpdateWithExemplar( - value, - tags, - isSampled: Activity.Current?.Recorded ?? false); - break; - default: -#if DEBUG - if (this.exemplarFilter != ExemplarFilterType.AlwaysOff) - { - Debug.Fail("Unexpected ExemplarFilterType"); - } -#endif - this.metricPoints[metricPointIndex].Update(value); - break; + this.metricPoints[metricPointIndex].Update(value); + } + else if (exemplarFilterType == ExemplarFilterType.AlwaysOn) + { + this.metricPoints[metricPointIndex].UpdateWithExemplar( + value, + tags, + isSampled: true); + } + else + { + this.metricPoints[metricPointIndex].UpdateWithExemplar( + value, + tags, + isSampled: Activity.Current?.Recorded ?? false); } }