PHPackages                             zerethonapp/flow-laravel - 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. zerethonapp/flow-laravel

ActiveLibrary

zerethonapp/flow-laravel
========================

Laravel instrumentation adapter for Flow real trace capture.

v0.1.0(yesterday)01↑2900%MITPHP ^8.1

Since Jul 22Compare

[ Source](https://github.com/zerethonapp/flow-laravel)[ Packagist](https://packagist.org/packages/zerethonapp/flow-laravel)[ RSS](/packages/zerethonapp-flow-laravel/feed)WikiDiscussions Synced today

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

 [![Flow logo](https://camo.githubusercontent.com/23b3781dd972fa4abff11ad8b52f8ab0701d102494c8891dae913017bcf95234/68747470733a2f2f666c6f772e7a65726574686f6e2e636f6d2f69636f6e2e737667)](https://camo.githubusercontent.com/23b3781dd972fa4abff11ad8b52f8ab0701d102494c8891dae913017bcf95234/68747470733a2f2f666c6f772e7a65726574686f6e2e636f6d2f69636f6e2e737667)

flow-laravel
============

[](#flow-laravel)

[![Tests](https://github.com/zerethonapp/flow-laravel/actions/workflows/tests.yml/badge.svg)](https://github.com/zerethonapp/flow-laravel/actions/workflows/tests.yml)[![License: MIT](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![PHP](https://camo.githubusercontent.com/092d545f529c0bc11f393035f40f9cced2c9db2a0d148532f4fc2aa5409dc992/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e312d3737374242342e737667)](composer.json)[![Packagist Version](https://camo.githubusercontent.com/bc5687c3abba1be83dca8625ea64c490b62136d196fb9ccb68aeee9a9624a1e9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7a65726574686f6e6170702f666c6f772d6c61726176656c2e737667)](https://packagist.org/packages/zerethonapp/flow-laravel)[![Packagist Downloads](https://camo.githubusercontent.com/c2a0ccc4fa86d33396d617558a8ae85dc2bd6898d8d0452ec178706e019e0619/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7a65726574686f6e6170702f666c6f772d6c61726176656c2e737667)](https://packagist.org/packages/zerethonapp/flow-laravel)

Laravel instrumentation adapter for Flow Phase 3 &amp; 4 (real runtime traces).

**Want to see it running before installing anything?**[flow-laravel-demo](https://github.com/zerethonapp/flow-laravel-demo) is a runnable Laravel app with 7 instrumented demo routes — clone it, `composer install`, and hit a route to see a real captured trace.

Contributing? See [CONTRIBUTING.md](CONTRIBUTING.md). Found a security issue? See [SECURITY.md](SECURITY.md), not a public issue. Release history: [CHANGELOG.md](CHANGELOG.md). This project follows the [Contributor Covenant](CODE_OF_CONDUCT.md).

Why Flow?
---------

[](#why-flow)

Most developers:

- ❌ Optimize database first (without proof)
- ❌ Guess bottlenecks based on intuition
- ❌ Rely on generic monitoring tools

**Flow shows the REAL bottleneck instantly:**

- ✅ Identifies actual slow operations
- ✅ Prevents wasted optimization effort
- ✅ Provides clear, explainable insights

### Real Example

[](#real-example)

Your request takes **100ms**. Where's the bottleneck?

**Without Flow:**

- Maybe add database index? 🤔
- Cache everything? 🤔
- Optimize queries? 🤔

**With Flow:**

```
╔═══════════════════════════════════════════════════════════════════════════╗
║                           FLOW EXECUTION ANALYSIS                         ║
╚═══════════════════════════════════════════════════════════════════════════╝

  Top Bottleneck:    UserService.fetch
  Duration:          90ms
  Impact:            90%
  Classification:    clear bottleneck

  Database:          2ms (2%)

```

**Conclusion:** Database is NOT the problem. Focus on service logic instead.

---

What this package does
----------------------

[](#what-this-package-does)

- **Zero-config**: Automatically captures HTTP requests after install
- Captures one real Laravel HTTP request as a Flow trace
- Produces real nodes and edges from runtime execution
- Stores trace records in `.zerethon/flow-history.json` (CLI-compatible format)
- Supports manual service/external instrumentation for v1 practicality
- Captures database query timings through Laravel's DB listener

Scope (v1)
----------

[](#scope-v1)

Included:

- request lifecycle node
- controller scoped node
- database query nodes
- manual service traces (`Flow::trace(...)`)
- manual external traces (`Flow::external(...)`)
- JSON storage compatible with `flow-cli scan/analyze`

Not included yet:

- distributed tracing
- queue/job tracing
- automatic service discovery
- UI/dashboard

Install
-------

[](#install)

```
composer require zerethonapp/flow-laravel
```

**That's it!** Flow will now automatically trace HTTP requests in every environment except `testing`.

Hit any route:

```
curl http://your-app.test/any-route
```

Check the trace:

```
cat .zerethon/flow-history.json
```

Or browse individual traces:

```
ls storage/flow-traces/
```

Zero-Config Experience
----------------------

[](#zero-config-experience)

By default, Flow:

- ✅ Automatically registers middleware globally
- ✅ Captures all HTTP requests (web + api)
- ✅ Captures controller execution
- ✅ Captures database queries
- ✅ Writes traces to `.zerethon/flow-history.json`
- ✅ Runs everywhere except `testing` (production included by default — see Connected Mode below)

**No code changes required.**

Connected Mode (Push Traces to Flow)
------------------------------------

[](#connected-mode-push-traces-to-flow)

By default, traces only ever land in the local `.zerethon/flow-history.json`file above (**Offline mode**) — nothing leaves your machine/server unless you configure Connected mode. To have every captured trace pushed automatically to Flow, get a project's credentials from the Flow dashboard (shown once, at project creation) and add them to `.env`:

```
FLOW_SERVER=https://flow-api.zerethon.com
FLOW_PROJECT_ID=
FLOW_SECRET_KEY=flw_sk_...
```

Then verify it's wired up correctly:

```
php artisan flow:install
```

That's it — no other code changes. Traces still write to the local file too (Connected mode is additive, not a replacement); if any of the three env vars are missing, Flow just skips the push silently and behaves exactly as it did before.

Production is enabled by default (`except_environments` only excludes `testing`, see Configuration below) — the three `FLOW_*` env vars above are all that's needed on a real deployed environment. If you want Flow off in a *specific* environment (e.g. a staging server you don't want traced), publish the config (`php artisan vendor:publish --tag=flow-config`) and add that environment to `except_environments` — this check runs before anything else in `FlowServiceProvider::boot()`, so an excluded environment gets zero overhead, not just a silenced push.

Building an adapter for a different language/framework? `flow-docs/ADAPTER_PROTOCOL.md` documents the exact wire contract this package's push implements — it's plain HTTP+JSON, no PHP/Laravel-specific mechanism involved.

Configuration (Optional)
------------------------

[](#configuration-optional)

Publish config if you want to customize behavior:

```
php artisan vendor:publish --tag=flow-config
```

The published config file at `config/flow.php` provides fine-grained control:

### Enable/Disable

[](#enabledisable)

```
// Explicitly enable or disable (null = auto-detect based on environment)
'enabled' => env('FLOW_ENABLED'),

// Environments where Flow should NOT run
'except_environments' => ['testing'],

// URI patterns to exclude from tracing
'except' => [
    'telescope*',
    'horizon*',
],

// Sample rate (0.0 - 1.0): trace only a percentage of requests
'sample_rate' => env('FLOW_SAMPLE_RATE', 1.0),
```

### Sources

[](#sources)

Control which data sources are active:

```
'sources' => [
    'request' => true,      // Request lifecycle
    'controller' => true,   // Controller execution
    'database' => true,     // Database queries
    'external' => true,     // External HTTP calls
],
```

### Source Options

[](#source-options)

Configure behavior per source:

```
'options' => [
    'database' => [
        'capture_sql' => false,      // Include SQL text in trace
        'capture_bindings' => false, // Include query bindings
    ],
],
```

### Storage

[](#storage)

```
'storage_path' => base_path('.zerethon/flow-history.json'),
'trace_directory' => storage_path('flow-traces'),
'max_records' => 1000,
```

Enable request capture middleware
---------------------------------

[](#enable-request-capture-middleware)

Add middleware alias `flow.trace` to routes you want to capture.

Example:

```
Route::middleware(['flow.trace'])->group(function () {
    Route::get('/orders/{id}', [OrderController::class, 'show']);
});
```

Manual service and external tracing
-----------------------------------

[](#manual-service-and-external-tracing)

Use the Facade:

```
use Zerethon\Flow\Laravel\Facades\Flow;

$order = Flow::traceService('OrderService.findOrder', function () use ($id) {
    return $this->orderService->findOrder($id);
});

$payload = Flow::traceExternal('BillingApi.charge', function () use ($order) {
    return Http::post('https://billing.example.com/charge', ['order_id' => $order->id])->json();
});
```

Or use the global helper:

```
flow()->traceService('UserService.findUser', fn () => $service->findUser($id));
```

Generic trace method:

```
Flow::trace('service', 'UserService.findUser', fn () => $service->findUser($id));
Flow::trace('external', 'PaymentApi.charge', fn () => $api->charge($amount));
```

Assisted Tracing
----------------

[](#assisted-tracing)

Flow provides multiple ways to make tracing easier and less verbose:

### Using the Traceable Trait

[](#using-the-traceable-trait)

Add the trait to your service classes:

```
use Zerethon\Flow\Laravel\Support\Traceable;

class UserService
{
    use Traceable;

    public function findUser(int $id): User
    {
        return $this->traceService('UserService.findUser', function () use ($id) {
            // Business logic here
            return User::find($id);
        });
    }

    public function syncWithExternalApi(): void
    {
        $this->traceExternal('ExternalUserApi.sync', function () {
            // External API call
            Http::post('https://api.example.com/sync');
        });
    }
}
```

### Using PHP Attributes (Future)

[](#using-php-attributes-future)

```
use Zerethon\Flow\Laravel\Support\Trace;

class OrderService
{
    #[Trace('service')]
    public function processOrder(int $orderId): void
    {
        // Automatically traced as "OrderService.processOrder"
    }

    #[Trace('external', 'PaymentAPI.charge')]
    public function chargePayment(float $amount): void
    {
        // Automatically traced with custom label
    }
}
```

**Note:** Attribute-based tracing requires additional AOP/interceptor setup and is not yet fully implemented.

Output format
-------------

[](#output-format)

Traces are appended to:

- `.zerethon/flow-history.json` (default)

Record shape matches Flow core storage:

- `traceId`
- `timestamp`
- `flow` (`schema_version`, `trace_id`, `nodes`, `edges`, `meta`)
- `result` (`status`, `totalTime`, `nodeCount`, `executedNodes`, optional `errors`)

Analyze with existing CLI
-------------------------

[](#analyze-with-existing-cli)

From the Laravel app root (where `.zerethon/flow-history.json` exists):

```
flow scan
flow analyze
flow status
```

Raw JSON mode:

```
flow scan --json
```

Demo scenario (real request trace)
----------------------------------

[](#demo-scenario-real-request-trace)

Use middleware + manual service/external blocks:

```
// routes/web.php
Route::middleware(['flow.trace'])->get('/flow-demo', function () {
    $user = \Zerethon\Flow\Laravel\Helpers\Flow::trace('service', 'UserService.findUser', function () {
        return DB::table('users')->where('id', 1)->first();
    });

    $remote = \Zerethon\Flow\Laravel\Helpers\Flow::external('BillingApi.status', function () {
        return Http::get('https://httpbin.org/status/200')->status();
    });

    return response()->json(['user' => $user?->id, 'remote_status' => $remote]);
});
```

Then call the route once and run:

```
flow scan
```

Config
------

[](#config)

`config/flow.php`

- `enabled`
- `storage_path`
- `max_records`
- `capture_controller`
- `capture_query_sql`

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance100

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

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

1d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/aedd19319f5dd222e88b9050142cfc5664d11eb2e4dbd21720d9a2a83c61c7fb?d=identicon)[leeseawuyhs](/maintainers/leeseawuyhs)

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/zerethonapp-flow-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/zerethonapp-flow-laravel/health.svg)](https://phpackages.com/packages/zerethonapp-flow-laravel)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[mike-bronner/laravel-model-caching

Automatic caching for Eloquent models.

2.4k96.5k1](/packages/mike-bronner-laravel-model-caching)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45444.2k1](/packages/pressbooks-pressbooks)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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