Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Symfony Messenger Queue Events Bundle Laravel Package

halloverden/symfony-messenger-queue-events-bundle

Symfony bundle that adds queue lifecycle events to Messenger. Hook into message dispatching, processing, success and failure to add logging, metrics or monitoring without touching your handlers. Works with any transport via the existing event dispatcher.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check before you install. This is a Symfony bundle, not a Laravel package — it extends symfony/messenger, which Laravel does not use for its own queue system. It's only relevant if you're running Symfony Messenger inside a Laravel app (rare, usually via a bridge or a shared codebase), or if you're maintaining both a Laravel and a Symfony service. If you're on Laravel's native queues, stop here and use JobProcessing / JobProcessed / JobFailed instead.

Minimal steps (Symfony side):

  1. composer require halloverden/symfony-messenger-queue-events-bundle
  2. Register it in config/bundles.php:
    HalloVerden\MessengerQueueEventsBundle\MessengerQueueEventsBundle::class => ['all' => true],
    
  3. Confirm symfony/messenger is configured with at least one transport — the bundle is useless without one.
  4. Build a listener for one event and watch the log stream while consuming a queue.

Where to look first. Open src/ and find the event classes (typically under Event/ or Events/) and the subscriber/listener that dispatches them. That subscriber is the contract: it tells you exactly which lifecycle points are covered, what payload each event carries, and whether dispatch is wrapped in a try/catch. Read DependencyInjection/ for any config tree — many small bundles have a single toggle for enabling/disabling dispatch.

First use case. Structured audit logging: listen to the "message queued/sent" event, log message class + transport name + message id as JSON, and ship it to whatever log aggregator you use. It's low-risk, proves the wiring works, and immediately gives you visibility you didn't have.

Implementation Patterns

Listener with the attribute, not YAML. Assuming Symfony 5.3+/6.x:

#[AsEventListener(event: MessageQueuedEvent::class)]
final class LogQueuedMessage
{
    public function __construct(private LoggerInterface $logger) {}

    public function __invoke(MessageQueuedEvent $event): void
    {
        $this->logger->info('messenger.queued', [
            'message' => $event->getEnvelope()->getMessage()::class,
            'transport' => $event->getEnvelope()->getReceivedFrom()?->__toString(),
        ]);
    }
}

Adjust the accessors to whatever the bundle actually exposes — this is the main thing to verify against the source. Ensure your services.yaml has _defaults: autoconfigure: true so #[AsEventListener] is picked up.

The four patterns that pay for themselves:

Pattern Trigger Why
Metrics counters queued / processed / failed Feed Prometheus/StatsD; alert on failure rate per transport
Correlation IDs queued Stamp a UUID into a header/stamp, propagate into logs downstream
Dead-letter alerting failed/retried Catch poison messages before they silently vanish
Integration tests any Assert an event fired with a TraceableEventDispatcher

Keep listeners dumb and fast. These fire inside the consumer loop. A listener that does a synchronous HTTP call or a heavy DB write will directly throttle your throughput. Buffer into an in-memory array and flush every N messages, or republish onto a dedicated (low-priority) transport.

Wrap it in your own adapter. Create a small MessengerAudit service that takes the bundle's events and exposes your domain API (onQueued, onFailed). When the bundle inevitably drifts or you swap it for hand-rolled middleware, only the adapter changes.

Combine with core Messenger events. The bundle earns its keep by covering gaps in Messenger's built-in WorkerMessageFailedEvent, SendMessageToTransportEvent, etc. Register both, but de-duplicate in your metrics layer — otherwise a failed message with three retries counts as four failures.

Testing. Use messenger:consume --limit=1 in a functional test, and assert against a spy listener. For unit tests, instantiate the event directly rather than booting a kernel.

Gotchas and Tips

  • Zero stars, zero dependents. That's not a disqualifier, but it means no community validation, no StackOverflow answers, and no guarantee of a Symfony 7 upgrade. Pin the exact version in composer.json, read every line of src/ before trusting it in production, and keep a fork path open. Check the composer.json constraints against your PHP and Symfony versions first — this is the #1 install failure.
  • Not Laravel-native. Don't try to shoehorn it into a standard Laravel app. Laravel's equivalents (Illuminate\Queue\Events\*, Queue::before, Queue::failing) are richer for the Laravel queue driver; mixing the two means two event systems and no shared context.
  • No request context in the worker. Events fire in the consumer process, so Auth::user(), tenant resolvers, and request-scoped bindings are all gone. Anything you need must be serialized into the message (headers/stamps) at dispatch time.
  • Retries re-emit. A message retried three times will fire your "queued" and "failed" listeners three times. Deduplicate by message ID, or your metrics will lie.
  • Listener exceptions may or may not be fatal. Check whether the bundle dispatches with a plain dispatch() (your exception can kill the worker) or wraps it. If it's the former, wrap every listener body in try/catch and log the failure — never let an audit listener take down message consumption.
  • Autoconfiguration is the usual culprit when "nothing happens." Verify your src/EventSubscriber (or wherever listeners live) is in a resource-loaded path in services.yaml; if not, tag explicitly with kernel.event_listener.
  • Extension point worth knowing: decorate the bundle's dispatcher service rather than subclassing it. It's the cleanest way to add a no-op mode for local dev, where you likely don't want six log lines per message.
  • Disable in dev. If there's a config toggle in the extension, turn it off for dev and test and only enable it in prod — the event volume on a busy queue is genuinely noisy.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib