diff --git a/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs
index 14e68b05588..fc99c1b9c81 100644
--- a/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs
+++ b/src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs
@@ -15,6 +15,7 @@
//
#if !NET452
+using System.Runtime.CompilerServices;
using System.Threading;
namespace OpenTelemetry.Context
@@ -38,12 +39,14 @@ public AsyncLocalRuntimeContextSlot(string name)
}
///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override T Get()
{
return this.slot.Value;
}
///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void Set(T value)
{
this.slot.Value = value;
diff --git a/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs
index 315674e4681..c96caa57b2c 100644
--- a/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs
+++ b/src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs
@@ -17,6 +17,7 @@
#if NET452
using System.Collections;
using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Runtime.Remoting.Messaging;
namespace OpenTelemetry.Context
@@ -50,6 +51,7 @@ public RemotingRuntimeContextSlot(string name)
}
///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override T Get()
{
var wrapper = CallContext.LogicalGetData(this.Name) as BitArray;
@@ -63,6 +65,7 @@ public override T Get()
}
///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void Set(T value)
{
var wrapper = new BitArray(0);
diff --git a/src/OpenTelemetry.Api/Context/RuntimeContext.cs b/src/OpenTelemetry.Api/Context/RuntimeContext.cs
index c4db55c679e..625556c751c 100644
--- a/src/OpenTelemetry.Api/Context/RuntimeContext.cs
+++ b/src/OpenTelemetry.Api/Context/RuntimeContext.cs
@@ -17,6 +17,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Runtime.CompilerServices;
namespace OpenTelemetry.Context
{
@@ -41,7 +42,8 @@ public sealed class RuntimeContext
///
/// The name of the context slot.
/// The type of the underlying value.
- public static void RegisterSlot(string name)
+ /// The slot registered.
+ public static RuntimeContextSlot RegisterSlot(string name)
{
lock (Slots)
{
@@ -52,10 +54,23 @@ public static void RegisterSlot(string name)
var type = ContextSlotType.MakeGenericType(typeof(T));
var ctor = type.GetConstructor(new Type[] { typeof(string) });
- Slots[name] = ctor.Invoke(new object[] { name });
+ var slot = (RuntimeContextSlot)ctor.Invoke(new object[] { name });
+ Slots[name] = slot;
+ return slot;
}
}
+ ///
+ /// Get a registered slot from a given name.
+ ///
+ /// The name of the context slot.
+ /// The type of the underlying value.
+ /// The slot previously registered.
+ public static RuntimeContextSlot GetSlot(string name)
+ {
+ return (RuntimeContextSlot)Slots[name];
+ }
+
/*
public static void Apply(IDictionary snapshot)
{
@@ -86,6 +101,7 @@ public static IDictionary Snapshot()
/// The name of the context slot.
/// The value to be set.
/// The type of the value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SetValue(string name, T value)
{
var slot = (RuntimeContextSlot)Slots[name];
@@ -98,6 +114,7 @@ public static void SetValue(string name, T value)
/// The name of the context slot.
/// The type of the value.
/// The value retrieved from the context slot.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T GetValue(string name)
{
var slot = (RuntimeContextSlot)Slots[name];
diff --git a/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs b/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs
index a18cc69c193..b1314f9b4b3 100644
--- a/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs
+++ b/src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs
@@ -14,6 +14,7 @@
// limitations under the License.
//
+using System.Runtime.CompilerServices;
using System.Threading;
namespace OpenTelemetry.Context
@@ -37,12 +38,14 @@ public ThreadLocalRuntimeContextSlot(string name)
}
///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override T Get()
{
return this.slot.Value;
}
///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void Set(T value)
{
this.slot.Value = value;
diff --git a/src/OpenTelemetry/Sdk.cs b/src/OpenTelemetry/Sdk.cs
index eb85d063102..38f0889feaf 100644
--- a/src/OpenTelemetry/Sdk.cs
+++ b/src/OpenTelemetry/Sdk.cs
@@ -17,7 +17,9 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Threading;
+using OpenTelemetry.Context;
using OpenTelemetry.Metrics;
using OpenTelemetry.Metrics.Export;
using OpenTelemetry.Trace;
@@ -32,7 +34,53 @@ namespace OpenTelemetry
///
public static class Sdk
{
- private static TimeSpan defaultPushInterval = TimeSpan.FromSeconds(60);
+ private static readonly TimeSpan DefaultPushInterval = TimeSpan.FromSeconds(60);
+
+ private static readonly RuntimeContextSlot SuppressInstrumentationRuntimeContextSlot = RuntimeContext.RegisterSlot("otel.suppress_instrumentation");
+
+ ///
+ /// Gets or sets a value indicating whether automatic telemetry
+ /// collection in the current context should be suppressed (disabled).
+ /// Default value: False.
+ ///
+ ///
+ /// Set to
+ /// when you want to turn off automatic telemetry collection.
+ /// This is typically used to prevent infinite loops created by
+ /// collection of internal operations, such as exporting traces over HTTP.
+ ///
+ /// public override async Task<ExportResult> ExportAsync(
+ /// IEnumerable<Activity> batch,
+ /// CancellationToken cancellationToken)
+ /// {
+ /// var currentSuppressionPolicy = Sdk.SuppressInstrumentation;
+ /// Sdk.SuppressInstrumentation = true;
+ /// try
+ /// {
+ /// await this.SendBatchActivityAsync(batch, cancellationToken).ConfigureAwait(false);
+ /// return ExportResult.Success;
+ /// }
+ /// finally
+ /// {
+ /// Sdk.SuppressInstrumentation = currentSuppressionPolicy;
+ /// }
+ /// }
+ ///
+ ///
+ public static bool SuppressInstrumentation
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ return SuppressInstrumentationRuntimeContextSlot.Get();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set
+ {
+ SuppressInstrumentationRuntimeContextSlot.Set(value);
+ }
+ }
///
/// Creates MeterProvider with the configuration provided.
@@ -60,7 +108,7 @@ public static MeterProvider CreateMeterProvider(Action configure)
meterRegistry,
metricProcessor,
metricExporter,
- meterBuilder.MetricPushInterval == default(TimeSpan) ? defaultPushInterval : meterBuilder.MetricPushInterval,
+ meterBuilder.MetricPushInterval == default(TimeSpan) ? DefaultPushInterval : meterBuilder.MetricPushInterval,
cancellationTokenSource);
var meterProviderSdk = new MeterProviderSdk(metricProcessor, meterRegistry, controller, cancellationTokenSource);