diff --git a/Directory.Packages.props b/Directory.Packages.props
index af1039e95ef..13fb63b9f08 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -29,6 +29,7 @@
+
diff --git a/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt
index e69de29bb2d..8b137891791 100644
--- a/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt
+++ b/src/OpenTelemetry.Extensions.Hosting/.publicApi/Stable/PublicAPI.Unshipped.txt
@@ -0,0 +1 @@
+
diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md
index f9ab8b5d8ed..6b801fc615c 100644
--- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md
+++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md
@@ -6,6 +6,12 @@
version to `8.0.0`.
([#5051](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5051))
+* The `OpenTelemetryBuilder.WithMetrics` method will now register an
+ `IMetricsListener` named 'OpenTelemetry' into the `IServiceCollection` to
+ enable metric management via the new `Microsoft.Extensions.Diagnostics` .NET 8
+ APIs.
+ ([#4958](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4958))
+
## 1.7.0-alpha.1
Released 2023-Oct-16
diff --git a/src/OpenTelemetry.Extensions.Hosting/Implementation/OpenTelemetryMetricsListener.cs b/src/OpenTelemetry.Extensions.Hosting/Implementation/OpenTelemetryMetricsListener.cs
new file mode 100644
index 00000000000..51c8c0d1826
--- /dev/null
+++ b/src/OpenTelemetry.Extensions.Hosting/Implementation/OpenTelemetryMetricsListener.cs
@@ -0,0 +1,120 @@
+//
+// Copyright The OpenTelemetry Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System.Diagnostics;
+using System.Diagnostics.Metrics;
+using Microsoft.Extensions.Diagnostics.Metrics;
+
+namespace OpenTelemetry.Metrics;
+
+internal sealed class OpenTelemetryMetricsListener : IMetricsListener, IDisposable
+{
+ private readonly MeterProviderSdk meterProviderSdk;
+ private IObservableInstrumentsSource? observableInstrumentsSource;
+
+ public OpenTelemetryMetricsListener(MeterProvider meterProvider)
+ {
+ var meterProviderSdk = meterProvider as MeterProviderSdk;
+
+ Debug.Assert(meterProviderSdk != null, "meterProvider was not MeterProviderSdk");
+
+ this.meterProviderSdk = meterProviderSdk!;
+
+ this.meterProviderSdk.OnCollectObservableInstruments += this.OnCollectObservableInstruments;
+ }
+
+ public string Name => "OpenTelemetry";
+
+ public void Dispose()
+ {
+ this.meterProviderSdk.OnCollectObservableInstruments -= this.OnCollectObservableInstruments;
+ }
+
+ public MeasurementHandlers GetMeasurementHandlers()
+ {
+ return new MeasurementHandlers()
+ {
+ ByteHandler = (instrument, value, tags, state)
+ => this.MeasurementRecordedLong(instrument, value, tags, state),
+ ShortHandler = (instrument, value, tags, state)
+ => this.MeasurementRecordedLong(instrument, value, tags, state),
+ IntHandler = (instrument, value, tags, state)
+ => this.MeasurementRecordedLong(instrument, value, tags, state),
+ LongHandler = this.MeasurementRecordedLong,
+ FloatHandler = (instrument, value, tags, state)
+ => this.MeasurementRecordedDouble(instrument, value, tags, state),
+ DoubleHandler = this.MeasurementRecordedDouble,
+ };
+ }
+
+ public bool InstrumentPublished(Instrument instrument, out object? userState)
+ {
+ userState = this.meterProviderSdk.InstrumentPublished(instrument, listeningIsManagedExternally: true);
+ return userState != null;
+ }
+
+ public void MeasurementsCompleted(Instrument instrument, object? userState)
+ {
+ var meterProvider = this.meterProviderSdk;
+
+ if (meterProvider.ViewCount > 0)
+ {
+ meterProvider.MeasurementsCompleted(instrument, userState);
+ }
+ else
+ {
+ meterProvider.MeasurementsCompletedSingleStream(instrument, userState);
+ }
+ }
+
+ public void Initialize(IObservableInstrumentsSource source)
+ {
+ this.observableInstrumentsSource = source;
+ }
+
+ private void OnCollectObservableInstruments()
+ {
+ this.observableInstrumentsSource?.RecordObservableInstruments();
+ }
+
+ private void MeasurementRecordedDouble(Instrument instrument, double value, ReadOnlySpan> tagsRos, object? userState)
+ {
+ var meterProvider = this.meterProviderSdk;
+
+ if (meterProvider.ViewCount > 0)
+ {
+ meterProvider.MeasurementRecordedDouble(instrument, value, tagsRos, userState);
+ }
+ else
+ {
+ meterProvider.MeasurementRecordedDoubleSingleStream(instrument, value, tagsRos, userState);
+ }
+ }
+
+ private void MeasurementRecordedLong(Instrument instrument, long value, ReadOnlySpan> tagsRos, object? userState)
+ {
+ var meterProvider = this.meterProviderSdk;
+
+ if (meterProvider.ViewCount > 0)
+ {
+ meterProvider.MeasurementRecordedLong(instrument, value, tagsRos, userState);
+ }
+ else
+ {
+ meterProvider.MeasurementRecordedLongSingleStream(instrument, value, tagsRos, userState);
+ }
+ }
+}
diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetry.Extensions.Hosting.csproj b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetry.Extensions.Hosting.csproj
index 0d589aae7da..cc6b1b078a1 100644
--- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetry.Extensions.Hosting.csproj
+++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetry.Extensions.Hosting.csproj
@@ -10,6 +10,7 @@
+
diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs
index 805808488a1..00af83db167 100644
--- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs
+++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs
@@ -15,6 +15,7 @@
//
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Diagnostics.Metrics;
using OpenTelemetry.Internal;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
@@ -61,13 +62,13 @@ public OpenTelemetryBuilder ConfigureResource(
Guard.ThrowIfNull(configure);
this.Services.ConfigureOpenTelemetryMeterProvider(
- (sp, builder) => builder.ConfigureResource(configure));
+ builder => builder.ConfigureResource(configure));
this.Services.ConfigureOpenTelemetryTracerProvider(
- (sp, builder) => builder.ConfigureResource(configure));
+ builder => builder.ConfigureResource(configure));
this.Services.ConfigureOpenTelemetryLoggerProvider(
- (sp, builder) => builder.ConfigureResource(configure));
+ builder => builder.ConfigureResource(configure));
return this;
}
@@ -76,9 +77,15 @@ public OpenTelemetryBuilder ConfigureResource(
/// Adds metric services into the builder.
///
///
- /// Note: This is safe to be called multiple times and by library authors.
+ /// Notes:
+ ///
+ /// - This is safe to be called multiple times and by library authors.
/// Only a single will be created for a given
- /// .
+ /// .
+ /// - This method automatically registers an named 'OpenTelemetry' into the .
+ ///
///
/// The supplied for chaining
/// calls.
@@ -95,11 +102,9 @@ public OpenTelemetryBuilder WithMetrics()
/// calls.
public OpenTelemetryBuilder WithMetrics(Action configure)
{
- Guard.ThrowIfNull(configure);
-
- var builder = new MeterProviderBuilderBase(this.Services);
-
- configure(builder);
+ OpenTelemetryMetricsBuilderExtensions.RegisterMetricsListener(
+ this.Services,
+ configure);
return this;
}
diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryMetricsBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryMetricsBuilderExtensions.cs
new file mode 100644
index 00000000000..a34cea3ea3e
--- /dev/null
+++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryMetricsBuilderExtensions.cs
@@ -0,0 +1,81 @@
+//
+// Copyright The OpenTelemetry Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System.Diagnostics;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using OpenTelemetry.Internal;
+using OpenTelemetry.Metrics;
+
+namespace Microsoft.Extensions.Diagnostics.Metrics;
+
+///
+/// Contains extension methods for registering OpenTelemetry metrics with an
+/// instance.
+///
+internal static class OpenTelemetryMetricsBuilderExtensions
+{
+ ///
+ /// Adds an OpenTelemetry named 'OpenTelemetry' to the .
+ ///
+ ///
+ /// Note: This is safe to be called multiple times and by library authors.
+ /// Only a single will be created for a given
+ /// .
+ ///
+ /// .
+ /// The supplied for chaining
+ /// calls.
+ public static IMetricsBuilder UseOpenTelemetry(
+ this IMetricsBuilder metricsBuilder)
+ => UseOpenTelemetry(metricsBuilder, b => { });
+
+ ///
+ /// Adds an OpenTelemetry named 'OpenTelemetry' to the .
+ ///
+ ///
+ /// .
+ ///
+ /// configuration callback.
+ /// The supplied for chaining
+ /// calls.
+ public static IMetricsBuilder UseOpenTelemetry(
+ this IMetricsBuilder metricsBuilder,
+ Action configure)
+ {
+ Guard.ThrowIfNull(metricsBuilder);
+
+ RegisterMetricsListener(metricsBuilder.Services, configure);
+
+ return metricsBuilder;
+ }
+
+ internal static void RegisterMetricsListener(
+ IServiceCollection services,
+ Action configure)
+ {
+ Debug.Assert(services != null, "services was null");
+
+ Guard.ThrowIfNull(configure);
+
+ var builder = new MeterProviderBuilderBase(services!);
+
+ services!.TryAddEnumerable(
+ ServiceDescriptor.Singleton());
+
+ configure(builder);
+ }
+}
diff --git a/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs b/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs
index 1cbba26f9f8..67a668cf3d5 100644
--- a/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs
+++ b/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs
@@ -347,6 +347,18 @@ public void LoggerProcessStateSkipped(string type, string reason)
this.WriteEvent(51, type, reason);
}
+ [Event(52, Message = "Instrument '{0}', Meter '{1}' has been deactivated.", Level = EventLevel.Informational)]
+ public void MetricInstrumentDeactivated(string instrumentName, string meterName)
+ {
+ this.WriteEvent(52, instrumentName, meterName);
+ }
+
+ [Event(53, Message = "Instrument '{0}', Meter '{1}' has been removed.", Level = EventLevel.Informational)]
+ public void MetricInstrumentRemoved(string instrumentName, string meterName)
+ {
+ this.WriteEvent(53, instrumentName, meterName);
+ }
+
#if DEBUG
public class OpenTelemetryEventListener : EventListener
{
diff --git a/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs
index 5776241441d..e4cf260aa16 100644
--- a/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs
+++ b/src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggingExtensions.cs
@@ -50,15 +50,43 @@ public static class OpenTelemetryLoggingExtensions
/// The supplied for call chaining.
public static ILoggingBuilder AddOpenTelemetry(
this ILoggingBuilder builder)
+ => AddOpenTelemetryInternal(builder, configureBuilder: null, configureOptions: null);
+
+ ///
+ /// Adds an OpenTelemetry logger named 'OpenTelemetry' to the .
+ ///
+ ///
+ /// The to use.
+ /// Optional configuration action.
+ /// The supplied for call chaining.
+ public static ILoggingBuilder AddOpenTelemetry(
+ this ILoggingBuilder builder,
+ Action? configure)
+ => AddOpenTelemetryInternal(builder, configureBuilder: null, configureOptions: configure);
+
+ private static ILoggingBuilder AddOpenTelemetryInternal(
+ ILoggingBuilder builder,
+ Action? configureBuilder,
+ Action? configureOptions)
{
Guard.ThrowIfNull(builder);
builder.AddConfiguration();
+ var services = builder.Services;
+
+ if (configureOptions != null)
+ {
+ // TODO: Move this below the RegisterLoggerProviderOptions call so
+ // that user-supplied delegate fires AFTER the options are bound to
+ // Logging:OpenTelemetry configuration.
+ services.Configure(configureOptions);
+ }
+
// Note: This will bind logger options element (eg "Logging:OpenTelemetry") to OpenTelemetryLoggerOptions
- RegisterLoggerProviderOptions(builder.Services);
+ RegisterLoggerProviderOptions(services);
- new LoggerProviderBuilderBase(builder.Services).ConfigureBuilder(
+ var loggingBuilder = new LoggerProviderBuilderBase(services).ConfigureBuilder(
(sp, logging) =>
{
var options = sp.GetRequiredService>().CurrentValue;
@@ -78,7 +106,9 @@ public static ILoggingBuilder AddOpenTelemetry(
options.Processors.Clear();
});
- builder.Services.TryAddEnumerable(
+ configureBuilder?.Invoke(loggingBuilder);
+
+ services.TryAddEnumerable(
ServiceDescriptor.Singleton(
sp => new OpenTelemetryLoggerProvider(
sp.GetRequiredService(),
@@ -107,23 +137,4 @@ static void RegisterLoggerProviderOptions(IServiceCollection services)
LoggerProviderOptions.RegisterProviderOptions(services);
}
}
-
- ///
- /// Adds an OpenTelemetry logger named 'OpenTelemetry' to the .
- ///
- ///
- /// The to use.
- /// Optional configuration action.
- /// The supplied for call chaining.
- public static ILoggingBuilder AddOpenTelemetry(
- this ILoggingBuilder builder,
- Action? configure)
- {
- if (configure != null)
- {
- builder.Services.Configure(configure);
- }
-
- return AddOpenTelemetry(builder);
- }
}
diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs
index d5c979604bf..767cf30714b 100644
--- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs
+++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs
@@ -277,6 +277,8 @@ public static MeterProviderBuilder SetMaxMetricPointsPerMetricStream(this MeterP
/// The supplied for chaining.
public static MeterProviderBuilder SetResourceBuilder(this MeterProviderBuilder meterProviderBuilder, ResourceBuilder resourceBuilder)
{
+ Guard.ThrowIfNull(resourceBuilder);
+
meterProviderBuilder.ConfigureBuilder((sp, builder) =>
{
if (builder is MeterProviderBuilderSdk meterProviderBuilderSdk)
@@ -297,6 +299,8 @@ public static MeterProviderBuilder SetResourceBuilder(this MeterProviderBuilder
/// The supplied for chaining.
public static MeterProviderBuilder ConfigureResource(this MeterProviderBuilder meterProviderBuilder, Action configure)
{
+ Guard.ThrowIfNull(configure);
+
meterProviderBuilder.ConfigureBuilder((sp, builder) =>
{
if (builder is MeterProviderBuilderSdk meterProviderBuilderSdk)
diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs
index 73880837dce..74405b02be2 100644
--- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs
+++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs
@@ -31,6 +31,7 @@ internal sealed class MeterProviderSdk : MeterProvider
internal int ShutdownCount;
internal bool Disposed;
internal bool ShouldReclaimUnusedMetricPoints;
+ internal Action? OnCollectObservableInstruments;
private const string EmitOverFlowAttributeConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE";
private const string ReclaimUnusedMetricPointsConfigKey = "OTEL_DOTNET_EXPERIMENTAL_METRICS_RECLAIM_UNUSED_METRIC_POINTS";
@@ -41,6 +42,7 @@ internal sealed class MeterProviderSdk : MeterProvider
private readonly MeterListener listener;
private readonly MetricReader? reader;
private readonly CompositeMetricReader? compositeMetricReader;
+ private readonly Func shouldListenTo = instrument => false;
internal MeterProviderSdk(
IServiceProvider serviceProvider,
@@ -149,16 +151,15 @@ internal MeterProviderSdk(
}
// Setup Listener
- Func shouldListenTo = instrument => false;
if (state.MeterSources.Any(s => WildcardHelper.ContainsWildcard(s)))
{
var regex = WildcardHelper.GetWildcardRegex(state.MeterSources);
- shouldListenTo = instrument => regex.IsMatch(instrument.Meter.Name);
+ this.shouldListenTo = instrument => regex.IsMatch(instrument.Meter.Name);
}
else if (state.MeterSources.Any())
{
var meterSourcesToSubscribe = new HashSet(state.MeterSources, StringComparer.OrdinalIgnoreCase);
- shouldListenTo = instrument => meterSourcesToSubscribe.Contains(instrument.Meter.Name);
+ this.shouldListenTo = instrument => meterSourcesToSubscribe.Contains(instrument.Meter.Name);
}
OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Listening to following meters = \"{string.Join(";", state.MeterSources)}\".");
@@ -168,116 +169,19 @@ internal MeterProviderSdk(
OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Number of views configured = {viewConfigCount}.");
+ this.listener.InstrumentPublished = (instrument, listener) =>
+ {
+ object? state = this.InstrumentPublished(instrument, listeningIsManagedExternally: false);
+ if (state != null)
+ {
+ listener.EnableMeasurementEvents(instrument, state);
+ }
+ };
+
// We expect that all the readers to be added are provided before MeterProviderSdk is built.
// If there are no readers added, we do not enable measurements for the instruments.
if (viewConfigCount > 0)
{
- this.listener.InstrumentPublished = (instrument, listener) =>
- {
- bool enabledMeasurements = false;
-
- if (!shouldListenTo(instrument))
- {
- OpenTelemetrySdkEventSource.Log.MetricInstrumentIgnored(instrument.Name, instrument.Meter.Name, "Instrument belongs to a Meter not subscribed by the provider.", "Use AddMeter to add the Meter to the provider.");
- return;
- }
-
- try
- {
- OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Started publishing Instrument = \"{instrument.Name}\" of Meter = \"{instrument.Meter.Name}\".");
-
- // Creating list with initial capacity as the maximum
- // possible size, to avoid any array resize/copy internally.
- // There may be excess space wasted, but it'll eligible for
- // GC right after this method.
- var metricStreamConfigs = new List(viewConfigCount);
- for (var i = 0; i < viewConfigCount; ++i)
- {
- var viewConfig = this.viewConfigs[i];
- MetricStreamConfiguration? metricStreamConfig = null;
-
- try
- {
- metricStreamConfig = viewConfig(instrument);
-
- // The SDK provides some static MetricStreamConfigurations.
- // For example, the Drop configuration. The static ViewId
- // should not be changed for these configurations.
- if (metricStreamConfig != null && !metricStreamConfig.ViewId.HasValue)
- {
- metricStreamConfig.ViewId = i;
- }
-
- if (metricStreamConfig is HistogramConfiguration
- && instrument.GetType().GetGenericTypeDefinition() != typeof(Histogram<>))
- {
- metricStreamConfig = null;
-
- OpenTelemetrySdkEventSource.Log.MetricViewIgnored(
- instrument.Name,
- instrument.Meter.Name,
- "The current SDK does not allow aggregating non-Histogram instruments as Histograms.",
- "Fix the view configuration.");
- }
- }
- catch (Exception ex)
- {
- OpenTelemetrySdkEventSource.Log.MetricViewIgnored(instrument.Name, instrument.Meter.Name, ex.Message, "Fix the view configuration.");
- }
-
- if (metricStreamConfig != null)
- {
- metricStreamConfigs.Add(metricStreamConfig);
- }
- }
-
- if (metricStreamConfigs.Count == 0)
- {
- // No views matched. Add null
- // which will apply defaults.
- // Users can turn off this default
- // by adding a view like below as the last view.
- // .AddView(instrumentName: "*", MetricStreamConfiguration.Drop)
- metricStreamConfigs.Add(null);
- }
-
- if (this.reader != null)
- {
- if (this.compositeMetricReader == null)
- {
- var metrics = this.reader.AddMetricsListWithViews(instrument, metricStreamConfigs);
- if (metrics.Count > 0)
- {
- listener.EnableMeasurementEvents(instrument, metrics);
- enabledMeasurements = true;
- }
- }
- else
- {
- var metricsSuperList = this.compositeMetricReader.AddMetricsSuperListWithViews(instrument, metricStreamConfigs);
- if (metricsSuperList.Any(metrics => metrics.Count > 0))
- {
- listener.EnableMeasurementEvents(instrument, metricsSuperList);
- enabledMeasurements = true;
- }
- }
- }
-
- if (enabledMeasurements)
- {
- OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Measurements for Instrument = \"{instrument.Name}\" of Meter = \"{instrument.Meter.Name}\" will be processed and aggregated by the SDK.");
- }
- else
- {
- OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Measurements for Instrument = \"{instrument.Name}\" of Meter = \"{instrument.Meter.Name}\" will be dropped by the SDK.");
- }
- }
- catch (Exception)
- {
- OpenTelemetrySdkEventSource.Log.MetricInstrumentIgnored(instrument.Name, instrument.Meter.Name, "SDK internal error occurred.", "Contact SDK owners.");
- }
- };
-
// Everything double
this.listener.SetMeasurementEventCallback(this.MeasurementRecordedDouble);
this.listener.SetMeasurementEventCallback((instrument, value, tags, state) => this.MeasurementRecordedDouble(instrument, value, tags, state));
@@ -292,92 +196,186 @@ internal MeterProviderSdk(
}
else
{
- this.listener.InstrumentPublished = (instrument, listener) =>
- {
- bool enabledMeasurements = false;
+ // Everything double
+ this.listener.SetMeasurementEventCallback(this.MeasurementRecordedDoubleSingleStream);
+ this.listener.SetMeasurementEventCallback((instrument, value, tags, state) => this.MeasurementRecordedDoubleSingleStream(instrument, value, tags, state));
+
+ // Everything long
+ this.listener.SetMeasurementEventCallback(this.MeasurementRecordedLongSingleStream);
+ this.listener.SetMeasurementEventCallback((instrument, value, tags, state) => this.MeasurementRecordedLongSingleStream(instrument, value, tags, state));
+ this.listener.SetMeasurementEventCallback((instrument, value, tags, state) => this.MeasurementRecordedLongSingleStream(instrument, value, tags, state));
+ this.listener.SetMeasurementEventCallback((instrument, value, tags, state) => this.MeasurementRecordedLongSingleStream(instrument, value, tags, state));
+
+ this.listener.MeasurementsCompleted = (instrument, state) => this.MeasurementsCompletedSingleStream(instrument, state);
+ }
+
+ this.listener.Start();
+
+ OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent("MeterProvider built successfully.");
+ }
+
+ internal Resource Resource { get; }
+
+ internal List