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

Workflow Logger Bundle Laravel Package

fintem/workflow-logger-bundle

Fintem Workflow Logger Bundle adds structured logging around workflow transitions and events, making it easier to trace state changes, debug process flows, and audit activity in PHP applications. Capture context-rich records for every workflow step and troubleshoot issues faster.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the mismatch. This is a Symfony bundle, not a Laravel package. It has no service provider, no facade, no config/workflow-logger.php. It ships a Symfony Bundle class, a DependencyInjection extension, and Resources/config/services.xml — none of which Laravel's container knows how to boot. As a Laravel developer you have three realistic entry points:

  1. You've inherited a Symfony service that uses Symfony Workflow and this bundle is already in its composer.json.
  2. You want the behaviour (audit every state transition) in a Laravel app and are evaluating whether to reuse the code.
  3. You're bridging the two — a Symfony sidecar that owns the state machine, called from Laravel.

Look here first in vendor/fintem/workflow-logger-bundle/:

  • src/DependencyInjection/*Extension.php — the config tree (channel name, enable/disable flags).
  • Resources/config/services.xml (or services.yaml) — this tells you exactly which classes are registered and what they're injected with. This is the whole package in one file.
  • The event subscriber/listener class — it almost certainly subscribes to Symfony\Component\Workflow\Event\Event via WorkflowEvents::TRANSITION, ::ENTERED, ::COMPLETED, etc., and writes to a PSR-3 logger.

Minimal first use case: log order: pending → paid → shipped transitions with the actor and a timestamp, into a dedicated channel you can grep. Do not start by trying to register the bundle.

composer require symfony/workflow   # the component works fine without Symfony
composer require fintem/workflow-logger-bundle  # read it, don't boot it

The symfony/workflow component is framework-agnostic — DefinitionBuilder, MethodMarkingStore, Registry, and a standalone Symfony\Component\EventDispatcher\EventDispatcher all instantiate cleanly inside a Laravel service provider. That is the useful half. The bundle is just 100-ish lines of wiring around it.

Implementation Patterns

Pattern A — port the subscriber, keep the semantics. Read the listener, then rewrite it as a Laravel-flavoured class that takes Psr\Log\LoggerInterface (Laravel's Log manager resolves to a PSR-3 Logger, so injection is free):

class WorkflowLogSubscriber implements EventSubscriberInterface
{
    public function __construct(private LoggerInterface $logger) {}

    public static function getSubscribedEvents(): array
    {
        return [
            WorkflowEvents::TRANSITION => 'onTransition',
            WorkflowEvents::ENTERED    => 'onEntered',
        ];
    }

    public function onTransition(Event $event): void
    {
        $this->logger->info('workflow.transition', [
            'workflow'   => $event->getWorkflowName(),
            'subject'    => $event->getSubject()::class,
            'subject_id' => $event->getSubject()->getId(),
            'transition' => $event->getTransition()->getName(),
            'from'       => array_keys($event->getMarking()->getPlaces()),
            'to'         => $event->getTransition()->getTos(),
        ]);
    }
}

Register it in a WorkflowServiceProvider and attach it to the shared Symfony EventDispatcher you pass into each workflow — not to Laravel's dispatcher directly. The two are different objects; confusing them is the single most common integration bug.

Pattern B — structured audit table instead of log files. Log files are fine for debugging, useless for "who moved this order and when." Mirror the subscriber into an workflow_transitions Eloquent model (subject_type, subject_id, transition, from, to, actor_id, context JSON, created_at). Keep the PSR-3 call as well, at debug level, so you get both.

Pattern C — dedicated channel. Add config/logging.php → 'workflow' => ['driver' => 'daily', 'path' => storage_path('logs/workflow.log'), 'days' => 30] and point the subscriber at it. The bundle's extension typically exposes a channel/logger config key; replicate that as a constructor arg rather than a hardcoded Log::channel().

Pattern D — Symfony sidecar. If the state machine genuinely lives in a Symfony app, let the bundle do its job there (register in bundles.php, configure the channel under fintem_workflow_logger:), and have Laravel consume the resulting audit table or a queue message. Don't proxy workflow calls over HTTP just to get logging.

Testing. With Log::spy() (or Log::shouldReceive('info')), assert exact payload shape — workflow, transition, from, to — for one happy path and one guard-rejected path. Guard rejections fire WorkflowEvents::GUARD and never reach TRANSITION, so your audit trail silently misses failed attempts unless you subscribe to that too.

Gotchas and Tips

  • Last release 2018-02-19, 1 star, 0 dependents. Assume composer.json pins php: ^7.0 and symfony/symfony: ^3.4. On PHP 8.2+ you'll get deprecation noise at best and a hard constraint conflict at worst. Force-install only if you're reading the source, never in production.
  • No Laravel auto-discovery. Without a LaravelServiceProvider in extra.laravel.providers, composer require gives you nothing but files on disk. Everything is manual.
  • The bundle kernel is dead weight in Laravel. Extension::load(), services.xml, and any CompilerPass never execute. Don't spend time trying to make config/packages/fintem_workflow_logger.yaml equivalent work — just instantiate the listener yourself.
  • Log volume. announce, entered, completed, and transition all fire per hop. A four-place workflow generates roughly four events per transition. Filter by event type at the subscriber level, not by log level after the fact.
  • PII in context. $event->getContext() is whatever you put there — often the full subject or request payload. Strip it or whitelist keys before logging.
  • getMarking() timing. On TRANSITION the marking is pre-transition; on ENTERED it's post. Getting from/to from the wrong event produces logs that contradict each other.
  • Debugging "no logs". In Symfony: bin/console debug:event-dispatcher. In Laravel: confirm the subscriber is attached to the dispatcher instance actually passed to new Workflow(...) — a Registry built with a fresh dispatcher per workflow is a classic silent failure.
  • Extension points. The only genuinely reusable pieces are the subscriber's payload schema and its event selection. Everything else — config tree, service definitions — is four lines of Laravel you'd write anyway.
  • Recommendation. Vendor the listener into app/Workflows/ (it's MIT, ~100 lines) and drop the dependency. You get the same audit trail, PHP 8 compatibility, and no abandoned package in your composer.lock — which matters more than 1 star suggests when a security scanner flags it in 2026.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo