Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
18 / 18
CRAP
100.00% covered (success)
100.00%
1 / 1
Logger
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
18 / 18
26
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 addWriters
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 addWriter
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getWriters
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLogLimit
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setTimestampFormat
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getTimestampFormat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLevel
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLogLevel
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 emergency
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 alert
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 critical
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 error
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 warning
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 notice
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 info
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 debug
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 log
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Log;
15
16use Pop\Log\Writer\WriterInterface;
17
18/**
19 * Logger class
20 *
21 * @category   Pop
22 * @package    Pop\Log
23 * @author     Nick Sagona, III <dev@nolainteractive.com>
24 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
25 * @license    http://www.popphp.org/license     New BSD License
26 * @version    4.0.0
27 */
28class Logger
29{
30
31    /**
32     * Constants for log levels
33     * @var int
34     */
35    const EMERGENCY = 0;
36    const ALERT     = 1;
37    const CRITICAL  = 2;
38    const ERROR     = 3;
39    const WARNING   = 4;
40    const NOTICE    = 5;
41    const INFO      = 6;
42    const DEBUG     = 7;
43
44    /**
45     * Message level short codes
46     * @var array
47     */
48    protected array $levels = [
49        0 => 'EMERGENCY',
50        1 => 'ALERT',
51        2 => 'CRITICAL',
52        3 => 'ERROR',
53        4 => 'WARNING',
54        5 => 'NOTICE',
55        6 => 'INFO',
56        7 => 'DEBUG'
57    ];
58
59    /**
60     * Log writers
61     * @var array
62     */
63    protected array $writers = [];
64
65    /**
66     * Log timestamp format
67     * @var string
68     */
69    protected string $timestampFormat = 'Y-m-d H:i:s';
70
71    /**
72     * Constructor
73     *
74     * Instantiate the logger object
75     *
76     * @param  WriterInterface|array|null $writer
77     * @param  string                 $timestampFormat
78     */
79    public function __construct(WriterInterface|array|null $writer = [], string $timestampFormat = 'Y-m-d H:i:s')
80    {
81        if ($timestampFormat !== null) {
82            $this->setTimestampFormat($timestampFormat);
83        }
84
85        if ($writer !== null) {
86            if (is_array($writer)) {
87                $this->addWriters($writer);
88            } else {
89                $this->addWriter($writer);
90            }
91        }
92    }
93
94    /**
95     * Add log writers
96     *
97     * @param  array $writers
98     * @return Logger
99     */
100    public function addWriters(array $writers): Logger
101    {
102        foreach ($writers as $writer) {
103            $this->addWriter($writer);
104        }
105        return $this;
106    }
107
108    /**
109     * Add a log writer
110     *
111     * @param  Writer\WriterInterface $writer
112     * @return Logger
113     */
114    public function addWriter(Writer\WriterInterface $writer): Logger
115    {
116        $this->writers[] = $writer;
117        return $this;
118    }
119
120    /**
121     * Get all log writers
122     *
123     * @return array
124     */
125    public function getWriters(): array
126    {
127        return $this->writers;
128    }
129
130    /**
131     * Set log level limit for all log writers
132     *
133     * @param  int $level
134     * @return Logger
135     */
136    public function setLogLimit(int $level): Logger
137    {
138        foreach ($this->writers as $writer) {
139            $writer->setLogLimit($level);
140        }
141        return $this;
142    }
143
144    /**
145     * Set timestamp format
146     *
147     * @param  string $format
148     * @return Logger
149     */
150    public function setTimestampFormat(string $format = 'Y-m-d H:i:s'): Logger
151    {
152        $this->timestampFormat = $format;
153        return $this;
154    }
155
156    /**
157     * Get timestamp format
158     *
159     * @return string
160     */
161    public function getTimestampFormat(): string
162    {
163        return $this->timestampFormat;
164    }
165
166    /**
167     * Get level
168     *
169     * @param  int $level
170     * @return string
171     */
172    public function getLevel(int $level): string
173    {
174        return $this->levels[(int)$level] ?? '';
175    }
176
177    /**
178     * Static method to get log level
179     *
180     * @param  int $level
181     * @return string
182     */
183    public static function getLogLevel(int $level): string
184    {
185        return (new self())->getLevel($level);
186    }
187
188    /**
189     * Add an EMERGENCY log entry
190     *
191     * @param  mixed $message
192     * @param  array $context
193     * @return Logger
194     */
195    public function emergency(mixed $message, array $context = []): Logger
196    {
197        return $this->log(self::EMERGENCY, $message, $context);
198    }
199
200    /**
201     * Add an ALERT log entry
202     *
203     * @param  mixed $message
204     * @param  array $context
205     * @return Logger
206     */
207    public function alert(mixed $message, array $context = []): Logger
208    {
209        return $this->log(self::ALERT, $message, $context);
210    }
211
212    /**
213     * Add a CRITICAL log entry
214     *
215     * @param  mixed $message
216     * @param  array $context
217     * @return Logger
218     */
219    public function critical(mixed $message, array $context = []): Logger
220    {
221        return $this->log(self::CRITICAL, $message, $context);
222    }
223
224    /**
225     * Add an ERROR log entry
226     *
227     * @param  mixed $message
228     * @param  array $context
229     * @return Logger
230     */
231    public function error(mixed $message, array $context = []): Logger
232    {
233        return $this->log(self::ERROR, $message, $context);
234    }
235
236    /**
237     * Add a WARNING log entry
238     *
239     * @param  mixed $message
240     * @param  array $context
241     * @return Logger
242     */
243    public function warning(mixed $message, array $context = []): Logger
244    {
245        return $this->log(self::WARNING, $message, $context);
246    }
247
248    /**
249     * Add a NOTICE log entry
250     *
251     * @param  mixed $message
252     * @param  array $context
253     * @return Logger
254     */
255    public function notice(mixed $message, array $context = []): Logger
256    {
257        return $this->log(self::NOTICE, $message, $context);
258    }
259
260    /**
261     * Add an INFO log entry
262     *
263     * @param  mixed $message
264     * @param  array $context
265     * @return Logger
266     */
267    public function info(mixed $message, array $context = []): Logger
268    {
269        return $this->log(self::INFO, $message, $context);
270    }
271
272    /**
273     * Add a DEBUG log entry
274     *
275     * @param  mixed $message
276     * @param  array $context
277     * @return Logger
278     */
279    public function debug(mixed $message, array $context = []): Logger
280    {
281        return $this->log(self::DEBUG, $message, $context);
282    }
283
284    /**
285     * Add a log entry
286     *
287     * @param  mixed $level
288     * @param  mixed $message
289     * @param  array $context
290     * @return Logger
291     */
292    public function log(mixed $level, mixed $message, array $context = []): Logger
293    {
294        if (!isset($context['timestamp'])) {
295            $context['timestamp'] = date($this->timestampFormat);
296        }
297        if (!isset($context['name'])) {
298            $context['name'] = $this->levels[$level];
299        }
300
301        foreach ($this->writers as $writer) {
302            $writer->writeLog($level, (string)$message, $context);
303        }
304
305        return $this;
306    }
307
308}