The Dynatrace MAUI SDK provides comprehensive web request monitoring capabilities.
HttpClient using the Dynatrace HttpMessageHandler.You can optionally use the following method to turn on the auto-instrumentation of web requests. The HttpMessageHandler used by HttpClient takes care of the web request instrumentation.
using Dynatrace.MAUI;var httpHandler = Agent.Instance.GetHttpMessageHandler(null, null);var httpClient = new HttpClient(httpHandler);
Moreover, you can also have your own HTTP handler:
using Dynatrace.MAUI;var defaultHttpHandler = new HttpClientHandler();var httpHandler = Agent.Instance.GetHttpMessageHandler(defaultHttpHandler, null);var httpClient = new HttpClient(httpHandler);
When you use the Dynatrace HttpMessageHandler, the following data is captured for every request.
The HttpClientOptions parameter in GetHttpMessageHandler is used for accurate request size calculation. By default, HttpClient might append headers that aren't visible to the handler at request time. If you modify or add custom headers that affect request size, provide them in HttpClientOptions so the size calculation remains accurate:
using Dynatrace.MAUI;using Dynatrace.MAUI.Abstraction.Core;using System.Net.Http;var customHeaders = new Dictionary<string, string[]>{["User-Agent"] = new[] { "MyApp/1.0" },["Accept-Encoding"] = new[] { "gzip", "deflate" }};var options = new HttpClientOptions(customHeaders);var handler = Agent.Instance.GetHttpMessageHandler(null, options);var httpClient = new HttpClient(handler);
The requestHeaders parameter doesn't add headers to your requests. It only informs the handler about headers that are automatically added by HttpClient for accurate size calculation.
The SDK supports W3C Trace Context (external) for distributed tracing, allowing you to correlate mobile requests with backend services instrumented by Dynatrace.
For background and examples, see W3C Trace Context.
When automatic web request instrumentation is turned on, the Dynatrace HttpMessageHandler may propagate W3C trace context on outgoing requests by setting the following headers.
traceparent: Identifies the request as part of a distributed trace.tracestate: Carries vendor-specific context. Dynatrace adds Dynatrace-specific information here.The Dynatrace HttpMessageHandler sets these headers automatically as part of its web request instrumentation.
W3C Trace Context headers (traceparent / tracestate) are used for distributed tracing correlation across services.
In most cases, you don't need to set W3C Trace Context headers yourself. When automatic web request instrumentation is turned on, the Dynatrace HttpMessageHandler inspects each outgoing request and decides whether to generate, preserve, or leave trace context headers unchanged based on what it finds.
traceparent and adds a corresponding tracestate entry with Dynatrace-specific context. It activates correlation between the mobile request and the service-side trace. See Mobile firewall constraints.traceparent header: If the request already contains a valid traceparent, the handler keeps it and updates tracestate by adding Dynatrace vendor-specific information, without overwriting existing vendor entries.If the combined tracestate grows too large, entries may be trimmed to stay within W3C limits. Dynatrace data is preserved whenever possible.
If you use a custom networking stack or don't use the Dynatrace HttpMessageHandler, you can propagate W3C Trace Context headers yourself and still correlate the request with Dynatrace distributed traces.
Use Agent.Instance.GenerateTraceContext(traceparent, tracestate) to create or enrich trace context according to the official W3C Trace Context specification.
traceparent is null, the SDK generates a new traceparent and a corresponding tracestate (including Dynatrace-specific information).traceparent is present and valid, the SDK keeps it and enriches tracestate with Dynatrace vendor-specific information (without overwriting existing vendor entries).traceparent or capture/tagging isn't allowed), the API returns null and you shouldn't change the request headers.You can then reuse the resulting traceparent to correlate a manually reported web request event.
using Dynatrace.MAUI;using System.Net.Http;var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com/data");// Read existing headers (if any)string? existingTraceparent = request.Headers.Contains("traceparent")? request.Headers.GetValues("traceparent").FirstOrDefault(): null;string? existingTracestate = request.Headers.Contains("tracestate")? request.Headers.GetValues("tracestate").FirstOrDefault(): null;// Generate/enrich trace contextvar traceContext = Agent.Instance.GenerateTraceContext(existingTraceparent, existingTracestate);string? traceparentForReporting = traceContext?.GetTraceparent();if (traceContext != null){traceContext.ApplyTo(request.Headers);}// ...execute your HTTP request here...var requestData = new HttpRequestEventData(request.RequestUri.ToString(), request.Method.Method).WithDuration(duration).WithStatusCode(statusCode);if (traceparentForReporting != null){requestData.WithTraceparentHeader(traceparentForReporting);}Agent.Instance.SendHttpRequestEvent(requestData);
Use the following code snippet to instrument web requests:
using Dynatrace.MAUI;// Create an actionIRootAction webAction = Agent.Instance.EnterAction(actionName: "WebRequest Action");// Generate a new unique tag associated with the web request actionstring requestTag = webAction.GetRequestTag(url);string requestTagHeader = webAction.GetRequestTagHeader();// Place the Dynatrace HTTP header on your web requesthttpClient.DefaultRequestHeaders.Add(requestTagHeader, requestTag);// Generate a WebRequestTiming object based on the unique tagIWebRequestTiming timing = Agent.Instance.GetWebRequestTiming(requestTag, url);// Start web request timing before the HTTP request is senttiming.StartWebRequestTiming();try{var response = await httpClient.GetAsync(url);// Stop web request timing when the HTTP response is received and the response body is obtainedtiming.StopWebRequestTiming(url, (int)response.StatusCode, response.ReasonPhrase);}catch (HttpRequestException exception){// Stop web request timing when a connection exception occurstiming.StopWebRequestTiming(url, -1, exception.ToString());}finally{// Leave an actionwebAction.LeaveAction();}
For HTTP libraries or custom implementations not supported by automatic instrumentation, you can manually report web requests using SendHttpRequestEvent.
Use SendHttpRequestEvent to report a completed HTTP request. The URL and request method are required; all other fields are optional.
using Dynatrace.MAUI;using System.Net.Http;using System.Diagnostics;var url = "https://api.example.com/data";var httpClient = new HttpClient();var stopwatch = Stopwatch.StartNew();var response = await httpClient.GetAsync(url);stopwatch.Stop();var eventData = new HttpRequestEventData(url, "GET").WithStatusCode((int)response.StatusCode).WithDuration(stopwatch.ElapsedMilliseconds).WithBytesReceived((int)response.Content.Headers.ContentLength);Agent.Instance.SendHttpRequestEvent(eventData);
To correlate manually reported requests with distributed traces, include the traceparent header in the event. For details on generating trace context, see W3C Trace Context (distributed tracing).
using Dynatrace.MAUI;var requestData = new HttpRequestEventData(url, "GET").WithDuration(duration).WithStatusCode(statusCode).WithTraceparentHeader(traceContext?.GetTraceparent());Agent.Instance.SendHttpRequestEvent(requestData);
You can report failed HTTP requests by attaching the exception:
using Dynatrace.MAUI;using System.Net.Http;try{var response = await httpClient.GetAsync("https://api.example.com/data");}catch (Exception ex){var eventData = new HttpRequestEventData("https://api.example.com/data", "GET").WithException(ex);Agent.Instance.SendHttpRequestEvent(eventData);}
You can enrich HTTP request events with custom properties for additional context:
using Dynatrace.MAUI;using System.Net.Http;using System.Diagnostics;var stopwatch = Stopwatch.StartNew();var response = await httpClient.PostAsync(url, content);stopwatch.Stop();var eventData = new HttpRequestEventData(url, "POST").WithStatusCode((int)response.StatusCode).WithDuration(stopwatch.ElapsedMilliseconds).WithBytesSent(1024).WithBytesReceived(2048).WithReasonPhrase(response.ReasonPhrase).AddEventProperty("event_properties.endpoint", "/data").AddEventProperty("event_properties.api_version", "v2");Agent.Instance.SendHttpRequestEvent(eventData);
| Method | Type | Description |
|---|---|---|
| Constructor | Creates a new HTTP request event. URL and method are required. |
|
| Duration of the request in milliseconds. Negative or non-finite values default to 0. |
|
| HTTP response status code. Codes 400–599 mark the request as failed. Negative values are dropped. |
|
| HTTP response reason phrase (for example, "OK", "Not Found"). |
|
| Number of bytes sent in the request body. Negative values are dropped. |
|
| Number of bytes received in the response body. Negative values are dropped. |
|
| W3C traceparent header value for distributed tracing. Use |
|
| Exception that occurred during the request. Adds type, message, and stack trace to the event. |
|
| Adds a custom event property. Keys need to be prefixed with |
HTTP event modifiers allow you to customize HTTP event data before it's sent to Dynatrace. Common use cases include adding custom properties based on request or response details, redacting sensitive information from URLs, filtering out specific requests, and enriching events with business context.
HTTP event modifiers only work with events automatically captured by the Dynatrace HttpMessageHandler and don't apply to manually reported HTTP events.
HTTP events can also be modified via the general event modifier API, but the HTTP event modifier provides additional parameters to access the HTTP request and response details. When both modifier types are registered, general event modifiers run first, followed by HTTP event modifiers.
Implement the IHttpEventModifier interface and register it with AddHttpEventModifier:
using Dynatrace.MAUI;using System.Net.Http;class MyHttpEventModifier : IHttpEventModifier{public Dictionary<string, object>? ModifyHttpEvent(Dictionary<string, object> fields,HttpRequestMessage request,HttpResponseMessage? response,Exception? exception){// Add custom metadata based on the requestfields["event_properties.endpoint"] = request.RequestUri?.AbsolutePath ?? "unknown";// Redact sensitive URL partsif (fields.ContainsKey("url.full")){var url = fields["url.full"]?.ToString() ?? "";fields["url.full"] = url.Replace("/users/12345/", "/users/{id}/");}// Filter out requests to internal health check endpointsif (request.RequestUri?.AbsolutePath == "/health"){return null; // Drop the event}return fields;}}// Register the modifierIHttpEventModifier modifier = new MyHttpEventModifier();Agent.Instance.AddHttpEventModifier(modifier);
Remove modifiers when they're no longer needed:
using Dynatrace.MAUI;Agent.Instance.RemoveHttpEventModifier(modifier);
| Parameter | Type | Description |
|---|---|---|
|
| The HTTP event data containing fields like |
|
| The HTTP request object with URL, method, and headers. |
|
| The HTTP response. Null if the request failed before a response was received. |
|
| Any exception that occurred. Null for successful requests. |
Most fields entries are read-only. The fields open for modification are url.full, exception.stack_trace, and any key prefixed with event_properties..
Modifiers run in the order they were added. If any modifier returns null, the event is discarded and subsequent modifiers don't run. Exceptions thrown inside a modifier are logged but don't block other modifiers.