PHPackages                             tibisoft/wide-events-bundle - 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. tibisoft/wide-events-bundle

ActiveSymfony-bundle[Logging &amp; Monitoring](/categories/logging)

tibisoft/wide-events-bundle
===========================

Wide events (canonical log lines) for Symfony — one structured JSON event per request

0.0.4(1mo ago)19MITPHPPHP &gt;=8.2

Since Apr 16Pushed 1mo agoCompare

[ Source](https://github.com/tibisoft/wide-events-symfony)[ Packagist](https://packagist.org/packages/tibisoft/wide-events-bundle)[ RSS](/packages/tibisoft-wide-events-bundle/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (8)Versions (5)Used By (0)

Wide Events Bundle
==================

[](#wide-events-bundle)

A Symfony bundle for [wide events](https://loggingsucks.com) — also known as canonical log lines.

Instead of scattering dozens of log statements across your codebase, you emit **one rich, structured JSON event per request**. It gets built up progressively as the request moves through your application, then emitted in a single shot after the response is sent.

> *"Instead of logging what your code is doing, log what happened to this request."*— [loggingsucks.com](https://loggingsucks.com)

---

Installation
------------

[](#installation)

```
composer require tibisoft/wide-events-bundle
```

Register the bundle in `config/bundles.php`:

```
return [
    // ...
    Tibisoft\WideEventsBundle\WideEventsBundle::class => ['all' => true],
];
```

---

Configuration
-------------

[](#configuration)

Create `config/packages/wide_events.yaml`:

```
wide_events:
    service_name: '%env(APP_NAME)%'   # added to every event
    service_version: '1.0.0'          # optional
    emitter: stdout                   # stdout | monolog | null
    sampler: tail                     # tail | always
    tail_sampler:
        slow_threshold_ms: 1000       # requests slower than this are always emitted
        default_rate: 0.05            # 5% of fast, successful requests are emitted
```

### Emitters

[](#emitters)

ValueBehaviour`stdout`Writes one JSON line to stdout — ideal for containerised environments`monolog`Passes the event to Monolog as a structured context array`null`Discards everything — useful in `test` environments### Samplers

[](#samplers)

ValueBehaviour`tail`Retains 100% of errors (`4xx`/`5xx`), 100% of slow requests, and a random sample of everything else`always`Retains every single event — useful during development---

What you get for free
---------------------

[](#what-you-get-for-free)

Every event is automatically seeded with the following fields on each request:

FieldSource`timestamp`RFC 3339 with milliseconds`request_id``X-Request-Id` / `X-Correlation-Id` header, or a generated hex ID`service.name`From config`service.version`From config (if set)`http.method`Request method`http.path`Request path`http.user_agent``User-Agent` header`http.client_ip`Client IP`http.status_code`Response status code`duration_ms`Total request duration in milliseconds`error.class`Exception class (only when an exception occurs)`error.message`Exception message (only when an exception occurs)`error.code`Exception code (only when an exception occurs)---

Adding your own context
-----------------------

[](#adding-your-own-context)

Inject `WideEventStore` anywhere in your application and call `set()`:

```
use Tibisoft\WideEventsBundle\WideEventStore;

final class CheckoutController
{
    public function __construct(private readonly WideEventStore $wideEvents) {}

    public function checkout(Order $order, User $user): Response
    {
        $this->wideEvents->current()
            ?->set('user.id', $user->getId())
            ->set('user.tier', $user->getSubscriptionTier())
            ->set('order.id', $order->getId())
            ->set('order.total', $order->getTotal())
            ->set('order.item_count', $order->getItemCount());

        // ... handle the request
    }
}
```

You can call `set()` from any service, at any point during the request. Everything lands in the same event.

---

Enrichers
---------

[](#enrichers)

For context that should be added to **every** event (e.g. the authenticated user), implement `EnricherInterface`. It is called automatically just before the event is emitted.

```
use Tibisoft\WideEventsBundle\Contract\EnricherInterface;
use Tibisoft\WideEventsBundle\WideEvent;

final class AuthenticatedUserEnricher implements EnricherInterface
{
    public function __construct(
        private readonly Security $security,
    ) {}

    public function enrich(WideEvent $event): void
    {
        $user = $this->security->getUser();
        if ($user === null) {
            return;
        }

        $event
            ->set('user.id', $user->getId())
            ->set('user.email', $user->getUserIdentifier());
    }
}
```

With Symfony's autoconfigure enabled (the default), this is all you need — the bundle automatically picks up any service implementing `EnricherInterface` via the `wide_events.enricher` tag.

---

Example output
--------------

[](#example-output)

A single request to `POST /checkout` might produce this event:

```
{
    "timestamp": "2026-04-16T14:23:01.847+00:00",
    "request_id": "a3f8c2d19e4b",
    "service.name": "shop-api",
    "service.version": "3.12.0",
    "http.method": "POST",
    "http.path": "/checkout",
    "http.user_agent": "Mozilla/5.0",
    "http.client_ip": "93.184.216.34",
    "http.status_code": 200,
    "duration_ms": 142.5,
    "user.id": 8821,
    "user.email": "alice@example.com",
    "user.tier": "premium",
    "order.id": "ord_9f3a",
    "order.total": 129.99,
    "order.item_count": 3,
    "payment.method": "card",
    "payment.last4": "4242",
    "feature.new_checkout": true
}
```

One event. Everything you need to debug, audit, or analyse — no log archaeology required.

---

Tail sampling
-------------

[](#tail-sampling)

Wide events can generate a lot of data. The built-in tail sampler helps keep costs under control by making retention decisions *after* the request completes, when you have full context:

- **Always retain** requests with `4xx` or `5xx` status codes
- **Always retain** requests that exceed `slow_threshold_ms`
- **Randomly sample** everything else at `default_rate` (default 5%)

This means you never miss an error or a slow request, while routine successful traffic is sampled down significantly.

---

Extending
---------

[](#extending)

You can swap out any part of the bundle by implementing the relevant interface and binding it in your container:

InterfacePurpose`EmitterInterface`Controls how/where the event is written`SamplerInterface`Controls which events are retained`EnricherInterface`Adds fields to every event before emit

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance89

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity39

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

Every ~0 days

Total

4

Last Release

54d ago

### Community

Maintainers

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

---

Tags

symfonyloggingobservabilitywide-eventscanonical-log-lines

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/tibisoft-wide-events-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/tibisoft-wide-events-bundle/health.svg)](https://phpackages.com/packages/tibisoft-wide-events-bundle)
```

PHPackages © 2026

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