zenstruck/messenger-monitor-bundle
Symfony bundle to monitor Symfony Messenger: track dispatched messages, handlers, retries and failures with a built-in dashboard and persistence. Helps debug async workflows and gain insight into queue activity in dev or production.
Installation Add the bundle via Composer:
composer require zenstruck/messenger-monitor-bundle
Register the bundle in config/bundles.php (Symfony) or ensure it’s auto-discovered (Laravel).
Publish Assets Run:
php artisan vendor:publish --provider="Zenstruck\MessengerMonitorBundle\MessengerMonitorBundle" --tag="assets"
This generates the UI assets in public/build/messenger-monitor.
Enable the Bundle
Add the route to your routes/web.php (Laravel) or config/routes.yaml (Symfony):
use Zenstruck\MessengerMonitorBundle\MessengerMonitorBundle;
// Laravel
MessengerMonitorBundle::routes($router);
// Symfony
messenger_monitor:
resource: "@MessengerMonitorBundle/Resources/config/routing.yaml"
First Use Case
Visit /_messenger-monitor (or your configured path) to see:
Monitoring Workers
prod, staging) via query params:
/_messenger-monitor?env=prod
Debugging Stuck Messages
status:failed.Transport Management
max_retries) via config:
# config/messenger.yaml
transports:
async:
dsn: "sync://"
options:
max_retries: 5
Scheduling Inspection
schedule:run or Symfony’s messenger:consume commands.Performance Tuning
MESSENGER_WORKERS env vars:
MESSENGER_WORKERS=4 php artisan messenger:consume async --env=prod
message_type:App\Notifications\*).MessageBus—no extra config needed.vendor/zenstruck/messenger-monitor-bundle/Resources/views) to add custom fields (e.g., user IDs for logged-in workers).MessengerMonitorBundle\Monitor\Monitor service to build custom CLI tools:
$monitor = $this->container->get('messenger_monitor.monitor');
$workers = $monitor->getWorkers();
Permission Issues
/_messenger-monitor route requires ROLE_MESSENGER_MONITOR by default.// Laravel (app/Http/Kernel.php)
'web' => [
\Zenstruck\MessengerMonitorBundle\Http\Middleware\Authenticate::class,
// ...
];
# config/packages/security.yaml
access_control:
- { path: ^/_messenger-monitor, roles: ROLE_MESSENGER_MONITOR }
Worker Visibility Lag
Message Retention
php artisan messenger:failed-table:purge --hours=72
Transport-Specific Quirks
doctrine/messenger bundle.Custom Message Classes
Serializable or use #[AsMessage] attribute).config/messenger.php for serializer settings.MESSENGER_LOG_LEVEL to debug for verbose worker logs.// config/packages/twig.yaml
debug: '%kernel.debug%'
php artisan messenger:failed-table:dump --path=/tmp/failed_messages.json
Custom Tabs
Add new tabs by extending the MessengerMonitorBundle\Monitor\Monitor service and overriding the getTabs() method.
Message Metadata Attach custom metadata to messages via middleware:
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
#[AsMessageHandler]
public function handle(MyMessage $message, MessageBusInterface $bus) {
$message->setMetadata(['custom_key' => 'value']);
}
Theming Override the default Twig templates by publishing them:
php artisan vendor:publish --provider="Zenstruck\MessengerMonitorBundle\MessengerMonitorBundle" --tag="templates"
Then modify resources/views/messenger-monitor/.
API Endpoints
Create custom API routes using the Monitor service:
use Zenstruck\MessengerMonitorBundle\Monitor\Monitor;
public function workerStats(Monitor $monitor) {
return response()->json($monitor->getWorkers());
}
How can I help you explore Laravel packages today?