Structured Logger Generator
Creates structured logging infrastructure for observability and request tracing.
When to Use
| Scenario | Example |
|---|---|
| Distributed tracing | Correlate logs across microservices |
| Request debugging | Track full request lifecycle |
| Audit logging | Structured records with context |
| Error investigation | Rich context in error logs |
Component Characteristics
CorrelationId
- Value Object wrapping UUIDv4
- Immutable, self-validating
- Propagated via
X-Request-IDheader
CorrelationIdProcessor
- Monolog processor adding
correlation_idto every record - Reads from CorrelationIdHolder thread-local storage
- Zero-config: auto-enriches all log entries
RequestContextProcessor
- Monolog processor adding request metadata
- Captures method, URI, IP, user-agent
- Enables filtering logs by request attributes
CorrelationIdMiddleware
- PSR-15 middleware extracting or generating X-Request-ID
- Stores in CorrelationIdHolder for downstream use
- Adds correlation ID to response headers
CorrelationIdHolder
- Static thread-local storage for correlation ID
- Set once per request, available globally
- Reset after request completes
Generation Process
Step 1: Generate Core Components
Path: src/Infrastructure/Logging/
CorrelationId.php— Value Object with UUID validationCorrelationIdHolder.php— Thread-local correlation ID storage
Step 2: Generate Monolog Processors
Path: src/Infrastructure/Logging/Processor/
CorrelationIdProcessor.php— Adds correlation_id to log recordsRequestContextProcessor.php— Adds request context to log records
Step 3: Generate Middleware
Path: src/Infrastructure/Logging/
CorrelationIdMiddleware.php— PSR-15 middleware for correlation ID
Step 4: Generate Tests
CorrelationIdTest.php— Value Object testsCorrelationIdProcessorTest.php— Processor enrichment testsCorrelationIdMiddlewareTest.php— Middleware behavior tests
File Placement
| Component | Path |
|---|---|
| Core Classes | src/Infrastructure/Logging/ |
| Processors | src/Infrastructure/Logging/Processor/ |
| Unit Tests | tests/Unit/Infrastructure/Logging/ |
Naming Conventions
| Component | Pattern | Example |
|---|---|---|
| Value Object | CorrelationId |
CorrelationId |
| Holder | CorrelationIdHolder |
CorrelationIdHolder |
| Processor | {Context}Processor |
CorrelationIdProcessor |
| Middleware | CorrelationIdMiddleware |
CorrelationIdMiddleware |
| Test | {ClassName}Test |
CorrelationIdTest |
Quick Template Reference
CorrelationId
final readonly class CorrelationId
{
public function __construct(public string $value)
{
// Validates UUID v4 format
}
public static function generate(): self;
public function toString(): string;
}
CorrelationIdProcessor
final readonly class CorrelationIdProcessor
{
public function __invoke(LogRecord $record): LogRecord;
}
CorrelationIdMiddleware
final readonly class CorrelationIdMiddleware implements MiddlewareInterface
{
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface;
}
Usage Example
// Middleware extracts or generates correlation ID
$middleware = new CorrelationIdMiddleware(headerName: 'X-Request-ID');
// Monolog processor auto-enriches every log entry
$logger->pushProcessor(new CorrelationIdProcessor());
$logger->pushProcessor(new RequestContextProcessor($request));
// Log entry output:
// {"message":"Order created","correlation_id":"550e8400-...","method":"POST","uri":"/orders"}
Log Flow
Request ──→ CorrelationIdMiddleware
│
Extract/Generate X-Request-ID
│
Store in CorrelationIdHolder
│
CorrelationIdProcessor ──→ Adds correlation_id to every log
RequestContextProcessor ──→ Adds method, URI, IP to every log
│
Response ──→ Add X-Request-ID header
Anti-patterns to Avoid
| Anti-pattern | Problem | Solution |
|---|---|---|
| Manual correlation IDs | Inconsistent, easy to forget | Auto-enrich via processor |
| Unstructured logs | Cannot query or filter | Use structured JSON format |
| No request context | Cannot trace request flow | Add request processor |
| Global mutable logger | Thread safety issues | Use holder with request scope |
| Missing response header | Client cannot correlate | Return X-Request-ID in response |
| No holder cleanup | Memory leak between requests | Reset holder after request |
References
For complete PHP templates and examples, see:
references/templates.md— CorrelationId, Processors, Middleware, Holder templatesreferences/examples.md— Service integration examples and tests