PHPackages                             michallkanak/symfony-message-flow-visualizer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. michallkanak/symfony-message-flow-visualizer

ActiveSymfony-bundle[Queues &amp; Workers](/categories/queues)

michallkanak/symfony-message-flow-visualizer
============================================

Visual tracing and debugging tool for Symfony Messenger - track message flows, visualize DAG graphs, and analyze async processing

0.1.0(4mo ago)711[5 PRs](https://github.com/michallkanak/symfony-message-flow-visualizer/pulls)MITPHPPHP &gt;=8.2CI passing

Since Jan 5Pushed 4mo agoCompare

[ Source](https://github.com/michallkanak/symfony-message-flow-visualizer)[ Packagist](https://packagist.org/packages/michallkanak/symfony-message-flow-visualizer)[ RSS](/packages/michallkanak-symfony-message-flow-visualizer/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (11)Versions (2)Used By (0)

Message Flow Visualizer for Symfony Messenger (Beta)
====================================================

[](#message-flow-visualizer-for-symfony-messenger-beta)

[![CI](https://github.com/michallkanak/symfony-message-flow-visualizer/actions/workflows/ci.yml/badge.svg)](https://github.com/michallkanak/symfony-message-flow-visualizer/actions/workflows/ci.yml)[![PHP 8.2](https://camo.githubusercontent.com/edc2fe5e63944581d97b5f25f468b5b1b2cd71914b9e16836d9978609669d6b0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e322d626c7565)](https://www.php.net/)[![PHP 8.3](https://camo.githubusercontent.com/54b7804384d76a107e2ed3874a2715c33f236220aba6986869de4a3db326eb40/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e332d626c7565)](https://www.php.net/)[![PHP 8.4](https://camo.githubusercontent.com/e0116062178c4560000df4990a7f47f8191778aa382b463b1ee1dc68ffd93044/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e342d626c7565)](https://www.php.net/)[![Symfony 6.4|7.x](https://camo.githubusercontent.com/207c77f8153dcfe889a5b2580d361eefffbdf54af62759f60951c9a5e308993e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73796d666f6e792d362e34253230253743253230372e782d707572706c65)](https://symfony.com/)[![PHPStan Level 8](https://camo.githubusercontent.com/44dc5f71fec76653887c975fe3db546a82ff603d094798eb6414a38369db1f44/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068707374616e2d6c6576656c253230382d627269676874677265656e)](https://phpstan.org/)[![License MIT](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](LICENSE)

Visual tracing and debugging tool for Symfony Messenger. Track message flows, visualize DAG graphs, analyze async processing, and debug message chains.

Features
--------

[](#features)

- 📊 **Flow Graph Visualization** - Interactive DAG diagrams showing message relationships
- ⏱️ **Timeline View** - Jaeger-style timeline with processing and queue wait times
- 🔍 **Symfony Profiler Integration** - Dedicated panel in the web debug toolbar
- 💻 **CLI Commands** - Inspect flows from the command line
- 📈 **Statistics** - Track message patterns and performance
- 🔗 **Parent-Child Tracking** - Trace message chains with correlation IDs
- ⚡ **Dual Timing Metrics** - Separate processing time vs queue wait time
- 🎯 **Sampling Support** - Production-safe with configurable sampling

Screenshots
-----------

[](#screenshots)

### Dashboard - Flow List

[](#dashboard---flow-list)

[![Dashboard showing list of message flows](docs/images/dashboard_list.png)](docs/images/dashboard_list.png)

### Flow Graph Visualization

[](#flow-graph-visualization)

[![Interactive DAG graph showing message relationships with async markers](docs/images/flow_graph.png)](docs/images/flow_graph.png)

### Timeline View

[](#timeline-view)

[![Jaeger-style timeline with processing and queue wait times](docs/images/timeline_view.png)](docs/images/timeline_view.png)

### Steps Table

[](#steps-table)

[![Detailed table with message, handler, transport, status and timing info](docs/images/steps_table.png)](docs/images/steps_table.png)

### Symfony Profiler Integration

[](#symfony-profiler-integration)

[![Message Flow panel integrated in Symfony Profiler](docs/images/profiler_graph.png)](docs/images/profiler_graph.png)

### Profiler Timeline

[](#profiler-timeline)

[![Timeline view in Symfony Profiler showing message timing](docs/images/profiler_timeline.png)](docs/images/profiler_timeline.png)

### Profiler Steps Table

[](#profiler-steps-table)

[![Steps table in Symfony Profiler with all message details](docs/images/profiler_steps.png)](docs/images/profiler_steps.png)

Installation &amp; Configuration
--------------------------------

[](#installation--configuration)

```
composer require michallkanak/symfony-message-flow-visualizer
```

Register the bundle:

```
// config/bundles.php
return [
    // ...
    MichalKanak\MessageFlowVisualizerBundle\MessageFlowVisualizerBundle::class => ['all' => true],
];
```

Add to your environment:

```
# .env
MESSAGE_FLOW_ENABLED=true
```

Create configuration file:

```
# config/packages/message_flow_visualizer.yaml
message_flow_visualizer:
    enabled: '%env(bool:MESSAGE_FLOW_ENABLED)%'
    storage:
        type: filesystem  # filesystem | doctrine | redis | memory
        path: '%kernel.project_dir%/var/message_flow'  # for filesystem
        connection: 'default'  # for redis/doctrine
    sampling:
        enabled: false    # Enable for production
        rate: 0.01        # 1% of flows when sampling enabled
    cleanup:
        retention_days: 7
    slow_threshold_ms: 500  # Mark flows >500ms as slow
```

### Full Configuration Reference

[](#full-configuration-reference)

```
message_flow_visualizer:
    # Enable/disable the bundle (default: env MESSAGE_FLOW_ENABLED)
    enabled: true

    # Storage backend configuration
    storage:
        # Storage type: filesystem, doctrine, redis, memory
        type: filesystem

        # Path for filesystem storage (default: %kernel.project_dir%/var/message_flow)
        path: '%kernel.project_dir%/var/message_flow'

        # Connection name for doctrine/redis (default: 'default')
        # For Redis: 'redis://localhost:6379' or 'redis://user:pass@host:6379'
        connection: 'default'

    # Sampling configuration - recommended for production
    sampling:
        # Enable to track only a percentage of flows (default: false)
        enabled: false

        # Percentage of flows to track: 0.01 = 1%, 0.1 = 10%, 1.0 = 100%
        # When a flow is sampled, ALL nested messages are tracked (sampling continuity)
        rate: 0.01

    # Data cleanup settings
    cleanup:
        # Days to keep flow data before cleanup command removes it (default: 7)
        retention_days: 7

    # Performance threshold - flows exceeding this are marked as slow (default: 500)
    slow_threshold_ms: 500
```

### Environment-specific Examples

[](#environment-specific-examples)

**Development** (full tracking):

```
# config/packages/dev/message_flow_visualizer.yaml
message_flow_visualizer:
    enabled: true
    storage:
        type: filesystem
    sampling:
        enabled: false  # Track all flows
    slow_threshold_ms: 2000  # Higher threshold for dev
```

**Production** (sampling + Doctrine):

```
# config/packages/prod/message_flow_visualizer.yaml
message_flow_visualizer:
    enabled: true
    storage:
        type: doctrine
    sampling:
        enabled: true
        rate: 0.01  # 1% sampling
    cleanup:
        retention_days: 30
    slow_threshold_ms: 1000
```

**Production** (sampling + Redis):

```
# config/packages/prod/message_flow_visualizer.yaml
message_flow_visualizer:
    enabled: true
    storage:
        type: redis
        connection: '%env(REDIS_URL)%'
    sampling:
        enabled: true
        rate: 0.05  # 5% sampling
```

**Test** (in-memory):

```
# config/packages/test/message_flow_visualizer.yaml
message_flow_visualizer:
    enabled: true
    storage:
        type: memory  # No persistence, fast for tests
```

Register the middleware:

```
# config/packages/messenger.yaml
framework:
    messenger:
        buses:
            messenger.bus.default:
                middleware:
                    - MichalKanak\MessageFlowVisualizerBundle\Middleware\TraceMiddleware
```

Usage
-----

[](#usage)

### Symfony Profiler

[](#symfony-profiler)

The bundle automatically adds a "Message Flow" panel to the Symfony Profiler showing:

- Flow graph visualization
- Timeline view with timing breakdown
- List of all message steps with details

### CLI Commands

[](#cli-commands)

```
# List recent flows
bin/console messenger:flow:list --limit=20 --status=failed

# List with pagination
bin/console messenger:flow:list --limit=10 --page=2

# Show only slow flows
bin/console messenger:flow:list --slow

# Filter by message class
bin/console messenger:flow:list --message-class=OrderMessage

# Show specific flow details
bin/console messenger:flow:show --id=abc12345

# Show flow by trace ID
bin/console messenger:flow:show --trace=xyz789

# View statistics
bin/console messenger:flow:stats --from="1 hour ago"

# Cleanup old data
bin/console messenger:flow:cleanup --older-than="7 days"

# Dry-run cleanup (preview what would be deleted)
bin/console messenger:flow:cleanup --older-than="7 days" --dry-run
```

### Optional Dashboard

[](#optional-dashboard)

The bundle includes an optional web dashboard. To enable it, add routing:

```
# config/routes/message_flow.yaml
message_flow:
    resource: '@MessageFlowVisualizerBundle/src/Controller/'
    type: attribute
```

Then access at `/message-flow/`.

Storage Options
---------------

[](#storage-options)

The bundle supports multiple storage backends for persisting flow data. Choose based on your needs:

StorageBest ForPersistenceSetup Effort**Filesystem**Development, simple deploymentsFile-basedNone**Redis**High-performance, distributed systemsIn-memory with TTLLow**Doctrine**Production, long-term analyticsDatabaseMedium**InMemory**Testing onlyNone (request-scoped)None### Filesystem (Default)

[](#filesystem-default)

Zero configuration required. Stores JSON files in your project directory.

```
# config/packages/message_flow_visualizer.yaml
message_flow_visualizer:
    enabled: true
    storage:
        type: filesystem
        path: '%kernel.project_dir%/var/message_flow'
```

**Setup:** None required. Directory is created automatically.

**Cleanup:**

```
bin/console messenger:flow:cleanup --older-than="7 days"
```

---

### Redis

[](#redis)

Fast, ephemeral storage with automatic TTL-based cleanup. Requires [predis/predis](https://github.com/predis/predis).

**1. Install Predis:**

```
composer require predis/predis
```

**2. Configure bundle:**

```
# config/packages/message_flow_visualizer.yaml
message_flow_visualizer:
    enabled: true
    storage:
        type: redis
        connection: 'redis://localhost:6379'
        # Or with password: 'redis://user:password@localhost:6379'
```

**3. Configure Predis service (optional, for custom options):**

```
# config/services.yaml
services:
    Predis\Client:
        arguments:
            - '%env(REDIS_URL)%'
```

**Note:** Data expires automatically based on TTL (default: 7 days).

---

### Doctrine

[](#doctrine)

Persistent database storage with full query capabilities. Uses your existing Doctrine connection.

**1. Configure bundle:**

```
# config/packages/message_flow_visualizer.yaml
message_flow_visualizer:
    enabled: true
    storage:
        type: doctrine
```

**2. Generate and run migrations:**

```
# Generate migration for bundle tables
bin/console doctrine:migrations:diff

# Run migrations
bin/console doctrine:migrations:migrate
```

This creates two tables:

- `mfv_flow_run` - Flow runs with indexes on `trace_id`, `started_at`, `status`
- `mfv_flow_step` - Steps with foreign key to flow runs

**Cleanup:**

```
bin/console messenger:flow:cleanup --older-than="30 days"
```

---

### InMemory (Testing Only)

[](#inmemory-testing-only)

⚠️ **WARNING:** Not suitable for production with async messages!

Data is stored only in PHP process memory and lost when process ends. Since Messenger workers run in separate processes, async message statuses will NOT be updated.

```
# config/packages/message_flow_visualizer.yaml (test environment only)
message_flow_visualizer:
    enabled: true
    storage:
        type: memory
```

**Use cases:**

- Unit and integration tests
- Development with synchronous transport only

Timing Metrics
--------------

[](#timing-metrics)

Each message step tracks:

- **Processing Duration** - Time spent in the handler
- **Queue Wait Duration** - Time waiting in async queue
- **Total Duration** - Sum of both

```
[dispatch] ----[queue wait]---- [processing] [complete]
            ↑                   ↑
            queueWaitDurationMs processingDurationMs
            ←───────── totalDurationMs ──────────→

```

Sampling for Production
-----------------------

[](#sampling-for-production)

Enable sampling to reduce overhead in production:

```
message_flow_visualizer:
    sampling:
        enabled: true
        rate: 0.01  # Track 1% of flows
```

**Important**: When a flow is sampled, ALL related messages are tracked (sampling continuity). No fragmented traces.

Data Model
----------

[](#data-model)

### FlowRun

[](#flowrun)

Represents a complete message flow:

FieldDescriptionidUnique identifiertraceIdCorrelation ID for distributed tracingstatusrunning / completed / failedstartedAtFlow start timestampfinishedAtFlow end timestampinitiatorWhat triggered the flow (HTTP request, CLI, etc.)### FlowStep

[](#flowstep)

Represents a single message dispatch/handling:

FieldDescriptionmessageClassFQCN of the messagehandlerClassFQCN of the handlertransportsync / doctrine / redis / rabbitmqisAsyncWhether processed asynchronouslystatuspending / handled / failed / retriedprocessingDurationMsHandler execution timequeueWaitDurationMsTime in queue (async only)totalDurationMsTotal time from dispatch to completeTechnologies Used
-----------------

[](#technologies-used)

### Graph Visualization

[](#graph-visualization)

The bundle uses **native SVG with JavaScript** for rendering interactive DAG (Directed Acyclic Graph) visualizations:

- **SVG-based rendering** - Lightweight, no external dependencies required
- **Hierarchical layout** - Automatic tree-like positioning for message flows
- **Interactive tooltips** - Hover over nodes to see message details, handler info, and timing metrics
- **Async indicators** - Visual distinction between sync and async message processing
- **Responsive design** - Graphs automatically adjust to container size

The graph visualization is implemented in vanilla JavaScript to minimize bundle dependencies and ensure maximum compatibility with Symfony projects.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Symfony 6.4 or 7.x
- Symfony Messenger component

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

Contributing
------------

[](#contributing)

Contributions are welcome! Please read the contributing guidelines before submitting PRs.

Credits
-------

[](#credits)

Created by [Michał Kanak](https://github.com/michallkanak)

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance77

Regular maintenance activity

Popularity8

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

127d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/35bdeeb4e748dac6cbbc8369be22264af99743a23bb39c033b760385663a6dc1?d=identicon)[michal.kanak](/maintainers/michal.kanak)

---

Top Contributors

[![michallkanak](https://avatars.githubusercontent.com/u/12290176?v=4)](https://github.com/michallkanak "michallkanak (2 commits)")

---

Tags

asyncsymfonyprofilerdebuggingtracingMessengervisualizationmessage-flow

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/michallkanak-symfony-message-flow-visualizer/health.svg)

```
[![Health](https://phpackages.com/badges/michallkanak-symfony-message-flow-visualizer/health.svg)](https://phpackages.com/packages/michallkanak-symfony-message-flow-visualizer)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[contao/core-bundle

Contao Open Source CMS

1231.6M2.4k](/packages/contao-core-bundle)[jwage/phpamqplib-messenger

Symfony messenger transport for the php-amqplib/php-amqplib library.

84149.7k1](/packages/jwage-phpamqplib-messenger)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

7310.3k29](/packages/open-dxp-opendxp)[rcsofttech/audit-trail-bundle

Enterprise-grade, high-performance Symfony audit trail bundle. Automatically track Doctrine entity changes with split-phase architecture, multiple transports (HTTP, Queue, Doctrine), and sensitive data masking.

1022.4k](/packages/rcsofttech-audit-trail-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
