PHPackages                             smartness/traceflow-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. [Logging &amp; Monitoring](/categories/logging)
4. /
5. smartness/traceflow-laravel

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

smartness/traceflow-laravel
===========================

Production-ready distributed tracing SDK for Laravel with event-sourced architecture, async HTTP transport, and cross-service context propagation

v2.6.1(1mo ago)0159↑50%MITPHPPHP ^8.1

Since Feb 3Pushed 1mo agoCompare

[ Source](https://github.com/smartpricing/traceflow-laravel)[ Packagist](https://packagist.org/packages/smartness/traceflow-laravel)[ Docs](https://github.com/smartpricing/traceflow-sdk)[ RSS](/packages/smartness-traceflow-laravel/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (18)Versions (14)Used By (0)

TraceFlow SDK for Laravel
=========================

[](#traceflow-sdk-for-laravel)

> **📦 Packagist Package:** This package is automatically synchronized to [`smartpricing/traceflow-laravel`](https://github.com/smartpricing/traceflow-laravel) for Packagist distribution. Install via Composer from the split repository.

[![Packagist Version](https://camo.githubusercontent.com/d05639cd924fa9d8e7150d31072a01500624618a40821e92707bc93fc7e08ac9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736d6172746e6573732f7472616365666c6f772d6c61726176656c2e737667)](https://packagist.org/packages/smartness/traceflow-laravel)[![PHP Version](https://camo.githubusercontent.com/45d36955804bf3f4f17097b05a7f41a28e578dc24e0d3ad0d21ae9d9762f44c6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312b2d626c75652e737667)](https://www.php.net/)[![Laravel Version](https://camo.githubusercontent.com/d57bb09b232424c2efd4de556f6cacef3822097d4ee8a2d635ace57feea9b45a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d313025323025374325323031312d6f72616e67652e737667)](https://laravel.com/)[![License: MIT](https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667)](LICENSE)[![Tests](https://camo.githubusercontent.com/3e5c58346fdf51e69f9b04f69e54d7fcdf9abb5b0bec88d687a4853ef02e1538/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54657374732d50617373696e672d627269676874677265656e2e737667)](tests/)

**Production-ready, stateless distributed tracing SDK for Laravel applications with event-sourced architecture.**

TraceFlow SDK for Laravel provides enterprise-grade distributed tracing capabilities with zero local state dependencies. Built on an event-sourced architecture, it delivers comprehensive observability across microservices using HTTP or Kafka transport, without compromising application reliability or performance.

Table of Contents
-----------------

[](#table-of-contents)

- [Features](#features)
- [Installation](#installation)
- [Configuration](#configuration)
- [Quick Start](#quick-start)
- [Pattern Examples](#pattern-examples)
- [API Reference](#api-reference)
- [Cross-Service Tracing](#cross-service-tracing)
- [Testing](#testing)
- [Performance &amp; Async Transport](#performance--async-transport)
- [Production Best Practices](#production-best-practices)
- [Examples](#examples)
- [Contributing](#contributing)
- [License](#license)

✨ Features
----------

[](#-features)

- 📦 **Stateless Architecture** - No Redis, no databases, pure event streaming
- ⚡ **Non-Blocking Performance** - Async HTTP transport with &lt;2ms overhead per event
- 🔀 **Transport Agnostic** - Use HTTP REST API or Kafka with identical API
- 🧵 **Context-Aware** - Automatic context propagation across service boundaries
- 🔄 **Retry Logic** - Built-in exponential backoff and circuit breaker patterns
- 🛡️ **Production-Ready** - Silent error mode ensures tracing never fails your application
- 🎯 **Type-Safe** - Full PHP 8.1+ support with typed properties and enums
- 📝 **Event-Based** - Append-only event model for audit trails and replay capabilities
- 🚀 **Laravel Integration** - Seamless integration via Middleware, Facade, and Service Provider
- 🌐 **Cross-Service Tracing** - Propagate trace context across distributed systems
- 📨 **Queue Context Propagation** - Automatic trace context flow through queue jobs
- ✅ **90%+ Test Coverage** - Comprehensive unit and integration test suite

📦 Installation
--------------

[](#-installation)

```
composer require smartness/traceflow-laravel
```

⚙️ Configuration
----------------

[](#️-configuration)

Publish configuration:

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

Configure in `.env`:

```
TRACEFLOW_TRANSPORT=http
TRACEFLOW_SOURCE=my-laravel-app
TRACEFLOW_URL=http://localhost:3009
TRACEFLOW_API_KEY=your-api-key

# Optional
TRACEFLOW_TIMEOUT=5.0
TRACEFLOW_MAX_RETRIES=3
TRACEFLOW_SILENT_ERRORS=true

# Performance (Async HTTP enabled by default)
TRACEFLOW_ASYNC_HTTP=true

# Queue context propagation (enabled by default)
TRACEFLOW_QUEUE_PROPAGATE=true
```

🚀 Quick Start
-------------

[](#-quick-start)

### Using Facade

[](#using-facade)

```
use Smartness\TraceFlow\Facades\TraceFlow;

// Start a trace
$trace = TraceFlow::startTrace(
    traceType: 'api_request',
    title: 'Process User Request'
);

// Start a step
$step = $trace->startStep(name: 'Validate Input');
$step->log('Validation successful');
$step->finish(['valid' => true]);

// Finish trace
$trace->finish(['success' => true]);
```

### Using Middleware (Recommended)

[](#using-middleware-recommended)

Add middleware to `app/Http/Kernel.php`:

```
protected $middleware = [
    // ...
    \Smartness\TraceFlow\Middleware\TraceFlowMiddleware::class,
];
```

Now all HTTP requests are automatically traced!

```
// In your controller
public function show(Request $request, string $id)
{
    // Get trace from request
    $trace = $request->attributes->get('trace');

    // Add steps
    $step = $trace->startStep(name: 'Fetch User from DB');
    $user = User::find($id);
    $step->finish(['user_id' => $user->id]);

    return response()->json($user);
    // Trace auto-completes after response
}
```

### Using Dependency Injection

[](#using-dependency-injection)

```
use Smartness\TraceFlow\TraceFlowSDK;

class UserController extends Controller
{
    public function __construct(private TraceFlowSDK $sdk)
    {
    }

    public function index()
    {
        $trace = $this->sdk->startTrace(
            traceType: 'list_users',
            title: 'List Users'
        );

        $step = $trace->startStep(name: 'Query Database');
        $users = User::all();
        $step->finish(['count' => $users->count()]);

        $trace->finish(['users' => $users]);

        return response()->json($users);
    }
}
```

💡 Pattern Examples
------------------

[](#-pattern-examples)

### Pattern 1: HTTP Request with Custom ID

[](#pattern-1-http-request-with-custom-id)

```
use Smartness\TraceFlow\Facades\TraceFlow;

Route::post('/orders', function (Request $request) {
    // Start trace with custom ID
    $traceId = $request->header('X-Request-ID') ?? Str::uuid();

    $trace = TraceFlow::startTrace(
        traceId: $traceId,
        traceType: 'create_order',
        title: 'Create Order'
    );

    // Process order...
    $step1 = $trace->startStep(name: 'Validate Order');
    $step1->finish();

    $step2 = $trace->startStep(name: 'Save to Database');
    $order = Order::create($request->all());
    $step2->finish(['order_id' => $order->id]);

    $trace->finish(['order' => $order]);

    return response()->json($order);
});
```

### Pattern 2: Service Layer Integration

[](#pattern-2-service-layer-integration)

```
class OrderService
{
    public function __construct(private TraceFlowSDK $sdk)
    {
    }

    public function createOrder(array $data, string $traceId): Order
    {
        // Retrieve trace in service layer
        $trace = $this->sdk->getTrace($traceId);

        $trace->log('Starting order creation');

        $step = $trace->startStep(
            name: 'Create Order',
            stepType: 'database',
            input: $data
        );

        try {
            $order = Order::create($data);

            // Send notification (nested operation)
            $this->sendOrderNotification($order, $traceId);

            $step->finish(['order_id' => $order->id]);

            return $order;
        } catch (\Exception $e) {
            $step->fail($e);
            throw $e;
        }
    }

    private function sendOrderNotification(Order $order, string $traceId): void
    {
        $trace = $this->sdk->getTrace($traceId);

        $step = $trace->startStep(name: 'Send Email Notification');

        // Send email...
        Mail::to($order->user)->send(new OrderCreated($order));

        $step->finish(['sent' => true]);
    }
}
```

### Pattern 3: Static Context Access

[](#pattern-3-static-context-access)

Access the current trace from anywhere without DI:

```
use Smartness\TraceFlow\Context\TraceFlowContext;

class DeeplyNestedService
{
    public function doWork(): void
    {
        // No SDK injection needed — works anywhere during the request
        $traceId = TraceFlowContext::currentTraceId();

        if (TraceFlowContext::hasActiveTrace()) {
            // Use $traceId for logging, external API calls, etc.
            Log::info('Processing', ['trace_id' => $traceId]);
        }
    }
}
```

### Pattern 4: Queue Jobs with Automatic Context

[](#pattern-4-queue-jobs-with-automatic-context)

Use the `TracedJob` trait for automatic trace propagation through queue jobs:

```
use Smartness\TraceFlow\Queue\TracedJob;

class ProcessOrderJob implements ShouldQueue
{
    use TracedJob;

    public function __construct(public Order $order)
    {
        $this->initializeTracedJob(); // Captures current trace context
    }

    public function handle(): void
    {
        // Trace context is automatically restored!
        $trace = TraceFlow::getCurrentTrace();

        $step = $trace->startStep(
            name: 'Background Processing',
            stepType: 'job'
        );

        try {
            $this->order->process();

            // Dispatching another job? Context propagates automatically.
            SendConfirmationEmail::dispatch($this->order);

            $step->finish(['processed' => true]);
        } catch (\Exception $e) {
            $step->fail($e);
            throw $e;
        }
    }
}

// Dispatch — no need to pass trace ID manually
Route::post('/orders', function (Request $request) {
    $trace = TraceFlow::startTrace(title: 'Create Order');

    $order = Order::create($request->all());
    ProcessOrderJob::dispatch($order); // Context captured automatically

    return response()->json($order);
});
```

The trace context chains through any depth of job dispatches: Job A -&gt; Job B -&gt; Job C all share the same trace ID.

### Pattern 5: Long-Running Processes

[](#pattern-5-long-running-processes)

```
use Smartness\TraceFlow\Facades\TraceFlow;

class ImportUsersCommand extends Command
{
    public function handle(): void
    {
        $trace = TraceFlow::startTrace(
            traceType: 'batch_import',
            title: 'Import Users from CSV'
        );

        $users = $this->loadUsersFromCSV();

        foreach ($users as $index => $userData) {
            $step = $trace->startStep(
                name: "Import User #{$index}",
                input: $userData
            );

            User::create($userData);

            $step->finish();

            // Send heartbeat every 100 users
            if ($index % 100 === 0) {
                TraceFlow::heartbeat($trace->traceId);
            }
        }

        $trace->finish(['imported' => count($users)]);
    }
}
```

📚 API Reference
---------------

[](#-api-reference)

### TraceFlowSDK Methods

[](#traceflowsdk-methods)

```
// Start trace
$trace = TraceFlow::startTrace(
    traceType: 'process_type',     // Optional
    title: 'Human readable title', // Optional
    description: 'Description',    // Optional
    owner: 'team-name',           // Optional
    tags: ['tag1', 'tag2'],       // Optional
    metadata: ['key' => 'value'], // Optional
    params: $inputData,           // Optional
    traceTimeoutMs: 5000,         // Optional - custom timeout
    stepTimeoutMs: 2000           // Optional - custom step timeout
);

// Get existing trace
$trace = $sdk->getTrace('trace-id');

// Get current trace from context (checks SDK state + TraceFlowContext)
$trace = $sdk->getCurrentTrace();

// Set trace ID manually (used by queue middleware)
$sdk->setCurrentTraceId('trace-id');

// Send heartbeat
$sdk->heartbeat('trace-id');

// Start step (requires active trace)
$step = $sdk->startStep(
    name: 'Step Name',
    stepType: 'database',
    input: ['data'],
    metadata: ['key' => 'value']
);

// Log message
$sdk->log('Message', 'INFO', 'event_type', ['details']);
```

### TraceHandle Methods

[](#tracehandle-methods)

```
$trace->finish(result: ['data'], metadata: ['key' => 'value']);
$trace->fail(error: 'Error message');
$trace->cancel();
$trace->startStep(name: 'Step Name', ...);
$trace->log(message: 'Message', level: 'INFO', ...);
```

### StepHandle Methods

[](#stephandle-methods)

```
$step->finish(output: ['data'], metadata: ['key' => 'value']);
$step->fail(error: 'Error message');
$step->log(message: 'Message', level: 'INFO', ...);
```

🌐 Cross-Service Tracing
-----------------------

[](#-cross-service-tracing)

### Service A (API Gateway)

[](#service-a-api-gateway)

```
// Service A: Start trace
$trace = TraceFlow::startTrace(title: 'User Registration');

// Call Service B with trace ID
Http::withHeaders([
    'X-Trace-Id' => $trace->traceId,
])->post('http://service-b/api/endpoint', $data);

$trace->finish();
```

### Service B (Email Service)

[](#service-b-email-service)

```
// Service B: Retrieve existing trace
$traceId = request()->header('X-Trace-Id');

// Get the trace started by Service A
$trace = TraceFlow::getTrace($traceId);

// Add steps to the same trace
$trace->startStep(name: 'Send Welcome Email');

// Process...
$trace->finish();
```

🧪 Testing
---------

[](#-testing)

The SDK includes comprehensive test coverage for async transport:

```
# Run all tests
composer test

# Run unit tests only (async transport, SDK)
composer test:unit

# Run integration tests (end-to-end scenarios)
composer test:feature

# Generate coverage report
composer test:coverage

# Run static analysis
composer analyse
```

### Test Coverage

[](#test-coverage)

The SDK maintains comprehensive test coverage:

- **AsyncHttpTransport**: Non-blocking behavior, retries, promise handling
- **TraceFlowSDK**: Configuration, context propagation, lifecycle
- **Integration**: Complete workflows, performance benchmarks
- **90%+ code coverage** with unit and feature tests

See `tests/README.md` for detailed testing documentation.

### Example Test

[](#example-test)

```
use Smartness\TraceFlow\Facades\TraceFlow;

class UserControllerTest extends TestCase
{
    public function test_creates_user()
    {
        // TraceFlow::fake(); // Coming soon

        $response = $this->post('/users', ['name' => 'John']);

        $response->assertStatus(201);
        $response->assertHeader('X-Trace-Id');
    }
}
```

📋 Configuration Reference
-------------------------

[](#-configuration-reference)

```
// config/traceflow.php
return [
    'transport' => 'http',                    // or 'kafka'
    'async_http' => true,                     // Use async HTTP (default: true)
    'source' => env('APP_NAME'),
    'endpoint' => 'http://localhost:3009',  // env: TRACEFLOW_URL
    'api_key' => 'your-api-key',
    'timeout' => 5.0,
    'max_retries' => 3,
    'retry_delay' => 1000,
    'silent_errors' => true,

    'middleware' => [
        'enabled' => true,
        'header_name' => 'X-Trace-Id',
    ],

    'queue' => [
        'propagate_context' => true,
    ],
];
```

⚡ Performance &amp; Async Transport
-----------------------------------

[](#-performance--async-transport)

**By default, the SDK uses non-blocking async HTTP** for maximum performance:

### Performance Comparison

[](#performance-comparison)

TransportOverhead per EventBlocking**Async HTTP** (default)**~2ms**❌ NoBlocking HTTP~50-200ms✅ Yes### How Async Works

[](#how-async-works)

1. **Fire-and-forget**: `send()` returns immediately without waiting for HTTP response
2. **Promise-based**: Uses Guzzle async promises under the hood
3. **Auto-flush**: Promises automatically settled on Laravel shutdown
4. **Retry logic**: Exponential backoff handled asynchronously

### Configuration

[](#configuration)

```
# Enabled by default (recommended)
TRACEFLOW_ASYNC_HTTP=true

# Disable for debugging or compatibility
TRACEFLOW_ASYNC_HTTP=false
```

### Trade-offs

[](#trade-offs)

**Async (default)**:

- **Pros**: Minimal latency impact (~2ms), no additional infrastructure needed
- **Cons**: Events lost if PHP crashes before shutdown, slightly higher memory usage

**Blocking**:

- **Pros**: Guaranteed delivery before request completes
- **Cons**: High latency impact (50-200ms per event), slows down user requests

🔒 Production Best Practices
---------------------------

[](#-production-best-practices)

1. **Always use silent errors in production**

    ```
    TRACEFLOW_SILENT_ERRORS=true
    ```
2. **Use middleware for automatic HTTP tracing**
3. **Use the `TracedJob` trait** for automatic queue context propagation
4. **Send heartbeats for long-running processes**
5. **Use environment variables for configuration**

📖 Examples
----------

[](#-examples)

See `examples/` directory for:

- **BasicExample.php** - Fundamental SDK usage patterns
- **CustomTimeouts.php** - Configuring trace and step timeouts
- **AsyncPerformance.php** - Performance comparison and async transport demo
- Laravel API integration
- Background jobs
- Distributed tracing
- Long-running processes

🤝 Contributing
--------------

[](#-contributing)

Contributions are welcome! Please follow these steps:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

Please ensure:

- All tests pass (`composer test`)
- Code follows PSR-12 standards (`composer format`)
- Static analysis passes (`composer analyse`)
- You've added tests for new features

📄 License
---------

[](#-license)

MIT License - see [LICENSE](LICENSE) file for details.

Copyright © 2025 Smartness

###  Health Score

44

—

FairBetter than 92% of packages

Maintenance91

Actively maintained with recent releases

Popularity15

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 80% 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

Every ~4 days

Total

13

Last Release

46d ago

Major Versions

v1.0.0 → v2.3.02026-02-18

### Community

Maintainers

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

---

Top Contributors

[![albertovincenzi](https://avatars.githubusercontent.com/u/9381203?v=4)](https://github.com/albertovincenzi "albertovincenzi (20 commits)")[![andreiborcea](https://avatars.githubusercontent.com/u/188456772?v=4)](https://github.com/andreiborcea "andreiborcea (3 commits)")[![emanuele-em](https://avatars.githubusercontent.com/u/100081325?v=4)](https://github.com/emanuele-em "emanuele-em (2 commits)")

---

Tags

asynclaravelmonitoringapmtracingevent sourcingtelemetrymicroservicesobservabilitykafkadistributed-tracing

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/smartness-traceflow-laravel/health.svg)

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

PHPackages © 2026

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