Newer
Older
// $Id$
Dries Buytaert
committed
* The dblog module monitors your site and keeps a list of
* recorded events containing usage and performance data, errors,
* warnings, and similar operational information.
*
* @see watchdog().
*/
/**
* Implementation of hook_help().
*/
Dries Buytaert
committed
function dblog_help($section) {
Dries Buytaert
committed
case 'admin/help#dblog':
$output = '<p>'. t('The dblog module monitors your system, capturing system events in a log to be reviewed by an authorized individual at a later time. This is useful for site administrators who want a quick overview of activities on their site. The logs also record the sequence of events, so it can be useful for debugging site errors.') .'</p>';
$output .= '<p>'. t('The dblog log is simply a list of recorded events containing usage data, performance data, errors, warnings and operational information. Administrators should check the dblog report on a regular basis to ensure their site is working properly.') .'</p>';
$output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@dblog">Dblog page</a>.', array('@dblog' => 'http://drupal.org/handbook/modules/dblog/')) .'</p>';
Dries Buytaert
committed
return $output;
case 'admin/logs':
Dries Buytaert
committed
return '<p>'. t('The dblog module monitors your website, capturing system events in a log to be reviewed by an authorized individual at a later time. The dblog log is simply a list of recorded events containing usage data, performance data, errors, warnings and operational information. It is vital to check the dblog report on a regular basis as it is often the only way to tell what is going on.') .'</p>';
Dries Buytaert
committed
/**
* Implementation of hook_theme()
*/
Dries Buytaert
committed
function dblog_theme() {
Dries Buytaert
committed
return array(
Dries Buytaert
committed
'dblog_form_overview' => array(
Dries Buytaert
committed
'arguments' => array('form' => NULL),
),
);
}
Dries Buytaert
committed
function dblog_menu() {
$items['admin/settings/logging/dblog'] = array(
'title' => t('Database logging'),
'description' => t('Settings for logging to the Drupal database logs. This is the most common method for small to medium sites on shared hosting. The logs are viewable from the admin pages.'),
Dries Buytaert
committed
'page callback' => 'drupal_get_form',
'page arguments' => array('dblog_admin_settings'),
);
$items['admin/logs/dblog'] = array(
Dries Buytaert
committed
'title' => t('Recent log entries'),
'description' => t('View events that have recently been logged.'),
Dries Buytaert
committed
'page callback' => 'dblog_overview',
Dries Buytaert
committed
'weight' => -1,
);
$items['admin/logs/page-not-found'] = array(
'title' => t("Top 'page not found' errors"),
'description' => t("View 'page not found' errors (404s)."),
Dries Buytaert
committed
'page callback' => 'dblog_top',
Dries Buytaert
committed
'page arguments' => array('page not found'),
);
$items['admin/logs/access-denied'] = array(
'title' => t("Top 'access denied' errors"),
'description' => t("View 'access denied' errors (403s)."),
Dries Buytaert
committed
'page callback' => 'dblog_top',
Dries Buytaert
committed
'page arguments' => array('access denied'),
);
$items['admin/logs/event/%'] = array(
'title' => t('Details'),
Dries Buytaert
committed
'page callback' => 'dblog_event',
Dries Buytaert
committed
'page arguments' => array(3),
'type' => MENU_CALLBACK,
);
return $items;
}
Dries Buytaert
committed
function dblog_init() {
Dries Buytaert
committed
if (arg(0) == 'admin' && arg(1) == 'logs') {
// Add the CSS for this module
Dries Buytaert
committed
drupal_add_css(drupal_get_path('module', 'dblog') .'/dblog.css', 'module', 'all', FALSE);
Dries Buytaert
committed
function dblog_admin_settings() {
$form['dblog_row_limit'] = array(
'#type' => 'select',
'#title' => t('Discard log entries above the following row limit'),
'#default_value' => variable_get('dblog_row_limit', 1000),
'#options' => drupal_map_assoc(array(100, 1000, 10000, 100000, 1000000)),
'#description' => t('The maximum number of rows to keep in the database log. Older entries will be automatically discarded. Requires crontab.')
);
return system_settings_form($form);
}
/**
* Implementation of hook_cron().
*
Dries Buytaert
committed
function dblog_cron() {
// Cleanup the watchdog table
$min = db_result(db_query('SELECT MIN(wid) FROM {watchdog}'));
if ($min) {
$max = db_result(db_query('SELECT MAX(wid) FROM {watchdog}'));
if ($max) {
if (($max - $min) > variable_get('dblog_row_limit', 1000)) {
db_query('DELETE FROM {watchdog} WHERE wid < %d', $max - $min);
}
}
}
Gerhard Killesreiter
committed
/**
* Implementation of hook_user().
*/
Dries Buytaert
committed
function dblog_user($op, &$edit, &$user) {
Gerhard Killesreiter
committed
if ($op == 'delete') {
db_query('UPDATE {watchdog} SET uid = 0 WHERE uid = %d', $user->uid);
Gerhard Killesreiter
committed
}
}
Dries Buytaert
committed
function dblog_form_overview() {
Dries Buytaert
committed
$names['all'] = t('all messages');
Dries Buytaert
committed
foreach (_dblog_get_message_types() as $type) {
$names[$type] = t('!type messages', array('!type' => t($type)));
Dries Buytaert
committed
}
Dries Buytaert
committed
if (empty($_SESSION['dblog_overview_filter'])) {
$_SESSION['dblog_overview_filter'] = 'all';
Dries Buytaert
committed
}
Dries Buytaert
committed
'#type' => 'select',
'#title' => t('Filter by message type'),
'#options' => $names,
Dries Buytaert
committed
'#default_value' => $_SESSION['dblog_overview_filter']
$form['submit'] = array('#type' => 'submit', '#value' => t('Filter'));
Dries Buytaert
committed
$form['#redirect'] = FALSE;
return $form;
}
/**
* Menu callback; displays a listing of log messages.
*/
Dries Buytaert
committed
function dblog_overview() {
$rows = array();
$icons = array(WATCHDOG_NOTICE => '',
WATCHDOG_WARNING => theme('image', 'misc/watchdog-warning.png', t('warning'), t('warning')),
WATCHDOG_ERROR => theme('image', 'misc/watchdog-error.png', t('error'), t('error')));
Dries Buytaert
committed
$classes = array(WATCHDOG_NOTICE => 'dblog-notice', WATCHDOG_WARNING => 'dblog-warning', WATCHDOG_ERROR => 'dblog-error');
Dries Buytaert
committed
$output = drupal_get_form('dblog_form_overview');
Dries Buytaert
committed
Dries Buytaert
committed
array('data' => t('Type'), 'field' => 'w.type'),
array('data' => t('Date'), 'field' => 'w.wid', 'sort' => 'desc'),
array('data' => t('Message'), 'field' => 'w.message'),
array('data' => t('User'), 'field' => 'u.name'),
Dries Buytaert
committed
array('data' => t('Operations'))
$sql = "SELECT w.wid, w.uid, w.severity, w.type, w.timestamp, w.message, w.link, u.name FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid";
$tablesort = tablesort_sql($header);
Dries Buytaert
committed
$type = $_SESSION['dblog_overview_filter'];
if ($type != 'all') {
$result = pager_query($sql ." WHERE w.type = '%s'". $tablesort, 50, 0, NULL, $type);
}
else {
$result = pager_query($sql . $tablesort, 50);
}
Dries Buytaert
committed
while ($dblog = db_fetch_object($result)) {
Steven Wittens
committed
$rows[] = array('data' =>
array(
// Cells
Dries Buytaert
committed
$icons[$dblog->severity],
t($dblog->type),
format_date($dblog->timestamp, 'small'),
l(truncate_utf8($dblog->message, 56, TRUE, TRUE), 'admin/logs/event/'. $dblog->wid, array('html' => TRUE)),
theme('username', $dblog),
$dblog->link,
Steven Wittens
committed
),
// Attributes for tr
Dries Buytaert
committed
'class' => "dblog-". preg_replace('/[^a-z]/i', '-', $dblog->type) .' '. $classes[$dblog->severity]
Dries Buytaert
committed
$rows[] = array(array('data' => t('No log messages available.'), 'colspan' => 6));
Dries Buytaert
committed
$output .= theme('table', $header, $rows);
Gerhard Killesreiter
committed
$output .= theme('pager', NULL, 50, 0);
Dries Buytaert
committed
return $output;
}
/**
* Menu callback; generic function to display a page of the most frequent
Dries Buytaert
committed
* dblog events of a specified type.
*/
Dries Buytaert
committed
function dblog_top($type) {
$header = array(
array('data' => t('Count'), 'field' => 'count', 'sort' => 'desc'),
array('data' => t('Message'), 'field' => 'message')
);
$result = pager_query("SELECT COUNT(wid) AS count, message FROM {watchdog} WHERE type = '%s' GROUP BY message ". tablesort_sql($header), 30, 0, "SELECT COUNT(DISTINCT(message)) FROM {watchdog} WHERE type = '%s'", $type);
Dries Buytaert
committed
$rows = array();
Dries Buytaert
committed
while ($dblog = db_fetch_object($result)) {
$rows[] = array($dblog->count, truncate_utf8($dblog->message, 56, TRUE, TRUE));
}
Dries Buytaert
committed
if (empty($rows)) {
$rows[] = array(array('data' => t('No log messages available.'), 'colspan' => 2));
}
$output = theme('table', $header, $rows);
$output .= theme('pager', NULL, 30, 0);
Dries Buytaert
committed
function theme_dblog_form_overview($form) {
Dries Buytaert
committed
return '<div class="container-inline">'. drupal_render($form) .'</div>';
Dries Buytaert
committed
function dblog_form_overview_submit($form_id, $form_values) {
$_SESSION['dblog_overview_filter'] = $form_values['filter'];
/**
* Menu callback; displays details about a log message.
*/
Dries Buytaert
committed
function dblog_event($id) {
$severity = array(WATCHDOG_NOTICE => t('notice'), WATCHDOG_WARNING => t('warning'), WATCHDOG_ERROR => t('error'));
$output = '';
$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);
Dries Buytaert
committed
if ($dblog = db_fetch_object($result)) {
Dries Buytaert
committed
$rows = array(
array(
array('data' => t('Type'), 'header' => TRUE),
Dries Buytaert
committed
t($dblog->type),
Dries Buytaert
committed
),
array(
array('data' => t('Date'), 'header' => TRUE),
Dries Buytaert
committed
format_date($dblog->timestamp, 'large'),
Dries Buytaert
committed
),
array(
array('data' => t('User'), 'header' => TRUE),
Dries Buytaert
committed
theme('username', $dblog),
Dries Buytaert
committed
),
array(
array('data' => t('Location'), 'header' => TRUE),
Dries Buytaert
committed
l($dblog->location, $dblog->location),
Dries Buytaert
committed
),
array(
array('data' => t('Referrer'), 'header' => TRUE),
Dries Buytaert
committed
l($dblog->referer, $dblog->referer),
Dries Buytaert
committed
),
array(
array('data' => t('Message'), 'header' => TRUE),
Dries Buytaert
committed
$dblog->message,
Dries Buytaert
committed
),
array(
array('data' => t('Severity'), 'header' => TRUE),
Dries Buytaert
committed
$severity[$dblog->severity],
Dries Buytaert
committed
),
array(
array('data' => t('Hostname'), 'header' => TRUE),
Dries Buytaert
committed
$dblog->hostname,
Dries Buytaert
committed
),
array(
array('data' => t('Operations'), 'header' => TRUE),
Dries Buytaert
committed
$dblog->link,
Dries Buytaert
committed
);
Dries Buytaert
committed
$attributes = array('class' => 'dblog-event');
Dries Buytaert
committed
$output = theme('table', array(), $rows, $attributes);
}
return $output;
}
Dries Buytaert
committed
function _dblog_get_message_types() {
$result = db_query('SELECT DISTINCT(type) FROM {watchdog} ORDER BY type');
while ($object = db_fetch_object($result)) {
$types[] = $object->type;
}
return $types;
}
Dries Buytaert
committed
function dblog_watchdog($log = array()) {
$current_db = db_set_active();
db_query("INSERT INTO {watchdog}
(uid, type, message, severity, link, location, referer, hostname, timestamp)
VALUES
(%d, '%s', '%s', %d, '%s', '%s', '%s', '%s', %d)",
$log['user']->uid,
$log['type'],
$log['message'],
$log['severity'],
$log['link'],
$log['request_uri'],
$log['referer'],
$log['ip'],
$log['timestamp']);
if ($current_db) {
db_set_active($current_db);
}
}