Skip to content

Commit 1d039a3

Browse files
committed
docs: Update README to include details on DefaultProcessor and custom context processors
1 parent 54a121b commit 1d039a3

File tree

2 files changed

+95
-6
lines changed

2 files changed

+95
-6
lines changed

README.md

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,20 @@ The logger maps PSR-3 log levels to RoadRunner logging methods as follows:
109109

110110
## Context Handling
111111

112-
The logger supports structured logging with context arrays. When context data is provided, it's passed through to the underlying RoadRunner logger, which can handle complex data structures including:
112+
The logger supports structured logging with context arrays. Context data is processed by a context processor before being passed to the underlying RoadRunner logger.
113+
114+
### Default Context Processor
115+
116+
By default, `RpcLogger` uses `DefaultProcessor` which can handle:
113117

114118
- Scalar values (string, int, float, bool)
115119
- Arrays and nested arrays
116-
- Objects that implement `\Stringable`
117-
- DateTime objects and exceptions (TODO)
120+
- Resources (converted to resource type description)
121+
- Objects via built-in object processors:
122+
- **DateTimeProcessor**: Converts `\DateTimeInterface` objects to ISO 8601 format (ATOM)
123+
- **StringableProcessor**: Converts `\Stringable` objects to their string representation
124+
- **ThrowableProcessor**: Converts exceptions/errors to structured arrays with class, message, code, file, line, and trace
125+
- **FallbackProcessor**: Converts any other objects to arrays with class name and public properties
118126

119127
```php
120128
$logger->info('Order processed', [
@@ -131,3 +139,84 @@ $logger->info('Order processed', [
131139
]
132140
]);
133141
```
142+
143+
### Extending DefaultProcessor
144+
145+
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.
146+
147+
```php
148+
/**
149+
* @implements ObjectProcessor<ActiveRecord>
150+
*/
151+
class EntityProcessor implements ObjectProcessor
152+
{
153+
public function canProcess(object $value): bool
154+
{
155+
return $value instanceof ActiveRecord;
156+
}
157+
158+
public function process(object $value, callable $processor): mixed
159+
{
160+
return $processor($value->toArray());
161+
}
162+
}
163+
164+
// Extend default processor with your custom processor
165+
$processor = DefaultProcessor::createDefault()
166+
->withObjectProcessors(new EntityProcessor());
167+
168+
$logger = new RpcLogger($appLogger, $processor);
169+
170+
// Now entity objects will be automatically converted to arrays with essential data
171+
$logger->info('Order created', [
172+
'user' => $user, // User entity instance
173+
'order' => $order, // Order entity instance
174+
]);
175+
```
176+
177+
> [!NOTE]
178+
> Custom processors added via `withObjectProcessors()` are placed **before** the built-in processors.
179+
> This means your custom processors take precedence and can override the default behavior for specific object types.
180+
181+
```php
182+
// Add multiple custom processors at once
183+
$processor = DefaultProcessor::createDefault()
184+
->withObjectProcessors(
185+
new EntityProcessor(),
186+
new MoneyProcessor(),
187+
new CustomValueObjectProcessor(),
188+
);
189+
190+
$logger = new RpcLogger($appLogger, $processor);
191+
```
192+
193+
You can also start with an empty processor and add only the processors you need:
194+
195+
```php
196+
use RoadRunner\PsrLogger\Context\ObjectProcessor\DateTimeProcessor;
197+
198+
// Create empty processor and add only specific processors
199+
$processor = DefaultProcessor::create()
200+
->withObjectProcessors(
201+
new DateTimeProcessor(),
202+
new EntityProcessor()
203+
);
204+
205+
$logger = new RpcLogger($appLogger, $processor);
206+
```
207+
208+
### Custom Context Processor
209+
210+
For advanced use cases, you can provide a completely custom context processor to the `RpcLogger` constructor:
211+
212+
```php
213+
use RoadRunner\Logger\Logger as AppLogger;
214+
use RoadRunner\PsrLogger\RpcLogger;
215+
216+
// Using a completely custom processor
217+
$customProcessor = function (mixed $context): mixed {
218+
// Your custom processing logic
219+
return $context;
220+
};
221+
$logger = new RpcLogger($appLogger, $customProcessor);
222+
```

src/RpcLogger.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ class RpcLogger implements LoggerInterface
2020
use LoggerTrait;
2121

2222
private readonly AppLogger $logger;
23-
private readonly \Closure $objectProcessor;
23+
private readonly \Closure $processor;
2424

2525
public function __construct(AppLogger $logger, ?callable $processor = null)
2626
{
2727
$this->logger = $logger;
28-
$this->objectProcessor = ($processor ?? DefaultProcessor::createDefault())(...);
28+
$this->processor = ($processor ?? DefaultProcessor::createDefault())(...);
2929
}
3030

3131
/**
@@ -47,7 +47,7 @@ public function log($level, \Stringable|string $message, array $context = []): v
4747
});
4848

4949
// Process context data for structured logging using the processor manager
50-
$processedContext = ($this->objectProcessor)($context);
50+
$processedContext = ($this->processor)($context);
5151

5252
match ($normalizedLevel) {
5353
PsrLogLevel::EMERGENCY,

0 commit comments

Comments
 (0)