summaryrefslogtreecommitdiff
path: root/framework/Util/TLogRoute.php
blob: 10222c01fa2a141115e75fe99380535d845b6f75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<?php
/**
 * TLogRouter, TLogRoute, TFileLogRoute, TEmailLogRoute class file
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link http://www.pradosoft.com/
 * @copyright Copyright &copy; 2005-2014 PradoSoft
 * @license http://www.pradosoft.com/license/
 * @package System.Util
 */

/**
 * TLogRoute class.
 *
 * TLogRoute is the base class for all log route classes.
 * A log route object retrieves log messages from a logger and sends it
 * somewhere, such as files, emails.
 * The messages being retrieved may be filtered first before being sent
 * to the destination. The filters include log level filter and log category filter.
 *
 * To specify level filter, set {@link setLevels Levels} property,
 * which takes a string of comma-separated desired level names (e.g. 'Error, Debug').
 * To specify category filter, set {@link setCategories Categories} property,
 * which takes a string of comma-separated desired category names (e.g. 'System.Web, System.IO').
 *
 * Level filter and category filter are combinational, i.e., only messages
 * satisfying both filter conditions will they be returned.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @package System.Util
 * @since 3.0
 */
abstract class TLogRoute extends TApplicationComponent
{
	/**
	 * @var array lookup table for level names
	 */
	protected static $_levelNames=array(
		TLogger::DEBUG=>'Debug',
		TLogger::INFO=>'Info',
		TLogger::NOTICE=>'Notice',
		TLogger::WARNING=>'Warning',
		TLogger::ERROR=>'Error',
		TLogger::ALERT=>'Alert',
		TLogger::FATAL=>'Fatal'
	);
	/**
	 * @var array lookup table for level values
	 */
	protected static $_levelValues=array(
		'debug'=>TLogger::DEBUG,
		'info'=>TLogger::INFO,
		'notice'=>TLogger::NOTICE,
		'warning'=>TLogger::WARNING,
		'error'=>TLogger::ERROR,
		'alert'=>TLogger::ALERT,
		'fatal'=>TLogger::FATAL
	);
	/**
	 * @var integer log level filter (bits)
	 */
	private $_levels=null;
	/**
	 * @var array log category filter
	 */
	private $_categories=null;

	/**
	 * Initializes the route.
	 * @param TXmlElement configurations specified in {@link TLogRouter}.
	 */
	public function init($config)
	{
	}

	/**
	 * @return integer log level filter
	 */
	public function getLevels()
	{
		return $this->_levels;
	}

	/**
	 * @param integer|string integer log level filter (in bits). If the value is
	 * a string, it is assumed to be comma-separated level names. Valid level names
	 * include 'Debug', 'Info', 'Notice', 'Warning', 'Error', 'Alert' and 'Fatal'.
	 */
	public function setLevels($levels)
	{
		if(is_integer($levels))
			$this->_levels=$levels;
		else
		{
			$this->_levels=null;
			$levels=strtolower($levels);
			foreach(explode(',',$levels) as $level)
			{
				$level=trim($level);
				if(isset(self::$_levelValues[$level]))
					$this->_levels|=self::$_levelValues[$level];
			}
		}
	}

	/**
	 * @return array list of categories to be looked for
	 */
	public function getCategories()
	{
		return $this->_categories;
	}

	/**
	 * @param array|string list of categories to be looked for. If the value is a string,
	 * it is assumed to be comma-separated category names.
	 */
	public function setCategories($categories)
	{
		if(is_array($categories))
			$this->_categories=$categories;
		else
		{
			$this->_categories=null;
			foreach(explode(',',$categories) as $category)
			{
				if(($category=trim($category))!=='')
					$this->_categories[]=$category;
			}
		}
	}

	/**
	 * @param integer level value
	 * @return string level name
	 */
	protected function getLevelName($level)
	{
		return isset(self::$_levelNames[$level])?self::$_levelNames[$level]:'Unknown';
	}

	/**
	 * @param string level name
	 * @return integer level value
	 */
	protected function getLevelValue($level)
	{
		return isset(self::$_levelValues[$level])?self::$_levelValues[$level]:0;
	}

	/**
	 * Formats a log message given different fields.
	 * @param string message content
	 * @param integer message level
	 * @param string message category
	 * @param integer timestamp
	 * @return string formatted message
	 */
	protected function formatLogMessage($message,$level,$category,$time)
	{
		return @date('M d H:i:s',$time).' ['.$this->getLevelName($level).'] ['.$category.'] '.$message."\n";
	}

	/**
	 * Retrieves log messages from logger to log route specific destination.
	 * @param TLogger logger instance
	 */
	public function collectLogs(TLogger $logger)
	{
		$logs=$logger->getLogs($this->getLevels(),$this->getCategories());
		if(!empty($logs))
			$this->processLogs($logs);
	}

	/**
	 * Processes log messages and sends them to specific destination.
	 * Derived child classes must implement this method.
	 * @param array list of messages.  Each array elements represents one message
	 * with the following structure:
	 * array(
	 *   [0] => message
	 *   [1] => level
	 *   [2] => category
	 *   [3] => timestamp);
	 */
	abstract protected function processLogs($logs);
}