behnamhosseini/log-to-json
Convert Laravel log output to JSON. Choose between two logging modes via a simple config setting, and publish the package config to customize behavior. Install via Composer and integrate with your existing Laravel logging setup.
Installation
composer require behnamhosseini/log-to-json
Add the service provider to config/app.php under providers:
BehnamHosseini\LogToJson\LogToJsonServiceProvider::class,
First Use Case
Publish the config file (if needed) and ensure your Laravel logs are already configured in config/logging.php. The package automatically converts log entries to JSON format when writing to files (e.g., single, daily, or syslog channels).
Test by forcing a log entry:
\Log::info('Test JSON log entry');
Check the log file (e.g., storage/logs/laravel.log)—entries should now appear in JSON format.
Log Channel Integration
single, daily). No manual channel configuration is required.BehnamHosseini\LogToJson\Handlers\JsonHandler to integrate with third-party log handlers (e.g., Monolog).Structured Logging
\Log::debug('User action', [
'user_id' => 123,
'action' => 'login',
'metadata' => ['ip' => '192.168.1.1']
]);
Output:
{"level":"debug","message":"User action","context":{"user_id":123,"action":"login","metadata":{"ip":"192.168.1.1"}}}
Conditional JSON Conversion
shouldConvertToJson method in a custom handler.Log Rotation
logrotate). Ensure your rotation scripts handle JSON-formatted files correctly.JsonHandler:
$handler = new \Monolog\Handler\StreamHandler(storage_path('logs/custom.log'));
$jsonHandler = new \BehnamHosseini\LogToJson\Handlers\JsonHandler($handler);
$logger->pushHandler($jsonHandler);
\Log::error('API failure', ['request_id' => $request->header('X-Request-ID')]);
File Permissions
storage/logs directory is writable by the web server user. JSON logs may fail silently if permissions are incorrect.Log Parsing Tools
grep, tail) may not handle JSON natively. Use jq for CLI parsing:
tail -f storage/logs/laravel.log | jq
Performance Overhead
Legacy Systems
LogToJsonServiceProvider in config/app.php.format method in JsonHandler to customize JSON structure:
protected function format(array $record): string
{
return json_encode([
'timestamp' => $record['datetime']->format('Y-m-d H:i:s'),
'level' => $record['level_name'],
'message' => $record['message'],
'context' => $record['context'] ?? [],
'extra' => $record['extra'] ?? [],
]);
}
Custom Handlers
Extend JsonHandler to add fields (e.g., user agent, request duration):
class CustomJsonHandler extends \BehnamHosseini\LogToJson\Handlers\JsonHandler
{
protected function getContext(array $context): array
{
$context['request_duration'] = microtime(true) - LARAVEL_START;
return $context;
}
}
Dynamic JSON Keys Use a closure in the config to dynamically rename keys:
'json_keys' => [
'message' => fn($record) => strtoupper($record['message']),
],
Log Anonymization Sanitize sensitive data before JSON serialization:
\Log::info('User data', ['email' => 'user@example.com']);
// Override in handler:
protected function getContext(array $context): array
{
$context['email'] = '*****@example.com';
return $context;
}
How can I help you explore Laravel packages today?