Skip to content

Commit c443974

Browse files
Make HttpContext available for sampling decisions (#1682)
1 parent 7817016 commit c443974

File tree

9 files changed

+37
-3
lines changed

9 files changed

+37
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
### Features
1111

1212
- Move tunnel functionality into Sentry.AspNetCore ([#1645](https://github.com/getsentry/sentry-dotnet/pull/1645))
13+
- Make `HttpContext` available for sampling decisions ([#1682](https://github.com/getsentry/sentry-dotnet/pull/1682))
1314
- Initial support for .NET MAUI ([#1663](https://github.com/getsentry/sentry-dotnet/pull/1663)) ([#1670](https://github.com/getsentry/sentry-dotnet/pull/1670))
1415
- Initial support for `net6.0-android` apps ([#1288](https://github.com/getsentry/sentry-dotnet/pull/1288)) ([#1669](https://github.com/getsentry/sentry-dotnet/pull/1669))
1516

samples/Sentry.Samples.AspNetCore5.Mvc/Program.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>
2020
o.Dsn = "https://[email protected]/5428537";
2121
o.TracesSampler = ctx =>
2222
{
23+
// This is an example of using a custom HTTP request header to make the sampling decision
24+
var httpContext = ctx.TryGetHttpContext()!;
25+
var requestHeaders = httpContext.Request.Headers;
26+
if (requestHeaders.ContainsKey("X-Sentry-No-Tracing"))
27+
{
28+
return 0;
29+
}
30+
31+
// This is an example of changing the sample rate for a specific HTTP route
2332
if (string.Equals(ctx.TryGetHttpRoute(), "/Home/Privacy", StringComparison.Ordinal))
2433
{
2534
// Collect fewer traces for this page

src/Sentry.AspNetCore/SamplingExtensions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.ComponentModel;
2+
using Microsoft.AspNetCore.Http;
23

34
namespace Sentry.AspNetCore;
45

@@ -11,6 +12,7 @@ public static class SamplingExtensions
1112
internal const string KeyForHttpMethod = "__HttpMethod";
1213
internal const string KeyForHttpRoute = "__HttpRoute";
1314
internal const string KeyForHttpPath = "__HttpPath";
15+
internal const string KeyForHttpContext = "__HttpContext";
1416

1517
/// <summary>
1618
/// Gets the HTTP method associated with the transaction.
@@ -44,4 +46,15 @@ public static class SamplingExtensions
4446
/// </remarks>
4547
public static string? TryGetHttpPath(this TransactionSamplingContext samplingContext) =>
4648
samplingContext.CustomSamplingContext.GetValueOrDefault(KeyForHttpPath) as string;
49+
50+
/// <summary>
51+
/// Gets the <see cref="HttpContext"/> associated with the transaction.
52+
/// May return null if the value has not been set by the integration.
53+
/// </summary>
54+
/// <remarks>
55+
/// This method extracts data from <see cref="TransactionSamplingContext.CustomSamplingContext"/>
56+
/// which is populated by Sentry's ASP.NET Core integration.
57+
/// </remarks>
58+
public static HttpContext? TryGetHttpContext(this TransactionSamplingContext samplingContext) =>
59+
samplingContext.CustomSamplingContext.GetValueOrDefault(KeyForHttpContext) as HttpContext;
4760
}

src/Sentry.AspNetCore/SentryTracingMiddleware.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,12 @@ public SentryTracingMiddleware(
7272
? new TransactionContext(transactionName ?? string.Empty, OperationName, traceHeader)
7373
: new TransactionContext(transactionName ?? string.Empty, OperationName);
7474

75-
var customSamplingContext = new Dictionary<string, object?>(3, StringComparer.Ordinal)
75+
var customSamplingContext = new Dictionary<string, object?>(4, StringComparer.Ordinal)
7676
{
7777
[SamplingExtensions.KeyForHttpMethod] = context.Request.Method,
7878
[SamplingExtensions.KeyForHttpRoute] = context.TryGetRouteTemplate(),
79-
[SamplingExtensions.KeyForHttpPath] = context.Request.Path.Value
79+
[SamplingExtensions.KeyForHttpPath] = context.Request.Path.Value,
80+
[SamplingExtensions.KeyForHttpContext] = context,
8081
};
8182

8283
var transaction = hub.StartTransaction(transactionContext, customSamplingContext);

test/Sentry.AspNetCore.Tests/ApiApprovalTests.Run.Core2_1.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace Sentry.AspNetCore
2323
}
2424
public static class SamplingExtensions
2525
{
26+
public static Microsoft.AspNetCore.Http.HttpContext? TryGetHttpContext(this Sentry.TransactionSamplingContext samplingContext) { }
2627
public static string? TryGetHttpMethod(this Sentry.TransactionSamplingContext samplingContext) { }
2728
public static string? TryGetHttpPath(this Sentry.TransactionSamplingContext samplingContext) { }
2829
public static string? TryGetHttpRoute(this Sentry.TransactionSamplingContext samplingContext) { }

test/Sentry.AspNetCore.Tests/ApiApprovalTests.Run.Core3_1.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace Sentry.AspNetCore
2323
}
2424
public static class SamplingExtensions
2525
{
26+
public static Microsoft.AspNetCore.Http.HttpContext? TryGetHttpContext(this Sentry.TransactionSamplingContext samplingContext) { }
2627
public static string? TryGetHttpMethod(this Sentry.TransactionSamplingContext samplingContext) { }
2728
public static string? TryGetHttpPath(this Sentry.TransactionSamplingContext samplingContext) { }
2829
public static string? TryGetHttpRoute(this Sentry.TransactionSamplingContext samplingContext) { }

test/Sentry.AspNetCore.Tests/ApiApprovalTests.Run.DotNet5_0.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace Sentry.AspNetCore
2323
}
2424
public static class SamplingExtensions
2525
{
26+
public static Microsoft.AspNetCore.Http.HttpContext? TryGetHttpContext(this Sentry.TransactionSamplingContext samplingContext) { }
2627
public static string? TryGetHttpMethod(this Sentry.TransactionSamplingContext samplingContext) { }
2728
public static string? TryGetHttpPath(this Sentry.TransactionSamplingContext samplingContext) { }
2829
public static string? TryGetHttpRoute(this Sentry.TransactionSamplingContext samplingContext) { }

test/Sentry.AspNetCore.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace Sentry.AspNetCore
2323
}
2424
public static class SamplingExtensions
2525
{
26+
public static Microsoft.AspNetCore.Http.HttpContext? TryGetHttpContext(this Sentry.TransactionSamplingContext samplingContext) { }
2627
public static string? TryGetHttpMethod(this Sentry.TransactionSamplingContext samplingContext) { }
2728
public static string? TryGetHttpPath(this Sentry.TransactionSamplingContext samplingContext) { }
2829
public static string? TryGetHttpRoute(this Sentry.TransactionSamplingContext samplingContext) { }

test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ public async Task Transaction_sampling_context_contains_HTTP_context_data()
198198
{
199199
// Arrange
200200
TransactionSamplingContext samplingContext = null;
201+
HttpContext httpContext = null;
201202

202203
var sentryClient = Substitute.For<ISentryClient>();
203204

@@ -226,7 +227,11 @@ public async Task Transaction_sampling_context_contains_HTTP_context_data()
226227
app.UseRouting();
227228
app.UseSentryTracing();
228229

229-
app.UseEndpoints(routes => routes.Map("/person/{id}", _ => Task.CompletedTask));
230+
app.UseEndpoints(routes => routes.Map("/person/{id}", context =>
231+
{
232+
httpContext = context;
233+
return Task.CompletedTask;
234+
}));
230235
}));
231236

232237
var client = server.CreateClient();
@@ -239,6 +244,7 @@ public async Task Transaction_sampling_context_contains_HTTP_context_data()
239244
samplingContext.TryGetHttpMethod().Should().Be("GET");
240245
samplingContext.TryGetHttpRoute().Should().Be("/person/{id}");
241246
samplingContext.TryGetHttpPath().Should().Be("/person/13");
247+
samplingContext.TryGetHttpContext().Should().BeSameAs(httpContext);
242248
}
243249

244250
[Fact]

0 commit comments

Comments
 (0)