|
1 <?php |
|
2 // $Id: dblog.admin.inc,v 1.6.2.1 2008/09/17 05:47:53 goba Exp $ |
|
3 |
|
4 /** |
|
5 * @file |
|
6 * Administrative page callbacks for the dblog module. |
|
7 */ |
|
8 |
|
9 /** |
|
10 * dblog module settings form. |
|
11 * |
|
12 * @ingroup forms |
|
13 * @see system_settings_form() |
|
14 */ |
|
15 function dblog_admin_settings() { |
|
16 $form['dblog_row_limit'] = array( |
|
17 '#type' => 'select', |
|
18 '#title' => t('Discard log entries above the following row limit'), |
|
19 '#default_value' => variable_get('dblog_row_limit', 1000), |
|
20 '#options' => drupal_map_assoc(array(100, 1000, 10000, 100000, 1000000)), |
|
21 '#description' => t('The maximum number of rows to keep in the database log. Older entries will be automatically discarded. (Requires a correctly configured <a href="@cron">cron maintenance task</a>.)', array('@cron' => url('admin/reports/status'))) |
|
22 ); |
|
23 |
|
24 return system_settings_form($form); |
|
25 } |
|
26 |
|
27 /** |
|
28 * Menu callback; displays a listing of log messages. |
|
29 */ |
|
30 function dblog_overview() { |
|
31 $filter = dblog_build_filter_query(); |
|
32 $rows = array(); |
|
33 $icons = array( |
|
34 WATCHDOG_DEBUG => '', |
|
35 WATCHDOG_INFO => '', |
|
36 WATCHDOG_NOTICE => '', |
|
37 WATCHDOG_WARNING => theme('image', 'misc/watchdog-warning.png', t('warning'), t('warning')), |
|
38 WATCHDOG_ERROR => theme('image', 'misc/watchdog-error.png', t('error'), t('error')), |
|
39 WATCHDOG_CRITICAL => theme('image', 'misc/watchdog-error.png', t('critical'), t('critical')), |
|
40 WATCHDOG_ALERT => theme('image', 'misc/watchdog-error.png', t('alert'), t('alert')), |
|
41 WATCHDOG_EMERG => theme('image', 'misc/watchdog-error.png', t('emergency'), t('emergency')), |
|
42 ); |
|
43 $classes = array( |
|
44 WATCHDOG_DEBUG => 'dblog-debug', |
|
45 WATCHDOG_INFO => 'dblog-info', |
|
46 WATCHDOG_NOTICE => 'dblog-notice', |
|
47 WATCHDOG_WARNING => 'dblog-warning', |
|
48 WATCHDOG_ERROR => 'dblog-error', |
|
49 WATCHDOG_CRITICAL => 'dblog-critical', |
|
50 WATCHDOG_ALERT => 'dblog-alert', |
|
51 WATCHDOG_EMERG => 'dblog-emerg', |
|
52 ); |
|
53 |
|
54 $output = drupal_get_form('dblog_filter_form'); |
|
55 |
|
56 $header = array( |
|
57 ' ', |
|
58 array('data' => t('Type'), 'field' => 'w.type'), |
|
59 array('data' => t('Date'), 'field' => 'w.wid', 'sort' => 'desc'), |
|
60 t('Message'), |
|
61 array('data' => t('User'), 'field' => 'u.name'), |
|
62 array('data' => t('Operations')), |
|
63 ); |
|
64 |
|
65 $sql = "SELECT w.wid, w.uid, w.severity, w.type, w.timestamp, w.message, w.variables, w.link, u.name FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid"; |
|
66 $tablesort = tablesort_sql($header); |
|
67 if (!empty($filter['where'])) { |
|
68 $result = pager_query($sql ." WHERE ". $filter['where'] . $tablesort, 50, 0, NULL, $filter['args']); |
|
69 } |
|
70 else { |
|
71 $result = pager_query($sql . $tablesort, 50); |
|
72 } |
|
73 |
|
74 while ($dblog = db_fetch_object($result)) { |
|
75 $rows[] = array('data' => |
|
76 array( |
|
77 // Cells |
|
78 $icons[$dblog->severity], |
|
79 t($dblog->type), |
|
80 format_date($dblog->timestamp, 'small'), |
|
81 l(truncate_utf8(_dblog_format_message($dblog), 56, TRUE, TRUE), 'admin/reports/event/'. $dblog->wid, array('html' => TRUE)), |
|
82 theme('username', $dblog), |
|
83 $dblog->link, |
|
84 ), |
|
85 // Attributes for tr |
|
86 'class' => "dblog-". preg_replace('/[^a-z]/i', '-', $dblog->type) .' '. $classes[$dblog->severity] |
|
87 ); |
|
88 } |
|
89 |
|
90 if (!$rows) { |
|
91 $rows[] = array(array('data' => t('No log messages available.'), 'colspan' => 6)); |
|
92 } |
|
93 |
|
94 $output .= theme('table', $header, $rows, array('id' => 'admin-dblog')); |
|
95 $output .= theme('pager', NULL, 50, 0); |
|
96 |
|
97 return $output; |
|
98 } |
|
99 |
|
100 /** |
|
101 * Menu callback; generic function to display a page of the most frequent |
|
102 * dblog events of a specified type. |
|
103 */ |
|
104 function dblog_top($type) { |
|
105 |
|
106 $header = array( |
|
107 array('data' => t('Count'), 'field' => 'count', 'sort' => 'desc'), |
|
108 array('data' => t('Message'), 'field' => 'message') |
|
109 ); |
|
110 |
|
111 $result = pager_query("SELECT COUNT(wid) AS count, message, variables FROM {watchdog} WHERE type = '%s' GROUP BY message, variables ". tablesort_sql($header), 30, 0, "SELECT COUNT(DISTINCT(message)) FROM {watchdog} WHERE type = '%s'", $type); |
|
112 |
|
113 $rows = array(); |
|
114 while ($dblog = db_fetch_object($result)) { |
|
115 $rows[] = array($dblog->count, truncate_utf8(_dblog_format_message($dblog), 56, TRUE, TRUE)); |
|
116 } |
|
117 |
|
118 if (empty($rows)) { |
|
119 $rows[] = array(array('data' => t('No log messages available.'), 'colspan' => 2)); |
|
120 } |
|
121 |
|
122 $output = theme('table', $header, $rows); |
|
123 $output .= theme('pager', NULL, 30, 0); |
|
124 |
|
125 return $output; |
|
126 } |
|
127 |
|
128 /** |
|
129 * Menu callback; displays details about a log message. |
|
130 */ |
|
131 function dblog_event($id) { |
|
132 $severity = watchdog_severity_levels(); |
|
133 $output = ''; |
|
134 $result = db_query('SELECT w.*, u.name, u.uid FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid WHERE w.wid = %d', $id); |
|
135 if ($dblog = db_fetch_object($result)) { |
|
136 $rows = array( |
|
137 array( |
|
138 array('data' => t('Type'), 'header' => TRUE), |
|
139 t($dblog->type), |
|
140 ), |
|
141 array( |
|
142 array('data' => t('Date'), 'header' => TRUE), |
|
143 format_date($dblog->timestamp, 'large'), |
|
144 ), |
|
145 array( |
|
146 array('data' => t('User'), 'header' => TRUE), |
|
147 theme('username', $dblog), |
|
148 ), |
|
149 array( |
|
150 array('data' => t('Location'), 'header' => TRUE), |
|
151 l($dblog->location, $dblog->location), |
|
152 ), |
|
153 array( |
|
154 array('data' => t('Referrer'), 'header' => TRUE), |
|
155 l($dblog->referer, $dblog->referer), |
|
156 ), |
|
157 array( |
|
158 array('data' => t('Message'), 'header' => TRUE), |
|
159 _dblog_format_message($dblog), |
|
160 ), |
|
161 array( |
|
162 array('data' => t('Severity'), 'header' => TRUE), |
|
163 $severity[$dblog->severity], |
|
164 ), |
|
165 array( |
|
166 array('data' => t('Hostname'), 'header' => TRUE), |
|
167 check_plain($dblog->hostname), |
|
168 ), |
|
169 array( |
|
170 array('data' => t('Operations'), 'header' => TRUE), |
|
171 $dblog->link, |
|
172 ), |
|
173 ); |
|
174 $attributes = array('class' => 'dblog-event'); |
|
175 $output = theme('table', array(), $rows, $attributes); |
|
176 } |
|
177 return $output; |
|
178 } |
|
179 |
|
180 /** |
|
181 * Build query for dblog administration filters based on session. |
|
182 */ |
|
183 function dblog_build_filter_query() { |
|
184 if (empty($_SESSION['dblog_overview_filter'])) { |
|
185 return; |
|
186 } |
|
187 |
|
188 $filters = dblog_filters(); |
|
189 |
|
190 // Build query |
|
191 $where = $args = array(); |
|
192 foreach ($_SESSION['dblog_overview_filter'] as $key => $filter) { |
|
193 $filter_where = array(); |
|
194 foreach ($filter as $value) { |
|
195 $filter_where[] = $filters[$key]['where']; |
|
196 $args[] = $value; |
|
197 } |
|
198 if (!empty($filter_where)) { |
|
199 $where[] = '('. implode(' OR ', $filter_where) .')'; |
|
200 } |
|
201 } |
|
202 $where = !empty($where) ? implode(' AND ', $where) : ''; |
|
203 |
|
204 return array( |
|
205 'where' => $where, |
|
206 'args' => $args, |
|
207 ); |
|
208 } |
|
209 |
|
210 |
|
211 /** |
|
212 * List dblog administration filters that can be applied. |
|
213 */ |
|
214 function dblog_filters() { |
|
215 $filters = array(); |
|
216 |
|
217 foreach (_dblog_get_message_types() as $type) { |
|
218 $types[$type] = $type; |
|
219 } |
|
220 |
|
221 if (!empty($types)) { |
|
222 $filters['type'] = array( |
|
223 'title' => t('Type'), |
|
224 'where' => "w.type = '%s'", |
|
225 'options' => $types, |
|
226 ); |
|
227 } |
|
228 |
|
229 $filters['severity'] = array( |
|
230 'title' => t('Severity'), |
|
231 'where' => 'w.severity = %d', |
|
232 'options' => watchdog_severity_levels(), |
|
233 ); |
|
234 |
|
235 return $filters; |
|
236 } |
|
237 |
|
238 /** |
|
239 * Formats a log message for display. |
|
240 * |
|
241 * @param $dblog |
|
242 * An object with at least the message and variables properties |
|
243 */ |
|
244 function _dblog_format_message($dblog) { |
|
245 // Legacy messages and user specified text |
|
246 if ($dblog->variables === 'N;') { |
|
247 return $dblog->message; |
|
248 } |
|
249 // Message to translate with injected variables |
|
250 else { |
|
251 return t($dblog->message, unserialize($dblog->variables)); |
|
252 } |
|
253 } |
|
254 |
|
255 |
|
256 /** |
|
257 * Return form for dblog administration filters. |
|
258 * |
|
259 * @ingroup forms |
|
260 * @see dblog_filter_form_submit() |
|
261 * @see dblog_filter_form_validate() |
|
262 */ |
|
263 function dblog_filter_form() { |
|
264 $session = &$_SESSION['dblog_overview_filter']; |
|
265 $session = is_array($session) ? $session : array(); |
|
266 $filters = dblog_filters(); |
|
267 |
|
268 $form['filters'] = array( |
|
269 '#type' => 'fieldset', |
|
270 '#title' => t('Filter log messages'), |
|
271 '#theme' => 'dblog_filters', |
|
272 '#collapsible' => TRUE, |
|
273 '#collapsed' => empty($session), |
|
274 ); |
|
275 foreach ($filters as $key => $filter) { |
|
276 $form['filters']['status'][$key] = array( |
|
277 '#title' => $filter['title'], |
|
278 '#type' => 'select', |
|
279 '#multiple' => TRUE, |
|
280 '#size' => 8, |
|
281 '#options' => $filter['options'], |
|
282 ); |
|
283 if (!empty($session[$key])) { |
|
284 $form['filters']['status'][$key]['#default_value'] = $session[$key]; |
|
285 } |
|
286 } |
|
287 |
|
288 $form['filters']['buttons']['submit'] = array( |
|
289 '#type' => 'submit', |
|
290 '#value' => t('Filter'), |
|
291 ); |
|
292 if (!empty($session)) { |
|
293 $form['filters']['buttons']['reset'] = array( |
|
294 '#type' => 'submit', |
|
295 '#value' => t('Reset') |
|
296 ); |
|
297 } |
|
298 |
|
299 return $form; |
|
300 } |
|
301 |
|
302 /** |
|
303 * Validate result from dblog administration filter form. |
|
304 */ |
|
305 function dblog_filter_form_validate($form, &$form_state) { |
|
306 if ($form_state['values']['op'] == t('Filter') && empty($form_state['values']['type']) && empty($form_state['values']['severity'])) { |
|
307 form_set_error('type', t('You must select something to filter by.')); |
|
308 } |
|
309 } |
|
310 |
|
311 /** |
|
312 * Process result from dblog administration filter form. |
|
313 */ |
|
314 function dblog_filter_form_submit($form, &$form_state) { |
|
315 $op = $form_state['values']['op']; |
|
316 $filters = dblog_filters(); |
|
317 switch ($op) { |
|
318 case t('Filter'): |
|
319 foreach ($filters as $name => $filter) { |
|
320 if (isset($form_state['values'][$name])) { |
|
321 $_SESSION['dblog_overview_filter'][$name] = $form_state['values'][$name]; |
|
322 } |
|
323 } |
|
324 break; |
|
325 case t('Reset'): |
|
326 $_SESSION['dblog_overview_filter'] = array(); |
|
327 break; |
|
328 } |
|
329 return 'admin/reports/dblog'; |
|
330 } |