mongodb_watchdog.admin.inc in MongoDB 6
Same filename and directory in other branches
Settings for mongodb. Moved back to module file.
File
mongodb_watchdog/mongodb_watchdog.admin.incView source
<?php
/**
* @file
* Settings for mongodb. Moved back to module file.
*/
/**
* Display watchdogs entries in MongoDB.
*
* @TODO
* Use theme function.
* Use exposed filter like dblog.
*
* @return array
* a form array
*/
function mongodb_watchdog_overview() {
drupal_add_css(drupal_get_path('module', 'mongodb_watchdog') . '/mongodb_watchdog.css', 'module', 'all', FALSE);
$rows = array();
$icons = array(
WATCHDOG_DEBUG => '',
WATCHDOG_INFO => '',
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')),
WATCHDOG_CRITICAL => theme('image', 'misc/watchdog-error.png', t('critical'), t('critical')),
WATCHDOG_ALERT => theme('image', 'misc/watchdog-error.png', t('alert'), t('alert')),
WATCHDOG_EMERG => theme('image', 'misc/watchdog-error.png', t('emergency'), t('emergency')),
);
$classes = array(
WATCHDOG_DEBUG => 'mongodb_watchdog-debug',
WATCHDOG_INFO => 'mongodb_watchdog-info',
WATCHDOG_NOTICE => 'mongodb_watchdog-notice',
WATCHDOG_WARNING => 'mongodb_watchdog-warning',
WATCHDOG_ERROR => 'mongodb_watchdog-error',
WATCHDOG_CRITICAL => 'mongodb_watchdog-critical',
WATCHDOG_ALERT => 'mongodb_watchdog-alert',
WATCHDOG_EMERG => 'mongodb_watchdog-emergency',
);
global $pager_page_array, $pager_total, $pager_total_items, $pager_limits;
$per_page = 50;
$page = isset($_GET['page']) ? $_GET['page'] : '';
$pager_page_array = explode(',', $page);
$on_page = $pager_page_array[0];
$cursor = mongodb_collection(variable_get('mongodb_watchdog', 'watchdog'))
->find(mongodb_watchdog_build_filter_query())
->limit($per_page)
->skip($on_page * $per_page)
->sort(array(
'timestamp' => -1,
));
$build['mongodb_watchdog_filter_form'] = mongodb_watchdog_filter_form();
$build['mongodb_watchdog_clear_log_form'] = mongodb_watchdog_clear_log_form();
$header = array(
// Icon column.
'',
t('#'),
array(
'data' => t('Type'),
),
array(
'data' => t('Date'),
),
t('Source'),
t('Message'),
);
$rows = array();
foreach ($cursor as $id => $value) {
if ($value['type'] == 'php' && $value['message'] == '%type: %message in %function (line %line of %file).') {
$collection = mongodb_collection(variable_get('mongodb_watchdog', 'watchdog'));
$collection = $collection->db
->selectCollection('watchdog_event_' . $value['_id']);
if ($result = $collection
->find()
->sort(array(
'$natural' => -1,
))
->limit(1)
->getNext()) {
$value['file'] = basename($result['variables']['%file']);
$value['line'] = $result['variables']['%line'];
$value['message'] = '%type in %function';
$value['variables'] = $result['variables'];
}
}
$message = truncate_utf8(strip_tags(_mongodb_watchdog_format_message($value)), 56, TRUE, TRUE);
$rows[$id] = array(
$icons[$value['severity']],
isset($value['count']) && $value['count'] > 1 ? $value['count'] : '',
// The entry type comes from code as the first parameter to a watchdog()
// call and is not a dynamic string, so it is ok to pass to t().
t($value['type']),
empty($value['timestamp']) ? '' : format_date($value['timestamp'], 'small'),
empty($value['file']) ? '' : truncate_utf8(basename($value['file']), 30) . (empty($value['line']) ? '' : '+' . $value['line']),
l($message, "admin/reports/mongodb/{$id}"),
);
}
$attributes = array(
'id' => 'admin-mongodb_watchdog',
);
$build['mongodb_watchdog_table'] = array(
'#type' => 'markup',
'#value' => theme('table', $header, $rows, $attributes),
);
// Add the pager.
if ($on_page > 0 || count($rows) >= $per_page) {
$pager_total_items[0] = mongodb_collection(variable_get('mongodb_watchdog', 'watchdog'))
->find(mongodb_watchdog_build_filter_query())
->count();
$pager_total[0] = ceil($pager_total_items[0] / $per_page);
$pager_page_array[0] = max(0, min((int) $pager_page_array[0], (int) $pager_total[0] - 1));
$pager_limits[0] = $per_page;
$build['pager'] = array(
'#theme' => 'pager',
);
}
return $build;
}
/**
* Display watchdogs entry details in MongoDB.
*
* @param array $dblog
* A log entry in array form.
*/
function mongodb_watchdog_event(array $dblog) {
$severity = watchdog_severity_levels();
$rows = array(
array(
array(
'data' => t('Type'),
'header' => TRUE,
),
// The entry type comes from code as the first parameter to a watchdog()
// call and is not a dynamic string, so it is ok to pass to t().
t($dblog['type']),
),
array(
array(
'data' => t('Severity'),
'header' => TRUE,
),
$severity[$dblog['severity']],
),
array(
array(
'data' => t('Function'),
'header' => TRUE,
),
isset($dblog['function']) ? $dblog['function'] : '',
),
array(
array(
'data' => t('File'),
'header' => TRUE,
),
isset($dblog['file']) ? $dblog['file'] : '',
),
array(
array(
'data' => t('Line'),
'header' => TRUE,
),
isset($dblog['line']) ? $dblog['line'] : '',
),
array(
array(
'data' => t('Count'),
'header' => TRUE,
),
isset($dblog['count']) ? $dblog['count'] : '',
),
);
$build = theme('table', NULL, $rows, array(
'class' => 'dblog-event',
));
// The count is unreliable, so just get the actual number of entries.
$collection = mongodb_collection(variable_get('mongodb_watchdog', 'watchdog'));
$collection = $collection->db
->selectCollection('watchdog_event_' . $dblog['_id']);
$total = $collection
->count();
$limit = 20;
$pagenumber = mongodb_watchdog_pager_init(0, $limit, $total);
$result = $collection
->find()
->skip($pagenumber * $limit)
->limit($limit)
->sort(array(
'$natural' => -1,
));
$severity = watchdog_severity_levels();
$rows = array();
$header = array(
array(
'data' => t('Date'),
'header' => TRUE,
),
array(
'data' => t('User'),
'header' => TRUE,
),
array(
'data' => t('Location'),
'header' => TRUE,
),
array(
'data' => t('Referrer'),
'header' => TRUE,
),
array(
'data' => t('Hostname'),
'header' => TRUE,
),
array(
'data' => t('Message'),
'header' => TRUE,
),
array(
'data' => t('Operations'),
'header' => TRUE,
),
);
foreach ($result as $event) {
if (isset($event['wd-user'])) {
$account = $event['wd-user'];
unset($event['wd-user']);
$ip = $dblog['ip'];
$request_uri = $dblog['request_uri'];
$referer = $dblog['referer'];
$link = $dblog['link'];
$dblog['variables'] = $event;
}
else {
$account = $event['user'];
$ip = $event['ip'];
$request_uri = $event['request_uri'];
$referer = $event['referer'];
$link = $event['link'];
$dblog['variables'] = $event['variables'];
}
$rows[] = array(
// Build the user account page link, instead of theme('username'),
// theme('username') do not retrieve links to disabled accounts page.
format_date($event['timestamp'], 'small'),
l($account['name'], 'user/' . $account['uid']),
$request_uri ? l(truncate_utf8(basename($request_uri), 20), $request_uri) : '',
$referer ? l(truncate_utf8(basename($referer), 20), $referer) : '',
check_plain($ip),
_mongodb_watchdog_format_message($dblog),
$link,
);
}
$build .= theme('table', $header, $rows);
if ($total > $limit) {
$build .= theme('pager');
}
return $build;
}
/**
* Initialize the pager variables for use in a mongodb_watchdog event list.
*/
function mongodb_watchdog_pager_init($element, $limit, $total) {
global $pager_page_array, $pager_total, $pager_total_items;
// Initialize pager, see pager.inc.
$page = isset($_GET['page']) ? $_GET['page'] : '';
$pager_page_array = explode(',', $page);
if (!isset($pager_page_array[$element])) {
$pager_page_array[$element] = 0;
}
$pager_total_items[$element] = $total;
$pager_total[$element] = ceil($pager_total_items[$element] / $limit);
$pager_page_array[$element] = max(0, min((int) $pager_page_array[$element], (int) $pager_total[$element] - 1));
return isset($pager_page_array[$element]) ? $pager_page_array[$element] : 0;
}
/**
* Formats a log message for display.
*
* @param array $dblog
* An object with at least the message and variables properties.
*
* @return string
* The formatted message.
*/
function _mongodb_watchdog_format_message(array $dblog) {
// Legacy messages and user specified text.
if (!isset($dblog['variables'])) {
return $dblog['message'];
}
// Message to translate with injected variables. The message is actually
// supposed to be a template string from code, not a dynamically generated one
// so using it as a parameter for t() is correct.
return t($dblog['message'], $dblog['variables']);
}
/**
* List mongodb_watchdog administration filters that can be applied.
*
* @return array
* A form array
*/
function mongodb_watchdog_filters() {
$filters = array();
foreach (_mongodb_watchdog_get_message_types() as $type) {
$types[$type] = $type;
}
if (!empty($types)) {
$filters['type'] = array(
'title' => t('Type'),
'options' => $types,
);
}
$filters['severity'] = array(
'title' => t('Severity'),
'options' => watchdog_severity_levels(),
);
return $filters;
}
/**
* Build the filter form.
*
* @return array
* A form array
*/
function mongodb_watchdog_filter_form($form_state = array()) {
$filters = mongodb_watchdog_filters();
$form = array();
$form['filters'] = array(
'#type' => 'fieldset',
'#title' => t('Filter log messages'),
'#collapsible' => TRUE,
'#collapsed' => empty($_SESSION),
);
foreach ($filters as $key => $filter) {
$form['filters']['status'][$key] = array(
'#title' => check_plain($filter['title']),
'#type' => 'select',
'#multiple' => TRUE,
'#size' => 8,
'#options' => $filter['options'],
);
if (!empty($_SESSION['mongodb_watchdog_overview_filter'][$key])) {
$form['filters']['status'][$key]['#default_value'] = $_SESSION['mongodb_watchdog_overview_filter'][$key];
}
}
$form['filters']['buttons']['submit'] = array(
'#type' => 'submit',
'#value' => t('Filter'),
'#element_validate' => array(
'mongodb_watchdog_filter_form_validate',
),
'#submit' => array(
'mongodb_watchdog_filter_form_submit',
),
);
if (!empty($_SESSION['mongodb_watchdog_overview_filter'])) {
$form['filters']['buttons']['reset'] = array(
'#type' => 'submit',
'#value' => t('Reset'),
'#element_validate' => array(
'mongodb_watchdog_filter_form_validate',
),
'#submit' => array(
'mongodb_watchdog_filter_form_submit',
),
);
}
return $form;
}
/**
* Validate result from mongodb_watchdog administration filter form.
*/
function mongodb_watchdog_filter_form_validate($form, &$form_state) {
if ($form_state['values']['op'] == t('Filter') && empty($form_state['values']['type']) && empty($form_state['values']['severity'])) {
form_set_error('type', t('You must select something to filter by.'));
}
}
/**
* Process result from mongodb_watchdog administration filter form.
*/
function mongodb_watchdog_filter_form_submit($form, &$form_state) {
$op = $form_state['values']['op'];
$filters = mongodb_watchdog_filters();
switch ($op) {
case t('Filter'):
foreach ($filters as $name => $filter) {
if (isset($form_state['values'][$name])) {
$_SESSION['mongodb_watchdog_overview_filter'][$name] = $form_state['values'][$name];
}
}
break;
case t('Reset'):
$_SESSION['mongodb_watchdog_overview_filter'] = array();
break;
}
return 'admin/reports/mongodb';
}
/**
* Gets all available filter types.
*
* @return array
* An array of message type names.
*/
function _mongodb_watchdog_get_message_types() {
// As of version 1.0.1, the PHP driver doesn't expose the 'distinct' command.
$collection = mongodb_collection(variable_get('mongodb_watchdog', 'watchdog'));
$result = $collection->db
->command(array(
'distinct' => $collection
->getName(),
'key' => 'type',
));
return $result['values'];
}
/**
* Return form for mongodb_watchdog clear button.
*
* @ingroup forms
*
* @see dblog_clear_log_submit()
*
* @return array
* A form array.
*/
function mongodb_watchdog_clear_log_form($form_state = array()) {
$form = array();
$form['mongodb_watchdog_clear'] = array(
'#type' => 'fieldset',
'#title' => t('Clear log messages'),
'#description' => t('This will permanently remove the log messages from the database.'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['mongodb_watchdog_clear']['clear'] = array(
'#type' => 'submit',
'#value' => t('Clear log messages'),
'#submit' => array(
'mongodb_watchdog_clear_log_submit',
),
);
return $form;
}
/**
* Submit callback: clear database with log messages.
*/
function mongodb_watchdog_clear_log_submit() {
try {
// Drop the watchdog collection.
$collection = mongodb_collection(variable_get('mongodb_watchdog', 'watchdog'));
$collection->db
->dropCollection($collection
->getName());
// Recreate the indexes.
module_load_include('install', 'mongodb_watchdog');
mongodb_watchdog_ensure_indexes();
// Drop the event collections.
foreach ($collection->db
->listCollections() as $table) {
$parts = explode('.', $table);
if (substr($parts[1], 0, 15) == 'watchdog_event_') {
$collection->db
->dropCollection($table);
}
}
drupal_set_message(t('MongoDB log cleared.'));
} catch (Exception $e) {
drupal_set_message(t('An error occured while clearing the MongoDB log.'), 'error');
}
}
/**
* Build a MongoDB query based on the selected filters.
*
* MongoDB issue regarding the $in value is PHP-1051.
* MongoDB issue regarding numeric keys on objects is PHP-104.
*
* @see https://jira.mongodb.org/browse/PHP-1051
* @see https://jira.mongodb.org/browse/PHP-104
*
* @return array
* An array to build a MongoDB query.
*/
function mongodb_watchdog_build_filter_query() {
if (empty($_SESSION['mongodb_watchdog_overview_filter'])) {
return array();
}
// Build query.
$where = $args = array();
$types = $_SESSION['mongodb_watchdog_overview_filter']['type'] ? $_SESSION['mongodb_watchdog_overview_filter']['type'] : NULL;
$severities = $_SESSION['mongodb_watchdog_overview_filter']['severity'] ? $_SESSION['mongodb_watchdog_overview_filter']['severity'] : NULL;
$find = array();
if ($types) {
$find['type'] = array(
'$in' => array_values($types),
);
}
if ($severities) {
// MongoDB is picky about types, ensure the severities are all integers.
$find['severity'] = array(
'$in' => array_values(array_map('intval', $severities)),
);
}
return $find;
}
/**
* Page callback for "admin/reports/[access-denied|page-not-found]".
*
* @return array
* A render array.
*/
function mongodb_watchdog_page_top($type) {
$ret = '';
$message_wrapper = array(
'#prefix' => '<div class="mongodb-watchdog-message">',
'#suffix' => '</div>',
);
$type_param = array(
'%type' => $type,
);
$limit = 50;
// Safety net.
$types = array(
'page not found',
'access denied',
);
if (!in_array($type, $types)) {
drupal_set_message(t('Unknown top report type: %type', $type_param), 'error');
watchdog('mongodb_watchdog', 'Unknown top report type: %type', $type_param, WATCHDOG_WARNING);
$ret = '';
return $ret;
}
// Find _id for the error type.
$watchdog = mongodb_collection(variable_get('mongodb_watchdog', 'watchdog'));
$template = $watchdog
->findOne(array(
'type' => $type,
), array(
'_id',
));
// MongoDB findOne() will return NULL if no row is found.
if (empty($template)) {
$ret['empty'] = array(
'#value' => t('No "%type" message found', $type_param),
) + $message_wrapper;
$ret = drupal_render($ret);
return $ret;
}
// Find occurrences of error type.
$key = $template['_id'];
$event_collection = mongodb_collection('watchdog_event_' . $key);
$reduce = <<<EOT
function (doc, accumulator) {
accumulator.count++;
}
EOT;
$counts = $event_collection
->group(array(
'variables.@param' => 1,
), array(
'count' => array(),
), $reduce);
if (!$counts['ok']) {
drupal_set_message(t('No "%type" occurrence found', $type_param), 'error');
$ret = '';
return $ret;
}
$counts = $counts['retval'];
usort($counts, '_mongodb_watchdog_sort_top');
$counts = array_slice($counts, 0, $limit);
$header = array(
t('#'),
t('Paths'),
);
$rows = array();
foreach ($counts as $count) {
$rows[] = array(
$count['variables.@param'],
$count['count'],
);
}
$ret = array(
'#value' => theme('table', $header, $rows),
) + $message_wrapper;
$ret = drupal_render($ret);
return $ret;
}
/**
* Helper function for usort() to sort top entries returned from a group query.
*
* @param array $x
* The first entry to compare.
* @param array $y
* The second entry to compare.
*
* @return bool
* As per uasort() expectations.
*/
function _mongodb_watchdog_sort_top(array $x, array $y) {
$cx = $x['count'];
$cy = $y['count'];
return $cy - $cx;
}
Functions
Name![]() |
Description |
---|---|
mongodb_watchdog_build_filter_query | Build a MongoDB query based on the selected filters. |
mongodb_watchdog_clear_log_form | Return form for mongodb_watchdog clear button. |
mongodb_watchdog_clear_log_submit | Submit callback: clear database with log messages. |
mongodb_watchdog_event | Display watchdogs entry details in MongoDB. |
mongodb_watchdog_filters | List mongodb_watchdog administration filters that can be applied. |
mongodb_watchdog_filter_form | Build the filter form. |
mongodb_watchdog_filter_form_submit | Process result from mongodb_watchdog administration filter form. |
mongodb_watchdog_filter_form_validate | Validate result from mongodb_watchdog administration filter form. |
mongodb_watchdog_overview | Display watchdogs entries in MongoDB. |
mongodb_watchdog_pager_init | Initialize the pager variables for use in a mongodb_watchdog event list. |
mongodb_watchdog_page_top | Page callback for "admin/reports/[access-denied|page-not-found]". |
_mongodb_watchdog_format_message | Formats a log message for display. |
_mongodb_watchdog_get_message_types | Gets all available filter types. |
_mongodb_watchdog_sort_top | Helper function for usort() to sort top entries returned from a group query. |