Log   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 210
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 27
eloc 51
dl 0
loc 210
rs 10
c 1
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A error() 0 7 2
A info() 0 7 2
A emergency() 0 7 2
A debug() 0 7 2
A exception() 0 12 3
A warning() 0 7 2
A alert() 0 7 2
A notice() 0 7 2
A log() 0 18 2
A critical() 0 7 2
A interpolate() 0 16 5
A init() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Source\Infra\Logger;
6
7
/**
8
 * Logger class, following the PSR-3 recomendation...
9
 *
10
 * @version 0.1.0
11
 * @author Murilo Chianfa <github.com/MuriloChianfa
12
 * @package Source\Infra\Logger\Log
13
 */
14
abstract class Log implements LoggerInterface
15
{
16
    /**
17
     * @return void
18
     */
19
    final public static function init(): void
20
    {
21
        openlog('Mailler', LOG_PERROR, LOG_USER);
22
    }
23
24
    /**
25
     * System is unusable.
26
     *
27
     * @param string $message
28
     * @param array $context
29
     * @return void
30
     */
31
    final public static function emergency(string $message, array $context = []): void
32
    {
33
        if (LOG_LEVEL < LOG_EMERG) {
34
            return;
35
        }
36
37
        syslog(LOG_EMERG, self::interpolate($message, $context, LOG_EMERG));
38
    }
39
40
    /**
41
     * Action must be taken immediately.
42
     *
43
     * Example: Entire website down, database unavailable, etc. This should
44
     * trigger the SMS alerts and wake you up.
45
     *
46
     * @param string $message
47
     * @param array $context
48
     * @return void
49
     */
50
    final public static function alert(string $message, array $context = []): void
51
    {
52
        if (LOG_LEVEL < LOG_ALERT) {
53
            return;
54
        }
55
56
        syslog(LOG_ALERT, self::interpolate($message, $context, LOG_ALERT));
57
    }
58
59
    /**
60
     * Critical conditions.
61
     *
62
     * Example: Application component unavailable, unexpected exception.
63
     *
64
     * @param string $message
65
     * @param array $context
66
     * @return void
67
     */
68
    final public static function critical(string $message, array $context = []): void
69
    {
70
        if (LOG_LEVEL < LOG_CRIT) {
71
            return;
72
        }
73
74
        syslog(LOG_CRIT, self::interpolate($message, $context, LOG_CRIT));
75
    }
76
77
    /**
78
     * Runtime errors that do not require immediate action but should typically
79
     * be logged and monitored.
80
     *
81
     * @param string $message
82
     * @param array $context
83
     * @return void
84
     */
85
    final public static function error(string $message, array $context = []): void
86
    {
87
        if (LOG_LEVEL < LOG_ERR) {
88
            return;
89
        }
90
91
        syslog(LOG_ERR, self::interpolate($message, $context, LOG_ERR));
92
    }
93
94
    /**
95
     * Exceptional occurrences that are not errors.
96
     *
97
     * Example: Use of deprecated APIs, poor use of an API, undesirable things
98
     * that are not necessarily wrong.
99
     *
100
     * @param string $message
101
     * @param array $context
102
     * @return void
103
     */
104
    final public static function warning(string $message, array $context = []): void
105
    {
106
        if (LOG_LEVEL < LOG_WARNING) {
107
            return;
108
        }
109
110
        syslog(LOG_WARNING, self::interpolate($message, $context, LOG_WARNING));
111
    }
112
113
    /**
114
     * Normal but significant events.
115
     *
116
     * @param string $message
117
     * @param array $context
118
     * @return void
119
     */
120
    final public static function notice(string $message, array $context = []): void
121
    {
122
        if (LOG_LEVEL < LOG_NOTICE) {
123
            return;
124
        }
125
126
        syslog(LOG_NOTICE, self::interpolate($message, $context, LOG_NOTICE));
127
    }
128
129
    /**
130
     * Interesting events.
131
     *
132
     * Example: User logs in, SQL logs.
133
     *
134
     * @param string $message
135
     * @param array $context
136
     * @return void
137
     */
138
    final public static function info(string $message, array $context = []): void
139
    {
140
        if (LOG_LEVEL < LOG_INFO) {
141
            return;
142
        }
143
144
        syslog(LOG_INFO, self::interpolate($message, $context, LOG_INFO));
145
    }
146
147
    /**
148
     * Detailed debug information.
149
     *
150
     * @param string $message
151
     * @param array $context
152
     * @return void
153
     */
154
    final public static function debug(string $message, array $context = []): void
155
    {
156
        if (LOG_LEVEL < LOG_DEBUG) {
157
            return;
158
        }
159
160
        syslog(LOG_DEBUG, self::interpolate($message, $context, LOG_DEBUG));
161
    }
162
163
    /**
164
     * Logs with an arbitrary level.
165
     *
166
     * @param mixed $level
167
     * @param string $message
168
     * @param array $context
169
     * @return void
170
     */
171
    final public static function log(int $level, string $message, array $context = []): void
172
    {
173
        if (
174
            !in_array($level, [
175
            LOG_EMERG,
176
            LOG_ALERT,
177
            LOG_CRIT,
178
            LOG_ERR,
179
            LOG_WARNING,
180
            LOG_NOTICE,
181
            LOG_INFO,
182
            LOG_DEBUG
183
            ])
184
        ) {
185
            $level = LOG_NOTICE;
186
        }
187
188
        syslog($level, self::interpolate($message, $context, $level));
189
    }
190
191
    final public static function exception(\Throwable $exception): void
192
    {
193
        $errorCode = @$exception->getCode();
194
        $errorMessage = @$exception->getMessage();
195
        $errorClass = @get_class($exception) ?? 'unrecognized';
196
197
        if (!empty($exception->getTrace())) {
198
            $errorLine = @$exception->getTrace()[0]['line'] ?? '';
199
            $errorFile = @$exception->getTrace()[0]['file'] ?? '';
200
        }
201
202
        Log::error((empty($errorLine)) ? "[{$errorCode}][$errorClass] {$errorMessage}" : "[{$errorCode}][$errorClass] {$errorMessage} on line {$errorLine} of file {$errorFile}");
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $errorFile does not seem to be defined for all execution paths leading up to this point.
Loading history...
203
    }
204
205
    /**
206
     * Interpolates context values into the message placeholders.
207
     */
208
    private static function interpolate(string $message, array $context = [], $logLevel = LOG_DEBUG): string
209
    {
210
        // build a replacement array with braces around the context keys
211
        $replace = [];
212
213
        // check that the value can be cast to string
214
        foreach ($context as $key => $val) {
215
            if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
216
                $replace['{' . $key . '}'] = $val;
217
            }
218
        }
219
220
        $logLevelName = getLogLevelName($logLevel);
221
222
        // interpolate replacement values into the message and return
223
        return strtr("[{$logLevelName}] - " . $message, $replace);
224
    }
225
}
226