Lightweight distributed tracing for Symfony. Propagates a correlation ID across your entire stack (HTTP, HTTP Client, Monolog, Messenger, Mercure, Twig) without the overhead of a full APM solution.
Worker-mode ready: the storage implements ResetInterface and is scoped per request/message. Works out of the box with FrankenPHP worker mode and Messenger workers.
composer require aubes/correlation-bundle
The bundle auto-registers via Symfony Flex.
The bundle captures or generates a correlation ID at the start of each HTTP request or console command, stores it in a request-scoped storage, and propagates it to all configured integrations.
CorrelationIdStorage is final, self-materializes an ID via the configured generator on first get(), and memoizes the resultCorrelationIdProviderInterface::get() always returns a valid, non-null stringset() validates its input (printable ASCII, 1-255 chars) and throws InvalidCorrelationIdException on invalid values. Last write winsResetInterface for worker/long-running process safety--correlation-idX-Correlation-Id from incoming requests (configurable header name)Each integration activates automatically when its dependency is installed, and can be explicitly disabled.
| Integration | Dependency | What it does |
|---|---|---|
| HTTP Client | symfony/http-client |
Forwards the correlation ID as a header on outgoing HTTP requests. Any caller-provided correlation header is overwritten (the storage is the single source of truth) |
| Monolog | monolog/monolog |
Injects the ID into every log record's extra array |
| Messenger | symfony/messenger |
Stamps the ID on dispatch, restores it on consume |
| Mercure | symfony/mercure-bundle |
Injects the ID into JSON object payloads |
| Twig | twig/twig |
Provides a correlation_id() template function |
# config/packages/correlation.yaml
correlation:
# Core
generator: 'Aubes\CorrelationBundle\Generator\UuidCorrelationIdGenerator' # or Hex32CorrelationIdGenerator
uuid_version: 7 # 4, 6, or 7 (ignored when using a non-UUID generator)
# HTTP
http:
header_name: 'X-Correlation-Id'
send_response_header: true
# Optional integrations
http_client:
enabled: true
header: 'X-Correlation-Id'
force_header: true # false = caller-provided header takes precedence
clients: ['http_client']
monolog:
enabled: true
field_name: 'correlation_id'
channels: [] # empty = all channels
handlers: [] # empty = all handlers
messenger:
enabled: true
buses: [] # empty = all buses
mercure:
enabled: true
field_name: 'correlation_id'
hubs: ['default']
twig:
enabled: true
All values shown above are defaults. Zero configuration is needed for the common case.
CorrelationIdProviderInterfaceRead-only access. Inject this when you only need to read the current ID.
use Aubes\CorrelationBundle\Storage\CorrelationIdProviderInterface;
final class MyService
{
public function __construct(private readonly CorrelationIdProviderInterface $provider) {}
public function doSomething(): void
{
$correlationId = $this->provider->get(); // guaranteed non-null
}
}
CorrelationIdStorageInterfaceFull access: read, write, and reset. Extends CorrelationIdProviderInterface and ResetInterface.
public function get(): string;
public function set(string $id): void; // throws InvalidCorrelationIdException
public function reset(): void;
CorrelationIdGeneratorInterfacepublic function generate(): string;
| Generator | Format | Use case |
|---|---|---|
UuidCorrelationIdGenerator (default) |
UUID v4/v6/v7 (550e8400-e29b-…) |
General-purpose correlation |
Hex32CorrelationIdGenerator |
32-char lowercase hex (a1b2c3d4…) |
W3C Trace Context / ECS trace.id compatibility |
To switch generator:
correlation:
generator: 'Aubes\CorrelationBundle\Generator\Hex32CorrelationIdGenerator'
Implement CorrelationIdGeneratorInterface and reference your service:
use Aubes\CorrelationBundle\Generator\CorrelationIdGeneratorInterface;
final class MyGenerator implements CorrelationIdGeneratorInterface
{
public function generate(): string
{
// must return 1-255 printable ASCII characters
return my_custom_id();
}
}
correlation:
generator: App\MyGenerator
Note: the service referenced by
generatormust implementAubes\CorrelationBundle\Generator\CorrelationIdGeneratorInterface.
Inject CorrelationIdStorageInterface and call $storage->set($id) before the first downstream read:
use Aubes\CorrelationBundle\Exception\InvalidCorrelationIdException;
try {
$storage->set($idFromExternalSource);
} catch (InvalidCorrelationIdException) {
// untrusted source: fall back to the generator
}
The correlation:debug command displays active integrations, the generator class, and the current correlation ID:
php bin/console correlation:debug
When the Web Profiler is enabled, a correlation ID panel shows the ID source (generated vs provided) and the list of active integrations.
MIT
How can I help you explore Laravel packages today?