drinks-it/sf-consumer-logger-bundle
Installation
composer require drinks-it/sf-consumer-logger-bundle
Ensure your Symfony project is configured to autoload the bundle (check config/bundles.php).
Enable the Bundle
Add the bundle to your config/bundles.php:
return [
// ...
DrinksIt\SfConsumerLoggerBundle\SfConsumerLoggerBundle::class => ['all' => true],
];
Basic Configuration
Override default settings in config/packages/sf_consumer_logger.yaml:
sf_consumer_logger:
on_start: info
on_start_message: 'Consumer started'
on_stop: warning
on_stop_message: 'Consumer stopped gracefully'
First Use Case
Integrate with a Symfony Messenger consumer (e.g., Command or Worker). The bundle logs lifecycle events automatically when the consumer starts/stops.
Consumer Command Integration
Extend Symfony\Component\Messenger\Command\ConsumeMessagesCommand or use a custom worker. The bundle hooks into Symfony’s event system (kernel.terminate, kernel.request, etc.) to log transitions.
Example:
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Messenger\Command\ConsumeMessagesCommand;
class CustomConsumer extends ConsumeMessagesCommand
{
protected static $defaultName = 'app:consume-custom';
protected function configure(): void
{
$this->setDescription('Process custom messages with logging');
}
}
Dynamic Logging Levels
Use placeholders in on_start_message/on_stop_message to include dynamic data:
sf_consumer_logger:
on_start_message: 'Consumer "%name%" started for queue "%queue%"'
Access via Twig or PHP in your consumer logic.
Asynchronous Workers
For background workers (e.g., symfony/process), wrap execution in a try-catch and log failures explicitly:
use Psr\Log\LoggerInterface;
class AsyncWorker
{
public function __construct(private LoggerInterface $logger)
{
}
public function run(): void
{
try {
// Worker logic
} catch (\Throwable $e) {
$this->logger->error('Worker failed', ['exception' => $e]);
}
}
}
Event-Driven Logging
Subscribe to SfConsumerLoggerEvents for custom logic:
use DrinksIt\SfConsumerLoggerBundle\Event\ConsumerEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CustomLoggerSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
'sf_consumer_logger.start' => 'onStart',
'sf_consumer_logger.stop' => 'onStop',
];
}
public function onStart(ConsumerEvent $event): void
{
// Custom logic (e.g., metrics, notifications)
}
}
Event Dispatcher Timing
exit() or uncaught exceptions), on_stop may not trigger. Use registerShutdownFunction() as a fallback:
register_shutdown_function(function () {
if (!\PHP_SAPI === 'cli') return;
$this->logger->warning('Consumer terminated unexpectedly');
});
Configuration Overrides
sf_consumer_logger.yaml are not merged with defaults. Explicitly define all keys to avoid null values overriding your expectations (e.g., on_running: null disables logging entirely).Logger Context
%queue%) require Twig or manual string replacement. For PHP, use:
on_start_message: 'Processing queue "%queue%"'
Then in your consumer:
$this->logger->info(str_replace('%queue%', $queueName, $config['on_start_message']));
Performance Impact
info/debug levels during high-throughput consumers may slow processing. Use on_running: null to disable mid-execution logs:
sf_consumer_logger:
on_running: null # Disable "running" logs
Environment-Specific Logging
Use %kernel.environment% in messages to tailor logs to dev/staging/prod:
on_start_message: 'Consumer started in %kernel.environment%'
Structured Logging Pass context arrays for richer logs:
on_start_message: 'Consumer started'
In your consumer:
$this->logger->info($config['on_start_message'], [
'queue' => $queueName,
'worker' => $workerId,
'env' => $_ENV['APP_ENV'],
]);
Testing Mock the logger in tests to verify events:
$logger = $this->createMock(LoggerInterface::class);
$logger->expects($this->once())->method('info')->with('Consumer started');
$this->container->set('logger', $logger);
Extending the Bundle
# config/services.yaml
DrinksIt\SfConsumerLoggerBundle\Logger\ConsumerLogger:
arguments:
$decorated: '@logger'
$prefix: '[CONSUMER] '
How can I help you explore Laravel packages today?