Native Observability records what a Drupal site does at runtime: request traces, execution spans, cache and database behavior, metrics aggregated per route, and export to OpenTelemetry, Prometheus and Grafana. It runs inside the application, with no core patches and no external agent.
What it does
- Traces every request with a correlation ID carried across the full hop chain.
- Builds execution spans and draws them on a timeline in the dashboard.
- Captures outbound HTTP through a middleware on Drupal's shared handler stack, so calls issued by libraries that wrap
http_client are recorded without touching them.
- Observes the cache: hits, misses, tag invalidations and cacheability decisions, per route and for the events that never reach a route.
- Observes the database: query counts, timing, and slow query evidence per route and per query hash.
- Aggregates metrics per route: request count, throughput, average, P95 and P99 latency, error rate.
- Reconstructs a single route in the Forensic Route Analysis view, correlating its traces, spans, cache signals and outbound calls, and exports that view as a self contained HTML document.
- Exports over OTLP to OpenTelemetry, serves a Prometheus scrape endpoint behind a bearer token, and writes a long form observability report. Nothing leaves the site until the site owner chooses an exposure grade, and no export carries a request path.
- Measures its own runtime cost on the server where it runs, in paired blocks with capture on and capture off, and reports the figure with its sample size, its noise floor and a verdict.
- Publishes observability events to ECA for event driven automation.
- Serves its data to AI agents through a read-only MCP server, and the site owner decides what leaves the site.
Connect an AI agent (MCP)
The native_observability_mcp submodule, new in 2.2.0, lets an AI agent read this data and answer why a page is slow. The agent gets no database or admin access.
- Read-only. No tool writes, so an agent cannot change the site or the exposure grade.
- The site owner picks what leaves the site: nothing, aggregates by route name, or single requests. A new site starts at nothing.
- Route machine names only. No path, URL, query value or IP address reaches the agent.
- OAuth 2.1 with PKCE. A new client waits for admin approval, and every call is logged.
- A vocabulary tells the agent how to read each field, so it does not guess what a number means.
It needs Drupal 11, PHP 8.3 and the MCP Server, Tool API and Simple OAuth modules.
Documentation
Installation, configuration, the settings reference with a screenshot of every tab, the data model and the developer surface are documented on the project site. It is built from the repository, so it describes the branch rather than the last release.
Read the documentation
Where to start
The pages an operator reaches for first.
Install
composer require drupal/native_observability, then enable the sub-modules you need. The documentation covers which sub-module does what and the order to turn them on.
Requirements
- Drupal 10, 11 or 12. The MCP submodule needs Drupal 11.
- PHP 8.2 or newer, 8.3 for the MCP submodule. This is above Drupal 10's own minimum, and it is deliberate: the code uses language features that Drupal 10 does not require.
- The
zlib PHP extension. The dashboard compresses its record exports itself rather than leaving it to the web server, so the extension is a hard requirement and not an optimization.
- The dashboard pulls Apache ECharts through
wikimedia/composer-merge-plugin, configured in the dashboard's composer.libraries.json.
- The ECA bridge needs the ECA module, and only if you want event driven automation.
- OTLP push needs a reachable OTLP/HTTP collector. Grafana Alloy works without extra configuration.
Full tracing adds work to every observed request, and most of it is paid before the response is sent. Only the flush of span, cache and database rows is deferred to kernel.terminate. In the run documented under Measuring the overhead, that flush was 6.1% of the module's cost, and the visitor waited for the other 93.9%. Set retention and record limits, and write exclusion rules for the paths you do not want observed, before turning full tracing on in production.
Run drush no:overhead:measure to get that cost for your own installation. A figure measured on someone else's server does not describe yours.
Status
2.2.x is the current branch and 2.1.x is still supported. Older branches are not. The dashboard, the exporters and the report are covered by the test module testing_native_observability, which drives the pipeline end to end. The MCP submodule is experimental.