Logger::error()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
/**
3
 * Logging utility for Erdiko
4
 *
5
 * @package     erdiko/core
6
 * @copyright   2012-2017 Arroyo Labs, Inc. http://www.arroyolabs.com
7
 * @author      Varun Brahme
8
 * @author      Coleman Tung
9
 * @author      John Arroyo <[email protected]>
10
 */
11
namespace erdiko\core;
12
13
use erdiko\core\datasource\File;
14
use \Psr\Log\LoggerInterface;
15
use \Psr\Log\InvalidArgumentException;
16
use \Psr\Log\LogLevel;
17
18
19
class Logger extends File implements LoggerInterface
20
{
21
    
22
    /** Log files */
23
    protected $_logFiles = array(
24
        "default" => "system.log",
25
    );
26
    protected $_defaultPath = '/var/logs';
27
    
28
    /**
29
     * Constructor
30
     *
31
     * @param array $logFiles
32
     * @param string $logDir fully qualified path or a path relative to the erdiko root
33
     */
34
    public function __construct($logFiles = array(), $logDir = null)
35
    {
36
        // Set the log files
37
        if (!empty($logFiles)) {
38
            $this->_logFiles = array_merge($this->_logFiles, array_change_key_case($logFiles));
39
        }
40
        
41
        // Set the logging directory
42
        if (!empty($logDir)) {
43
            if (is_dir($logDir)) {
44
                $this->_filePath = $logDir; // fully qualified & valid path
45
            } else {
46
                $this->_filePath = \ERDIKO_ROOT.$logDir; // otherwise assume it's relative to the root
47
            }
48
        } else {
49
            $this->_filePath = \ERDIKO_ROOT.$this->_defaultPath;
50
        }
51
    }
52
    
53
    /**
54
     * Log
55
     *
56
     * @param string $level
57
     * @param string or an object with a __toString() method$ message
58
     * @param array $context
59
     * @return bool
60
     */
61
    public function log($level, $message, array $context = array())
62
    {
63
        switch ($level) {
64
            case \Psr\Log\LogLevel::EMERGENCY:
65
                return $this->emergency($message, $context);
66
            case \Psr\Log\LogLevel::ALERT:
67
                return $this->alert($message, $context);
68
            case \Psr\Log\LogLevel::CRITICAL:
69
                return $this->critical($message, $context);
70
            case \Psr\Log\LogLevel::ERROR:
71
                return $this->error($message, $context);
72
            case \Psr\Log\LogLevel::WARNING:
73
                return $this->warning($message, $context);
74
            case \Psr\Log\LogLevel::NOTICE:
75
                return $this->notice($message, $context);
76
            case \Psr\Log\LogLevel::INFO:
77
                return $this->info($message, $context);
78
            case \Psr\Log\LogLevel::DEBUG:
79
                return $this->debug($message, $context);
80
            default:
81
                // PSR-3 states that we must throw a \Psr\Log\InvalidArgumentException
82
                // if we don't recognize the level
83
                throw new \InvalidArgumentException(
84
                    "Unknown severity level passed to Logger"
85
                );
86
        }
87
    }
88
89
    /**
90
     * Add Record
91
     *
92
     * @param string $level
93
     * @param string or an object with a __toString() method$ message
94
     * @param array $context
95
     * @return bool
96
     */
97
    public function addRecord($level, $message, array $context = array())
98
    {
99
        $message = (string) $message;
100
        $logString=date('Y-m-d H:i:s')." ".$level.": ".$this->interpolate($message, $context).PHP_EOL;
101
        $logFileName=$this->_logFiles["default"]; // If log key is null use the default log file
102
103
        return $this->write($logString, $logFileName, null, "a");
104
    }
105
106
    /**
107
     * Implementation of Placeholder Interpolation
108
     * The message MAY contain placeholders which implementors MAY replace with values from the context array.
109
     * Placeholder names MUST correspond to keys in the context array.
110
     *
111
     * @param string $message or an object with a __toString() method
112
     * @param array $context replacement values for placeholders
113
     * @return bool
114
     */
115
    function interpolate($message, array $context = array())
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
116
    {
117
        // build a replacement array with braces around the context keys
118
        $replace = array();
119
        foreach ($context as $key => $val) {
120
            if ($key == "exception" && $val instanceof \Exception) {
121
                $replace['{' . $key . '}'] = $val->getMessage();
122
            } else {
123
                $replace['{' . $key . '}'] = $val;
124
            }
125
        }
126
127
        // interpolate replacement values into the message and return
128
        return strtr($message, $replace);
129
    }
130
131
    /**
132
     * Add log file
133
     * Valid if multiple log files exist
134
     *
135
     * @param mixed $key
136
     * @param string $logFileName
137
     * @return bool
138
     */
139
    public function addLogFile($key, $logFileName)
140
    {
141
        $arrayKey=strtolower($key);
142
        return $this->_logFiles[$arrayKey] = $logFileName;
143
    }
144
145
    /**
146
     * Remove log file
147
     * Valid if multiple log files exist
148
     *
149
     * @param mixed $key
150
     */
151
    public function removeLogFile($key)
152
    {
153
         $arrayKey=strtolower($key);
154
         unset($this->_logFiles[$arrayKey]);
155
         return true;
156
    }
157
158
     /**
159
      * Clear Log
160
      *
161
      * @param string $logKey
162
      * @return bool
163
      */
164
    public function clearLog($logKey = null)
165
    {
166
        $ret=true;
167
        if ($logKey==null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $logKey of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
168
            foreach ($this->_logFiles as $key => $logFile) {
169
                $ret = $ret && $this->write("", $logFile);
170
            }
171
            return $ret;
172
        } else {
173
            $arrayKey=strtolower($logKey);
174
            if (isset($this->_logFiles[$arrayKey])) {
175
                return $this->write("", $this->_logFiles[$arrayKey]);
176
            } else {
177
                return 0;
178
            }
179
        }
180
    }
181
182
    /** Destructor */
183
    public function __destruct()
184
    {
185
    }
186
187
    /**
188
     * System is unusable.
189
     *
190
     * @param string $message
191
     * @param array $context
192
     *
193
     * @return null
194
     */
195
    public function emergency($message, array $context = array())
196
    {
197
        // TODO: Implement emergency() method.
198
        return $this->addRecord(\Psr\Log\LogLevel::EMERGENCY, $message, $context);
199
    }
200
201
    /**
202
     * Action must be taken immediately.
203
     *
204
     * Example: Entire website down, database unavailable, etc. This should
205
     * trigger the SMS alerts and wake you up.
206
     *
207
     * @param string $message
208
     * @param array $context
209
     *
210
     * @return null
211
     */
212
    public function alert($message, array $context = array())
213
    {
214
        // TODO: Implement alert() method.
215
        return $this->addRecord(\Psr\Log\LogLevel::ALERT, $message, $context);
216
    }
217
218
    /**
219
     * Critical conditions.
220
     *
221
     * Example: Application component unavailable, unexpected exception.
222
     *
223
     * @param string $message
224
     * @param array $context
225
     *
226
     * @return null
227
     */
228
    public function critical($message, array $context = array())
229
    {
230
        // TODO: Implement critical() method.
231
        return $this->addRecord(\Psr\Log\LogLevel::CRITICAL, $message, $context);
232
    }
233
234
    /**
235
     * Runtime errors that do not require immediate action but should typically
236
     * be logged and monitored.
237
     *
238
     * @param string $message
239
     * @param array $context
240
     *
241
     * @return null
242
     */
243
    public function error($message, array $context = array())
244
    {
245
        // TODO: Implement error() method.
246
        return $this->addRecord(\Psr\Log\LogLevel::ERROR, $message, $context);
247
    }
248
249
    /**
250
     * Exceptional occurrences that are not errors.
251
     *
252
     * Example: Use of deprecated APIs, poor use of an API, undesirable things
253
     * that are not necessarily wrong.
254
     *
255
     * @param string $message
256
     * @param array $context
257
     *
258
     * @return null
259
     */
260
    public function warning($message, array $context = array())
261
    {
262
        // TODO: Implement warning() method.
263
        return $this->addRecord(\Psr\Log\LogLevel::WARNING, $message, $context);
264
    }
265
266
    /**
267
     * Normal but significant events.
268
     *
269
     * @param string $message
270
     * @param array $context
271
     *
272
     * @return null
273
     */
274
    public function notice($message, array $context = array())
275
    {
276
        // TODO: Implement notice() method.
277
        return $this->addRecord(\Psr\Log\LogLevel::NOTICE, $message, $context);
278
    }
279
280
    /**
281
     * Interesting events.
282
     *
283
     * Example: User logs in, SQL logs.
284
     *
285
     * @param string $message
286
     * @param array $context
287
     *
288
     * @return null
289
     */
290
    public function info($message, array $context = array())
291
    {
292
        // TODO: Implement info() method.
293
        return $this->addRecord(\Psr\Log\LogLevel::INFO, $message, $context);
294
    }
295
296
    /**
297
     * Detailed debug information.
298
     *
299
     * @param string $message
300
     * @param array $context
301
     *
302
     * @return null
303
     */
304
    public function debug($message, array $context = array())
305
    {
306
        // TODO: Implement debug() method.
307
        return $this->addRecord(\Psr\Log\LogLevel::DEBUG, $message, $context);
308
    }
309
}
310