philiprehberger/laravel-correlation-id

Laravel middleware that generates or propagates correlation IDs for request tracing with automatic log context injection

Maintainers

Package info

github.com/philiprehberger/laravel-correlation-id

pkg:composer/philiprehberger/laravel-correlation-id

Fund package maintenance!

philiprehberger

Statistics

Installs: 43

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.1.0 2026-04-01 13:46 UTC

This package is auto-updated.

Last update: 2026-04-06 16:21:27 UTC


README

Tests Latest Version on Packagist Last updated

Laravel middleware that generates or propagates correlation IDs for request tracing with automatic log context injection.

Requirements

  • PHP 8.2+
  • Laravel 11 or 12

Installation

composer require philiprehberger/laravel-correlation-id

Laravel's auto-discovery registers the service provider automatically.

Publish the config (optional)

php artisan vendor:publish --tag=correlation-id-config

This copies config/correlation-id.php into your application so you can customise it.

Usage

Register the Middleware

Add the middleware to your HTTP kernel in bootstrap/app.php:

use PhilipRehberger\CorrelationId\AddCorrelationId;

->withMiddleware(function (Middleware $middleware) {
    $middleware->prepend(AddCorrelationId::class);
})

Accessing the Correlation ID

// From the request object
$correlationId = $request->attributes->get('correlation_id');

// Via the helper class
use PhilipRehberger\CorrelationId\CorrelationId;

$id = CorrelationId::get();
CorrelationId::set('my-custom-id');

Configuration

// config/correlation-id.php
return [
    'request_headers' => ['X-Request-Id', 'X-Correlation-ID'],
    'response_header' => 'X-Request-Id',
    'log_context_key' => 'correlation_id',
    'sentry'          => true,
];

How It Works

  1. The middleware inspects incoming request headers in the order defined by request_headers.
  2. The first non-empty value found is used as-is (propagation path).
  3. When no matching header is present, a new UUID v4 is generated.
  4. The ID is stored as a request attribute and shared with the log context.
  5. After the handler returns, the ID is written to the response header defined by response_header.

Queue Job Propagation

Propagate the correlation ID from the dispatching context into queued jobs:

use PhilipRehberger\CorrelationId\Concerns\TracksCorrelationId;
use PhilipRehberger\CorrelationId\Middleware\CorrelationIdJobMiddleware;

class ProcessOrder implements ShouldQueue
{
    use TracksCorrelationId;

    public function middleware(): array
    {
        return [new CorrelationIdJobMiddleware];
    }

    public function handle(): void
    {
        // CorrelationId::get() returns the same ID from dispatch time
    }
}

The TracksCorrelationId trait captures the current correlation ID when the job is created. The CorrelationIdJobMiddleware restores it when the job runs on a worker.

HTTP Client Propagation

Automatically forward the correlation ID to outgoing HTTP requests made with Laravel's HTTP client:

use Illuminate\Support\Facades\Http;
use PhilipRehberger\CorrelationId\CorrelationId;

$response = Http::withMiddleware(CorrelationId::httpMiddleware())
    ->get('https://api.example.com/orders');

// Uses a custom header name
$response = Http::withMiddleware(CorrelationId::httpMiddleware('X-Request-Id'))
    ->get('https://api.example.com/orders');

The middleware adds the X-Correlation-ID header (or your custom header) to every outgoing request.

Trace Spans

Track the timing of operations within a request using lightweight trace spans:

use PhilipRehberger\CorrelationId\CorrelationId;

$span = CorrelationId::startSpan('external-api-call', ['url' => $url]);

$response = Http::get($url);

$ended = CorrelationId::endSpan($span);

// Access span data
$ended->durationMs();  // Duration in milliseconds
$ended->toArray();     // Full array representation

// Retrieve all completed spans
$spans = CorrelationId::spans();

// Clear spans (e.g., between tests)
CorrelationId::clearSpans();

Spans are immutable value objects. Calling endSpan() returns a new instance with the end time set and stores it for later retrieval.

Sentry Integration

When sentry/sentry-laravel is installed and 'sentry' => true, the middleware sets correlation_id as a tag on every Sentry event captured during the request.

API

Class / Method Description
AddCorrelationId middleware Generates or propagates the correlation ID and injects it into logs and responses
CorrelationId::get() Read the current correlation ID (null if not yet set)
CorrelationId::set(string $id) Override the correlation ID (useful in tests or CLI commands)
CorrelationId::httpMiddleware(?string $headerName) Returns a Guzzle middleware closure for HTTP client propagation
CorrelationId::startSpan(string $name, array $metadata) Start a new trace span linked to the current correlation ID
CorrelationId::endSpan(Span $span) End a span and store it for retrieval
CorrelationId::spans() Get all completed trace spans
CorrelationId::clearSpans() Clear all stored trace spans
TracksCorrelationId trait Captures the correlation ID at dispatch time for queue jobs
CorrelationIdJobMiddleware Queue job middleware that restores the correlation ID
PropagateCorrelationId::handler() Static factory for the HTTP client propagation middleware
Span value object Immutable span with name, durationMs(), toArray()
$request->attributes->get('correlation_id') Read the ID from the current request
X-Request-Id response header Outgoing header carrying the correlation ID (configurable)
correlation_id log context key Key injected into every Log::* call during the request (configurable)

Development

composer install
vendor/bin/phpunit
vendor/bin/pint --test
vendor/bin/phpstan analyse

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT