From d341e81cdf62e7d5ef86819a2044ecfdb1de9eaa Mon Sep 17 00:00:00 2001 From: Yun-Ting Date: Fri, 2 Feb 2024 15:55:58 -0800 Subject: [PATCH 1/9] draft --- .../Experimental/PublicAPI.Unshipped.txt | 2 + .../Builder/MeterProviderBuilderExtensions.cs | 2 +- src/OpenTelemetry/Metrics/MetricReaderExt.cs | 6 +++ .../Metrics/MetricStreamConfiguration.cs | 40 ++++++++++++-- .../Metrics/MetricViewTests.cs | 52 +++++++++++++++++-- 5 files changed, 94 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt index bb5bd1824f6..74622fc79f3 100644 --- a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -18,6 +18,8 @@ OpenTelemetry.Metrics.Exemplar.TraceId.get -> System.Diagnostics.ActivityTraceId OpenTelemetry.Metrics.ExemplarFilter OpenTelemetry.Metrics.ExemplarFilter.ExemplarFilter() -> void OpenTelemetry.Metrics.MetricPoint.GetExemplars() -> OpenTelemetry.Metrics.Exemplar[]! +OpenTelemetry.Metrics.MetricStreamConfiguration.MaxMetricPointsPerMetricStream.get -> int? +OpenTelemetry.Metrics.MetricStreamConfiguration.MaxMetricPointsPerMetricStream.set -> void OpenTelemetry.Metrics.TraceBasedExemplarFilter OpenTelemetry.Metrics.TraceBasedExemplarFilter.TraceBasedExemplarFilter() -> void static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProviderBuilder! diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs index 11844d3e7b4..4e33de18a66 100644 --- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs @@ -236,7 +236,7 @@ public static MeterProviderBuilder SetMaxMetricStreams(this MeterProviderBuilder /// This may change in the future. See: https://github.com/open-telemetry/opentelemetry-dotnet/issues/2360. /// /// . - /// Maximum maximum number of metric points allowed per metric stream. + /// Maximum number of metric points allowed per metric stream. /// The supplied for chaining. public static MeterProviderBuilder SetMaxMetricPointsPerMetricStream(this MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) { diff --git a/src/OpenTelemetry/Metrics/MetricReaderExt.cs b/src/OpenTelemetry/Metrics/MetricReaderExt.cs index a0575491378..c4fd6e239a8 100644 --- a/src/OpenTelemetry/Metrics/MetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/MetricReaderExt.cs @@ -136,6 +136,12 @@ internal List AddMetricsListWithViews(Instrument instrument, List @@ -10,6 +12,8 @@ public class MetricStreamConfiguration { private string? name; + private int? maxMetricPointsPerMetricStream = 2000; + /// /// Gets the drop configuration. /// @@ -91,11 +95,39 @@ public string[]? TagKeys } } + /// + /// Gets or sets a positive integer value + /// defining the maximum number of data points allowed to + /// per view. + /// + /// + /// Note: If there is no matching view, but the MetricReader + /// defines a default cardinality limit value based on the + /// instrument an aggregation is created for, that value + /// will be used. The default value of 2000 will be used + /// if neither the view nor the MetricReader configures + /// MaxMetricPointsPerMetricStream. + /// +#if EXPOSE_EXPERIMENTAL_FEATURES + public +#else + internal +#endif + int? MaxMetricPointsPerMetricStream + { + get => this.maxMetricPointsPerMetricStream; + set + { + if (value != null) + { + Guard.ThrowIfOutOfRange(value.Value, min: 1, max: int.MaxValue); + } + + this.maxMetricPointsPerMetricStream = value; + } + } + internal string[]? CopiedTagKeys { get; private set; } internal int? ViewId { get; set; } - - // TODO: MetricPoints caps can be configured here on - // a per stream basis, when we add such a capability - // in the future. } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs index 588c15bb277..8e0770506cb 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Metrics; +using System.Reflection; using OpenTelemetry.Internal; using OpenTelemetry.Tests; using Xunit; @@ -919,6 +920,34 @@ public void ViewConflict_OneInstrument_DifferentDescription() Assert.Equal(10, metricPoint2.GetSumLong()); } + [Fact] + public void MaxMetricPointsPerMetricStreamofMatchingViewTakesPrecedenceOverTheMetricReaderWhenBothWereSet() + { + using var meter = new Meter(Utils.GetCurrentMethodName()); + var exportedItems = new List(); + + using var container = this.BuildMeterProvider(out var meterProvider, builder => builder + .AddMeter(meter.Name) + .SetMaxMetricPointsPerMetricStream(3) + .AddView((instrument) => + { + return new MetricStreamConfiguration() { Name = "MetricStreamA", MaxMetricPointsPerMetricStream = 10000 }; + }) + .AddInMemoryExporter(exportedItems)); + + var counter = meter.CreateCounter("counter"); + counter.Add(100); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + var metric = exportedItems[0]; + + var aggregatorStore = typeof(Metric).GetField("aggStore", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(metric) as AggregatorStore; + var maxMetricPointsAttribute = (int)typeof(AggregatorStore).GetField("maxMetricPoints", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(aggregatorStore); + + Assert.Equal(10000, maxMetricPointsAttribute); + } + [Fact] public void ViewConflict_TwoDistinctInstruments_ThreeStreams() { @@ -930,13 +959,18 @@ public void ViewConflict_TwoDistinctInstruments_ThreeStreams() .AddMeter(meter.Name) .AddView((instrument) => { - return new MetricStreamConfiguration() { Name = "MetricStreamA", Description = "description" }; + return new MetricStreamConfiguration() { Name = "MetricStreamA", Description = "description", MaxMetricPointsPerMetricStream = 256 }; }) .AddView((instrument) => { return instrument.Description == "description1" - ? new MetricStreamConfiguration() { Name = "MetricStreamB" } - : new MetricStreamConfiguration() { Name = "MetricStreamC" }; + ? new MetricStreamConfiguration() { Name = "MetricStreamB", MaxMetricPointsPerMetricStream = 3 } + : new MetricStreamConfiguration() { Name = "MetricStreamC", MaxMetricPointsPerMetricStream = 200000 }; + }) + .AddView((instrument) => + { + // This view is ignored as the passed in MaxMetricPointsPerMetricStream is out of range. + return new MetricStreamConfiguration() { Name = "MetricStreamD", MaxMetricPointsPerMetricStream = -1 }; }) .AddInMemoryExporter(exportedItems)); @@ -953,12 +987,24 @@ public void ViewConflict_TwoDistinctInstruments_ThreeStreams() var metricB = exportedItems[1]; var metricC = exportedItems[2]; + var aggregatorStoreA = typeof(Metric).GetField("aggStore", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(metricA) as AggregatorStore; + var maxMetricPointsAttributeA = (int)typeof(AggregatorStore).GetField("maxMetricPoints", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(aggregatorStoreA); + + Assert.Equal(256, maxMetricPointsAttributeA); Assert.Equal("MetricStreamA", metricA.Name); Assert.Equal(20, GetAggregatedValue(metricA)); + var aggregatorStoreB = typeof(Metric).GetField("aggStore", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(metricB) as AggregatorStore; + var maxMetricPointsAttributeB = (int)typeof(AggregatorStore).GetField("maxMetricPoints", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(aggregatorStoreB); + + Assert.Equal(3, maxMetricPointsAttributeB); Assert.Equal("MetricStreamB", metricB.Name); Assert.Equal(10, GetAggregatedValue(metricB)); + var aggregatorStoreC = typeof(Metric).GetField("aggStore", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(metricC) as AggregatorStore; + var maxMetricPointsAttributeC = (int)typeof(AggregatorStore).GetField("maxMetricPoints", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(aggregatorStoreC); + + Assert.Equal(200000, maxMetricPointsAttributeC); Assert.Equal("MetricStreamC", metricC.Name); Assert.Equal(10, GetAggregatedValue(metricC)); From 1cad80774a34c928cd6af00625667bb64df68cc0 Mon Sep 17 00:00:00 2001 From: Yun-Ting Date: Mon, 5 Feb 2024 10:52:41 -0800 Subject: [PATCH 2/9] comments --- .../Experimental/PublicAPI.Unshipped.txt | 4 ++-- src/OpenTelemetry/Metrics/MetricReaderExt.cs | 4 ++-- .../Metrics/MetricStreamConfiguration.cs | 23 ++++++++----------- .../Metrics/MetricViewTests.cs | 10 ++++---- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt index 74622fc79f3..1f80fea01eb 100644 --- a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -18,8 +18,8 @@ OpenTelemetry.Metrics.Exemplar.TraceId.get -> System.Diagnostics.ActivityTraceId OpenTelemetry.Metrics.ExemplarFilter OpenTelemetry.Metrics.ExemplarFilter.ExemplarFilter() -> void OpenTelemetry.Metrics.MetricPoint.GetExemplars() -> OpenTelemetry.Metrics.Exemplar[]! -OpenTelemetry.Metrics.MetricStreamConfiguration.MaxMetricPointsPerMetricStream.get -> int? -OpenTelemetry.Metrics.MetricStreamConfiguration.MaxMetricPointsPerMetricStream.set -> void +OpenTelemetry.Metrics.MetricStreamConfiguration.CardinalityLimit.get -> int? +OpenTelemetry.Metrics.MetricStreamConfiguration.CardinalityLimit.set -> void OpenTelemetry.Metrics.TraceBasedExemplarFilter OpenTelemetry.Metrics.TraceBasedExemplarFilter.TraceBasedExemplarFilter() -> void static OpenTelemetry.Logs.LoggerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! loggerProviderBuilder, OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.LoggerProviderBuilder! diff --git a/src/OpenTelemetry/Metrics/MetricReaderExt.cs b/src/OpenTelemetry/Metrics/MetricReaderExt.cs index c4fd6e239a8..c8a5fa9696e 100644 --- a/src/OpenTelemetry/Metrics/MetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/MetricReaderExt.cs @@ -137,9 +137,9 @@ internal List AddMetricsListWithViews(Instrument instrument, List /// Gets the drop configuration. @@ -97,33 +97,30 @@ public string[]? TagKeys /// /// Gets or sets a positive integer value - /// defining the maximum number of data points allowed to - /// per view. + /// defining the maximum number of data points allowed to for the metric + /// managed by the view. /// /// - /// Note: If there is no matching view, but the MetricReader - /// defines a default cardinality limit value based on the - /// instrument an aggregation is created for, that value - /// will be used. The default value of 2000 will be used - /// if neither the view nor the MetricReader configures - /// MaxMetricPointsPerMetricStream. + /// Note: If not set, the SDK cardinality limit value will be used, which + /// defaults to 2000. Call + /// SetMaxMetricPointsPerMetricStream"/> to confiture the SDK defaults. /// #if EXPOSE_EXPERIMENTAL_FEATURES public #else internal #endif - int? MaxMetricPointsPerMetricStream + int? CardinalityLimit { - get => this.maxMetricPointsPerMetricStream; + get => this.cardinalityLimit; set { if (value != null) { - Guard.ThrowIfOutOfRange(value.Value, min: 1, max: int.MaxValue); + Guard.ThrowIfOutOfRange(value.Value, min: 3, max: int.MaxValue); } - this.maxMetricPointsPerMetricStream = value; + this.cardinalityLimit = value; } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs index 8e0770506cb..4a49cf4c97d 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs @@ -931,7 +931,7 @@ public void MaxMetricPointsPerMetricStreamofMatchingViewTakesPrecedenceOverTheMe .SetMaxMetricPointsPerMetricStream(3) .AddView((instrument) => { - return new MetricStreamConfiguration() { Name = "MetricStreamA", MaxMetricPointsPerMetricStream = 10000 }; + return new MetricStreamConfiguration() { Name = "MetricStreamA", CardinalityLimit = 10000 }; }) .AddInMemoryExporter(exportedItems)); @@ -959,18 +959,18 @@ public void ViewConflict_TwoDistinctInstruments_ThreeStreams() .AddMeter(meter.Name) .AddView((instrument) => { - return new MetricStreamConfiguration() { Name = "MetricStreamA", Description = "description", MaxMetricPointsPerMetricStream = 256 }; + return new MetricStreamConfiguration() { Name = "MetricStreamA", Description = "description", CardinalityLimit = 256 }; }) .AddView((instrument) => { return instrument.Description == "description1" - ? new MetricStreamConfiguration() { Name = "MetricStreamB", MaxMetricPointsPerMetricStream = 3 } - : new MetricStreamConfiguration() { Name = "MetricStreamC", MaxMetricPointsPerMetricStream = 200000 }; + ? new MetricStreamConfiguration() { Name = "MetricStreamB", CardinalityLimit = 3 } + : new MetricStreamConfiguration() { Name = "MetricStreamC", CardinalityLimit = 200000 }; }) .AddView((instrument) => { // This view is ignored as the passed in MaxMetricPointsPerMetricStream is out of range. - return new MetricStreamConfiguration() { Name = "MetricStreamD", MaxMetricPointsPerMetricStream = -1 }; + return new MetricStreamConfiguration() { Name = "MetricStreamD", CardinalityLimit = -1 }; }) .AddInMemoryExporter(exportedItems)); From 0fa65a483fd83ad9d5b722cfa5199c2537aea73c Mon Sep 17 00:00:00 2001 From: Yun-Ting Date: Mon, 5 Feb 2024 14:24:51 -0800 Subject: [PATCH 3/9] comments --- src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs | 8 +++++++- src/Shared/DiagnosticDefinitions.cs | 1 + test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs b/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs index 3a9dc2f4109..e266b33aca2 100644 --- a/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs +++ b/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif using OpenTelemetry.Internal; namespace OpenTelemetry.Metrics; @@ -106,6 +109,9 @@ public string[]? TagKeys /// SetMaxMetricPointsPerMetricStream"/> to confiture the SDK defaults. /// #if EXPOSE_EXPERIMENTAL_FEATURES +#if NET8_0_OR_GREATER +[Experimental(DiagnosticDefinitions.CardinalityLimitExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public #else internal @@ -117,7 +123,7 @@ public string[]? TagKeys { if (value != null) { - Guard.ThrowIfOutOfRange(value.Value, min: 3, max: int.MaxValue); + Guard.ThrowIfOutOfRange(value.Value, min: 1, max: int.MaxValue); } this.cardinalityLimit = value; diff --git a/src/Shared/DiagnosticDefinitions.cs b/src/Shared/DiagnosticDefinitions.cs index 8d2bf49723e..b772ea53652 100644 --- a/src/Shared/DiagnosticDefinitions.cs +++ b/src/Shared/DiagnosticDefinitions.cs @@ -12,4 +12,5 @@ internal static class DiagnosticDefinitions public const string LoggerProviderExperimentalApi = "OTEL1000"; public const string LogsBridgeExperimentalApi = "OTEL1001"; public const string ExemplarExperimentalApi = "OTEL1002"; + public const string CardinalityLimitExperimentalApi = "OTEL1003"; } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs index 4a49cf4c97d..ca8bbf3163b 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs @@ -921,7 +921,7 @@ public void ViewConflict_OneInstrument_DifferentDescription() } [Fact] - public void MaxMetricPointsPerMetricStreamofMatchingViewTakesPrecedenceOverTheMetricReaderWhenBothWereSet() + public void CardinalityLimitofMatchingViewTakesPrecedenceOverMetricProviderWhenBothWereSet() { using var meter = new Meter(Utils.GetCurrentMethodName()); var exportedItems = new List(); @@ -969,7 +969,7 @@ public void ViewConflict_TwoDistinctInstruments_ThreeStreams() }) .AddView((instrument) => { - // This view is ignored as the passed in MaxMetricPointsPerMetricStream is out of range. + // This view is ignored as the passed in CardinalityLimit is out of range. return new MetricStreamConfiguration() { Name = "MetricStreamD", CardinalityLimit = -1 }; }) .AddInMemoryExporter(exportedItems)); From 9adbd44334c134dab59ffcf1fbc4f397f18a887d Mon Sep 17 00:00:00 2001 From: Yun-Ting Date: Mon, 5 Feb 2024 14:36:20 -0800 Subject: [PATCH 4/9] changelog --- src/OpenTelemetry/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 4a284473573..62e4b570005 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -19,6 +19,10 @@ export. [#5255](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5255) +* Added support for setting `CardinalityLimit`, the maximum number of data + points, allowed for the metric managed by the view. + [#5312](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5312) + ## 1.7.0 Released 2023-Dec-08 From 90e9ed7789f97fe630ef5245bf18676f55995b67 Mon Sep 17 00:00:00 2001 From: Yun-Ting Date: Mon, 5 Feb 2024 15:00:00 -0800 Subject: [PATCH 5/9] OTEL1003 --- OpenTelemetry.sln | 1 + build/Common.props | 2 +- .../diagnostics/experimental-apis/OTEL1003.md | 29 +++++++++++++++++++ src/OpenTelemetry/Metrics/MetricReaderExt.cs | 2 ++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 docs/diagnostics/experimental-apis/OTEL1003.md diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 28c8c85b510..0b9de051d0d 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -329,6 +329,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "experimental-apis", "experi docs\diagnostics\experimental-apis\OTEL1000.md = docs\diagnostics\experimental-apis\OTEL1000.md docs\diagnostics\experimental-apis\OTEL1001.md = docs\diagnostics\experimental-apis\OTEL1001.md docs\diagnostics\experimental-apis\OTEL1002.md = docs\diagnostics\experimental-apis\OTEL1002.md + docs\diagnostics\experimental-apis\OTEL1003.md = docs\diagnostics\experimental-apis\OTEL1003.md docs\diagnostics\experimental-apis\README.md = docs\diagnostics\experimental-apis\README.md EndProjectSection EndProject diff --git a/build/Common.props b/build/Common.props index 763c91d057a..d54badad2c6 100644 --- a/build/Common.props +++ b/build/Common.props @@ -10,7 +10,7 @@ enable enable - $(NoWarn);OTEL1000;OTEL1001;OTEL1002 + $(NoWarn);OTEL1000;OTEL1001;OTEL1002;OTEL1003 diff --git a/docs/diagnostics/experimental-apis/OTEL1003.md b/docs/diagnostics/experimental-apis/OTEL1003.md new file mode 100644 index 00000000000..605da135874 --- /dev/null +++ b/docs/diagnostics/experimental-apis/OTEL1003.md @@ -0,0 +1,29 @@ +# OpenTelemetry .NET Diagnostic: OTEL1003 + +## Overview + +This is an Experimental API diagnostic covering the following API: + +* `MetricStreamConfiguration.CardinalityLimit.get` +* `MetricStreamConfiguration.CardinalityLimit.set` + +Experimental APIs may be changed or removed in the future. + +## Details + +The OpenTelemetry Specification defines the +[cardinality limit](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#configuration-1) +of a metric can be defined by the matching view. + +From the specification: + +> The cardinality limit for an aggregation is defined in one of three ways: +> A view with criteria matching the instrument an aggregation is created for has +> an aggregation_cardinality_limit value defined for the stream, that value +> SHOULD be used. If there is no matching view, but the MetricReader defines a +> default cardinality limit value based on the instrument an aggregation is +> created for, that value SHOULD be used. If none of the previous values are +> defined, the default value of 2000 SHOULD be used. + +We are exposing these APIs experimentally until the specification declares them +stable. diff --git a/src/OpenTelemetry/Metrics/MetricReaderExt.cs b/src/OpenTelemetry/Metrics/MetricReaderExt.cs index c8a5fa9696e..e4c43285ccd 100644 --- a/src/OpenTelemetry/Metrics/MetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/MetricReaderExt.cs @@ -137,10 +137,12 @@ internal List AddMetricsListWithViews(Instrument instrument, List Date: Mon, 5 Feb 2024 15:07:44 -0800 Subject: [PATCH 6/9] format --- src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs b/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs index e266b33aca2..e6ba0b16713 100644 --- a/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs +++ b/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs @@ -98,6 +98,7 @@ public string[]? TagKeys } } +#if EXPOSE_EXPERIMENTAL_FEATURES /// /// Gets or sets a positive integer value /// defining the maximum number of data points allowed to for the metric @@ -108,9 +109,8 @@ public string[]? TagKeys /// defaults to 2000. Call /// SetMaxMetricPointsPerMetricStream"/> to confiture the SDK defaults. /// -#if EXPOSE_EXPERIMENTAL_FEATURES #if NET8_0_OR_GREATER -[Experimental(DiagnosticDefinitions.CardinalityLimitExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] + [Experimental(DiagnosticDefinitions.CardinalityLimitExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] #endif public #else From 1088151660fe99655b0b43894c73ed5b4ffadd33 Mon Sep 17 00:00:00 2001 From: Yun-Ting Date: Mon, 5 Feb 2024 16:19:22 -0800 Subject: [PATCH 7/9] follow-ups --- docs/diagnostics/experimental-apis/OTEL1003.md | 2 +- docs/diagnostics/experimental-apis/README.md | 6 ++++++ src/OpenTelemetry/Metrics/MetricReaderExt.cs | 2 -- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/diagnostics/experimental-apis/OTEL1003.md b/docs/diagnostics/experimental-apis/OTEL1003.md index 605da135874..073505b746a 100644 --- a/docs/diagnostics/experimental-apis/OTEL1003.md +++ b/docs/diagnostics/experimental-apis/OTEL1003.md @@ -13,7 +13,7 @@ Experimental APIs may be changed or removed in the future. The OpenTelemetry Specification defines the [cardinality limit](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#configuration-1) -of a metric can be defined by the matching view. +of a metric can be set by the matching view. From the specification: diff --git a/docs/diagnostics/experimental-apis/README.md b/docs/diagnostics/experimental-apis/README.md index 3036596176a..a5d527de3ba 100644 --- a/docs/diagnostics/experimental-apis/README.md +++ b/docs/diagnostics/experimental-apis/README.md @@ -33,6 +33,12 @@ Description: Metrics Exemplar Support Details: [OTEL1002](./OTEL1002.md) +### OTEL1003 + +Description: MetricStreamConfiguration CardinalityLimit Support + +Details: [OTEL1003](./OTEL1003.md) + ## Inactive Experimental APIs which have been released stable or removed: diff --git a/src/OpenTelemetry/Metrics/MetricReaderExt.cs b/src/OpenTelemetry/Metrics/MetricReaderExt.cs index e4c43285ccd..c8a5fa9696e 100644 --- a/src/OpenTelemetry/Metrics/MetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/MetricReaderExt.cs @@ -137,12 +137,10 @@ internal List AddMetricsListWithViews(Instrument instrument, List Date: Mon, 5 Feb 2024 16:43:04 -0800 Subject: [PATCH 8/9] comment --- src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs b/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs index e6ba0b16713..21689b9915c 100644 --- a/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs +++ b/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs @@ -105,9 +105,10 @@ public string[]? TagKeys /// managed by the view. /// /// - /// Note: If not set, the SDK cardinality limit value will be used, which - /// defaults to 2000. Call - /// SetMaxMetricPointsPerMetricStream"/> to confiture the SDK defaults. + /// Note: If not set, the MeterProvider cardinality limit value will be + /// used, which defaults to 2000. + /// Call + /// to configure the MeterProvider default. /// #if NET8_0_OR_GREATER [Experimental(DiagnosticDefinitions.CardinalityLimitExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] From 30ad117d9bc9acde9b6dfc068d4696a09823ed95 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 6 Feb 2024 12:15:47 -0800 Subject: [PATCH 9/9] Nits --- docs/diagnostics/experimental-apis/OTEL1003.md | 2 +- src/OpenTelemetry/CHANGELOG.md | 11 ++++++----- .../Metrics/MetricStreamConfiguration.cs | 14 +++++++++----- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/docs/diagnostics/experimental-apis/OTEL1003.md b/docs/diagnostics/experimental-apis/OTEL1003.md index 073505b746a..d6ed954b2bc 100644 --- a/docs/diagnostics/experimental-apis/OTEL1003.md +++ b/docs/diagnostics/experimental-apis/OTEL1003.md @@ -12,7 +12,7 @@ Experimental APIs may be changed or removed in the future. ## Details The OpenTelemetry Specification defines the -[cardinality limit](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#configuration-1) +[cardinality limit](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#cardinality-limits) of a metric can be set by the matching view. From the specification: diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 62e4b570005..d6888194f10 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -11,17 +11,18 @@ * Fixed an issue where `SimpleExemplarReservoir` was not resetting internal state for cumulative temporality. - [#5230](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5230) + ([#5230](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5230)) * Fixed an issue causing `LogRecord`s to be incorrectly reused when wrapping an instance of `BatchLogRecordExportProcessor` inside another `BaseProcessor` which leads to missing or incorrect data during export. - [#5255](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5255) + ([#5255](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5255)) -* Added support for setting `CardinalityLimit`, the maximum number of data - points, allowed for the metric managed by the view. - [#5312](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5312) +* **Experimental (pre-release builds only):** Added support for setting + `CardinalityLimit` (the maximum number of data points allowed for a metric) + when configuring a view. + ([#5312](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5312)) ## 1.7.0 diff --git a/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs b/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs index 21689b9915c..077f332ea68 100644 --- a/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs +++ b/src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs @@ -100,14 +100,18 @@ public string[]? TagKeys #if EXPOSE_EXPERIMENTAL_FEATURES /// - /// Gets or sets a positive integer value - /// defining the maximum number of data points allowed to for the metric - /// managed by the view. + /// Gets or sets a positive integer value defining the maximum number of + /// data points allowed for the metric managed by the view. /// /// + /// WARNING: This is an experimental API which might change or + /// be removed in the future. Use at your own risk. + /// Spec reference: Cardinality + /// limits. /// Note: If not set, the MeterProvider cardinality limit value will be - /// used, which defaults to 2000. - /// Call + /// used, which defaults to 2000. Call /// to configure the MeterProvider default. /// #if NET8_0_OR_GREATER