~tsep-dev/tsep/0.9-beta

« back to all changes in this revision

Viewing changes to branches/symfony/cake/libs/cake_log.php

  • Committer: geoffreyfishing
  • Date: 2011-01-11 23:46:12 UTC
  • Revision ID: svn-v4:ae0de26e-ed09-4cbe-9a20-e40b4c60ac6c::125
Created a symfony branch for future migration to symfony

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Logging.
 
4
 *
 
5
 * Log messages to text files.
 
6
 *
 
7
 * PHP versions 4 and 5
 
8
 *
 
9
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 
10
 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
 
11
 *
 
12
 * Licensed under The MIT License
 
13
 * Redistributions of files must retain the above copyright notice.
 
14
 *
 
15
 * @copyright     Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
 
16
 * @link          http://cakephp.org CakePHP(tm) Project
 
17
 * @package       cake
 
18
 * @subpackage    cake.cake.libs
 
19
 * @since         CakePHP(tm) v 0.2.9
 
20
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 
21
 */
 
22
/**
 
23
 * Set up error level constants to be used within the framework if they are not defined within the
 
24
 * system.
 
25
 *
 
26
 */
 
27
        if (!defined('LOG_WARNING')) {
 
28
                define('LOG_WARNING', 3);
 
29
        }
 
30
        if (!defined('LOG_NOTICE')) {
 
31
                define('LOG_NOTICE', 4);
 
32
        }
 
33
        if (!defined('LOG_DEBUG')) {
 
34
                define('LOG_DEBUG', 5);
 
35
        }
 
36
        if (!defined('LOG_INFO')) {
 
37
                define('LOG_INFO', 6);
 
38
        }
 
39
 
 
40
/**
 
41
 * Logs messages to configured Log adapters.  One or more adapters can be configured
 
42
 * using CakeLogs's methods.  If you don't configure any adapters, and write to the logs
 
43
 * a default FileLog will be autoconfigured for you.
 
44
 *
 
45
 * @package       cake
 
46
 * @subpackage    cake.cake.libs
 
47
 */
 
