formatter) { $output = ($this->formatter)($record); $this->handledOutputs[] = $output; } else { $this->handledOutputs[] = $record->getMessage(); } } } it('demonstrates different formatters with same log data', function () { echo "\n🎨 Formatter Showcase:\n\n"; // Setup exception-enriched log record $processorManager = new ProcessorManager(); $processorManager = $processorManager->addProcessor(new ExceptionEnrichmentProcessor()); try { throw new RuntimeException('Database connection timeout'); } catch (RuntimeException $e) { $exception = new Exception('User operation failed', 500, $e); $context = LogContext::withData([ 'user_id' => 12345, 'operation' => 'create_order', 'request_id' => 'req_abc123', 'exception' => $exception, ])->addTags('error', 'order_processing'); // Create handlers with different formatters $lineHandler = new FormattableHandler(new LineFormatter()); $jsonHandler = new FormattableHandler(new JsonFormatter()); $devHandler = new FormattableHandler(new DevelopmentFormatter(colorOutput: false)); $structuredHandler = new FormattableHandler(new StructuredFormatter()); $logger = new DefaultLogger( handlers: [$lineHandler, $jsonHandler, $devHandler, $structuredHandler], processorManager: $processorManager ); $logger->error('Order creation failed due to database issues', $context); // Display different formatter outputs echo "1. LINE FORMAT:\n"; echo $lineHandler->handledOutputs[0] . "\n\n"; echo "2. JSON FORMAT:\n"; echo $jsonHandler->handledOutputs[0] . "\n\n"; echo "3. DEVELOPMENT FORMAT:\n"; echo $devHandler->handledOutputs[0] . "\n"; echo "4. STRUCTURED FORMAT (logfmt):\n"; echo $structuredHandler->handledOutputs[0] . "\n\n"; // Verify all handlers received the log expect($lineHandler->handledOutputs)->toHaveCount(1); expect($jsonHandler->handledOutputs)->toHaveCount(1); expect($devHandler->handledOutputs)->toHaveCount(1); expect($structuredHandler->handledOutputs)->toHaveCount(1); // Verify JSON is valid $jsonData = json_decode($jsonHandler->handledOutputs[0], true); expect($jsonData)->toBeArray(); expect($jsonData['extra']['exception_class'])->toBe(Exception::class); } }); it('demonstrates formatter customization options', function () { echo "\n⚙️ Formatter Customization:\n\n"; $context = LogContext::withData(['api_key' => 'sk_test_123', 'response_time' => 245]); // Custom line format $customLineFormatter = new LineFormatter( format: "{timestamp} | {level} | {message}", timestampFormat: 'H:i:s' ); // Pretty JSON $prettyJsonFormatter = new JsonFormatter(prettyPrint: true); // Structured as key-value $kvFormatter = new StructuredFormatter(format: 'kv'); $handlers = [ 'custom_line' => new FormattableHandler($customLineFormatter), 'pretty_json' => new FormattableHandler($prettyJsonFormatter), 'key_value' => new FormattableHandler($kvFormatter), ]; $logger = new DefaultLogger(handlers: array_values($handlers)); $logger->info('API request completed successfully', $context); echo "CUSTOM LINE FORMAT:\n"; echo $handlers['custom_line']->handledOutputs[0] . "\n\n"; echo "PRETTY JSON FORMAT:\n"; echo $handlers['pretty_json']->handledOutputs[0] . "\n\n"; echo "KEY-VALUE FORMAT:\n"; echo $handlers['key_value']->handledOutputs[0] . "\n\n"; // Verify customizations expect($handlers['custom_line']->handledOutputs[0])->toContain(' | INFO | '); expect($handlers['pretty_json']->handledOutputs[0])->toContain(' '); // Pretty print spacing expect($handlers['key_value']->handledOutputs[0])->toContain('level: INFO'); }); it('demonstrates formatter performance with batch logging', function () { $jsonFormatter = new JsonFormatter(); $handler = new FormattableHandler($jsonFormatter); $logger = new DefaultLogger(handlers: [$handler]); // Batch log multiple entries for ($i = 1; $i <= 5; $i++) { $context = LogContext::withData(['batch_id' => "batch_$i", 'item_count' => $i * 10]); $logger->info("Processed batch $i", $context); } expect($handler->handledOutputs)->toHaveCount(5); // Verify all are valid JSON foreach ($handler->handledOutputs as $output) { $decoded = json_decode($output, true); expect($decoded)->toBeArray(); expect($decoded['message'])->toContain('Processed batch'); } echo "\n📊 Batch Logging Demo: " . count($handler->handledOutputs) . " entries formatted as JSON\n"; });