Skip to content

Commit 907850b

Browse files
Added option to disable sentry tracing
1 parent 08d8711 commit 907850b

8 files changed

Lines changed: 147 additions & 49 deletions

File tree

samples/Sentry.Samples.OpenTelemetry.AspNetCore/Program.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
var builder = WebApplication.CreateBuilder(args);
99

10-
// Read the Sentry DSN from the environment variable, if it's not already set in code.
10+
// Read the Sentry DSN from the environment variable if it's not already set in code.
1111
#if SENTRY_DSN_DEFINED_IN_ENV
12-
var dsn = Environment.GetEnvironmentVariable("SENTRY_DSN") ?? throw new InvalidOperationException("SENTRY_DSN environment variable is not set");
12+
var dsn = Environment.GetEnvironmentVariable("SENTRY_DSN")
13+
?? throw new InvalidOperationException("SENTRY_DSN environment variable is not set");
1314
#else
1415
var dsn = SamplesShared.Dsn;
1516
#endif
@@ -27,8 +28,8 @@
2728
// The two lines below take care of configuring sources for ASP.NET Core and HttpClient
2829
.AddAspNetCoreInstrumentation()
2930
.AddHttpClientInstrumentation()
30-
// Finally, we configure OpenTelemetry to send traces to Sentry
31-
.AddSentry(dsn)
31+
// Finally, we configure OpenTelemetry over OTLP to send traces to Sentry
32+
.AddSentryOTLP(dsn)
3233
);
3334

3435
builder.WebHost.UseSentry(options =>
@@ -42,7 +43,7 @@
4243
options.Debug = builder.Environment.IsDevelopment();
4344
options.SendDefaultPii = true;
4445
options.TracesSampleRate = 1.0;
45-
options.UseOpenTelemetry(); // <-- Configure Sentry to use OpenTelemetry trace information
46+
options.UseOTLP(); // <-- Configure Sentry to use OpenTelemetry trace information
4647
});
4748

4849
builder.Services

