| Status | |
|---|---|
| Stability | alpha: metrics |
This receiver connects to a Chromium-based browser via the Chrome DevTools Protocol (CDP) and collects browser performance metrics. It works with any Chromium-based browser (Chrome, Chromium, Edge) that exposes a CDP debugging endpoint.
This receiver is not included in the core or contrib OpenTelemetry Collector distributions. To use it, build a custom Collector distribution using the OpenTelemetry Collector Builder (ocb).
Instructions on how to use the builder can be found here. The configuration needed in the builder-config.yaml to install this receiver is:
receivers:
- gomod: github.com/stuart23/chromiumreceiver v0.2.0Start Chrome/Chromium with the --remote-debugging-port flag to expose a CDP WebSocket endpoint:
chromium --headless --remote-debugging-port=9222 about:blankOr with Google Chrome:
google-chrome --headless --remote-debugging-port=9222 about:blankThe receiver connects to the CDP WebSocket endpoint at ws://localhost:9222.
If you already use Playwright to manage browser instances, you can expose a CDP endpoint from Playwright's launched browser instead of launching Chrome separately. Pass --remote-debugging-port through Playwright's launch arguments:
const { chromium } = require("playwright");
(async () => {
const browser = await chromium.launch({
headless: true,
args: ["--remote-debugging-port=9223"],
});
console.log("CDP endpoint available at ws://localhost:9223");
console.log("Playwright managing browser PID:", browser.process().pid);
// Keep alive — Playwright controls the browser lifecycle,
// the receiver connects via CDP on port 9223.
})();Playwright launches and manages the Chromium process; the receiver connects directly to the CDP port, bypassing Playwright's own protocol. This means:
- Playwright handles browser lifecycle (launch, crash recovery, cleanup).
- The receiver reads metrics via CDP without interfering with Playwright's test automation.
- Both can coexist on the same browser — Playwright drives pages through its API while the receiver passively observes performance data.
Set the receiver endpoint to the CDP port:
receivers:
chromium:
endpoint: ws://localhost:9223Tip: Use a different port for
--remote-debugging-port(e.g. 9223) than Playwright's own WebSocket endpoint to avoid conflicts.
In containerized environments, run a headless Chrome/Chromium as a sidecar or standalone deployment with --remote-debugging-port exposed. If using Playwright, include --remote-debugging-port in the launch args as shown above.
| Parameter | Required | Default | Description |
|---|---|---|---|
endpoint |
yes | — | CDP WebSocket endpoint URL (e.g. ws://localhost:9222) |
collection_interval |
no | 30s |
How often to scrape metrics |
receivers:
chromium:
endpoint: ws://chromium:9222
collection_interval: 30s| Metric | Description | Unit | Type |
|---|---|---|---|
chromium.targets.count |
Active browser targets by type | {target} |
Gauge |
These metrics are collected via the CDP Performance.getMetrics command on each page target. Each data point carries target.url identifying the page.
| Metric | Description | Unit | Type |
|---|---|---|---|
chromium.page.document.count |
Number of documents in the page | {document} |
Gauge |
chromium.page.frame.count |
Number of frames in the page | {frame} |
Gauge |
chromium.page.js_event_listener.count |
Number of JS event listeners | {listener} |
Gauge |
chromium.page.dom_node.count |
Number of DOM nodes | {node} |
Gauge |
chromium.page.js_heap.used_size |
Used JavaScript heap size | By |
Gauge |
chromium.page.js_heap.total_size |
Total JavaScript heap size | By |
Gauge |
chromium.page.layout.count |
Cumulative count of page layouts | {layout} |
Sum (monotonic) |
chromium.page.layout.duration |
Cumulative duration of page layouts | s |
Sum (monotonic) |
chromium.page.recalc_style.count |
Cumulative count of CSS recalculations | {recalculation} |
Sum (monotonic) |
chromium.page.recalc_style.duration |
Cumulative duration of CSS recalculations | s |
Sum (monotonic) |
chromium.page.script.duration |
Cumulative duration of JavaScript execution | s |
Sum (monotonic) |
chromium.page.task.duration |
Cumulative duration of all browser tasks | s |
Sum (monotonic) |
| Attribute | Description | Present on |
|---|---|---|
chromium.endpoint |
CDP WebSocket endpoint URL | All metrics |
target.type |
Target type (page, service_worker, browser, etc.) |
chromium.targets.count |
target.url |
URL of the page | Per-page metrics |
- The receiver connects to the Chrome DevTools Protocol WebSocket endpoint using chromedp.
- It enumerates all browser targets (pages, service workers, etc.) and emits
chromium.targets.countgrouped by type. - For each
pagetarget, it attaches via CDP, enables thePerformancedomain, and callsPerformance.getMetricsto collect per-page performance data.
chromium.targets.count{chromium.endpoint="ws://localhost:9222", target.type="page"} 2
chromium.page.js_heap.used_size{chromium.endpoint="ws://localhost:9222", target.type="page", target.url="https://example.com"} 2451968
chromium.page.js_heap.total_size{chromium.endpoint="ws://localhost:9222", target.type="page", target.url="https://example.com"} 4194304
chromium.page.dom_node.count{chromium.endpoint="ws://localhost:9222", target.type="page", target.url="https://example.com"} 26
chromium.page.layout.duration{chromium.endpoint="ws://localhost:9222", target.type="page", target.url="https://example.com"} 0.003
chromium.page.script.duration{chromium.endpoint="ws://localhost:9222", target.type="page", target.url="https://example.com"} 0.012
The integration tests launch a real headless Chrome instance.
go test -tags=integration -v -timeout 120s ./...Or point at an already-running Chrome instance:
CDP_ENDPOINT=ws://localhost:9222 go test -tags=integration -v -timeout 120s ./...