1: <?php
2: /**
3: * @copyright Copyright 2012-2013 Rackspace US, Inc.
4: See COPYING for licensing information.
5: * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0
6: * @version 1.5.9
7: * @author Jamie Hannaford <jamie.hannaford@rackspace.com>
8: */
9:
10: namespace OpenCloud\Common\Log;
11:
12: use OpenCloud\Common\Exceptions\LoggingException;
13:
14: /**
15: * Basic logger for OpenCloud which extends FIG's PSR-3 standard logger.
16: *
17: * @link https://github.com/php-fig/log
18: */
19: class Logger extends AbstractLogger
20: {
21: /**
22: * Is this debug class enabled or not?
23: *
24: * @var bool
25: */
26: private $enabled = false;
27:
28: /**
29: * These are the levels which will always be outputted - regardless of
30: * user-imposed settings.
31: *
32: * @var array
33: */
34: private $urgentLevels = array(
35: LogLevel::EMERGENCY,
36: LogLevel::ALERT,
37: LogLevel::CRITICAL
38: );
39:
40: /**
41: * Logging options.
42: *
43: * @var array
44: */
45: private $options = array(
46: 'outputToFile' => false,
47: 'logFile' => null,
48: 'dateFormat' => 'd/m/y H:I',
49: 'delimeter' => ' - '
50: );
51:
52: /**
53: * Determines whether a log level needs to be outputted.
54: *
55: * @param string $logLevel
56: * @return bool
57: */
58: private function outputIsUrgent($logLevel)
59: {
60: return in_array($logLevel, $this->urgentLevels);
61: }
62:
63: /**
64: * Interpolates context values into the message placeholders.
65: *
66: * @param string $message
67: * @param array $context
68: * @return type
69: */
70: private function interpolate($message, array $context = array())
71: {
72: // build a replacement array with braces around the context keys
73: $replace = array();
74: foreach ($context as $key => $val) {
75: $replace['{' . $key . '}'] = $val;
76: }
77:
78: // interpolate replacement values into the message and return
79: return strtr($message, $replace);
80: }
81:
82: /**
83: * Enable or disable the debug class.
84: *
85: * @param bool $enabled
86: * @return self
87: */
88: public function setEnabled($enabled)
89: {
90: $this->enabled = $enabled;
91: return $this;
92: }
93:
94: /**
95: * Is the debug class enabled?
96: *
97: * @return bool
98: */
99: public function getEnabled()
100: {
101: return $this->enabled;
102: }
103:
104: /**
105: * Set an array of options.
106: *
107: * @param array $options
108: */
109: public function setOptions(array $options = array())
110: {
111: foreach ($options as $key => $value) {
112: $this->setOption($key, $value);
113: }
114: }
115:
116: /**
117: * Get all options.
118: *
119: * @return array
120: */
121: public function getOptions()
122: {
123: return $this->options;
124: }
125:
126: /**
127: * Set an individual option.
128: *
129: * @param string $key
130: * @param string $value
131: */
132: public function setOption($key, $value)
133: {
134: if ($this->optionExists($key)) {
135: $this->options[$key] = $value;
136: }
137: }
138:
139: /**
140: * Get an individual option.
141: *
142: * @param string $key
143: * @return string|null
144: */
145: public function getOption($key)
146: {
147: if ($this->optionExists($key)) {
148: return $this->options[$key];
149: }
150: }
151:
152: /**
153: * Check whether an individual option exists.
154: *
155: * @param string $key
156: * @return bool
157: */
158: private function optionExists($key)
159: {
160: return array_key_exists($key, $this->getOptions());
161: }
162:
163: /**
164: * Outputs a log message if necessary.
165: *
166: * @param string $logLevel
167: * @param string $message
168: * @param string $context
169: */
170: public function log($level, $message, array $context = array())
171: {
172: if ($this->outputIsUrgent($level)
173: || $this->getEnabled() === true
174: || RAXSDK_DEBUG === true
175: ) {
176: $this->dispatch($message, $context);
177: }
178: }
179:
180: /**
181: * Used to format the line outputted in the log file.
182: *
183: * @param string $string
184: * @return string
185: */
186: private function formatFileLine($string)
187: {
188: $format = $this->getOption('dateFormat') . $this->getOption('delimeter');
189: return date($format) . $string;
190: }
191:
192: /**
193: * Dispatch a log output message.
194: *
195: * @param string $message
196: * @param array $context
197: * @throws LoggingException
198: */
199: private function dispatch($message, $context)
200: {
201: $output = $this->interpolate($message, $context) . PHP_EOL;
202:
203: if ($this->getOption('outputToFile') === true) {
204: $file = $this->getOption('logFile');
205:
206: if (!is_writable($file)) {
207: throw new LoggingException(
208: 'The log file either does not exist or is not writeable'
209: );
210: }
211:
212: // Output to file
213: file_put_contents($file, $this->formatFileLine($output));
214: } else {
215:
216: echo $output;
217: }
218: }
219:
220: }