event-engine/php-logger
Event Engine Logger for PHP: a lightweight logging package designed to integrate with Event Engine applications. Provides simple logger setup for capturing and routing application events and messages in your PHP services.
Installation
composer require event-engine/php-logger
Add to config/app.php under providers:
EventEngine\Logger\LoggerServiceProvider::class,
Publish config (optional but recommended):
php artisan vendor:publish --provider="EventEngine\Logger\LoggerServiceProvider"
Basic Usage Inject the logger via dependency injection:
use EventEngine\Logger\Logger;
class MyService {
public function __construct(private Logger $logger) {}
public function doSomething() {
$this->logger->info("User action triggered", ['user_id' => 123]);
}
}
First Use Case
Replace Log::info() with the structured logger for consistency:
// Before
Log::info('User logged in', ['user_id' => 123]);
// After
$this->logger->info('User logged in', ['user_id' => 123]);
Contextual Logging Attach metadata (e.g., request IDs, user IDs) via middleware:
$this->logger->withContext(['request_id' => $request->header('X-Request-ID')])
->info('Processing order', ['order_id' => $orderId]);
Error Handling
Use error() with exceptions:
try {
$this->processPayment();
} catch (\Exception $e) {
$this->logger->error('Payment failed', [
'exception' => $e,
'user_id' => auth()->id(),
]);
}
Performance Logging
Time operations with start()/stop():
$this->logger->start('database.query');
DB::table('users')->get();
$this->logger->stop('database.query', ['query_time_ms' => 150]);
Monolog Bridge: Extend existing Monolog handlers:
$handler = new \Monolog\Handler\StreamHandler(storage_path('logs/app.log'));
$this->logger->addHandler($handler);
Laravel Facade: Create a facade for convenience:
// app/LoggerFacade.php
namespace App;
use EventEngine\Logger\Logger;
use Illuminate\Support\Facades\Facade;
class LoggerFacade extends Facade {
protected static function getFacadeAccessor() { return 'logger'; }
}
Now use Logger::info() globally.
Queue Logs: Offload logs to a queue for async processing:
$this->logger->queue('critical', 'System down', ['service' => 'auth']);
Context Leakage
Avoid logging sensitive data (e.g., passwords) in contexts. Use withContext() sparingly:
// ❌ Bad
$this->logger->withContext(['password' => $request->password])->info('Login');
// ✅ Good
$this->logger->info('Login attempt', ['username' => $request->username]);
Performance Overhead Structured logging adds serialization overhead. Disable in production for non-critical logs:
$this->logger->setLevel(\Monolog\Logger::WARNING); // Only log warnings+
Handler Conflicts
Ensure no duplicate handlers are added (e.g., both StreamHandler and SyslogHandler writing to the same file).
debug() for development, info()/warning() for production.error() for automatic stack trace inclusion:
$this->logger->error('Failed', ['exception' => $e]); // Auto-includes trace
maxFiles in config/logger.php to prevent disk bloat:
'handlers' => [
'single' => [
'class' => \Monolog\Handler\StreamHandler::class,
'stream' => storage_path('logs/app.log'),
'maxFiles' => 30, // Rotate after 30 files
],
],
Custom Handlers
Extend EventEngine\Logger\Handler\AbstractHandler to create domain-specific loggers (e.g., SlackHandler):
class SlackHandler extends AbstractHandler {
public function handle(array $record) {
$this->client->send($record['message'], $record['context']);
}
}
Log Filters Filter logs before processing:
$this->logger->addFilter(function ($record) {
return !str_contains($record['message'], 'sensitive_data');
});
Dynamic Context Use closures for lazy context evaluation:
$this->logger->withContext(fn() => ['memory_usage' => memory_get_usage()])
->info('System health check');
How can I help you explore Laravel packages today?