PHP cookbook · Beginner
Add structured logging with request IDs in PHP
Make PHP logs searchable and correlate all log lines from one request.
Approach
Use Monolog with a JSON formatter writing to stderr (collected by Docker/systemd), add a processor that injects a request ID (from X-Request-ID or generated), and log with context arrays instead of string interpolation. Return the request ID in a response header so users can report it.
Solution
<?php
declare(strict_types=1);
use Monolog\Formatter\JsonFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
use Monolog\Logger;
use Monolog\LogRecord;
$requestId = preg_match('/^[a-zA-Z0-9-]{8,64}$/', $_SERVER['HTTP_X_REQUEST_ID'] ?? '')
? $_SERVER['HTTP_X_REQUEST_ID'] : bin2hex(random_bytes(8));
header("X-Request-ID: {$requestId}");
$handler = new StreamHandler('php://stderr', Level::Info);
$handler->setFormatter(new JsonFormatter());
$logger = new Logger('shop', [$handler]);
$logger->pushProcessor(function (LogRecord $record) use ($requestId): LogRecord {
return $record->with(extra: $record->extra + [
'request_id' => $requestId,
'path' => $_SERVER['REQUEST_URI'] ?? null,
]);
});
$logger->info('Order placed', ['order_id' => 1234, 'total_cents' => 4999]);
// {"message":"Order placed","context":{"order_id":1234,"total_cents":4999},"level_name":"INFO","extra":{"request_id":"9f2c...","path":"/checkout"},...}
Pitfalls
- Logging passwords, tokens or full card numbers.
- Trusting arbitrary incoming request IDs (validate format/length).
- Writing log files inside containers instead of stdout/stderr.
Variations
- Symfony/Laravel: configure Monolog channels in framework config and add the processor there.
- Ship logs to OpenTelemetry with the OTel PHP SDK for trace correlation.
Further reading: Monolog usage
Reference: https://github.com/Seldaek/monolog/blob/main/doc/01-usage.md
More PHP recipes
- Add CSRF protection to PHP forms
- Add health check endpoints to a PHP app
- Build a secure password reset flow in PHP
- Cache expensive queries with Redis in PHP
- Call external APIs with timeouts and retries in PHP
- Handle file uploads securely in PHP
- Implement rate limiting in a PHP API
- Make a PHP payment endpoint idempotent