Skip to content

Commit

Permalink
Make SuppressInstrumentation an IDisposable (#988)
Browse files Browse the repository at this point in the history
* Make SuppressInstrumentation an IDisposable

* Simplify SuppressInstrumentation

* Rename to SuppressInstrumentationScope

* Clean up comment

* Implicit operator instead of IsSuppressed property

* Make SuppressInstrumentationScope constructor internal

* Clean up some names

* Update changelog

Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Reiley Yang <reyang@microsoft.com>
  • Loading branch information
3 people committed Aug 5, 2020
1 parent fd0cc21 commit 099c3c7
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 46 deletions.
1 change: 1 addition & 0 deletions src/OpenTelemetry/CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

## Unreleased

* Introduce `SuppressInstrumentationScope` API (#988).
* `ActivityProcessor` implements `IDisposable`.
* When `Dispose` occurs, it calls `ShutdownAsync`.
* If you want a custom behavior for dispose, you will have to override the
Expand Down
48 changes: 2 additions & 46 deletions src/OpenTelemetry/Sdk.cs
Expand Up @@ -34,53 +34,9 @@ namespace OpenTelemetry
/// </summary>
public static class Sdk
{
private static readonly TimeSpan DefaultPushInterval = TimeSpan.FromSeconds(60);

private static readonly RuntimeContextSlot<bool> SuppressInstrumentationRuntimeContextSlot = RuntimeContext.RegisterSlot<bool>("otel.suppress_instrumentation");

/// <summary>
/// Gets or sets a value indicating whether automatic telemetry
/// collection in the current context should be suppressed (disabled).
/// Default value: False.
/// </summary>
/// <remarks>
/// Set <see cref="SuppressInstrumentation"/> to <see langword="true"/>
/// 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.
/// <code>
/// public override async Task&lt;ExportResult&gt; ExportAsync(
/// IEnumerable&lt;Activity&gt; 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;
/// }
/// }
/// </code>
/// </remarks>
public static bool SuppressInstrumentation
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return SuppressInstrumentationRuntimeContextSlot.Get();
}
public static readonly SuppressInstrumentationScope SuppressInstrumentation = new SuppressInstrumentationScope(false);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
SuppressInstrumentationRuntimeContextSlot.Set(value);
}
}
private static readonly TimeSpan DefaultPushInterval = TimeSpan.FromSeconds(60);

/// <summary>
/// Creates MeterProvider with the configuration provided.
Expand Down
74 changes: 74 additions & 0 deletions src/OpenTelemetry/SuppressInstrumentationScope.cs
@@ -0,0 +1,74 @@
// <copyright file="SuppressInstrumentationScope.cs" company="OpenTelemetry Authors">
// 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.
// </copyright>

using System;
using OpenTelemetry.Context;

namespace OpenTelemetry
{
public sealed class SuppressInstrumentationScope : IDisposable
{
private static readonly RuntimeContextSlot<bool> Slot = RuntimeContext.RegisterSlot<bool>("otel.suppress_instrumentation");

private readonly bool previousValue;
private bool disposed;

internal SuppressInstrumentationScope(bool value = true)
{
this.previousValue = Slot.Get();
Slot.Set(value);
}

public static implicit operator bool(SuppressInstrumentationScope unused) => Slot.Get();

/// <summary>
/// Begins a new scope in which instrumentation is suppressed (disabled).
/// </summary>
/// <param name="value">Value indicating whether to suppress instrumentation.</param>
/// <returns>Object to dispose to end the scope.</returns>
/// <remarks>
/// This is typically used to prevent infinite loops created by
/// collection of internal operations, such as exporting traces over HTTP.
/// <code>
/// public override async Task&lt;ExportResult&gt; ExportAsync(
/// IEnumerable&lt;Activity&gt; batch,
/// CancellationToken cancellationToken)
/// {
/// using (Sdk.SuppressInstrumentation.Begin())
/// {
/// // Instrumentation is suppressed (i.e., Sdk.SuppressInstrumentation == true)
/// }
///
/// // Instrumentation is not suppressed (i.e., Sdk.SuppressInstrumentation == false)
/// }
/// </code>
/// </remarks>
public IDisposable Begin(bool value = true)
{
return new SuppressInstrumentationScope(value);
}

/// <inheritdoc/>
public void Dispose()
{
if (!this.disposed)
{
Slot.Set(this.previousValue);
this.disposed = true;
}
}
}
}
45 changes: 45 additions & 0 deletions test/OpenTelemetry.Tests/SuppressInstrumentationTest.cs
@@ -0,0 +1,45 @@
// <copyright file="SuppressInstrumentationTest.cs" company="OpenTelemetry Authors">
// 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.
// </copyright>

using Xunit;

namespace OpenTelemetry.Tests
{
public class SuppressInstrumentationTest
{
[Fact]
public static void UsingSuppressInstrumentation()
{
using (var scope = Sdk.SuppressInstrumentation.Begin())
{
Assert.True(Sdk.SuppressInstrumentation);

using (var innerScope = Sdk.SuppressInstrumentation.Begin())
{
innerScope.Dispose();

Assert.True(Sdk.SuppressInstrumentation);

scope.Dispose();
}

Assert.False(Sdk.SuppressInstrumentation);
}

Assert.False(Sdk.SuppressInstrumentation);
}
}
}

0 comments on commit 099c3c7

Please sign in to comment.