Skip to content

Commit e34d680

Browse files
authored
Add guidance for using ActiveScope in an IHttpModule (#31386)
* Add guidance for using ActiveScope in an IHttpModule. * Fix typo and add code example
1 parent 4c28a75 commit e34d680

File tree

1 file changed

+54
-0
lines changed
  • content/en/tracing/trace_collection/custom_instrumentation/dotnet

1 file changed

+54
-0
lines changed

content/en/tracing/trace_collection/custom_instrumentation/dotnet/dd-api.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,60 @@ public class ShoppingCartController : Controller
181181
}
182182
```
183183

184+
### Usage with ASP.NET `IHttpModule`
185+
186+
To access the current request span from a custom ASP.NET `IHttpModule`, it is best to read `Tracer.Instance.ActiveScope` in the `PreRequestHandlerExecute` event (or `AcquireRequestState` if you require session state).
187+
188+
While Datadog creates the request span at the start of the ASP.NET pipeline, the execution order of `IHttpModules` is not guaranteed. If your module runs before Datadog's, `ActiveScope` may be `null` during early events like `BeginRequest`. The `PreRequestHandlerExecute` event occurs late enough in the lifecycle to ensure the Datadog module has run and the span is available.
189+
190+
Keep in mind that ActiveScope can still be `null` for requests that are not traced (due to sampling or filtering) or when instrumentation is disabled.
191+
192+
```csharp
193+
using System;
194+
using System.Web;
195+
using Datadog.Trace;
196+
197+
public class MyCustomModule : IHttpModule
198+
{
199+
public void Init(HttpApplication context)
200+
{
201+
// Prefer reading ActiveScope late in the pipeline
202+
context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
203+
204+
// If you need session state, you can also hook AcquireRequestState:
205+
// context.AcquireRequestState += OnPreRequestHandlerExecute;
206+
}
207+
208+
private void OnPreRequestHandlerExecute(object sender, EventArgs e)
209+
{
210+
// Earlier events (e.g., BeginRequest) may run before the Datadog module,
211+
// so ActiveScope can be null there. Here it should be available.
212+
var scope = Tracer.Instance.ActiveScope;
213+
if (scope == null)
214+
{
215+
return; // request not traced (sampling/filters) or instrumentation disabled
216+
}
217+
218+
// Example: add a custom tag
219+
scope.Span.SetTag("my.custom.tag", "some_value");
220+
221+
// SOAP-specific: tag the SOAP action if present
222+
if (sender is HttpApplication app)
223+
{
224+
var soapAction = app.Context?.Request?.Headers["SOAPAction"];
225+
if (!string.IsNullOrEmpty(soapAction))
226+
{
227+
// SOAPAction often includes quotes; trimming keeps it clean
228+
scope.Span.SetTag("http.soap_action", soapAction.Trim('"'));
229+
}
230+
}
231+
}
232+
233+
public void Dispose() { }
234+
}
235+
```
236+
237+
184238
### Set errors on a span
185239

186240
To mark errors that occur in your code, use the `Span.SetException(Exception)` method. The method marks the span as an error and adds [related span metadata][5] to provide insight into the exception.

0 commit comments

Comments
 (0)