This project is not covered by Drupal’s security advisory policy.

Request Audit (request_audit)

Allow collect telemetry data from requests.

Overview

request_audit instruments incoming requests in Drupal and records latency telemetry. It can log request timing data either to Watchdog or to database tables for reporting and chart visualization.

The module provides:

  • An admin settings form to enable/disable telemetry and select logging destination.
  • A charts page that renders latency over time buckets (via Chart.js).
  • An AJAX endpoint that returns bucketed latency series data.
  • A table of URLs below the chart, filtered by the current query and time range.
  • A “Top 10 slow URLs” section computed from recent aggregated buckets.
  • Zoom support in the chart, with automatic refresh of both the graph and the URL table.

Requirements

  • Drupal 10 (and core versions compatible with what’s declared in composer.json)
  • PHP requirements are inherited from Drupal.
  • A database supported by Drupal’s database layer.
  • Chart.js and its plugins available through the configured library paths.

Dependencies

In composer.json the module requires:

  • drupal/core (^10.6 || ^11 || ^12)
  • npm-asset/chart.js (^4.4)
  • npm-asset/chartjs-plugin-zoom (^2.2)
  • npm-asset/chartjs-adapter-date-fns (^3.0)

Installation

Install via Composer (recommended for contributed modules):

  1. From your Drupal root, require the module package:

    composer require drupal/request_audit

  2. Enable the module:

  • Via UI: Extend
  • Or with Drush:

    drush en request_audit

Run database updates if needed:

drush updb

When enabled, the module’s request_audit.install will create these tables if they do not exist:

  • request_audit_rel
  • request_audit_latency_agg

Configuration

Go to:

  • Configuration → System → Request audit settings
    • Route: /admin/config/system/settings (request_audit.settings)

Settings:

  • Log activity (active)
  • Database
    • Log database activity (database_log)
    • Log queries list (save_queries)
  • Log destination (log_to)
    • watchdog: logs the payload to Drupal logger
    • database: stores request timing + aggregated latency in DB

Admin permission

All admin routes require:

  • administer site configuration

Charts / Reporting

Go to:

  • Reports → Request Audit Charts
    • Route: /admin/reports/request-audit-charts (request_audit.request_audit_charts)

The page includes:

  • A URL pattern control (glob-like, e.g. /pay2/*)
  • A time window selector
  • An auto-refreshing Chart.js chart
  • A zoomable chart with drag-zoom and pan support
  • A table of URLs for the current filter/range
  • A “Top 10 slow URLs” section (based on average latency in recent buckets)

Chart series

The chart currently displays these series derived from the visible bucket values:

  • Avg latency (ms): the average latency of the buckets shown in the chart. This is the main blue line.
  • p25–p75: the middle 50% of the bucket values. It shows the typical spread of the data.
  • Median: the middle value of the bucket distribution. It is more robust than the average when there are spikes.
  • Mean: arithmetic average of the displayed bucket values. It is sensitive to large outliers.
  • p95: the value below which 95% of the bucket values fall. Useful to detect slow tail latency.
  • p99: the value below which 99% of the bucket values fall. Useful to detect severe tail latency and rare spikes.

URL table behavior

The table below the chart is updated automatically:

  • on initial page load
  • when the filter pattern changes
  • when the time window changes
  • when the user zooms into a range of the chart
  • when the user resets zoom

The table shows, for each URL:

  • position in the result set
  • URL path
  • number of requests
  • average latency
  • minimum latency
  • maximum latency

AJAX endpoint (data provider)

The chart fetches data from:

  • /admin/reports/request-audit-charts/block (request_audit.request_audit_charts_block)

Query parameters:

  • path (optional): exact path match
  • pattern (optional): glob-like pattern (e.g. /pay2/*)
  • windowMinutes (optional, default: 180)
  • bucketMinutes (optional, default: 5)
  • start (optional): explicit ISO 8601 UTC start of range
  • end (optional): explicit ISO 8601 UTC end of range

If both start and end are provided, the chart and the URL table use that explicit range.

This is what makes the zoomed view update correctly.

Response format

The AJAX endpoint returns JSON with:

  • buckets: bucketed latency data for the chart
  • path: the active path/pattern label
  • urls: the list of URLs that match the current filter and time range
  • range: the normalized start/end range used by the server

Data Model

request_audit_rel (per-request)

Created by request_audit.install and filled when logging to database is enabled.

Stores:

  • request_id, path, method
  • timing breakdown in milliseconds:
    • total_ms, routing_ms, controller_ms, render_ms, untracked_ms
  • DB timing breakdown:
    • db_total_ms, db_select_ms, db_write_ms
  • timestamp

request_audit_latency_agg (aggregated)

Stores aggregated latency per:

  • path
  • bucket_start / bucket_end (UTC buckets)

Fields include:

  • request_count
  • sum_latency_ms
  • avg_latency_ms
  • errors

Bucketing is done in the event subscriber with 5-minute UTC buckets.

Architecture Notes

Core logic lives in:

  • Drupal\request_audit\EventSubscriber\RequestTimingSubscriber

It subscribes to Kernel events:

  • REQUEST
  • CONTROLLER
  • VIEW
  • RESPONSE
  • TERMINATE

Key behaviors:

  • Generates a request id from X-Request-Id or via random_bytes().
  • When enabled and database_log is checked, starts Drupal DB query logging using Database::startLog().
  • On terminate:
    • analyzes logged queries
    • stores per-request data into request_audit_rel
    • updates aggregated bucket rows in request_audit_latency_agg

The chart UI JS lives in:

  • js/request_audit_charts.js

It is declared in:

  • request_audit.libraries.yml

and includes:

  • Chart.js
  • Chart.js zoom plugin
  • Chart.js date adapter

Frontend behavior

The chart page uses a Drupal behavior that:

  • initializes the chart only once
  • creates the canvas dynamically if needed
  • supports auto-refresh every configured interval
  • stores the current zoom range in the URL query string
  • reloads the chart and the URL table after zooming
  • allows zoom reset with a dedicated button

URL synchronization

The current state is written to the browser URL using query parameters:

  • pattern
  • windowMinutes
  • bucketMinutes
  • start
  • end

This allows reloading the page while preserving the selected range.

Uninstallation

On module uninstall, request_audit_uninstall() drops:

  • request_audit_rel
  • request_audit_latency_agg

Maintainers

Current maintainers for Drupal 10:

Project information

  • caution Minimally maintained
    Maintainers monitor issues, but fast responses are not guaranteed.
  • caution Maintenance fixes only
    Considered feature-complete by its maintainers.
  • Project categories: Performance
  • chart icon4 sites report using this module
  • Created by psf_ on , updated
  • shield alertThis project is not covered by the security advisory policy.
    Use at your own risk! It may have publicly disclosed vulnerabilities.

Releases