Logger::withFormatter()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Conia\Log;
6
7
use Conia\Log\Formatter\MessageFormatter;
8
use Psr\Log\InvalidArgumentException;
9
use Psr\Log\LoggerInterface as PsrLogger;
10
use Stringable;
11
12
/** @psalm-api */
13
class Logger implements PsrLogger
14
{
15
    public const DEBUG = 100;
16
    public const INFO = 200;
17
    public const NOTICE = 300;
18
    public const WARNING = 400;
19
    public const ERROR = 500;
20
    public const CRITICAL = 600;
21
    public const ALERT = 700;
22
    public const EMERGENCY = 800;
23
24
    /** @psalm-var array<int, non-empty-string> */
25
    protected array $levelLabels;
26
27 7
    public function __construct(
28
        protected ?string $logfile = null,
29
        protected ?Formatter $formatter = null,
30
        protected int $minimumLevel = self::DEBUG,
31
    ) {
32 7
        if (!$formatter) {
33 6
            $this->formatter = new MessageFormatter();
34
        }
35
36 7
        $this->levelLabels = [
37 7
            self::DEBUG => 'DEBUG',
38 7
            self::INFO => 'INFO',
39 7
            self::NOTICE => 'NOTICE',
40 7
            self::WARNING => 'WARNING',
41 7
            self::ERROR => 'ERROR',
42 7
            self::CRITICAL => 'CRITICAL',
43 7
            self::ALERT => 'ALERT',
44 7
            self::EMERGENCY => 'EMERGENCY',
45 7
        ];
46
    }
47
48 2
    public function formatter(Formatter $formatter): void
49
    {
50 2
        $this->formatter = $formatter;
51
    }
52
53 1
    public function withFormatter(Formatter $formatter): self
54
    {
55 1
        $new = clone $this;
56 1
        $new->formatter($formatter);
57
58 1
        return $new;
59
    }
60
61 7
    public function log(
62
        mixed $level,
63
        string|Stringable $message,
64
        array $context = [],
65
    ): void {
66 7
        $message = (string)$message;
67 7
        assert(is_int($level) || is_numeric($level));
68 7
        $level = (int)$level;
69
70 7
        if ($level < $this->minimumLevel) {
71 1
            return;
72
        }
73
74 7
        if (isset($this->levelLabels[$level])) {
75 6
            $levelLabel = $this->levelLabels[$level];
76
        } else {
77 1
            throw new InvalidArgumentException('Unknown log level: ' . (string)$level);
78
        }
79
80 6
        assert(!is_null($this->formatter));
81 6
        $message = $this->formatter->format(str_replace("\0", '', $message), $context);
82 6
        $time = date('Y-m-d H:i:s D T');
83 6
        $line = "[{$time}] {$levelLabel}: {$message}";
84
85 6
        if (is_string($this->logfile)) {
86 5
            error_log($line, 3, $this->logfile);
87
        } else {
88 1
            error_log($line);
89
        }
90
    }
91
92 3
    public function debug(string|Stringable $message, array $context = []): void
93
    {
94 3
        $this->log(self::DEBUG, $message, $context);
95
    }
96
97 3
    public function info(string|Stringable $message, array $context = []): void
98
    {
99 3
        $this->log(self::INFO, $message, $context);
100
    }
101
102 2
    public function notice(string|Stringable $message, array $context = []): void
103
    {
104 2
        $this->log(self::NOTICE, $message, $context);
105
    }
106
107 3
    public function warning(string|Stringable $message, array $context = []): void
108
    {
109 3
        $this->log(self::WARNING, $message, $context);
110
    }
111
112 3
    public function error(string|Stringable $message, array $context = []): void
113
    {
114 3
        $this->log(self::ERROR, $message, $context);
115
    }
116
117 2
    public function critical(string|Stringable $message, array $context = []): void
118
    {
119 2
        $this->log(self::CRITICAL, $message, $context);
120
    }
121
122 5
    public function alert(string|Stringable $message, array $context = []): void
123
    {
124 5
        $this->log(self::ALERT, $message, $context);
125
    }
126
127 3
    public function emergency(string|Stringable $message, array $context = []): void
128
    {
129 3
        $this->log(self::EMERGENCY, $message, $context);
130
    }
131
}
132