PHPackages                             paysera/lib-logging-extra-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. paysera/lib-logging-extra-bundle

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

paysera/lib-logging-extra-bundle
================================

Symfony bundle for further Monolog, Sentry and Graylog integration

3.5.0(3w ago)05.8k16[3 PRs](https://github.com/paysera/lib-logging-extra-bundle/pulls)MITPHPPHP ^7.4 || ^8.0CI passing

Since Jan 8Pushed 3w ago6 watchersCompare

[ Source](https://github.com/paysera/lib-logging-extra-bundle)[ Packagist](https://packagist.org/packages/paysera/lib-logging-extra-bundle)[ RSS](/packages/paysera-lib-logging-extra-bundle/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (65)Versions (18)Used By (0)

Logging extra bundle
====================

[](#logging-extra-bundle)

[![Latest Version on Packagist](https://camo.githubusercontent.com/f952734a2ca92ab8abd95a05a6a69360243590da3d5e2d6c920b0ab7cb4508f7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f706179736572612f6c69622d6c6f6767696e672d65787472612d62756e646c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/paysera/lib-logging-extra-bundle)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![Build Status](https://camo.githubusercontent.com/8c53f01876362c204689c5e67d162bbcb7e807995881e927967152d608387c8d/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f706179736572612f6c69622d6c6f6767696e672d65787472612d62756e646c652f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/paysera/lib-logging-extra-bundle)[![Coverage Status](https://camo.githubusercontent.com/e0e89561a92fbb4533bbcbc9671da766050d0b0dc24e2120ecaa262bbbcafafb/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f706179736572612f6c69622d6c6f6767696e672d65787472612d62756e646c652e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/paysera/lib-logging-extra-bundle/code-structure)[![Quality Score](https://camo.githubusercontent.com/90aebbff2589c675e9dd1ff766f5f51cf8c0c1fed7de43a6c43333511980d517/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f706179736572612f6c69622d6c6f6767696e672d65787472612d62756e646c652e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/paysera/lib-logging-extra-bundle)[![Total Downloads](https://camo.githubusercontent.com/343be2c9d72a88dbdfd49a44b40942bf33fc31bad2353157710df06f52fa3aec/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f706179736572612f6c69622d6c6f6767696e672d65787472612d62756e646c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/paysera/lib-logging-extra-bundle)

Symfony bundle for further Monolog, Sentry and Graylog integration.

Why?
----

[](#why)

Monolog already offers integration with both Sentry and Graylog. This bundle re-uses those integrations, adding the following features:

- clearer formatting for Graylog messages;
- adds correlation\_id to correlate messages in Sentry with messages in Graylog from the same process;
- adds trace\_id to correlate messages of one request across every service it touches;
- allows grouping some exceptions by their class, independently from where they were thrown at or what are their message;
- removes root prefix from messages (usually included in some exception messages);
- maps context to be available with logged sentry event.

Also recommended configuration is given to allow nice synergy between Graylog and Sentry.

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

[](#installation)

```
composer require symfony/monolog-bundle sentry/sentry-symfony paysera/lib-logging-extra-bundle
```

Register installed bundles in your kernel or `bundles.php` file, if not installed automatically by flex.

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

[](#configuration)

This is recommended configuration for all three bundles. This ensures that:

- `INFO` and above level log messages always goes to Graylog;
- in case `ERROR` and above level log message is received, all messages (even `DEBUG`, but maximum 50) goes to Graylog. This helps to debug any problems as you get much more information about what has happened;
- `ERROR` level log messages goes to Sentry, so you can see any errors occurring in your application;
- logging does not break or impact your application, even if your Sentry or Graylog servers are down:
    - Graylog uses UDP, so no need to wait for responses. Handler is also wrapped in a failsafe to avoid any errors on DNS resolution impacting your application;
    - Sentry uses HTTP, but has error handling by default, also sends the messages on process shutdown; configuration overrides default 3 retries to just one – if sentry is overwhelmed with requests already, no need to send any more messages 3 times in a row;
- messages are visible on console. You can pass arguments to any command for further verbosity level to see INFO or even DEBUG log messages.

```
monolog:
    handlers:
        info:
            type: filter
            accepted_levels: [INFO, NOTICE, WARNING]
            handler: graylog_failsafe
        debug_and_errors:
            type: filter
            accepted_levels: [DEBUG, ERROR, CRITICAL, ALERT, EMERGENCY]
            handler: graylog_fingers_crossed
        console:
            type: console
            process_psr_3_messages: false
            channels: ["!event", "!doctrine"]
        sentry:
            type: service
            id: paysera_logging_extra.sentry_handler
        graylog_fingers_crossed:
            type: fingers_crossed
            action_level: error
            handler: graylog_failsafe
            stop_buffering: false
            buffer_size: 50
            nested: true
        graylog_failsafe:
            type: whatfailuregroup
            members: [graylog]
            nested: true
        graylog:
            type: gelf
            publisher:
                hostname: '%env(GRAYLOG_HOSTNAME)%'
                port: '%env(GRAYLOG_PORT)%'
                chunk_size: 8154
            formatter: paysera_logging_extra.formatter.gelf_message     # registered by the bundle
            nested: true

sentry:
    dsn: '%env(SENTRY_DSN)%'
    register_error_listener: false
    tracing:
        enabled: false # If using self-hosted Sentry version < v20.6.0
    options:
        environment: '%kernel.environment%'
        release: '%env(VERSION)%' # your app version, optional

paysera_logging_extra:
  application_name: app-something   # customise this to know which project message was sent from
```

### Trace ID

[](#trace-id)

The `trace_id` field names an **entire request across every service it touches**. It is distinct from `correlation_id`, which names a single hop: each service regenerates its own correlation id and records the inbound one as `parent_corr_id`. So `correlation_id` finds the messages of one process, while `trace_id` finds the messages of one request everywhere it went.

It works out of the box — there is nothing to configure. The bundle reads the `Paysera-Trace-Id` header the public gateway stamps on every inbound request and records it as `trace_id` on every log line and as a searchable Sentry tag. Bump the library and each service is traceable; no per-service code is needed.

The incoming value is treated as untrusted: it is recorded only when non-empty, at most 200 characters (Sentry's tag-value limit), and made up of `[A-Za-z0-9._-]`. Anything else is ignored, so a hostile header cannot inject control characters or bloat log lines. Requests without the header (and console commands) simply carry no `trace_id` field, and the id is reset between reused iterations of a long-running process (PHP-FPM, RoadRunner) so it cannot leak from one request into the next.

### Dual-write to stdout (VictoriaLogs)

[](#dual-write-to-stdout-victorialogs)

To write every record to **both** Graylog and stdout (compact JSON Lines, collected by VictoriaLogs), add a `stdout` handler using `paysera_logging_extra.formatter.stdout_json` and make it a member of the existing `graylog_failsafe` `whatfailuregroup`. The `whatfailuregroup` isolates failures per member, so Graylog being unreachable cannot break stdout and vice-versa. No per-call-site changes are needed, and the existing Graylog delivery is untouched.

```
monolog:
    handlers:
        graylog_failsafe:
            type: whatfailuregroup
            members: [graylog, stdout]   # add stdout as a second dual-write target
            nested: true
        stdout:
            type: stream
            path: 'php://stdout'
            level: debug                 # upstream filters/fingers_crossed already gate what reaches the group
            formatter: paysera_logging_extra.formatter.stdout_json   # registered by the bundle
            nested: true
```

Each stdout line is one compact JSON object: `timestamp` (ISO-8601, microseconds + offset), `application_name`, `channel`, syslog `level` (DEBUG=7 … EMERGENCY=0), `level_name`, `message`, optional `full_message` (the raw original when the message is exception-shaped), optional `context`/`extra`, and top-level `correlation_id`, `parent_corr_id` and `trace_id` (all hoisted from `extra`, and each omitted when absent). Lines are capped at 32766 bytes; oversize records stay single-line, are flagged `truncated`, and are shrunk by dropping `full_message` first, then `context`/`extra`, then truncating `message` UTF-8-safely, and finally dropping `correlation_id`/`parent_corr_id`/`trace_id`. The three ids are hoisted so they survive the `extra`drop: oversize records are mostly exception dumps, which is exactly where a request needs to stay traceable.

Exception-shaped messages (`RuntimeException: boom in /app/src/Foo.php:42`) are split into a short `message` and the raw `full_message`, identically to the canonical formatter in `evp/lib-application-logging-bundle` (8.9.1/7.9.1). `Exception` matches capitalized or lowercase, and the split is anchored at the first ` in /` file path — not at the first word `in` — so tails like `in state NEW`, `in driver: ...` or SQL `IN (...)` stay in the short `message`. Messages without a `/`-prefixed file path are left unsplit and emit no `full_message`.

Usage
-----

[](#usage)

Log with INFO level and above to get messages in Graylog.

Log with ERROR level and above to get messages in Sentry.

Log with DEBUG level to get messages in Graylog in case any error occurs in the same request / process. To find those, start with error in Sentry and search messages in Graylog by provided `correlation_id`.

To follow one request across services instead of within one process, search by `trace_id` (see [Trace ID](#trace-id)).

Semantic versioning
-------------------

[](#semantic-versioning)

This bundle follows [semantic versioning](http://semver.org/spec/v2.0.0.html).

Public API of this bundle (in other words, you should only use these features if you want to easily update to new versions):

- only services that are not marked as `public="false"`;
- only classes, interfaces and class methods that are marked with `@api`;
- console commands;
- supported DIC tags.

For example, if only class method is marked with `@api`, you should not extend that class, as constructor could change in any release.

See [Symfony BC rules](https://symfony.com/doc/current/contributing/code/bc.html) for basic information about what can be changed and what not in the API. Keep in mind, that in this bundle everything is `@internal` by default.

Running tests
-------------

[](#running-tests)

```
composer update
composer test

```

Contributing
------------

[](#contributing)

Feel free to create issues and give pull requests.

### Running dependencies locally

[](#running-dependencies-locally)

```
cd example
docker-compose up -d
docker-compose exec sentry sentry upgrade

```

You'll find Graylog at  and Sentry at .

Open Graylog, login with `admin` `admin`, choose `System` -&gt; `Inputs` -&gt; `GELF UDP` -&gt; `Launch new input` -&gt; input any title and select the node -&gt; `Save`.

Open Sentry, login with user created by the last command, choose `Installation instructions` -&gt; `Symfony2` -&gt; copy the credentials part (protocol, hostname and port might be missing). Run following command, exchanging `HERE_GOES_CREDENTIALS` with real credentials:

```
export SENTRY_DSN=http://HERE_GOES_CREDENTIALS@localhost:9002/1

```

And run test PHP script:

```
php test.php

```

View logged data in Graylog and Sentry instances. Change the code for further test scenarios or just use Graylog and Sentry to set-up and test your real project.

Cleanup afterwards:

```
docker-compose down

```

###  Health Score

56

—

FairBetter than 97% of packages

Maintenance95

Actively maintained with recent releases

Popularity27

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity71

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

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 ~149 days

Recently: every ~8 days

Total

17

Last Release

25d ago

Major Versions

1.0.2 → 2.0.02023-03-09

2.2.0 → 3.0.02025-10-07

PHP version history (3 changes)1.0.0PHP &gt;=7.2,&lt;7.5

2.0.0PHP ^7.2 || ^8.0

3.1.0PHP ^7.4 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/9d385187c2b529d5c1189dfc3763972f76738d24293593ff3db876fff82321db?d=identicon)[paysera.com](/maintainers/paysera.com)

---

Top Contributors

[![vitalii-kostetskyi-paysera-net](https://avatars.githubusercontent.com/u/188339773?v=4)](https://github.com/vitalii-kostetskyi-paysera-net "vitalii-kostetskyi-paysera-net (24 commits)")[![siarhei-kruk](https://avatars.githubusercontent.com/u/274785579?v=4)](https://github.com/siarhei-kruk "siarhei-kruk (24 commits)")[![mSprunskas](https://avatars.githubusercontent.com/u/4427922?v=4)](https://github.com/mSprunskas "mSprunskas (10 commits)")[![oleksandr-smiezhyn-paysera](https://avatars.githubusercontent.com/u/311326854?v=4)](https://github.com/oleksandr-smiezhyn-paysera "oleksandr-smiezhyn-paysera (7 commits)")[![mariusbalcytis](https://avatars.githubusercontent.com/u/1590072?v=4)](https://github.com/mariusbalcytis "mariusbalcytis (4 commits)")[![borilyordanov](https://avatars.githubusercontent.com/u/11679283?v=4)](https://github.com/borilyordanov "borilyordanov (2 commits)")[![vbartusevicius](https://avatars.githubusercontent.com/u/7325630?v=4)](https://github.com/vbartusevicius "vbartusevicius (2 commits)")[![haiduk-paysera](https://avatars.githubusercontent.com/u/133983918?v=4)](https://github.com/haiduk-paysera "haiduk-paysera (1 commits)")[![ypppa](https://avatars.githubusercontent.com/u/5552596?v=4)](https://github.com/ypppa "ypppa (1 commits)")[![daniel-valchev-paysera](https://avatars.githubusercontent.com/u/95758316?v=4)](https://github.com/daniel-valchev-paysera "daniel-valchev-paysera (1 commits)")[![pelanis](https://avatars.githubusercontent.com/u/31431703?v=4)](https://github.com/pelanis "pelanis (1 commits)")

---

Tags

activebackendoss-librarypackagistlogloggingsentrymonologgraylog

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/paysera-lib-logging-extra-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/paysera-lib-logging-extra-bundle/health.svg)](https://phpackages.com/packages/paysera-lib-logging-extra-bundle)
```

###  Alternatives

[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9626.1k68](/packages/open-dxp-opendxp)

PHPackages © 2026

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