Skip to main content
Integrations

Drupal Integration

The Perfbase Drupal module provides automatic profiling for HTTP requests, Drush commands, cron runs, and queue workers. Supports Drupal 10.3+ and 11.x on PHP 8.1 through 8.5.

Installation

Install the Perfbase PHP extension first. This is what does the actual profiling:

bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"

Then install the Drupal module:

composer require perfbase/drupal

Enable the module:

drush en perfbase

Configuration

Configure via the admin UI at Configuration > Development > Perfbase, or override in settings.php for environment-specific values:

// settings.php
$settings['perfbase'] = [
    'enabled' => TRUE,
    'api_key' => 'your-api-key',
    'sample_rate' => 0.1,
    'environment' => 'production',
    'app_version' => '2026.04.08',
];

Configuration is resolved in three layers (later wins): module defaults → admin UI settings → settings.php overrides. The settings.php layer takes priority over the admin form, which is useful for keeping API keys out of config exports.

All options

KeyTypeDefaultDescription
enabledboolfalseMaster on/off switch. Requires api_key to be set.
api_keystring''Your project API key. Required.
api_urlstringhttps://ingress.perfbase.cloudIngestion endpoint.
sample_ratefloat0.1Fraction of eligible requests, commands, cron runs, and queue items to profile (0.0–1.0). 0.1 = 10%.
profile_http_status_codesint[]200..299, 500..599HTTP response status codes that should be submitted.
timeoutint10HTTP timeout in seconds for trace submission.
proxystring''Optional proxy URL (http, https, socks5, socks5h).
flagsint8145 (DefaultFlags)SDK feature flags bitmask. See Feature flags.
environmentstring''Environment label recorded on traces.
app_versionstring''Your application version, recorded on traces.
debugboolfalseWhen true, profiling errors are thrown instead of silently logged.
log_errorsbooltrueLog profiling errors via error_log().
exclude_admin_routesbooltrueSkip Drupal admin routes by default.

Context toggles

SettingDefaultDescription
profile_httpOnProfile page requests. Admin routes are skipped by default unless exclude_admin_routes is disabled.
profile_consoleOffProfile Drush and console commands.
profile_cronOnProfile Drupal cron runs.
profile_queueOnProfile queue worker item processing.

Include and exclude filters

Control what gets profiled per context with include/exclude patterns, configured in the admin UI (one pattern per line):

// settings.php example
$settings['perfbase'] = [
    'include' => [
        'http' => ['*'],                    // All routes (default)
        'console' => ['*'],
        'cron' => ['*'],
        'queue' => ['*'],
    ],
    'exclude' => [
        'http' => ['/admin/reports/*'],
        'console' => ['cache:*'],
    ],
];

Pattern types

  • Glob patterns: /admin/*, /node/* (shell-style matching)
  • Regex patterns: /^GET \/api\// (wrapped in forward slashes)
  • Catch-all: * or .* matches everything

HTTP patterns are tested against multiple representations of the request: {METHOD} {path}, the raw path, normalized path (with {id} and {uuid} placeholders), route name, and {METHOD} {route_name}.

HTTP profiling

HTTP requests are profiled automatically via a kernel event subscriber. The subscriber hooks into four Symfony kernel events:

  1. kernel.request (priority 1000): creates a profiling lifecycle and starts the trace span.
  2. kernel.response (priority -1000): records the HTTP status code.
  3. kernel.exception (priority -1000): records the exception message.
  4. kernel.terminate (priority -1000): stops the span and submits the trace. Runs after the response is sent.

Sub-requests are automatically skipped. Only the main request is profiled.

Each request uses the stable span name http. The route path template is recorded in the action attribute when available (e.g., GET /node/{node} rather than GET /node/42). Numeric path segments are normalized to {id} and UUIDs to {uuid} for low-cardinality grouping.

Automatic attributes

AttributeSource
hostnamegethostname()
php_versionPHP version
environmentConfig value
app_versionConfig value
sourcehttp
actione.g., GET /node/{node}
http_methodRequest method
http_urlScheme + host + path (no query string)
http_status_codeResponse status code
user_ipClient IP address
user_agentUser agent string
user_idDrupal user ID (from request account)
drupal.route_nameDrupal route name (e.g., entity.node.canonical)

Drush and console command profiling

Console commands are profiled via Symfony console event listeners when profile_console is enabled (off by default).

Each command uses the stable span name artisan. The command name is recorded in the action attribute, and the exit code and any exceptions are recorded as attributes.

Enable in the admin UI or via settings.php:

$settings['perfbase'] = [
    'profile_console' => TRUE,
];

Cron profiling

Drupal cron runs are profiled automatically via a service decorator that wraps the core cron service. Each cron execution uses the stable span name cron. Enabled by default.

Queue worker profiling

Queue item processing is profiled by wrapping every queue worker via a custom QueueWorkerManager. Each item processed uses the stable span name queue, with the worker plugin ID recorded in attributes. Enabled by default.

The module decorates the core plugin.manager.queue_worker service, so all queue workers, including contrib module workers, are automatically profiled without any code changes.

Sample rate

The sample rate controls what fraction of eligible HTTP requests, console commands, cron runs, and queue items are profiled:

$settings['perfbase'] = [
    'sample_rate' => 1.0,    // Profile everything (development)
    'sample_rate' => 0.1,    // 10% of eligible work (production)
    'sample_rate' => 0.01,   // 1% of requests (high-traffic)
];

The sample rate is checked per request, per command, per cron run, and per queue item independently. When a unit of work isn’t sampled, no extension trace span is started.

Error handling

Profiling never crashes your site. In production (debug: false), all profiling errors are caught and optionally logged via error_log(). In development (debug: true), errors are thrown so you can catch configuration issues early.

If the Perfbase PHP extension is not installed, the module detects this gracefully and silently disables profiling.

Using the SDK directly

Access the SDK via the perfbase.factory service for manual profiling:

/** @var \Perfbase\SDK\Perfbase|null $perfbase */
$perfbase = \Drupal::service('perfbase.factory')->getClient();
if ($perfbase) {
    $perfbase->setAttribute('entity_type', $entity->getEntityTypeId());
}

See the PHP SDK docs for the full API reference.

Admin settings page

The settings form at Configuration > Development > Perfbase provides:

  • API key and profiling toggle
  • Sample rate, timeout, and proxy configuration
  • Feature flags bitmask
  • Context toggles (HTTP, console, cron, queue)
  • Include/exclude filter textareas per context
  • HTTP status-code allowlist and admin-route exclusion controls
  • Environment and app version labels

Requires the administer site configuration permission.

Current scope

The Drupal module does not include dedicated Messenger worker support, Batch API support, install/update hook instrumentation, or Drupal-specific render/entity/cache enrichment beyond what the native PHP extension captures.