Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
ErrorLog
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
9
100.00% covered (success)
100.00%
1 / 1
 log
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray;
6
7use Override;
8use Psr\Log\AbstractLogger;
9use Psr\Log\LogLevel;
10use Stringable;
11use Throwable;
12
13/**
14 * The logger an application uses until it registers its own: records go to
15 * PHP's error log. The error handler marks the diagnostics it logs as handled
16 * and renders exceptions itself, so PHP would never report them otherwise.
17 * Debug and info records are left out: this logger stands in for PHP's error
18 * reporting, not for application chatter.
19 *
20 * @internal
21 */
22final class ErrorLog extends AbstractLogger
23{
24    /** @param array<array-key, mixed> $context */
25    #[Override]
26    public function log(mixed $level, string|Stringable $message, array $context = []): void
27    {
28        if ($level === LogLevel::DEBUG || $level === LogLevel::INFO) {
29            return;
30        }
31
32        $label = is_string($level) || is_int($level) ? strtoupper((string) $level) : 'LOG';
33        $replacements = [];
34
35        foreach ($context as $key => $value) {
36            if (is_scalar($value) || $value instanceof Stringable) {
37                $replacements['{' . $key . '}'] = (string) $value;
38            }
39        }
40
41        $line = $label . ': ' . strtr((string) $message, $replacements);
42        $exception = $context['exception'] ?? null;
43
44        if ($exception instanceof Throwable) {
45            // Includes the trace and the chain of previous exceptions.
46            $line .= ': ' . (string) $exception;
47        }
48
49        error_log($line);
50    }
51}