Skip to content

Commit 8138e5e

Browse files
authored
Fail-fast when using AddView with guaranteed conflict (#2785)
1 parent 26ac74d commit 8138e5e

File tree

3 files changed

+49
-27
lines changed

3 files changed

+49
-27
lines changed

src/OpenTelemetry/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
* Make `MetricPoint` of `MetricPointAccessor` readonly.
66
([2736](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2736))
77

8+
* Fail-fast when using AddView with guaranteed conflict.
9+
([2751](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2751))
10+
811
## 1.2.0-rc1
912

1013
Released 2021-Nov-29

src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProvid
5757
throw new ArgumentException($"Custom view name {name} is invalid.", nameof(name));
5858
}
5959

60+
if (instrumentName.IndexOf('*') != -1)
61+
{
62+
throw new ArgumentException(
63+
$"Instrument selection criteria is invalid. Instrument name '{instrumentName}' " +
64+
$"contains a wildcard character. This is not allowed when using a view to " +
65+
$"rename a metric stream as it would lead to conflicting metric stream names.",
66+
nameof(instrumentName));
67+
}
68+
6069
if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase)
6170
{
6271
return meterProviderBuilderBase.AddView(instrumentName, name);
@@ -86,6 +95,15 @@ public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProvid
8695
throw new ArgumentException($"Custom view name {metricStreamConfiguration.Name} is invalid.", nameof(metricStreamConfiguration.Name));
8796
}
8897

98+
if (metricStreamConfiguration.Name != null && instrumentName.IndexOf('*') != -1)
99+
{
100+
throw new ArgumentException(
101+
$"Instrument selection criteria is invalid. Instrument name '{instrumentName}' " +
102+
$"contains a wildcard character. This is not allowed when using a view to " +
103+
$"rename a metric stream as it would lead to conflicting metric stream names.",
104+
nameof(instrumentName));
105+
}
106+
89107
if (metricStreamConfiguration is ExplicitBucketHistogramConfiguration histogramConfiguration)
90108
{
91109
// Validate histogram boundaries

test/OpenTelemetry.Tests/Metrics/MetricViewTests.cs

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,34 @@ public void AddViewWithNullMetricStreamConfigurationThrowsArgumentnullException(
9292
.Build());
9393
}
9494

95+
[Fact]
96+
public void AddViewWithNameThrowsInvalidArgumentExceptionWhenConflict()
97+
{
98+
var exportedItems = new List<Metric>();
99+
100+
using var meter1 = new Meter("AddViewWithGuaranteedConflictThrowsInvalidArgumentException");
101+
102+
Assert.Throws<ArgumentException>(() => Sdk.CreateMeterProviderBuilder()
103+
.AddMeter(meter1.Name)
104+
.AddView("instrumenta.*", name: "newname")
105+
.AddInMemoryExporter(exportedItems)
106+
.Build());
107+
}
108+
109+
[Fact]
110+
public void AddViewWithNameInMetricStreamConfigurationThrowsInvalidArgumentExceptionWhenConflict()
111+
{
112+
var exportedItems = new List<Metric>();
113+
114+
using var meter1 = new Meter("AddViewWithGuaranteedConflictThrowsInvalidArgumentException");
115+
116+
Assert.Throws<ArgumentException>(() => Sdk.CreateMeterProviderBuilder()
117+
.AddMeter(meter1.Name)
118+
.AddView("instrumenta.*", new MetricStreamConfiguration() { Name = "newname" })
119+
.AddInMemoryExporter(exportedItems)
120+
.Build());
121+
}
122+
95123
[Theory]
96124
[MemberData(nameof(MetricTestData.InvalidHistogramBoundaries), MemberType = typeof(MetricTestData))]
97125
public void AddViewWithInvalidHistogramBoundsThrowsArgumentException(double[] boundaries)
@@ -277,33 +305,6 @@ public void ViewWithNullCustomNameTakesInstrumentName()
277305
Assert.Equal(counter1.Name, metric.Name);
278306
}
279307

280-
[Fact]
281-
public void ViewToRenameMetricWildCardMatch()
282-
{
283-
using var meter = new Meter(Utils.GetCurrentMethodName());
284-
var exportedItems = new List<Metric>();
285-
using var meterProvider = Sdk.CreateMeterProviderBuilder()
286-
.AddMeter(meter.Name)
287-
.AddView("counter*", "renamed")
288-
.AddInMemoryExporter(exportedItems)
289-
.Build();
290-
291-
// Expecting one metric stream.
292-
var counter1 = meter.CreateCounter<long>("counterA");
293-
counter1.Add(10);
294-
var counter2 = meter.CreateCounter<long>("counterB");
295-
counter2.Add(10);
296-
var counter3 = meter.CreateCounter<long>("counterC");
297-
counter3.Add(10);
298-
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
299-
300-
// counter* matches all 3 instruments which all
301-
// becomes "renamed" and only 1st one is exported.
302-
Assert.Single(exportedItems);
303-
var metric = exportedItems[0];
304-
Assert.Equal("renamed", metric.Name);
305-
}
306-
307308
[Fact]
308309
public void ViewToProduceMultipleStreamsFromInstrument()
309310
{

0 commit comments

Comments
 (0)