Skip to content

Database observer

Slow-query capture, the raw report, exports, deletion, and settings are provided by the native_observability_database_observer submodule. It is part of the DASHBOARD install tier; enable it with drush no:preset:dashboard, or directly with drush en native_observability_database_observer -y.

Routes

Route Path Permission
native_observability_database_observer.report /admin/reports/native-observability/database-observer access native observability database observer
native_observability_database_observer.view /admin/reports/native-observability/database-observer/{id} access native observability database observer
native_observability_database_observer.export /admin/reports/native-observability/database-observer/{id}/export access native observability database observer
native_observability_database_observer.export_filtered /admin/reports/native-observability/database-observer/export/filtered access native observability database observer
native_observability_database_observer.delete_all /admin/reports/native-observability/database-observer/delete-all administer native observability database observer
native_observability_database_observer.delete_filtered /admin/reports/native-observability/database-observer/delete-filtered administer native observability database observer
native_observability_database_observer.settings /admin/config/development/native-observability/settings/database-observer administer native observability database observer

Report

Open /admin/reports/native-observability/database-observer. DatabaseObserverListController::list() renders a filterable, paginated table (ID, relation, route/path, duration, slow flag, request/trace link, created date). Filters read from the query string: search, relation_type, is_slow.

The page states its scope explicitly: this RAW report stores only queries above the configured slow-query threshold. Aggregated per-request database counters, used to enrich trace payloads and the database summary span, are not listed row by row here.

Each row shows its relation_type (request_bound when the query is correlated to a captured request, unrelated otherwise) and, when the row has a request_id that matches a stored trace, a link to that trace via native_observability.trace_view_by_request_id.

Single query view

Follow a row's ID link, or open /admin/reports/native-observability/database-observer/{id} directly, for full details on one captured slow query.

Exports

Single query

/admin/reports/native-observability/database-observer/{id}/export downloads the raw stored record as JSON.

Filtered set

/admin/reports/native-observability/database-observer/export/filtered downloads the rows matching the current filter set as JSON.

Deletion

Two deletion actions are available, both gated by administer native observability database observer:

  • Delete all (delete_all): removes every stored slow-query record.
  • Delete filtered (delete_filtered): removes only the rows matching the filter set (search, relation_type, is_slow) currently applied on the report page.
flowchart LR
    A[Database observer records] --> B[Filtered: rows matching current filters]
    A --> C[All: every record]

Both forms redirect back to the report page after deletion, with a status message reporting how many rows were removed.

Settings

/admin/config/development/native-observability/settings/database-observer configures capture behavior, the slow-query threshold, whether SQL text is stored, the per-request query cap, and retention. See Database observer settings for the full list of keys and their default values.

With store_slow_query_text on, the SQL text is stored with every string and numeric literal replaced by ? and a list of placeholders collapsed to IN (?). Table and column names stay, so the text still shows the shape of the statement. Sites that already had the setting keep their value, new installations start with it off, and the status report warns while it is on.

The settings form also documents the module's runtime model directly: ordinary query counters stay in memory during the request for trace enrichment, and only queries above slow_query_threshold_ms are persisted to the RAW table (max_stored_queries_per_request caps how many of those a single request can write).

When a request produces more slow queries than the cap, the slowest ones are the ones kept, and they are written in the order they ran. The stored payload carries both counts, slow_query_count for what the request produced and stored_slow_queries for what was written, so a truncated request can be told apart from a complete one. The single record page prints them as "20 of 25 stored" and warns when they differ.