Backend Traces and Logs in RUM
Link each browser or mobile request to the backend trace it started, and see the logs a session wrote, from the Sessions Explorer drawers.
A slow click or a failed request in RUM is often only half the story: the time went into the backend. When the RUM SDK adds trace context to your app's API calls, KubeSense links each request to the backend trace it started, so you can go from what the user saw to the server work behind it without searching.
Where to find it
Open RUM → Sessions Explorer and click a row to open its drawer.
| Drawer | Tab | What it shows |
|---|---|---|
| Resource (one request) | Backend Trace | The backend spans of the trace this request started |
| View | Traces | The backend spans of every trace this view's requests started |
| Action | Traces | The backend spans of every trace this action's requests started |
| View | Logs | The browser logs written during this view |
| Action | Logs | The logs of the action's view, written while the action ran |
| Error | Logs | The logs of the error's view, in the five minutes either side of it |
| Session | Logs | Every browser log written during the session |
Click a span in any traces tab to open the full trace.
The traces tabs need the Traces feature and access to the Traces module; the Logs tabs need the Logs feature and access to the Logs module. Logs tabs appear only on browser applications.
A view or an action whose requests started more than 500 traces shows the first 500, and says so above the table.
1. Add trace context to your API calls
The SDK adds trace headers only to the URLs you list, so third-party APIs never receive them. List your own API:
import { kubesenseSdk } from '@kubesense/kubesense-browser-rum';
kubesenseSdk.init({
// ...your existing options
service: 'web-shop', // required with allowedTracingUrls
allowedTracingUrls: [
'https://api.example.com', // matched as a URL prefix
/^https:\/\/.*\.example\.com\/api/, // or a regular expression
{
match: 'https://payments.example.com',
propagatorTypes: ['tracecontext'], // choose the headers per URL
},
],
});You can also set the traced URLs without a deploy: in Settings → RUM, open the application, go to Configure and fill in Tracing URLs (each one a URL prefix, with optional header formats). This works when the app initialises the SDK with enableRemoteSdkConfiguration: true, and a saved change takes effect from the next page load. Saved Tracing URLs replace the app's own allowedTracingUrls rather than adding to them, and they need a service too: set service in the init, or fill in Service on the same tab. Without one the SDK does not start.
Header formats
propagatorTypes | Headers sent |
|---|---|
tracecontext | traceparent, tracestate (W3C) |
kubesense | x-kubesense-trace-id, x-kubesense-parent-id, x-kubesense-origin, x-kubesense-sampling-priority |
b3 | b3 |
b3multi | X-B3-TraceId, X-B3-SpanId, X-B3-Sampled |
Without propagatorTypes the SDK sends tracecontext and kubesense. It also sends a baggage header carrying the session id (and the user id, when set) unless propagateTraceBaggage is false. traceSampleRate (default 100) decides what share of sessions is traced; see Distributed Tracing.
Mobile apps list their API hosts too: setFirstPartyHosts(...) on Android (where the OkHttp client also needs KubesenseInterceptor), firstPartyHostsTracing on iOS and firstPartyHosts on Flutter. See the Android, iOS and Flutter guides.
2. Let your API accept the headers
When the app and its API are on different origins, the browser asks the API first (a CORS preflight) whether it accepts the trace headers. If the API's Access-Control-Allow-Headers does not list them, the browser blocks the request itself, not just the tracing. Add the headers for the formats you send:
traceparent, tracestate, baggage,
x-kubesense-trace-id, x-kubesense-parent-id, x-kubesense-origin, x-kubesense-sampling-priorityAdd b3, or X-B3-TraceId, X-B3-SpanId and X-B3-Sampled, if you send the b3 formats. Allow every header the SDK sends: one missing name fails the whole preflight.
An app and API on the same origin need no change.
3. Send backend traces that continue the trace
The backend must do two things:
- Continue the incoming trace. Its tracer has to read the header the SDK sent, and start its spans inside that trace rather than a new one. OpenTelemetry SDKs read W3C
traceparentby default. Datadog tracers read it whentracecontextis among their propagation styles (DD_TRACE_PROPAGATION_STYLE). - Send its traces to KubeSense. See Instrumentation for your language.
4. Send browser logs (for the Logs tabs)
The Logs tabs show logs from a browser logs SDK. A log carries the session and the view it was written in, which is how it is matched to a drawer, only when the logs SDK comes from the same vendor as the RUM SDK: @kubesense/kubesense-browser-logs beside the KubeSense RUM SDK, or @datadog/browser-logs beside Datadog's. Mixed, the logs arrive without a session and never show in these tabs. For the collector setup the logs need, see Datadog Browser Logs.
Check that it works
- Open your app with the browser's developer tools on the Network tab.
- Pick a request to your API and look at its request headers: it should carry
traceparent(or the headers you chose). - In KubeSense, open that request in Sessions Explorer → Resources and select Backend Trace.
Troubleshooting
| The tab says | What it means |
|---|---|
| This request carried no trace context | The request's URL is not in allowedTracingUrls, or its session was not sampled by traceSampleRate. |
| None of this view's (or action's) requests carried trace context | The same, for every request of the view or the action. |
| No backend spans found … | The requests did carry trace ids, but no backend span with them arrived within three hours either side. The backend may not be sending traces to KubeSense, or it started a new trace instead of continuing this one (step 3). |
| Couldn't load … | The query failed. Reopen the drawer. |
| Couldn't tell which view this is / Couldn't work out which logs belong here | The drawer's data has no view, action or session id to look up. |
If your app's API calls start failing with CORS errors after you add allowedTracingUrls, the API does not yet allow the trace headers (step 2).
Requests the SDK sent before tracing was turned on carry no trace id, so they have no backend trace to show.