src/Sentry.Maui.CommunityToolkit.Mvvm/SentryOptionsExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ public static class SentryOptionsExtensions
1313
/// </summary>
1414
public static SentryMauiOptions AddCommunityToolkitIntegration(this SentryMauiOptions options)
1515
{
16-
if (options.Instrumenter == Instrumenter.OpenTelemetry)
16+
if (options.DisableSentryTracing)
1717
{
18-
options.LogWarning("Skipping CommunityToolkit.Mvvm integration since OpenTelemetry instrumentation is enabled.");
18+
options.LogWarning("Skipping CommunityToolkit.Mvvm integration because OpenTelemetry is enabled.");
1919
}
2020
else
2121
{

src/Sentry.OpenTelemetry/SentryOptionsExtensions.cs

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Sentry.OpenTelemetry;
99
public static class SentryOptionsExtensions
1010
{
1111
/// <summary>
12-
/// Enables OpenTelemetry instrumentation with Sentry
12+
/// Configures Sentry to use OpenTelemetry for distributed tracing.
1313
/// </summary>
1414
/// <param name="options">The <see cref="SentryOptions"/> instance.</param>
1515
/// <param name="builder"><see cref="TracerProviderBuilder"/></param>
@@ -24,27 +24,98 @@ public static class SentryOptionsExtensions
2424
/// could wrap this in a <see cref="CompositeTextMapPropagator"/> if you needed other propagators as well.
2525
/// </para>
2626
/// </param>
27-
public static void UseOpenTelemetry(this SentryOptions options, TracerProviderBuilder builder, TextMapPropagator? textMapPropagator = null)
27+
/// <param name="disableSentryTracing">Whether to disable traces created using Sentry's tracing instrumentation.
28+
/// It's recommended that you set this to <c>true</c> since mixing OpenTelemetry and Sentry traces may yield
29+
/// unexpected results. It is <c>false</c> by default for backward compatibility only.
30+
/// </param>
31+
/// <remarks>
32+
/// This method of initialising the Sentry OpenTelemetry integration will be depricated in a future major release.
33+
/// We recommend you use <see cref="UseOTLP(SentryOptions, TracerProviderBuilder, TextMapPropagator?)"/> instead.
34+
/// </remarks>
35+
public static void UseOpenTelemetry(this SentryOptions options, TracerProviderBuilder builder,
36+
TextMapPropagator? textMapPropagator = null, bool disableSentryTracing = false)
2837
{
29-
options.UseOpenTelemetry();
38+
options.UseOpenTelemetry(disableSentryTracing);
3039
builder.AddSentry(textMapPropagator);
3140
}
3241

3342
/// <summary>
34-
/// <para>Configures Sentry to use OpenTelemetry for distributed tracing.</para>
43+
/// <para>Configures Sentry to use OpenTelemetry for distributed tracing.
44+
/// </para>
3545
/// <para>
36-
/// Note: if you are using this method to configure Sentry to work with OpenTelemetry, you will also have to call
46+
/// Note: if you are using this overload to configure Sentry to work with OpenTelemetry, you will also have to call
3747
/// <see cref="O:TracerProviderBuilderExtensions.AddSentry"/> when building your <see cref="TracerProviderBuilder"/>
3848
/// to ensure OpenTelemetry sends trace information to Sentry.
3949
/// </para>
4050
/// </summary>
4151
/// <param name="options">The <see cref="SentryOptions"/> instance.</param>
42-
public static void UseOpenTelemetry(this SentryOptions options)
52+
/// <param name="disableSentryTracing">Whether to disable traces created using Sentry's tracing instrumentation.
53+
/// It's recommended that you set this to <c>true</c> since mixing OpenTelemetry and Sentry traces may yield
54+
/// unexpected results. It is <c>false</c> by default for backward compatibility only.
55+
/// </param>
56+
/// <remarks>
57+
/// This method of initialising the Sentry OpenTelemetry integration will be depricated in a future major release.
58+
/// We recommend you use <see cref="UseOTLP(SentryOptions, TracerProviderBuilder, TextMapPropagator?)"/> instead.
59+
/// </remarks>
60+
public static void UseOpenTelemetry(this SentryOptions options, bool disableSentryTracing = false)
4361
{
4462
options.Instrumenter = Instrumenter.OpenTelemetry;
63+
options.DisableSentryTracing = disableSentryTracing;
4564
options.PropagationContextFactory = _ => new OtelPropagationContext();
4665
options.AddTransactionProcessor(
4766
new OpenTelemetryTransactionProcessor()
4867
);
4968
}
69+
70+
/// <summary>
71+
/// <para>Configures Sentry to use OpenTelemetry for distributed tracing. Sentry instrumented traces will be
72+
/// disabled (so all tracing instrumentation must be done using the OpenTelemetry <see cref="Activity"/> classes).
73+
/// </para>
74+
/// <para>
75+
/// This is the recommended way to set up Sentry's OpenTelemetry integration.
76+
/// </para>
77+
/// </summary>
78+
/// <param name="options">The <see cref="SentryOptions"/> instance.</param>
79+
/// <param name="builder"><see cref="TracerProviderBuilder"/></param>
80+
/// <param name="textMapPropagator">
81+
/// <para>The default TextMapPropagator to be used by OpenTelemetry.</para>
82+
/// <para>
83+
/// If this parameter is not supplied, the <see cref="SentryPropagator"/> will be used, which propagates the
84+
/// baggage header as well as Sentry trace headers.
85+
/// </para>
86+
/// <para>
87+
/// The <see cref="SentryPropagator"/> is required for Sentry's OpenTelemetry integration to work but you
88+
/// could wrap this in a <see cref="CompositeTextMapPropagator"/> if you needed other propagators as well.
89+
/// </para>
90+
/// </param>
91+
public static void UseOTLP(this SentryOptions options, TracerProviderBuilder builder, TextMapPropagator? textMapPropagator = null)
92+
{
93+
if (string.IsNullOrWhiteSpace(options.Dsn))
94+
{
95+
throw new ArgumentException("Sentry DSN must be set before calling `SentryOptions.UseOTLP`", nameof(options.Dsn));
96+
}
97+
builder.AddSentryOTLP(options.Dsn, textMapPropagator);
98+
options.UseOTLP();
99+
}
100+
101+
/// <summary>
102+
/// <para>Configures Sentry to use OpenTelemetry for distributed tracing. Sentry instrumented traces will be
103+
/// disabled (so all tracing instrumentation must be done using the OpenTelemetry <see cref="Activity"/> classes).
104+
/// </para>
105+
/// <para>
106+
/// This is the recommended way to set up Sentry's OpenTelemetry integration.
107+
/// </para>
108+
/// </summary>
109+
/// <remarks>
110+
/// Note: if you are using this overload to configure Sentry to work with OpenTelemetry, you will also have to call
111+
/// <see cref="TracerProviderBuilderExtensions.AddSentryOTLP"/>, when building your <see cref="TracerProviderBuilder"/>
112+
/// to ensure OpenTelemetry sends trace information to Sentry.
113+
/// </remarks>
114+
/// <param name="options">The <see cref="SentryOptions"/> instance.</param>
115+
public static void UseOTLP(this SentryOptions options)
116+
{
117+
options.Instrumenter = Instrumenter.OpenTelemetry;
118+
options.DisableSentryTracing = true;
119+
options.PropagationContextFactory = _ => new OtelPropagationContext();
120+
}
50121
}

src/Sentry.OpenTelemetry/TracerProviderBuilderExtensions.cs

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,17 @@ namespace Sentry.OpenTelemetry;
1313
public static class TracerProviderBuilderExtensions
1414
{
1515
/// <summary>
16-
/// Ensures OpenTelemetry trace information is sent to Sentry.
16+
/// <para>
17+
/// Ensures OpenTelemetry trace information is sent to Sentry. OpenTelemetry spans will be converted to Sentry spans
18+
/// using a span processor. This is no longer recommended. SDK users should consider using
19+
/// <see cref="AddSentryOTLP(TracerProviderBuilder, string, TextMapPropagator?)"/> instead, which is the recommended
20+
/// way to send OpenTelemetry trace information to Sentry moving forward.
21+
/// </para>
22+
/// <para>
23+
/// Note that if you use this method to configure the trace builder, you will also need to call
24+
/// <see cref="SentryOptionsExtensions.UseOpenTelemetry(SentryOptions, bool)"/> when initialising Sentry, for Sentry
25+
/// to work properly with OpenTelemetry.
26+
/// </para>
1727
/// </summary>
1828
/// <param name="tracerProviderBuilder">The <see cref="TracerProviderBuilder"/>.</param>
1929
/// <param name="defaultTextMapPropagator">
@@ -28,15 +38,45 @@ public static class TracerProviderBuilderExtensions
2838
/// </para>
2939
/// </param>
3040
/// <returns>The supplied <see cref="TracerProviderBuilder"/> for chaining.</returns>
31-
public static TracerProviderBuilder AddSentry(this TracerProviderBuilder tracerProviderBuilder, TextMapPropagator? defaultTextMapPropagator = null)
41+
public static TracerProviderBuilder AddSentry(this TracerProviderBuilder tracerProviderBuilder,
42+
TextMapPropagator? defaultTextMapPropagator = null)
3243
{
3344
defaultTextMapPropagator ??= new SentryPropagator();
3445
Sdk.SetDefaultTextMapPropagator(defaultTextMapPropagator);
3546
return tracerProviderBuilder.AddProcessor(ImplementationFactory);
3647
}
3748

49+
internal static BaseProcessor<Activity> ImplementationFactory(IServiceProvider services)
50+
{
51+
List<IOpenTelemetryEnricher> enrichers = [];
52+
53+
// AspNetCoreEnricher
54+
var userFactory = services.GetService<ISentryUserFactory>();
55+
if (userFactory is not null)
56+
{
57+
enrichers.Add(new AspNetCoreEnricher(userFactory));
58+
}
59+
60+
var hub = services.GetService<IHub>() ?? SentrySdk.CurrentHub;
61+
if (hub.IsEnabled)
62+
{
63+
return new SentrySpanProcessor(hub, enrichers);
64+
}
65+
66+
var logger = services.GetService<IDiagnosticLogger>();
67+
logger?.LogWarning("Sentry is disabled so no OpenTelemetry spans will be sent to Sentry.");
68+
return DisabledSpanProcessor.Instance;
69+
}
70+
3871
/// <summary>
72+
/// <para>
3973
/// Ensures OpenTelemetry trace information is sent to the Sentry OTLP endpoint.
74+
/// </para>
75+
/// <para>
76+
/// Note that if you use this method to configure the trace builder, you will also need to call
77+
/// <see cref="SentryOptionsExtensions.UseOTLP(SentryOptions)"/> when initialising Sentry, for Sentry to work
78+
/// properly with OpenTelemetry.
79+
/// </para>
4080
/// </summary>
4181
/// <param name="tracerProviderBuilder">The <see cref="TracerProviderBuilder"/>.</param>
4282
/// <param name="dsnString">The DSN for your Sentry project</param>
@@ -52,11 +92,12 @@ public static TracerProviderBuilder AddSentry(this TracerProviderBuilder tracerP
5292
/// </para>
5393
/// </param>
5494
/// <returns>The supplied <see cref="TracerProviderBuilder"/> for chaining.</returns>
55-
public static TracerProviderBuilder AddSentry(this TracerProviderBuilder tracerProviderBuilder, string dsnString, TextMapPropagator? defaultTextMapPropagator = null)
95+
public static TracerProviderBuilder AddSentryOTLP(this TracerProviderBuilder tracerProviderBuilder, string dsnString,
96+
TextMapPropagator? defaultTextMapPropagator = null)
5697
{
5798
if (string.IsNullOrWhiteSpace(dsnString))
5899
{
59-
throw new ArgumentException("OTLP endpoint must be provided", nameof(dsnString));
100+
throw new ArgumentException("Sentry DSN must be provided for OLTP instrumentation", nameof(dsnString));
60101
}
61102

62103
defaultTextMapPropagator ??= new SentryPropagator();
@@ -78,28 +119,6 @@ public static TracerProviderBuilder AddSentry(this TracerProviderBuilder tracerP
78119
return client;
79120
};
80121
});
81-
return tracerProviderBuilder.AddProcessor(ImplementationFactory);
82-
}
83-
84-
internal static BaseProcessor<Activity> ImplementationFactory(IServiceProvider services)
85-
{
86-
List<IOpenTelemetryEnricher> enrichers = new();
87-
88-
// AspNetCoreEnricher
89-
var userFactory = services.GetService<ISentryUserFactory>();
90-
if (userFactory is not null)
91-
{
92-
enrichers.Add(new AspNetCoreEnricher(userFactory));
93-
}
94-
95-
var hub = services.GetService<IHub>() ?? SentrySdk.CurrentHub;
96-
if (hub.IsEnabled)
97-
{
98-
return new SentrySpanProcessor(hub, enrichers);
99-
}
100-
101-
var logger = services.GetService<IDiagnosticLogger>();
102-
logger?.LogWarning("Sentry is disabled so no OpenTelemetry spans will be sent to Sentry.");
103-
return DisabledSpanProcessor.Instance;
122+
return tracerProviderBuilder;
104123
}
105124
}

src/Sentry/Internal/Hub.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,9 @@ internal ITransactionTracer StartTransaction(
185185
return NoOpTransaction.Instance;
186186
}
187187

188-
if (_options.Instrumenter == Instrumenter.OpenTelemetry)
188+
if (_options.DisableSentryTracing)
189189
{
190-
_options.LogWarning("This transaction will not be sent to Sentry. " +
191-
"Please instrument traces using the OpenTelemetry APIs when using Sentry's OpenTelemetry integration.");
190+
_options.LogWarning("Sentry transaction dropped because OpenTelemetry is enabled");
192191
return NoOpTransaction.Instance;
193192
}
194193

src/Sentry/SentryGraphQLHttpMessageHandler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ internal SentryGraphQLHttpMessageHandler(IHub? hub, SentryOptions? options,
5050
}
5151
request.SetFused(graphQlRequestContent);
5252

53-
if (_options?.Instrumenter == Instrumenter.OpenTelemetry)
53+
if (_options?.DisableSentryTracing ?? false)
5454
{
55-
_options.LogDebug("Skipping span creation in SentryGraphQLHttpMessageHandler because Instrumenter is set to OpenTelemetry");
55+
_options.LogDebug("Skipping span creation in SentryGraphQLHttpMessageHandler because OpenTelemetry is enabled");
5656
return null;
5757
}
5858

src/Sentry/SentryHttpMessageHandler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ internal SentryHttpMessageHandler(IHub? hub, SentryOptions? options, HttpMessage
6565
/// <inheritdoc />
6666
protected internal override ISpan? ProcessRequest(HttpRequestMessage request, string method, string url)
6767
{
68-
if (_options?.Instrumenter == Instrumenter.OpenTelemetry)
68+
if (_options?.DisableSentryTracing ?? false)
6969
{
70-
_options.LogDebug("Skipping span creation in SentryHttpMessageHandler because Instrumenter is set to OpenTelemetry");
70+
_options.LogDebug("Skipping span creation in SentryHttpMessageHandler because OpenTelemetry is enabled");
7171
return null;
7272
}
7373

src/Sentry/SentryOptions.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ internal IEnumerable<ISdkIntegration> Integrations
206206
#endif
207207

208208
#if HAS_DIAGNOSTIC_INTEGRATION
209-
if (Instrumenter == Instrumenter.Sentry && (_defaultIntegrations & DefaultIntegrations.SentryDiagnosticListenerIntegration) != 0)
209+
if (!DisableSentryTracing && (_defaultIntegrations & DefaultIntegrations.SentryDiagnosticListenerIntegration) != 0)
210210
{
211211
yield return new SentryDiagnosticListenerIntegration();
212212
}
@@ -222,7 +222,7 @@ internal IEnumerable<ISdkIntegration> Integrations
222222

223223
foreach (var integration in _integrations)
224224
{
225-
if (Instrumenter == Instrumenter.OpenTelemetry && integration is ISentryTracingIntegration)
225+
if (DisableSentryTracing && integration is ISentryTracingIntegration)
226226
{
227227
continue;
228228
}
@@ -1160,6 +1160,14 @@ public StackTraceMode StackTraceMode
11601160
/// </summary>
11611161
internal Instrumenter Instrumenter { get; set; } = Instrumenter.Sentry;
11621162

1163+
/// <summary>
1164+
/// During the transition period to OTLP we give SDK users the option to keep using Sentry's tracing in conjunction
1165+
/// with OTEL instrumentation. Setting this to true will disable Sentry's tracing entirely, which is the recommended
1166+
/// setting but would be a moajor change in behaviour, so we've made it opt-in for now.
1167+
/// TODO: Remove this option in a future major release and make it true / non-optional when using OTEL (i.e. implied by the Instrumenter)
1168+
/// </summary>
1169+
internal bool DisableSentryTracing { get; set; } = false;
1170+
11631171
/// <summary>
11641172
/// The default factory creates SentryPropagationContext instances... this should be replaced when using OTEL
11651173
/// </summary>

0 commit comments

Comments
 (0)