1 <?php
2 require_once 'Zend/Log.php';
3
4 /**
5 * Wrapper class for a logging handler like {@link Zend_Log}
6 * which takes a message (or a map of context variables) and
7 * sends it to one or more {@link Zend_Log_Writer_Abstract}
8 * subclasses for output.
9 *
10 * These priorities are currently supported:
11 * - SS_Log::ERR
12 * - SS_Log::WARN
13 * - SS_Log::NOTICE
14 *
15 * You can add an error writer by calling {@link SS_Log::add_writer()}
16 *
17 * Example usage of logging errors by email notification:
18 * <code>
19 * SS_Log::add_writer(new SS_LogEmailWriter('my@email.com'), SS_Log::ERR);
20 * </code>
21 *
22 * Example usage of logging errors by file:
23 * <code>
24 * SS_Log::add_writer(new SS_LogFileWriter('/var/log/silverstripe/errors.log'), SS_Log::ERR);
25 * </code>
26 *
27 * Example usage of logging at warnings and errors by setting the priority to '<=':
28 * <code>
29 * SS_Log::add_writer(new SS_LogEmailWriter('my@email.com'), SS_Log::WARN, '<=');
30 * </code>
31 *
32 * Each writer object can be assigned a formatter. The formatter is
33 * responsible for formatting the message before giving it to the writer.
34 * {@link SS_LogErrorEmailFormatter} is such an example that formats errors
35 * into HTML for human readability in an email client.
36 *
37 * Formatters are added to writers like this:
38 * <code>
39 * $logEmailWriter = new SS_LogEmailWriter('my@email.com');
40 * $myEmailFormatter = new MyLogEmailFormatter();
41 * $logEmailWriter->setFormatter($myEmailFormatter);
42 * </code>
43 *
44 * @package sapphire
45 * @subpackage dev
46 */
47 class SS_Log {
48
49 const ERR = Zend_Log::ERR;
50 const WARN = Zend_Log::WARN;
51 const NOTICE = Zend_Log::NOTICE;
52
53 /**
54 * Logger class to use.
55 * @see SS_Log::get_logger()
56 * @var string
57 */
58 public static $logger_class = 'SS_ZendLog';
59
60 /**
61 * @see SS_Log::get_logger()
62 * @var object
63 */
64 protected static $logger;
65
66 /**
67 * Get the logger currently in use, or create a new
68 * one if it doesn't exist.
69 *
70 * @return object
71 */
72 public static function get_logger() {
73 if(!self::$logger) {
74 self::$logger = new self::$logger_class;
75 }
76 return self::$logger;
77 }
78
79 /**
80 * Get all writers in use by the logger.
81 * @return array Collection of Zend_Log_Writer_Abstract instances
82 */
83 public static function get_writers() {
84 return self::get_logger()->getWriters();
85 }
86
87 /**
88 * Remove all writers currently in use.
89 */
90 public static function clear_writers() {
91 self::get_logger()->clearWriters();
92 }
93
94 /**
95 * Remove a writer instance from the logger.
96 * @param object $writer Zend_Log_Writer_Abstract instance
97 */
98 public static function remove_writer($writer) {
99 self::get_logger()->removeWriter($writer);
100 }
101
102 /**
103 * Add a writer instance to the logger.
104 * @param object $writer Zend_Log_Writer_Abstract instance
105 * @param const $priority Priority. Possible values: SS_Log::ERR, SS_Log::WARN or SS_Log::NOTICE
106 * @param $comparison Priority comparison operator. Acts on the integer values of the error
107 * levels, where more serious errors are lower numbers. By default this is "=", which means only
108 * the given priority will be logged. Set to "<=" if you want to track errors of *at least*
109 * the given priority.
110 */
111 public static function add_writer($writer, $priority = null, $comparison = '=') {
112 if($priority) $writer->addFilter(new Zend_Log_Filter_Priority($priority, $comparison));
113 self::get_logger()->addWriter($writer);
114 }
115
116 /**
117 * Dispatch a message by priority level.
118 *
119 * The message parameter can be either a string (a simple error
120 * message), or an array of variables. The latter is useful for passing
121 * along a list of debug information for the writer to handle, such as
122 * error code, error line, error context (backtrace).
123 *
124 * @param mixed $message Exception object or array of error context variables
125 * @param const $priority Priority. Possible values: SS_Log::ERR, SS_Log::WARN or SS_Log::NOTICE
126 */
127 public static function log($message, $priority) {
128 if($message instanceof Exception) {
129 $message = array(
130 'errno' => '',
131 'errstr' => $message->getMessage(),
132 'errfile' => $message->getFile(),
133 'errline' => $message->getLine(),
134 'errcontext' => $message->getTrace()
135 );
136 }
137 try {
138 self::get_logger()->log($message, $priority);
139 } catch(Exception $e) {
140 // @todo How do we handle exceptions thrown from Zend_Log?
141 // For example, an exception is thrown if no writers are added
142 }
143 }
144
145 }