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:
| Vital | From |
|---|---|
| Throughput | page loads (documentLoad spans) |
| Failure share | fetches that got a 5xx or no response |
| Slow share | page loads slower than the page's usual p90 |
| JavaScript errors | ERROR 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.