Docs » Instrument mobile and web applications for Splunk RUM » Instrument browser-based web applications for Splunk RUM » Manually instrument browser-based web applications

Manually instrument browser-based web applications ๐Ÿ”—

You can manually instrument front-end applications for Splunk RUM using the Browser RUM agent to collect additional telemetry, sanitize Personal Identifiable Information (PII), identify users, and more. The following API examples show several manual instrumentations for Splunk RUM.

To migrate manual instrumentation created for another vendor, see Migrate existing manual instrumentation. For the API reference of Browser RUM, see API reference for Browser RUM instrumentation.

Instrument your application using the OpenTelemetry API ๐Ÿ”—

To instrument your front-end application manually, use the OpenTelemetry API. The Browser RUM agent automatically registers its TraceProvider using @opentelemetry/api, so that your own instrumentations can access it.

Check the version of the OpenTelemetry API ๐Ÿ”—

To manually instrument your application, the version of @opentelemetry/api you use must match the same major version of @opentelemetry/api used by the Browser RUM agent.

To verify this, run window[Symbol.for('opentelemetry.js.api.1')].version in the browserโ€™s console from any page that youโ€™ve instrumented. The command returns the full version of the OpenTelemetry API.

Create a span ๐Ÿ”—

The following example shows how to create a span with an attribute:

import {trace} from '@opentelemetry/api'

const span = trace.getTracer('searchbox').startSpan('search');
span.setAttribute('searchLength', searchString.length);
// Time passes
span.end();

Set the user ID on all spans ๐Ÿ”—

The following example shows how to set the user ID globally:

SplunkRum.setGlobalAttributes({
   'enduser.id': 'Test User'
});

Create a custom event ๐Ÿ”—

The following example shows how to create a custom event:

import {trace} from '@opentelemetry/api'

const tracer = trace.getTracer('appModuleLoader');
const span = tracer.startSpan('test.module.load', {
attributes: {
   'workflow.name': 'test.module.load'
}
});
// time passes
span.end();

Note

To avoid load problems due to content blockers when using the CDN version of the Browser RUM agent, add if (window.SplunkRum) checks around SplunkRum API calls.

Sanitize Personally Identifiable Information (PII) ๐Ÿ”—

The metadata collected by the Browser RUM agent might include Personally Identifiable Information (PII) if your front-end application injects such data in its code. For example, UI components might include PII in their IDs.

To redact PII in the data collected for Splunk RUM, use the exporter.onAttributesSerializing setting when initializing the Browser RUM instrumentation, as in the following example:

SplunkRum.init({
// ...
exporter: {
// You can use the entire span as an optional second argument of the sanitizer if needed
   onAttributesSerializing: (attributes) => ({
      ...attributes,
      'http.url': /secret\=/.test(attributes['http.url']) ? '[redacted]' : attributes['http.url'],
   }),
},
});

Note

The Browser RUM automatic instrumentations do not collect or report any data from request payloads or POST bodies other than their size.

Add user metadata using global attributes ๐Ÿ”—

By default, the Browser RUM agent doesnโ€™t automatically link traces to users of your site. However, you might need to collect user metadata to filter or debug traces.

You can identify users by adding global attributes from the OpenTelemetry specification, such as enduser.id and enduser.role, to your spans.

The following examples show how to add identification metadata as global attributes when initializing the agent or after youโ€™ve initialized it, depending on whether user data is accessible at initialization:

Add identification metadata during initialization ๐Ÿ”—

<script src="https://cdn.signalfx.com/o11y-gdi-rum/latest/splunk-otel-web.js" crossorigin="anonymous"></script>
<script>
SplunkRum.init({
   beaconUrl: 'https://rum-ingest.<realm>.signalfx.com/v1/rum',
   rumAuth: '<RUM access token>',
   app: '<application-name>',
   globalAttributes: {
      // The following data is already available
      'enduser.id': 42,
      'enduser.role': 'admin',
   },
});
</script>

Add identification metadata after initialization ๐Ÿ”—

import SplunkRum from '@splunk/otel-web';

const user = await (await fetch('/api/user')).json();
// Spans generated prior to this call don't have user metadata
SplunkRum.setGlobalAttributes({
   'enduser.id': user ? user.id : undefined,
   'enduser.role': user ? user.role : undefined,
});

Add server trace context from Splunk APM ๐Ÿ”—

The Browser RUM agent collects server trace context using back-end data provided by APM instrumentation through the Server-Timing header. In some cases, you might want to generate the header manually.

To create the Server-Timing header manually, provide a Server-Timing header with the name traceparent, where the desc field holds the version, the trace ID, the parent ID, and the trace flag.

Consider the following HTTP header:

Server-Timing: traceparent;desc="00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"

The example resolves to a context containing the following data:

version=00 trace-id=4bf92f3577b34da6a3ce929d0e0e4736
parent-id=00f067aa0ba902b7 trace-flags=01

When generating a value for the traceparent header, make sure that it matches the following regular expression:

00-([0-9a-f]{32})-([0-9a-f]{16})-01

Server timing headers with values that donโ€™t match the pattern are automatically discarded. For more information, see the Server-Timing and traceparent documentation on the W3C website.

Note

If youโ€™re using cross-origin resource sharing (CORS) headers, such as Access-Control-*, you might need to grant permission to read the Server-Timing header. For example: Access-Control-Expose-Headers: Server-Timing.

Create workflow spans ๐Ÿ”—

With workflow spans you can add metadata to your spans to track the steps happening in your application workflows, such as filling out a form or checking a shopping cart.

Workflow spans have the following attributes:

Name

Type

Description

id

String

Unique ID for the workflow instance.

name

String

Semantic name for the current workflow.

The following snippet shows how to create a workflow span:

import {trace} from '@opentelemetry/api'

const tracer = trace.getTracer('appModuleLoader');
const span = tracer.startSpan('test.module.load', {
attributes: {
   'workflow.id': 1,
   'workflow.name': 'test.module.load'
}
});

// Time passes
span.end();

To activate error collection for workflow spans, add the error and error.message attributes:

import {trace} from '@opentelemetry/api'

const tracer = trace.getTracer('appModuleLoader');
const span = tracer.startSpan('test.module.load', {
attributes: {
   'workflow.id': 1,
   'workflow.name': 'test.module.load',
   'error': true,
   'error.message': 'Custom workflow error message'
}
});

span.end();