PHPackages                             phpdot/psr3-bridge - 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. phpdot/psr3-bridge

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

phpdot/psr3-bridge
==================

PSR-3 logger bridge into the PHPdot writer pipeline.

v0.1.0(1mo ago)00MITPHPPHP &gt;=8.5

Since Jul 18Pushed 2w agoCompare

[ Source](https://github.com/phpdot/psr3-bridge)[ Packagist](https://packagist.org/packages/phpdot/psr3-bridge)[ RSS](/packages/phpdot-psr3-bridge/feed)WikiDiscussions main Synced 2w ago

READMEChangelogDependencies (7)Versions (2)Used By (0)

phpdot/psr3-bridge
==================

[](#phpdotpsr3-bridge)

A PSR-3 / Monolog writer for the PHPdot observability engine.

`psr-bridge` is a **backend** for [phpdot/logs](https://github.com/phpdot/logs). It implements the engine's `WriterInterface` and forwards every record — a log line or a finished span — to an injected PSR-3 logger (Monolog, or any other). It owns no trace identity and writes no files; it is the adapter that lets the engine speak to the entire PSR-3 ecosystem.

It is a **peer** of [phpdot/tracelog](https://github.com/phpdot/tracelog) (the file backend). An application binds exactly one of them as its `WriterInterface`; the packages that log never know which. Because it depends only on [contracts](https://github.com/phpdot/contracts) and `psr/log` — **never on tracelog** — a Monolog-only app installs `{contracts, logs, psr-bridge}` and never pulls the file writer or its OpenSSL/encryption code.

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

[](#table-of-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
    - [Quick start](#quick-start)
    - [How records map](#how-records-map)
    - [Trace correlation](#trace-correlation)
    - [Crash-safety &amp; no sampling](#crash-safety--no-sampling)
    - [Any PSR-3 logger](#any-psr-3-logger)
- [Architecture](#architecture)
- [Testing](#testing)
- [License](#license)

Requirements
------------

[](#requirements)

RequirementConstraintPHP`>= 8.5``phpdot/container``^0.2``phpdot/contracts``^0.2``psr/log``^3.0`Installation
------------

[](#installation)

```
composer require phpdot/psr3-bridge monolog/monolog
```

(`monolog/monolog` is a suggestion, not a hard dependency — any PSR-3 logger works.)

Usage
-----

[](#usage)

### Quick start

[](#quick-start)

Bind `Psr3Writer` as the engine's `WriterInterface`, pointed at any PSR-3 logger:

```
use PHPdot\Contracts\Logs\WriterInterface;
use PHPdot\Psr3Bridge\Psr3Writer;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$container->set(WriterInterface::class, static fn () =>
    new Psr3Writer(
        (new Logger('app'))->pushHandler(new StreamHandler('php://stdout')),
    ),
);
```

Your packages keep logging against `TracerInterface` — only this binding changes. From here, everything the engine emits flows through your Monolog handler stack (Slack, syslog, Elasticsearch, rotating files, …).

### How records map

[](#how-records-map)

The engine hands the writer a flat `array`. `Psr3Writer` translates it to a PSR-3 `log($level, $message, $context)` call:

#### Log records

[](#log-records)

Forwarded at their own level, with the trace correlation attached to the PSR-3 context:

```
$tracer->channel('http')->warning('slow upstream', ['ms' => 820]);
```

```
// reaches the PSR-3 logger as:
$logger->log('warning', 'slow upstream', [
    'ms'       => 820,
    'channel'  => 'http',
    'trace_id' => '019f15…',
    'span_id'  => 'c17527…',
]);

```

The engine's level token is validated against the eight PSR-3 levels; an unknown token falls back to `info`.

#### Span records

[](#span-records)

A finished span becomes **one** line — `span ` — at `info`, or `error` when the span's status is `error`, with its metadata in the context:

```
$logger->log('info', 'span db.query', [
    'channel' => 'db', 'trace_id' => '019f15…', 'span_id' => 'a1b2c3…',
    'parent_span_id' => 'c17527…', 'kind' => 'client', 'duration_ms' => 4.2,
    'status' => 'ok', 'status_message' => '', 'attributes' => ['db.rows' => 5], 'events' => [],
]);

```

So even on a backend that has no concept of spans, the full span tree is preserved as correlated log lines you can group by `trace_id`.

### Trace correlation

[](#trace-correlation)

`channel`, `trace_id`, and `span_id` are always added to the PSR-3 context, so every line a downstream handler sees carries the trace — group by `trace_id` in your log aggregator to reassemble a request.

### Crash-safety &amp; no sampling

[](#crash-safety--no-sampling)

- **Never throws:** `write()` wraps the forward in a single `try/catch`. A misbehaving logger (a dead socket, a full disk) is swallowed so logging can never bring down the caller or the coroutine-end span flush. This is the *only* `try/catch` — it is crash-safety, never a drop decision.
- **No sampling:** every record received is forwarded. Sampling/retention is left to your Monolog handlers, not decided here.

### Any PSR-3 logger

[](#any-psr-3-logger)

Nothing here is Monolog-specific — `Psr3Writer` takes a `Psr\Log\LoggerInterface`. Bind Laminas, Symfony's logger, a test spy, or your own:

```
new Psr3Writer($anyPsr3Logger);
```

Architecture
------------

[](#architecture)

 ```
graph TD
    REC["Record from phpdot/logsarrives via WriterInterface"]
    W["Psr3Writerthe WriterInterface backend:maps each record to a PSR-3 call,keeps trace_id / span_id in context"]
    PSR["Any PSR-3 loggerMonolog, Laminas, Analog, …"]
    REC --> W --> PSR
```

      Loading Testing
-------

[](#testing)

The package is standalone-testable:

```
composer install
composer test        # PHPUnit (24 tests)
composer analyse     # PHPStan, level max + strict rules
composer cs-check    # PHP-CS-Fixer (@PER-CS2.0)
composer check       # all three
```

License
-------

[](#license)

MIT

**This repository is a read-only mirror**, generated by CI from [phpdot/monorepo](https://github.com/phpdot/monorepo). [Pull requests](https://github.com/phpdot/monorepo/pulls)and [issues](https://github.com/phpdot/monorepo/issues) belong in the monorepo.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance94

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

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

Unknown

Total

1

Last Release

46d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/62e82421bda4b5d6ba9a47ba6d88caca060dcd0d1a2862f351f3a97657385db0?d=identicon)[phpdot](/maintainers/phpdot)

---

Top Contributors

[![o3AM](https://avatars.githubusercontent.com/u/252500?v=4)](https://github.com/o3AM "o3AM (3 commits)")

---

Tags

psr-3loggerBridgeinterop

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/phpdot-psr3-bridge/health.svg)

```
[![Health](https://phpackages.com/badges/phpdot-psr3-bridge/health.svg)](https://phpackages.com/packages/phpdot-psr3-bridge)
```

###  Alternatives

[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.8k40.0k](/packages/matomo-matomo)[illuminate/log

The Illuminate Log package.

6426.0M719](/packages/illuminate-log)[markrogoyski/simplelog-php

Powerful PSR-3 logging. So easy, it's simple.

2819.7k4](/packages/markrogoyski-simplelog-php)

PHPackages © 2026

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