diff --git a/src/OpenTelemetry.Api/Metrics/MeterProvider.cs b/src/OpenTelemetry.Api/Metrics/MeterProvider.cs
index 80859e56cb5..bff2d0a271c 100644
--- a/src/OpenTelemetry.Api/Metrics/MeterProvider.cs
+++ b/src/OpenTelemetry.Api/Metrics/MeterProvider.cs
@@ -27,5 +27,10 @@ public class MeterProvider : BaseProvider
protected MeterProvider()
{
}
+
+ ///
+ /// Gets the default .
+ ///
+ internal static MeterProvider Default { get; } = new MeterProvider();
}
}
diff --git a/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs b/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs
index aa5a5ace8e5..39f563bc8a0 100644
--- a/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs
+++ b/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs
@@ -32,6 +32,10 @@ public abstract class MeterProviderBuilderBase : MeterProviderBuilder
{
internal const int MaxMetricsDefault = 1000;
internal const int MaxMetricPointsPerMetricDefault = 2000;
+
+ // Builds noop MeterProvider when this flag is set.
+ // This flag is controlled through reflection.
+ private static bool disableMeterProviderBuilder = false;
private readonly List instrumentationFactories = new();
private readonly List meterSources = new();
private readonly List> viewConfigs = new();
@@ -142,7 +146,9 @@ internal MeterProviderBuilder SetMaxMetricPointsPerMetricStream(int maxMetricPoi
/// .
protected MeterProvider Build()
{
- return new MeterProviderSdk(
+ if (!disableMeterProviderBuilder)
+ {
+ return new MeterProviderSdk(
this.resourceBuilder.Build(),
this.meterSources,
this.instrumentationFactories,
@@ -150,6 +156,11 @@ protected MeterProvider Build()
this.maxMetricStreams,
this.maxMetricPointsPerMetricStream,
this.MetricReaders.ToArray());
+ }
+ else
+ {
+ return MeterProvider.Default;
+ }
}
internal readonly struct InstrumentationFactory
diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs
index 0fd85d2a37d..f9a8e21f39e 100644
--- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs
+++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs
@@ -33,6 +33,10 @@ public abstract class TracerProviderBuilderBase : TracerProviderBuilder, IDeferr
{
internal readonly TracerProviderBuilderState? State;
+ // Builds noop TracerProvider when this flag is set.
+ // This flag is controlled through reflection.
+ private static bool disableTracerProviderBuilder = false;
+
private readonly bool ownsServices;
private IServiceCollection? services;
@@ -264,7 +268,14 @@ protected TracerProvider Build()
var serviceProvider = services.BuildServiceProvider();
- return new TracerProviderSdk(serviceProvider, ownsServiceProvider: true);
+ if (!disableTracerProviderBuilder)
+ {
+ return new TracerProviderSdk(serviceProvider, ownsServiceProvider: true);
+ }
+ else
+ {
+ return TracerProvider.Default;
+ }
}
private static BaseProcessor BuildExportProcessor(
diff --git a/test/OpenTelemetry.Tests/Metrics/MeterProviderTests.cs b/test/OpenTelemetry.Tests/Metrics/MeterProviderTests.cs
index aa034bdd406..4faee30fcc3 100644
--- a/test/OpenTelemetry.Tests/Metrics/MeterProviderTests.cs
+++ b/test/OpenTelemetry.Tests/Metrics/MeterProviderTests.cs
@@ -15,6 +15,7 @@
//
using System.Collections.Generic;
+using System.Reflection;
using OpenTelemetry.Exporter;
using Xunit;
@@ -34,6 +35,21 @@ public void MeterProviderFindExporterTest()
Assert.False(meterProvider.TryFindExporter(out MyExporter myExporter));
}
+ [Fact]
+ public void NoopMeterProviderWithDisabledMeterProviderBuilderFlag()
+ {
+ var buildMeterProviderBuilderField = typeof(MeterProviderBuilderBase).GetField("disableMeterProviderBuilder", BindingFlags.Static | BindingFlags.NonPublic);
+ buildMeterProviderBuilderField.SetValue(null, true);
+
+ var exportedItems = new List();
+ using var meterProvider = Sdk.CreateMeterProviderBuilder()
+ .AddInMemoryExporter(exportedItems)
+ .Build();
+
+ Assert.Same(meterProvider, MeterProvider.Default);
+ buildMeterProviderBuilderField.SetValue(null, false);
+ }
+
private class MyExporter : BaseExporter
{
public override ExportResult Export(in Batch batch)
diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs
index 73773b44e63..98abf734b55 100644
--- a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs
+++ b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs
@@ -18,6 +18,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using System.Reflection;
using OpenTelemetry.Instrumentation;
using OpenTelemetry.Resources;
using OpenTelemetry.Tests;
@@ -1209,6 +1210,21 @@ public void SdkSamplesAndProcessesLegacySourceWhenAddLegacySourceIsCalledWithWil
Assert.Contains(nonLegacyActivity.OperationName, onStopProcessedActivities); // Processor.OnEnd is called since we added a legacy OperationName
}
+ [Fact]
+ public void NoopTracerProviderWithDisabledTracerProviderBuilderFlag()
+ {
+ var buildTracerProviderBuilderField = typeof(TracerProviderBuilderBase).GetField("disableTracerProviderBuilder", BindingFlags.Static | BindingFlags.NonPublic);
+ buildTracerProviderBuilderField.SetValue(null, true);
+
+ using var source1 = new ActivitySource($"{Utils.GetCurrentMethodName()}.1");
+ var builder = Sdk.CreateTracerProviderBuilder();
+ builder.AddSource(source1.Name);
+ using var provider = builder.Build();
+
+ Assert.Same(provider, TracerProvider.Default);
+ buildTracerProviderBuilderField.SetValue(null, false);
+ }
+
public void Dispose()
{
GC.SuppressFinalize(this);