Events¶
Drupal\native_observability\Event\NativeObservabilityEvents defines two event name constants:
| Constant | Value | Event class | Dispatched from |
|---|---|---|---|
TRACE_RECORDED |
native_observability.trace_recorded |
Drupal\native_observability\Event\TraceRecordedEvent |
DatabaseTraceStorage::insert(), right after the trace row is inserted |
TRACES_DELETED |
native_observability.traces_deleted |
Drupal\native_observability\Event\TracesDeletedEvent |
TraceDeleteAllConfirmForm, after a bulk deletion completes |
Both events are dispatched synchronously, within the same request that triggered them. There is no deferred or queued delivery.
TraceRecordedEvent¶
final class TraceRecordedEvent extends Event {
public function __construct(array $trace);
public function getTrace(): array;
}
getTrace() returns the same associative array that was written to native_observability_trace:
| Key | Type | Notes |
|---|---|---|
id |
int |
The auto-increment ID of the inserted row |
request_id |
string |
ULID request correlation ID |
method |
string |
HTTP method |
path |
string |
Request path |
route_name |
string\|null |
Drupal route machine name |
status_code |
int\|null |
HTTP response status code |
is_ajax |
int |
1 or 0 |
duration_ms |
int\|null |
Request duration in milliseconds |
started_at |
int |
Unix timestamp |
ended_at |
null |
Reserved, always NULL on this event |
TracesDeletedEvent¶
final class TracesDeletedEvent extends Event {
public function __construct(int $deleted_count);
public function getDeletedCount(): int;
}
getDeletedCount() returns the number of trace rows removed by the bulk delete operation.
Example subscriber¶
The subscriber below lives in a custom module (my_module) and logs a warning for every request slower than 3 seconds. It follows the same shape as native_observability_spans's own TracesDeletedSubscriber: a final class implementing EventSubscriberInterface, with an explicit logger channel argument and public: true plus the event_subscriber tag, both required by Drupal's event-subscriber compiler pass.
my_module/src/EventSubscriber/SlowTraceSubscriber.php:
<?php
declare(strict_types=1);
namespace Drupal\my_module\EventSubscriber;
use Drupal\native_observability\Event\NativeObservabilityEvents;
use Drupal\native_observability\Event\TraceRecordedEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Logs a warning for every trace slower than the configured threshold.
*/
final class SlowTraceSubscriber implements EventSubscriberInterface {
private const THRESHOLD_MS = 3000;
public function __construct(
private readonly LoggerInterface $logger,
) {
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
return [
NativeObservabilityEvents::TRACE_RECORDED => 'onTraceRecorded',
];
}
public function onTraceRecorded(TraceRecordedEvent $event): void {
$trace = $event->getTrace();
$durationMs = (int) ($trace['duration_ms'] ?? 0);
if ($durationMs < self::THRESHOLD_MS) {
return;
}
$this->logger->warning('Slow request: @method @path took @duration ms (status @status).', [
'@method' => $trace['method'] ?? 'UNKNOWN',
'@path' => $trace['path'] ?? '',
'@duration' => $durationMs,
'@status' => $trace['status_code'] ?? 'n/a',
]);
}
}
my_module/my_module.services.yml:
services:
logger.channel.my_module:
class: Drupal\Core\Logger\LoggerChannel
factory: ['@logger.factory', 'get']
arguments: ['my_module']
my_module.slow_trace_subscriber:
class: Drupal\my_module\EventSubscriber\SlowTraceSubscriber
public: true
arguments:
$logger: '@logger.channel.my_module'
tags:
- { name: event_subscriber }
No other wiring is required. my_module does not need to declare a dependency on native_observability in its .info.yml for the subscriber to work, but it should: the event class is only autoloadable, and the event only fires, while native_observability is installed.