Adding Instrumentation to Browser Applications
For JavaScript applications running in the browser, adding instrumentation is a matter of integrating the appropriate OpenTelemetry libraries into your codebase. Unlike server-side instrumentation—where a Kubernetes annotation might suffice—browser instrumentation is implemented directly in your JavaScript bundle.
Signals
By default, the OpenTelemetry browser instrumentation collects traces from common browser events such as:
- Page Loads: Captured via the Document Load Instrumentation.
- User Interactions: Captured with the User Interaction Instrumentation.
- Network Requests: Captured automatically when using the
fetch
API orXMLHttpRequest
.
These signals provide insights into how users interact with your application, and no additional configuration is required to capture these events.
Instrumentation for JavaScript Browser Applications
Installation
Ensure that you have installed the necessary OpenTelemetry packages:
npm install --save @opentelemetry/api \
@opentelemetry/sdk-trace-web \
@opentelemetry/instrumentation-document-load \
@opentelemetry/exporter-trace-otlp-http \
@opentelemetry/resources \
@opentelemetry/instrumentation-fetch
# For Metrics Instrumentation
npm install --save @opentelemetry/exporter-metrics-otlp-http \
@opentelemetry/sdk-metrics
# For Logs Instrumentation
npm install --save @opentelemetry/exporter-logs-otlp-http \
@opentelemetry/sdk-logs \
@opentelemetry/api-logs
To enable browser instrumentation, add the following code snippet to your client-side JavaScript. This snippet initializes the tracer provider, sets up the required instrumentations, and includes custom resource attributes such as your service name. Before setting up Traces, Metrics, and Logs, we define a common resource object and initialize the OpenTelemetry provider with standard configurations.
Defining Resource Attributes
import { defaultResource, resourceFromAttributes } from '@opentelemetry/resources';
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
const resource = defaultResource().merge(
resourceFromAttributes({
[ATTR_SERVICE_NAME]: '<your_service_name>',
'service.domain': '<your_host_name>',
}),
);
Traces Instrumentation
Note: This module provides a trace-exporter for OTLP (http/json) using protocol version v0.20.0.
import { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import {
BatchSpanProcessor,
SimpleSpanProcessor,
ConsoleSpanExporter,
WebTracerProvider,
} from '@opentelemetry/sdk-trace-web';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
const fetchInstrumentation = new FetchInstrumentation();
const collectorOptions = {
url: '<your_collector_host_name>/v1/traces',
headers: {}, // an optional object containing custom headers to be sent with each request
concurrencyLimit: 10, // an optional limit on pending requests
};
const exporter = new OTLPTraceExporter(collectorOptions);
const provider = new WebTracerProvider({
resource: resource,
spanProcessors: [
new SimpleSpanProcessor(new ConsoleSpanExporter()),
new BatchSpanProcessor(exporter, {
// The maximum queue size. After the size is reached spans are dropped.
maxQueueSize: 100,
// The maximum batch size of every export. It must be smaller or equal to maxQueueSize.
maxExportBatchSize: 10,
// The interval between two consecutive exports
scheduledDelayMillis: 500,
// How long the export can run before it is cancelled
exportTimeoutMillis: 30000,
}),
]
});
provider.register();
registerInstrumentations({
instrumentations: [new DocumentLoadInstrumentation(),
fetchInstrumentation,],
});
fetchInstrumentation.setTracerProvider(provider);
Metrics Instrumentation
Note: This module provides a metrics-exporter for OTLP (http/json) using protocol version v0.20.0.
import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
const collectorOptions = {
url: '<your_collector_host_name>/v1/metrics',
headers: {}, // an optional object containing custom headers to be sent with each request
concurrencyLimit: 1, // an optional limit on pending requests
};
const metricExporter = new OTLPMetricExporter(collectorOptions);
const meterProvider = new MeterProvider({
resource: resource,
readers: [
new PeriodicExportingMetricReader({
exporter: metricExporter,
exportIntervalMillis: 10000,
}),
],
});
// Start recording data
const meter = meterProvider.getMeter('example-meter');
const counter = meter.createCounter('example-counter');
counter.add(10, { key: 'value' });
Logs Instrumentation
Note: This module provides a logs-exporter for OTLP (http/json) using protocol version v0.20.0
import { SeverityNumber } from '@opentelemetry/api-logs';
import {
LoggerProvider,
BatchLogRecordProcessor,
} from '@opentelemetry/sdk-logs';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
// exporter options. see all options in OTLPExporterConfigBase
const collectorOptions = {
url: '<your_collector_host_name>/v1/logs',
headers: {}, // an optional object containing custom headers to be sent with each request
concurrencyLimit: 1, // an optional limit on pending requests
};
const logExporter = new OTLPLogExporter(collectorOptions);
const loggerProvider = new LoggerProvider({ resource: resource });
loggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(logExporter));
const logger = loggerProvider.getLogger('default', '1.0.0');
logger.emit({
severityNumber: SeverityNumber.INFO,
severityText: 'info',
body: 'this is a log body',
attributes: { 'log.type': 'custom' },
});
Adding Ingress for the Gateway Collector
TBD