Modifying captured HTTP request info
Modifying captured HTTP request info
Embrace's SDK automatically instruments the HTTP requests your app makes and uploads basic information about them into your sessions. Because that instrumentation is automatic, you don't get a chance to review each URL before it is reported - and URLs can contain personally identifiable information (PII), such as a user ID or email address in a path segment.
HttpRequestInfoModifier lets you rewrite that captured information before it becomes telemetry. The most common use is redacting PII from URLs, but you can alter the reported HTTP method as well.
A modifier only changes what Embrace reports. It never changes the HTTP request your app actually executes, and it is not a network interceptor - you cannot use it to add headers, retry, or block a request.
Registering a modifier
Register a modifier on the Embrace instance. HttpRequestInfoModifier is a functional interface, so it can be implemented with a lambda:
Embrace.addHttpRequestInfoModifier { info ->
info.url = info.url.replace(USER_ID_REGEX, "/users/{id}")
}
Register your modifiers as early as possible - ideally immediately after starting the SDK in your Application.onCreate(). Only requests recorded after addHttpRequestInfoModifier returns are passed to the modifier, so any request that happens before registration is reported unmodified.
You can register more than one modifier. Each is invoked in turn on the same object, so a later modifier sees the changes made by an earlier one.
To stop using a modifier, pass the same instance to removeHttpRequestInfoModifier:
Embrace.removeHttpRequestInfoModifier(modifier)
Note that this requires you to hold a reference to the modifier, which a lambda expression does not give you. Registering the same instance twice has no additional effect.
What a modifier can see and change
Your callback is handed a MutableHttpRequestInfo, which extends HttpRequestInfo:
| Property | Description |
|---|---|
url | The request's URL. Must start with http:// or https://. |
httpMethod | The request's method (GET, PUT, POST, DELETE, PATCH, etc.). |
Both properties are mutable. Set them to the values you want Embrace to report; leave them alone to report what was captured.
The object passed to your modifier is only valid for the duration of the call. Don't retain it, and don't use it from another thread.
Redacting PII from URLs
Embrace already discards the query string and fragment of a captured URL, so https://example.com/profile?email=user@example.com is reported as https://example.com/profile. PII in a path segment is preserved, however, and that is what a modifier is for:
private val PII_PATH_SEGMENTS = Regex("/(users|accounts)/[^/]+")
Embrace.addHttpRequestInfoModifier { info ->
info.url = PII_PATH_SEGMENTS.replace(info.url) { match ->
"/${match.groupValues[1]}/{id}"
}
}
Prefer replacing sensitive segments with a stable placeholder rather than removing them. The reported URL is used to derive the span name and to group requests in the dashboard, so /users/{id}/settings keeps requests to the same endpoint grouped together, while deleting the segment entirely merges unrelated endpoints.
Do the same in reverse for values you want to keep: if your paths are opaque identifiers that are safe to report, you don't need a modifier at all.
Guidance
Keep your modifier fast and side effect free. It is invoked on the thread that recorded the request - once when a request starts and again when it ends, since the final URL may differ after redirects - so any work it does is work your app's network path pays for. Compile regexes once and hold them in a field rather than constructing them inside the callback.
If your modifier throws an exception, the SDK catches it and reports the request with the values as they stood at that point. A partially applied modifier can leak the data you meant to redact, so write your modifier defensively rather than relying on that behaviour.
A modifier applies to every request Embrace records, including requests recorded manually with recordNetworkRequest, and including requests made by third-party libraries in your app that you don't control.
Network body capture
Modifiers apply to the network request information reported in your sessions. They do not alter the payloads uploaded by network body capture, which are captured separately from the underlying request. If you use network body capture on endpoints that carry sensitive data, encrypt those payloads with a public key as described in that documentation.