48
class CakeLog {
 
49
 
 
50
/**
 
51
 * An array of connected streams.
 
52
 * Each stream represents a callable that will be called when write() is called.
 
53
 *
 
54
 * @var array
 
55
 * @access protected
 
56
 */
 
57
        var $_streams = array();
 
58
 
 
59
/**
 
60
 * Get an instance
 
61
 *
 
62
 * @return void
 
63
 * @static
 
64
 */
 
65
        function &getInstance() {
 
66
                static $instance = array();
 
67
                if (!isset($instance[0])) {
 
68
                        $instance[0] =& new CakeLog();
 
69
                }
 
70
                return $instance[0];
 
71
        }
 
72
 
 
73
/**
 
74
 * Configure and add a new logging stream to CakeLog
 
75
 * You can use add loggers from app/libs use app.loggername, or any plugin/libs using plugin.loggername.
 
76
 *
 
77
 * ### Usage:
 
78
 *
 
79
 * {{{
 
80
 * CakeLog::config('second_file', array(
 
81
 *              'engine' => 'FileLog',
 
82
 *              'path' => '/var/logs/my_app/'
 
83
 * ));
 
84
 * }}}
 
85
 *
 
86
 * Will configure a FileLog instance to use the specified path.  All options that are not `engine`
 
87
 * are passed onto the logging adapter, and handled there.  Any class can be configured as a logging
 
88
 * adapter as long as it implements a `write` method with the following signature.
 
89
 *
 
90
 * `write($type, $message)`
 
91
 *
 
92
 * For an explaination of these parameters, see CakeLog::write()
 
93
 *
 
94
 * @param string $key The keyname for this logger, used to remove the logger later.
 
95
 * @param array $config Array of configuration information for the logger
 
96
 * @return boolean success of configuration.
 
97
 * @static
 
98
 */
 
99
        function config($key, $config) {
 
100
                if (empty($config['engine'])) {
 
101
                        trigger_error(__('Missing logger classname', true), E_USER_WARNING);
 
102
                        return false;
 
103
                }
 
104
                $self =& CakeLog::getInstance();
 
105
                $className = $self->_getLogger($config['engine']);
 
106
                if (!$className) {
 
107
                        return false;
 
108
                }
 
109
                unset($config['engine']);
 
110
                $self->_streams[$key] = new $className($config);
 
111
                return true;
 
112
        }
 
113
 
 
114
/**
 
115
 * Attempts to import a logger class from the various paths it could be on.
 
116
 * Checks that the logger class implements a write method as well.
 
117
 *
 
118
 * @param string $loggerName the plugin.className of the logger class you want to build.
 
119
 * @return mixed boolean false on any failures, string of classname to use if search was successful.
 
120
 * @access protected
 
121
 */
 
122
        function _getLogger($loggerName) {
 
123
                list($plugin, $loggerName) = pluginSplit($loggerName);
 
124
 
 
125
                if ($plugin) {
 
126
                        App::import('Lib', $plugin . '.log/' . $loggerName);
 
127
                } else {
 
128
                        if (!App::import('Lib', 'log/' . $loggerName)) {
 
129
                                App::import('Core', 'log/' . $loggerName);
 
130
                        }
 
131
                }
 
132
                if (!class_exists($loggerName)) {
 
133
                        trigger_error(sprintf(__('Could not load logger class %s', true), $loggerName), E_USER_WARNING);
 
134
                        return false;
 
135
                }
 
136
                if (!is_callable(array($loggerName, 'write'))) {
 
137
                        trigger_error(
 
138
                                sprintf(__('logger class %s does not implement a write method.', true), $loggerName),
 
139
                                E_USER_WARNING
 
140
                        );
 
141
                        return false;
 
142
                }
 
143
                return $loggerName;
 
144
        }
 
145
 
 
146
/**
 
147
 * Returns the keynames of the currently active streams
 
148
 *
 
149
 * @return array Array of configured log streams.
 
150
 * @access public
 
151
 * @static
 
152
 */
 
153
        function configured() {
 
154
                $self =& CakeLog::getInstance();
 
155
                return array_keys($self->_streams);
 
156
        }
 
157
 
 
158
/**
 
159
 * Removes a stream from the active streams.  Once a stream has been removed
 
160
 * it will no longer have messages sent to it.
 
161
 *
 
162
 * @param string $keyname Key name of a configured stream to remove.
 
163
 * @return void
 
164
 * @access public
 
165
 * @static
 
166
 */
 
167
        function drop($streamName) {
 
168
                $self =& CakeLog::getInstance();
 
169
                unset($self->_streams[$streamName]);
 
170
        }
 
171
 
 
172
/**
 
173
 * Configures the automatic/default stream a FileLog.
 
174
 *
 
175
 * @return void
 
176
 * @access protected
 
177
 */
 
178
        function _autoConfig() {
 
179
                if (!class_exists('FileLog')) {
 
180
                        App::import('Core', 'log/FileLog');
 
181
                }
 
182
                $this->_streams['default'] =& new FileLog(array('path' => LOGS));
 
183
        }
 
184
 
 
185
/**
 
186
 * Writes the given message and type to all of the configured log adapters.
 
187
 * Configured adapters are passed both the $type and $message variables. $type
 
188
 * is one of the following strings/values.
 
189
 *
 
190
 * ### Types:
 
191
 *
 
192
 * - `LOG_WARNING` => 'warning',
 
193
 * - `LOG_NOTICE` => 'notice',
 
194
 * - `LOG_INFO` => 'info',
 
195
 * - `LOG_DEBUG` => 'debug',
 
196
 * - `LOG_ERR` => 'error',
 
197
 * - `LOG_ERROR` => 'error'
 
198
 *
 
199
 * ### Usage:
 
200
 *
 
201
 * Write a message to the 'warning' log:
 
202
 * 
 
203
 * `CakeLog::write('warning', 'Stuff is broken here');`
 
204
 *
 
205
 * @param string $type Type of message being written
 
206
 * @param string $message Message content to log
 
207
 * @return boolean Success
 
208
 * @access public
 
209
 * @static
 
210
 */
 
211
        function write($type, $message) {
 
212
                if (!defined('LOG_ERROR')) {
 
213
                        define('LOG_ERROR', 2);
 
214
                }
 
215
                if (!defined('LOG_ERR')) {
 
216
                        define('LOG_ERR', LOG_ERROR);
 
217
                }
 
218
                $levels = array(
 
219
                        LOG_WARNING => 'warning',
 
220
                        LOG_NOTICE => 'notice',
 
221
                        LOG_INFO => 'info',
 
222
                        LOG_DEBUG => 'debug',
 
223
                        LOG_ERR => 'error',
 
224
                        LOG_ERROR => 'error'
 
225
                );
 
226
 
 
227
                if (is_int($type) && isset($levels[$type])) {
 
228
                        $type = $levels[$type];
 
229
                }
 
230
                $self =& CakeLog::getInstance();
 
231
                if (empty($self->_streams)) {
 
232
                        $self->_autoConfig();
 
233
                }
 
234
                $keys = array_keys($self->_streams);
 
235
                foreach ($keys as $key) {
 
236
                        $logger =& $self->_streams[$key];
 
237
                        $logger->write($type, $message);
 
238
                }
 
239
                return true;
 
240
        }
 
241
 
 
242
/**
 
243
 * An error_handler that will log errors to file using CakeLog::write();
 
244
 * You can control how verbose and what type of errors this error_handler will 
 
245
 * catch using `Configure::write('log', $value)`.  See core.php for more information.
 
246
 *
 
247
 *
 
248
 * @param integer $code Code of error
 
249
 * @param string $description Error description
 
250
 * @param string $file File on which error occurred
 
251
 * @param integer $line Line that triggered the error
 
252
 * @param array $context Context
 
253
 * @return void
 
254
 */
 
255
        function handleError($code, $description, $file = null, $line = null, $context = null) {
 
256
                if ($code === 2048 || $code === 8192) {
 
257
                        return;
 
258
                }
 
259
                switch ($code) {
 
260
                        case E_PARSE:
 
261
                        case E_ERROR:
 
262
                        case E_CORE_ERROR:
 
263
                        case E_COMPILE_ERROR:
 
264
                        case E_USER_ERROR:
 
265
                                $error = 'Fatal Error';
 
266
                                $level = LOG_ERROR;
 
267
                        break;
 
268
                        case E_WARNING:
 
269
                        case E_USER_WARNING:
 
270
                        case E_COMPILE_WARNING:
 
271
                        case E_RECOVERABLE_ERROR:
 
272
                                $error = 'Warning';
 
273
                                $level = LOG_WARNING;
 
274
                        break;
 
275
                        case E_NOTICE:
 
276
                        case E_USER_NOTICE:
 
277
                                $error = 'Notice';
 
278
                                $level = LOG_NOTICE;
 
279
                        break;
 
280
                        default:
 
281
                                return;
 
282
                        break;
 
283
                }
 
284
                $message = $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']';
 
285
                CakeLog::write($level, $message);
 
286
        }
 
287
}
 
288
 
 
289
if (!defined('DISABLE_DEFAULT_ERROR_HANDLING')) {
 
290
        set_error_handler(array('CakeLog', 'handleError'));
 
291
}