diff --git a/docs/metrics/extending-the-sdk/README.md b/docs/metrics/extending-the-sdk/README.md index 8d7ceba3a..999e3e57e 100644 --- a/docs/metrics/extending-the-sdk/README.md +++ b/docs/metrics/extending-the-sdk/README.md @@ -54,8 +54,8 @@ class MyExporter : BaseExporter } ``` -A demo exporter which simply writes metric name and metric point start time -, tags to the console is shown [here](./MyExporter.cs). +A demo exporter which simply writes metric name, metric point start time +and tags to the console is shown [here](./MyExporter.cs). Apart from the exporter itself, you should also provide extension methods as shown [here](./MyExporterExtensions.cs). This allows users to add the Exporter diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index 999bcba5d..e8a8bd88c 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -207,7 +207,7 @@ namespace OpenTelemetry.Metrics } } - OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Succeeded publishing Instrument = \"{instrument.Name}\" of Meter = \"{instrument.Meter.Name}\"."); + OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Completed publishing Instrument = \"{instrument.Name}\" of Meter = \"{instrument.Meter.Name}\"."); } catch (Exception) { @@ -272,7 +272,7 @@ namespace OpenTelemetry.Metrics } } - OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Succeeded publishing Instrument = \"{instrument.Name}\" of Meter = \"{instrument.Meter.Name}\"."); + OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Completed publishing Instrument = \"{instrument.Name}\" of Meter = \"{instrument.Meter.Name}\"."); } catch (Exception) { diff --git a/src/OpenTelemetry/Metrics/MetricReaderExt.cs b/src/OpenTelemetry/Metrics/MetricReaderExt.cs index e81094bdb..2603da6d6 100644 --- a/src/OpenTelemetry/Metrics/MetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/MetricReaderExt.cs @@ -67,7 +67,21 @@ namespace OpenTelemetry.Metrics } else { - var metric = new Metric(instrumentIdentity, this.Temporality, this.maxMetricPointsPerMetricStream); + Metric metric = null; + try + { + metric = new Metric(instrumentIdentity, this.Temporality, this.maxMetricPointsPerMetricStream); + } + catch (NotSupportedException nse) + { + // TODO: This allocates string even if none listening. + // Could be improved with separate Event. + // Also the message could call out what Instruments + // and types (eg: int, long etc) are supported. + OpenTelemetrySdkEventSource.Log.MetricInstrumentIgnored(metricName, instrument.Meter.Name, "Unsupported instrument. Details: " + nse.Message, "Switch to a supported instrument type."); + return null; + } + this.instrumentIdentityToMetric[instrumentIdentity] = metric; this.metrics[index] = metric; this.metricStreamNames.Add(metricStreamName); diff --git a/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs b/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs index 2d464e6c8..b78e973ea 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs @@ -18,7 +18,9 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Metrics; +using System.Linq; using System.Threading; +using OpenTelemetry.Internal; using OpenTelemetry.Tests; using Xunit; using Xunit.Abstractions; @@ -1306,6 +1308,30 @@ namespace OpenTelemetry.Metrics.Tests counter.Add(10, new KeyValuePair("key", "value")); } + [Fact] + public void UnsupportedMetricInstrument() + { + using var meter = new Meter($"{Utils.GetCurrentMethodName()}"); + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddInMemoryExporter(exportedItems) + .Build(); + + using (var inMemoryEventListener = new InMemoryEventListener(OpenTelemetrySdkEventSource.Log)) + { + var counter = meter.CreateCounter("counter"); + counter.Add(1); + + // This validates that we log InstrumentIgnored event + // and not something else. + Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 33)); + } + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + Assert.Empty(exportedItems); + } + private static void ValidateMetricPointTags(List> expectedTags, ReadOnlyTagCollection actualTags) { int tagIndex = 0;