The OneAgent for iOS provides comprehensive web request monitoring capabilities:
URLSession.The OneAgent for iOS automatically instruments web requests made using Apple's URLSession API and stores them as events in Grail.
Each event consists of well-defined key-value fields as specified in the Semantic Dictionary for user events.
This data can be queried directly in Grail using DQL.
Additionally, the timing values from the mobile side are measured.
For each web request, the SDK captures:
The data captured will be structured and reported according to the fields specified in request.*.
Automatic instrumentation works with:
URLSession.dataTask(with:completionHandler:)URLSession.downloadTask(with:completionHandler:)URLSession.uploadTask(with:from:completionHandler:)URLSession.data(from:), etc.)NSURLRequest, NSURLConnection, NSURLProtocolWKWebView requestsNSData convenience methodsAutomatic instrumentation has the following limitations:
We don't recommend using several monitoring tools simultaneously with crash reporting or web request instrumentation functionality enabled. This might cause compatibility issues, reporting of wrong or invalid information, and loss of monitoring and crash data. Nevertheless, if you decide to do so, verify via manual testing that these tools are compatible.
To use both Dynatrace and Firebase, do one of the following.
Follow only one of the approaches above; don't perform both actions.
To use both Dynatrace and mPaaS, do one of the following.
Follow only one of the approaches above; don't perform both actions.
To disable automatic web request instrumentation, set the DTXInstrumentWebRequestTiming configuration key to false in your app's Info.plist file:
<key>DTXInstrumentWebRequestTiming</key><false/>
You may want to disable automatic instrumentation when:
| Request type | Instrumentation type | DTXInstrumentWebRequestTiming |
|---|---|---|
| HTTP(S) | Option A: Auto | true |
| Option B: Manual | false |
You cannot combine automatic and manual instrumentation for the same HTTP(S) request.
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 enabled, OneAgent 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.OneAgent 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 enabled, OneAgent 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 contexttraceparent header
traceparent, OneAgent keeps it and updates tracestate by adding Dynatrace vendor specific information, without overwriting existing vendor entriesIf the combined tracestate grows too large, OneAgent may trim entries to stay within W3C limits. Dynatrace data is preserved whenever possible.
If you use a custom networking stack, you can propagate W3C Trace Context headers yourself and still correlate the request with Dynatrace distributed traces.
Use Dynatrace.generateTraceContext(traceparent:tracestate:) (Swift) / generateTraceContext:tracestate: (Objective-C) to create or enrich trace context according to the official W3C Trace Context specification:
traceparent is nil, OneAgent generates a new traceparent and a corresponding tracestate (including Dynatrace vendor specific information)traceparent is present and valid, OneAgent keeps it and enriches tracestate with Dynatrace vendor specific information (without overwriting existing vendor entries)traceparent or capture/tagging is not allowed), the API returns nil and you must not change the request headersYou can then reuse the resulting traceparent to correlate a manually reported web request event.
import Dynatracevar request = URLRequest(url: URL(string: "https://api.example.com/data")!)// Read existing headers (if any)let existingTraceparent = request.value(forHTTPHeaderField: "traceparent")let existingTracestate = request.value(forHTTPHeaderField: "tracestate")// Generate/enrich trace contextvar traceparentForReporting: String?if let ctx = Dynatrace.generateTraceContext(existingTraceparent, tracestate: existingTracestate) {request.setValue(ctx.traceparent, forHTTPHeaderField: "traceparent")request.setValue(ctx.tracestate, forHTTPHeaderField: "tracestate")traceparentForReporting = ctx.traceparent} else {// No changes should be applied when context can't be created (for example, invalid traceparent)}// ...execute your HTTP request here...let requestData = DTXHttpRequestEventData(url: request.url!.absoluteString, method: request.httpMethod ?? "GET").withDuration(duration).withStatusCode(statusCode)if let traceparent = traceparentForReporting {requestData.withTraceparentHeader(traceparent)}Dynatrace.sendHttpRequestEvent(requestData)
For networking libraries not covered by automatic instrumentation, you can manually report web requests using DTXHttpRequestEventData.
import Dynatrace// Create the request data with the URL and HTTP methodlet requestData = DTXHttpRequestEventData(url: "https://api.example.com/data", method: "GET").withDuration(250) // Duration in milliseconds.withStatusCode(200) // HTTP status code.withBytesSent(128) // Bytes sent.withBytesReceived(4096) // Bytes received// Send the web request eventDynatrace.sendHttpRequestEvent(requestData)
When a request fails, include the error information:
let requestData = DTXHttpRequestEventData(url: "https://api.example.com/data", method: "POST").withDuration(1500).withError(error as NSError)Dynatrace.sendHttpRequestEvent(requestData)
To correlate manually reported requests with distributed traces, include the traceparent header:
// Report the event with the traceparentlet requestData = DTXHttpRequestEventData(url: url, method: "GET").withDuration(duration).withStatusCode(statusCode).withTraceparentHeader(traceparent)Dynatrace.sendHttpRequestEvent(requestData)
Add custom event properties to capture additional context:
let requestData = DTXHttpRequestEventData(url: url, method: "POST").withDuration(300).withStatusCode(201).addEventProperty("event_properties.api_version", value: "v2").addEventProperty("event_properties.endpoint", value: "users")Dynatrace.sendHttpRequestEvent(requestData)
Custom property keys must be prefixed with event_properties.—properties without this prefix will be dropped.
Event modifiers allow you to enrich web request events with additional data before they are sent. This is useful for adding context from the request/response that isn't captured automatically.
let subscriber = Dynatrace.addHttpEventModifier { event, context in// Access request details from the contextif let request = context?.request {// Add custom headers or request info as propertiesif let customHeader = request.value(forHTTPHeaderField: "X-Custom-Header") {event.fields["event_properties.custom_header"] = customHeader}}// Access response detailsif let httpResponse = context?.response as? HTTPURLResponse {if let serverTiming = httpResponse.value(forHTTPHeaderField: "Server-Timing") {event.fields["event_properties.server_timing"] = serverTiming}}// Return the modified event (or nil to drop it)return event}
The DTXHttpRequestEventContext provides access to:
| Property | Type | Description |
|---|---|---|
request | URLRequest | The original request |
response | URLResponse? | The server response (if available) |
responseBody | Data? | The response body data (if captured) |
error | NSError? | The error (if the request failed) |
When you no longer need the modifier, remove it using the subscriber reference:
Dynatrace.removeEventModifier(subscriber)
Return nil from the modifier to prevent the event from being sent:
let subscriber = Dynatrace.addHttpEventModifier { event, context in// Don't report requests to analytics endpointsif let url = context?.request.url?.absoluteString,url.contains("analytics.example.com") {return nil}return event}