PHPackages                             roadrunner/psr-logger - 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. roadrunner/psr-logger

ActiveLibrary

roadrunner/psr-logger
=====================

PSR Logger for RoadRunner

1.0.0(7mo ago)111.3k—5.5%1[1 issues](https://github.com/roadrunner-php/psr-logger/issues)2MITPHPPHP &gt;=8.1CI failing

Since Oct 1Pushed 7mo ago1 watchersCompare

[ Source](https://github.com/roadrunner-php/psr-logger)[ Packagist](https://packagist.org/packages/roadrunner/psr-logger)[ Docs](https://spiral.dev/)[ GitHub Sponsors](https://github.com/sponsors/roadrunner-server)[ RSS](/packages/roadrunner-psr-logger/feed)WikiDiscussions 1.x Synced 1mo ago

READMEChangelog (1)Dependencies (8)Versions (2)Used By (2)

RoadRunner PSR Logger
=====================

[](#roadrunner-psr-logger)

A PSR-3 compatible logger implementation that integrates with RoadRunner's logging system via RPC calls. This package provides a bridge between PSR-3 logging standards and RoadRunner's centralized logging infrastructure.

RPC Logger vs STDERR Logger
---------------------------

[](#rpc-logger-vs-stderr-logger)

The RPC logger provides several advantages over RoadRunner's built-in STDERR Logger:

- **Log Level Control**: RPC Logger controls the actual log level sent to RoadRunner server, ensuring proper level filtering and display in RoadRunner logs. Messages from STDERR Logger are processed by RoadRunner with `info` level.
- **Context Support**: RPC logger preserves structured context data (arrays, objects). STDERR Logger outputs only the message string, ignoring context.

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

[](#installation)

```
composer require roadrunner/psr-logger
```

[![PHP](https://camo.githubusercontent.com/feed96013efbba0bf2acf6cea1850a36c4b366d400910ac2589ab878fd337a8c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f726f616472756e6e65722f7073722d6c6f676765722e7376673f7374796c653d666c61742d737175617265266c6f676f3d706870)](https://packagist.org/packages/roadrunner/psr-logger)[![Latest Version on Packagist](https://camo.githubusercontent.com/4430ad2014d631d1c5ae07948779a58b0c64b5044d6978077b6b0f0f257a56ea/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f726f616472756e6e65722f7073722d6c6f676765722e7376673f7374796c653d666c61742d737175617265266c6f676f3d7061636b6167697374)](https://packagist.org/packages/roadrunner/psr-logger)[![License](https://camo.githubusercontent.com/32e9a6c439055a34bc96cd338aed18254b6de39c1a4e77cef6749929b8023929/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f726f616472756e6e65722f7073722d6c6f676765722e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Total DLoads](https://camo.githubusercontent.com/932bfadb2c877c9e6a5a4ba00439dd6ded6cc73a620b3ec3d1e5935312ee9b38/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f726f616472756e6e65722f7073722d6c6f676765722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/roadrunner/psr-logger/stats)

Usage
-----

[](#usage)

### Basic Setup

[](#basic-setup)

```
use RoadRunner\Logger\Logger as AppLogger;
use RoadRunner\PsrLogger\RpcLogger;

// Initialize the RoadRunner app logger
$rpc = \Spiral\Goridge\RPC\RPC::create('127.0.0.1:6001');
$appLogger = new AppLogger($rpc);

// Create the PSR-3 compatible logger
$logger = new RpcLogger($appLogger);
```

### Logging Examples

[](#logging-examples)

```
// Basic logging with different levels
$logger->emergency('System is unusable');
$logger->alert('Action must be taken immediately');
$logger->critical('Critical conditions');
$logger->error('Runtime errors');
$logger->warning('Warning conditions');
$logger->notice('Normal but significant condition');
$logger->info('Informational messages');
$logger->debug('Debug-level messages');

// Logging with context data
$logger->info('User logged in', [
    'user_id' => 123,
    'ip_address' => '192.168.1.1',
    'user_agent' => 'Mozilla/5.0...'
]);

// Using the generic log method
$logger->log(\Psr\Log\LogLevel::ERROR, 'Something went wrong', [
    'exception' => $exception->getMessage(),
    'trace' => $exception->getTraceAsString()
]);
```

Log Levels
----------

[](#log-levels)

### Supported Log Level Types

[](#supported-log-level-types)

The logger accepts log levels in multiple formats:

- **String values**: `'error'`, `'warning'`, `'info'`, `'debug'`
- **PSR-3 constants**: `\Psr\Log\LogLevel::ERROR`, `\Psr\Log\LogLevel::WARNING`
- **Stringable objects**: Any object implementing `\Stringable` interface
- **BackedEnum values**: PHP 8.1+ backed enums with string values

```
// String levels
$logger->log('error', 'Error message');

// PSR-3 constants
$logger->log(\Psr\Log\LogLevel::WARNING, 'Warning message');

// BackedEnum example
enum LogLevel: string
{
    case Error = 'error';
    case Warning = 'warning';
    case Info = 'info';
    case Debug = 'debug';
}

$logger->log(LogLevel::Error, 'Error via enum');
```

### Log Level Mapping

[](#log-level-mapping)

The logger maps PSR-3 log levels to RoadRunner logging methods as follows:

PSR-3 LevelRoadRunner MethodemergencyerroralerterrorcriticalerrorerrorerrorwarningwarningnoticeinfoinfoinfodebugdebugContext Handling
----------------

[](#context-handling)

The logger supports structured logging with context arrays. Context data is processed by a context processor before being passed to the underlying RoadRunner logger.

### Default Context Processor

[](#default-context-processor)

By default, `RpcLogger` uses `DefaultProcessor` which can handle:

- Scalar values (string, int, float, bool)
- Arrays and nested arrays
- Resources (converted to resource type description)
- Objects via built-in object processors:
    - **DateTimeProcessor**: Converts `\DateTimeInterface` objects to ISO 8601 format (ATOM)
    - **StringableProcessor**: Converts `\Stringable` objects to their string representation
    - **ThrowableProcessor**: Converts exceptions/errors to structured arrays with class, message, code, file, line, and trace
    - **FallbackProcessor**: Converts any other objects to arrays with class name and public properties

```
$logger->info('Order processed', [
    'order_id' => 12345,
    'customer' => [
        'id' => 67890,
        'email' => 'customer@example.com'
    ],
    'amount' => 99.99,
    'processed_at' => new \DateTime(),
    'metadata' => [
        'source' => 'web',
        'campaign' => 'summer_sale'
    ]
]);
```

### Extending DefaultProcessor

[](#extending-defaultprocessor)

The recommended approach is to extend `DefaultProcessor` with custom object processors using the `withObjectProcessors()` method. This allows you to add your own object handling while keeping all the built-in processors.

```
/**
 * @implements ObjectProcessor
 */
class EntityProcessor implements ObjectProcessor
{
    public function canProcess(object $value): bool
    {
        return $value instanceof ActiveRecord;
    }

    public function process(object $value, callable $processor): mixed
    {
        return $processor($value->toArray());
    }
}

// Extend default processor with your custom processor
$processor = DefaultProcessor::createDefault()
    ->withObjectProcessors(new EntityProcessor());

$logger = new RpcLogger($appLogger, $processor);

// Now entity objects will be automatically converted to arrays with essential data
$logger->info('Order created', [
    'user' => $user,     // User entity instance
    'order' => $order,   // Order entity instance
]);
```

Note

Custom processors added via `withObjectProcessors()` are placed **before** the built-in processors. This means your custom processors take precedence and can override the default behavior for specific object types.

```
// Add multiple custom processors at once
$processor = DefaultProcessor::createDefault()
    ->withObjectProcessors(
        new EntityProcessor(),
        new MoneyProcessor(),
        new CustomValueObjectProcessor(),
    );

$logger = new RpcLogger($appLogger, $processor);
```

You can also start with an empty processor and add only the processors you need:

```
use RoadRunner\PsrLogger\Context\ObjectProcessor\DateTimeProcessor;

// Create empty processor and add only specific processors
$processor = DefaultProcessor::create()
    ->withObjectProcessors(
        new DateTimeProcessor(),
        new EntityProcessor()
    );

$logger = new RpcLogger($appLogger, $processor);
```

### Custom Context Processor

[](#custom-context-processor)

For advanced use cases, you can provide a completely custom context processor to the `RpcLogger` constructor:

```
use RoadRunner\Logger\Logger as AppLogger;
use RoadRunner\PsrLogger\RpcLogger;

// Using a completely custom processor
$customProcessor = function (mixed $context): mixed {
    // Your custom processing logic
    return $context;
};
$logger = new RpcLogger($appLogger, $customProcessor);
```

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance42

Moderate activity, may be stable

Popularity29

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

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

Every ~0 days

Total

2

Last Release

230d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/110fa17dca123e71e4ef4132d1d6a66d20058a07fc6118e716dd67dd4316e886?d=identicon)[roxblnfk](/maintainers/roxblnfk)

---

Top Contributors

[![roxblnfk](https://avatars.githubusercontent.com/u/4152481?v=4)](https://github.com/roxblnfk "roxblnfk (20 commits)")[![hungthai1401](https://avatars.githubusercontent.com/u/22017922?v=4)](https://github.com/hungthai1401 "hungthai1401 (7 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/roadrunner-psr-logger/health.svg)

```
[![Health](https://phpackages.com/badges/roadrunner-psr-logger/health.svg)](https://phpackages.com/packages/roadrunner-psr-logger)
```

###  Alternatives

[elgg/elgg

Elgg is an award-winning social networking engine, delivering the building blocks that enable businesses, schools, universities and associations to create their own fully-featured social networks and applications.

1.7k15.7k5](/packages/elgg-elgg)[api-platform/metadata

API Resource-oriented metadata attributes and factories

243.5M96](/packages/api-platform-metadata)[neos/flow

Flow Application Framework

862.0M451](/packages/neos-flow)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[flowwow/cloudpayments-php-client

cloudpayments api client

2188.2k](/packages/flowwow-cloudpayments-php-client)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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