Observability

Benchmark

Benchmark lifecycle marks, runtime telemetry and HTTP response benchmark metadata.

Overview

Benchmark runtime lives under Observability\Benchmark. Benchmark holds current run state and BenchmarkRun captures marks, elapsed time and memory deltas.

Provider wiring

BenchmarkServiceProvider registers benchmark runtime services used by HTTP and CLI kernels.

$container->singleton(Benchmark::class, Benchmark::class);
$container->singleton(BenchmarkResponseInjector::class, BenchmarkResponseInjector::class);

Lifecycle marks

Benchmark marks are recorded during bootstrap, middleware and dispatch flow. Only marks listed below are part of the current runtime implementation.

$run->mark('start');
$run->mark('kernel_start');
$run->mark('config_loaded');
$run->mark('core_logger_ready');
$run->mark('framework_providers_registered');
$run->mark('app_providers_registered');
$run->mark('routes_registered'); // HTTP kernel
$run->mark('request_received');
$run->mark('middleware_enter');
$run->mark('benchmark_middleware_enter');
$run->mark('route_match_start');
$run->mark('route_matched');
$run->mark('controller_resolve_start');
$run->mark('controller_resolved');
$run->mark('controller_action_start');
$run->mark('controller_action_finished');
$run->mark('response_created');
$run->mark('response_ready');
$run->mark('finish');

HTTP benchmark flow

HTTP benchmark starts in Kernel::handle(), continues through Framework::run(), BenchmarkMiddleware, route dispatch and controller resolution. BenchmarkResponseInjector attaches benchmark metadata to the outgoing response.

$response = $response
    ->withHeader('X-Benchmark-Time-Ms', $elapsedMs)
    ->withHeader('X-Benchmark-Memory-Delta', (string) $memoryDeltaBytes)
    ->withHeader('X-Benchmark-Peak-Memory', (string) $peakBytes)
    ->withHeader('X-Benchmark-Peak-Allocated-Memory', (string) $peakAllocatedBytes);

CLI benchmark flow

CLI starts benchmark in CliKernel::handle() and records bootstrap marks as part of CLI command lifecycle. CLI-specific bootstrap also records providers_registered.

Benchmark logging

When benchmark.log.enabled=true, BenchmarkMiddleware writes a request.benchmark event through LogManager::benchmark().

$this->logs->benchmark()->info('request.benchmark', [
    ...$run->toArray(),
    'status' => $status,
    'elapsed_ms' => round($run->elapsedMs(), 3),
    'memory_delta_bytes' => $run->memoryDeltaBytes(),
]);

Reading benchmark data

Benchmark data is available through response headers, optional HTML response comment (benchmark.inject_html_comment) and benchmark log events. HTML comment injection is applied only for text/html responses.

Configuration

Benchmark output behavior is controlled by merged config (typically app/Config/Logging.php) via benchmark.* keys.

'benchmark' => [
    'inject_html_comment' => true,

    'log' => [
        'enabled' => true,
        'file' => 'benchmark.log',
        'days' => 7,
    ],
],