- Enhance logging handlers (Console, DockerJson, File, JsonFile, MultiFile) - Improve exception and line formatters - Update logger initialization and processor management - Add Ansible playbooks for staging 502 error troubleshooting - Update deployment documentation - Fix serializer and queue components - Update error kernel and queued log handler
172 lines
5.8 KiB
PHP
172 lines
5.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Integration;
|
|
|
|
use App\Framework\Logging\DefaultLogger;
|
|
use App\Framework\Logging\Formatter\DevelopmentFormatter;
|
|
use App\Framework\Logging\Formatter\JsonFormatter;
|
|
use App\Framework\Logging\Formatter\LineFormatter;
|
|
use App\Framework\Logging\Formatter\LogFormatter;
|
|
use App\Framework\Logging\Formatter\StructuredFormatter;
|
|
use App\Framework\Logging\LogHandler;
|
|
use App\Framework\Logging\LogRecord;
|
|
use App\Framework\Logging\ProcessorManager;
|
|
use App\Framework\Logging\Processors\ExceptionEnrichmentProcessor;
|
|
use App\Framework\Logging\ValueObjects\LogContext;
|
|
use Exception;
|
|
use RuntimeException;
|
|
|
|
/**
|
|
* Integration test demonstrating Formatter usage with handlers
|
|
*/
|
|
|
|
// Enhanced handler that supports formatters
|
|
class LogHandler implements LogHandler
|
|
{
|
|
public array $handledOutputs = [];
|
|
|
|
public function __construct(
|
|
private readonly ?LogFormatter $formatter = null
|
|
) {
|
|
}
|
|
|
|
public function isHandling(LogRecord $record): bool
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public function handle(LogRecord $record): void
|
|
{
|
|
if ($this->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 LogHandler(new LineFormatter());
|
|
$jsonHandler = new LogHandler(new JsonFormatter());
|
|
$devHandler = new LogHandler(new DevelopmentFormatter(colorOutput: false));
|
|
$structuredHandler = new LogHandler(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 LogHandler($customLineFormatter),
|
|
'pretty_json' => new LogHandler($prettyJsonFormatter),
|
|
'key_value' => new LogHandler($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 LogHandler($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";
|
|
});
|