BaseLogger::buildMessage()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 1
eloc 7
nc 1
nop 3
1
<?php
2
/*
3
 * This file is part of Yolk - Gamer Network's PHP Framework.
4
 *
5
 * Copyright (c) 2014 Gamer Network Ltd.
6
 * 
7
 * Distributed under the MIT License, a copy of which is available in the
8
 * LICENSE file that was bundled with this package, or online at:
9
 * https://github.com/gamernetwork/yolk-logger
10
 */
11
12
namespace yolk\log;
13
14
use yolk\contracts\log\Logger;
15
16
/**
17
 * Base logger class that defines the types of message that can be logged and
18
 * provides shortcut functions to log messages of a particular type.
19
 */
20
abstract class BaseLogger implements Logger {
21
22
	/**
23
	 * Messages above this level will not be logged.
24
	 * @var integer
25
	 */
26
	protected $threshold;
27
28
	/**
29
	 * Array of defined logging levels and their associated human-readable form.
30
	 * @var array
31
	 */
32
	protected $levels;
33
34
	public function __construct() {
35
36
		$this->setThreshold(LogLevel::WARNING);
37
38
		$this->levels = [
39
			LogLevel::EMERGENCY => 'emergency',
40
			LogLevel::ALERT     => 'alert',
41
			LogLevel::CRITICAL  => 'critical',
42
			LogLevel::ERROR     => 'error',
43
			LogLevel::WARNING   => 'warning',
44
			LogLevel::NOTICE    => 'notice',
45
			LogLevel::INFO      => 'info',
46
			LogLevel::DEBUG     => 'debug',
47
		];
48
49
	}
50
51
	/**
52
	 * Specify a threshold for logging messages.
53
	 * @param integer $level   new logging threshold level.
54
	 */
55
	public function setThreshold( $level ) {
56
		$this->threshold = $this->getLevel($level);
57
		return $this;
58
	}
59
60
	/**
61
	 * Get the current threshold.
62
	 * @return integer
63
	 */
64
	public function getThreshold() {
65
		return $this->threshold;
66
	}
67
68
	/**
69
	 * System is unusable.
70
	 * 
71
	 * @param string   $msg
72
	 * @param array    $context
73
	 * @return $this
74
	 */
75
	public function emergency( $msg, array $context = [] ) {
76
		return $this->log(LogLevel::EMERGENCY, $msg, $context);
77
	}
78
79
	/**
80
	 * Action must be taken immediately.
81
	 *
82
	 * Example: Entire website down, database unavailable, etc. This should
83
	 * trigger the SMS alerts and wake you up.
84
	 *
85
	 * @param string   $msg
86
	 * @param array    $context
87
	 * @return $this
88
	 */
89
	public function alert( $msg, array $context = [] ) {
90
		return $this->log(LogLevel::ALERT, $msg, $context);
91
	}
92
93
	/**
94
	 * Critical conditions.
95
	 *
96
	 * Example: Application component unavailable, unexpected exception.
97
	 *
98
	 * @param string   $msg
99
	 * @param array    $context
100
	 * @return $this
101
	 */
102
	public function critical( $msg, array $context = [] ) {
103
		return $this->log(LogLevel::CRITICAL, $msg, $context);
104
	}
105
106
	/**
107
	 * Runtime errors that do not require immediate action but should typically
108
	 * be logged and monitored.
109
	 *
110
	 * @param string   $msg
111
	 * @param array    $context
112
	 * @return $this
113
	 */
114
	public function error( $msg, array $context = [] ) {
115
		return $this->log(LogLevel::ERROR, $msg, $context);
116
	}
117
118
	/**
119
	 * Exceptional occurrences that are not errors.
120
	 *
121
	 * Example: Use of deprecated APIs, poor use of an API, undesirable things
122
	 * that are not necessarily wrong.
123
	 *
124
	 * @param string   $msg
125
	 * @param array    $context
126
	 * @return $this
127
	 */
128
	public function warning( $msg, array $context = [] ) {
129
		return $this->log(LogLevel::WARNING, $msg, $context);
130
	}
131
132
	/**
133
	 * Normal but significant events.
134
	 *
135
	 * @param string   $msg
136
	 * @param array    $context
137
	 * @return $this
138
	 */
139
	public function notice( $msg, array $context = [] ) {
140
		return $this->log(LogLevel::NOTICE, $msg, $context);
141
	}
142
143
	/**
144
	 * Interesting events.
145
	 *
146
	 * Example: User logs in, SQL logs.
147
	 *
148
	 * @param string   $msg
149
	 * @param array    $context
150
	 * @return $this
151
	 */
152
	public function info( $msg, array $context = [] ) {
153
		return $this->log(LogLevel::INFO, $msg, $context);
154
	}
155
156
	/**
157
	 * Detailed debug information.
158
	 *
159
	 * @param string   $msg
160
	 * @param array    $context
161
	 * @return $this
162
	 */
163
	public function debug( $msg, array $context = [] ) {
164
		return $this->log(LogLevel::DEBUG, $msg, $context);
165
	}
166
167
	/**
168
	 * Log a message of a specific level.
169
	 * @param integer  $level     one of the LOG_* constants.
170
	 * @param string   $msg       the message to log.
171
	 * @param array    $context   array of context information.
172
	 * @return $this
173
	 */
174
	public function log( $level, $msg, array $context = [] ) {
175
176
		$level = $this->getLevel($level);
177
178
		if( $level <= $this->threshold ) {
179
			$this->output(
180
				$level,
181
				$this->buildMessage($level, $msg, $context)
182
			);
183
		}
184
185
		return $this;
186
187
	}
188
189
	/**
190
	 * Send the message to the logger's output.
191
	 * @param string   $msg
192
	 * @param integer  $level
193
	 */
194
	abstract protected function output( $level, $msg );
195
196
	/**
197
	 * Make sure we have a valid level.
198
	 * @param  integer|string $level a 
199
	 * @return integer
200
	 */
201
	protected function getLevel( $level ) {
202
		if( $l = (int) $level )
203
			return $l;
204
		elseif( $l = (int) array_search($level, $this->levels) )
205
			return $l;
206
		else
207
			throw new \InvalidArgumentException("Invalid log level: '{$level}'");
208
	}
209
210
	/**
211
	 * Builds a nice error message including the level and current date/time.
212
	 * @param integer  $level   one of the LOG_* constants.
213
	 * @param string   $msg     the message to log.
214
	 * @param array    $context array of strings to be interpolated into the message
215
	 */
216
	protected function buildMessage( $level, $msg, $context = [] ) {
217
		return sprintf(
218
			"%s %s %s: %s\n",
219
			date('Y-m-d H:i:s'),
220
			$this->getPrefix($level),
221
			$this->levels[$level],
222
			trim($this->interpolate($msg, $context))
223
		);
224
	}
225
226
	/**
227
	 * Replace the token placeholders in a message with the corresponding values from the content array.
228
	 * @param  string $msg     the log message
229
	 * @param  array  $context the values to be interpolated into the log message
230
	 * @return string          the combined log message
231
	 */
232
	protected function interpolate( $msg, array $context ) {
233
		$replace = [];
234
		foreach( $context as $k => $v ) {
235
			$replace['{'.$k.'}'] = $v;
236
		}
237
		return strtr($msg, $replace);
238
	}
239
240
	/**
241
	 * A simple text token to indicate the level of a logged message
242
	 * @param  integer $level
243
	 * @return string
244
	 */
245
	protected function getPrefix( $level ) {
246
		$prefixes = [
247
			LogLevel::EMERGENCY => '[!!]',
248
			LogLevel::ALERT     => '[!!]',
249
			LogLevel::CRITICAL  => '[!!]',
250
			LogLevel::ERROR     => '[**]',
251
			LogLevel::WARNING   => '[**]',
252
			LogLevel::NOTICE    => '[--]',
253
			LogLevel::INFO      => '[--]',
254
			LogLevel::DEBUG     => '[..]',
255
		];
256
		return isset($prefixes[$level]) ? $prefixes[$level] : '[??]';
257
	}
258
259
}
260
261
// EOF