Skip to main content

Watching a web frontend

A page that stops loading, slows from 2 seconds to 9, or can't reach its API looks fine from the servers. Send the browser's own telemetry and InfraSage treats the frontend as a component with its own vital signs.

1. Allow your site's origin​

Browsers post OTLP from your page's origin. List the origins that may send it on the ingestion gateway:

RUM_ALLOWED_ORIGINS=https://shop.example.com,https://www.example.com

The gateway then answers CORS preflights on /v1/traces, /v1/metrics and /v1/logs for those origins only.

2. Use a browser key​

Anyone who loads the page can read the key it embeds. Create a separate API key with ingestion scope for the browser: it can send telemetry and nothing else. Revoke it if it's abused.

3. Instrument the page​

With the OpenTelemetry JS web SDK:

import { WebTracerProvider, BatchSpanProcessor } from '@opentelemetry/sdk-trace-web';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
import { resourceFromAttributes } from '@opentelemetry/resources';

const provider = new WebTracerProvider({
resource: resourceFromAttributes({
'service.name': 'shop-web',
'browser.name': navigator.userAgentData?.brands?.[0]?.brand ?? 'unknown',
'device.type': /Mobi/.test(navigator.userAgent) ? 'mobile' : 'desktop',
}),
spanProcessors: [new BatchSpanProcessor(new OTLPTraceExporter({
url: 'https://<gateway>/v1/traces',
headers: { 'X-API-Key': '<browser ingestion key>' },
}))],
});
provider.register();
registerInstrumentations({ instrumentations: [
new DocumentLoadInstrumentation(),
new FetchInstrumentation({ propagateTraceHeaderCorsUrls: [/api\.example\.com/] }),
]});

Set page.route on spans (the route template, such as /product/:id, never the full URL) so slow pages can be told apart. Send JavaScript errors as ERROR logs through the OTLP log exporter.

What InfraSage reads​

A service is treated as a frontend when most of its spans carry browser.name or device.type. You can also set it by hand with PUT /api/v1/services/{id}/component and {"kind": "frontend"}.

Every minute it records:

VitalFrom
Throughputpage loads (documentLoad spans)
Failure sharefetches that got a 5xx or no response
Slow sharepage loads slower than the page's usual p90
JavaScript errorsERROR logs from the frontend

Each page is judged on these like any other component. Distributed tracing links a page's fetches to the API spans they caused, so the Atlas and causal search can follow a slow page to the service behind it.