123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- <?php
- /**
- * @file
- * Drush integration for the Performance module.
- */
- /**
- * Implements hook_drush_command().
- */
- function performance_drush_command() {
- $items = array();
- $limit = "Limit the number of records. Defaults to 25.";
- $direction = "Sort direction, defaults to descending: asc or desc.";
- $items['performance-summary'] = array(
- 'callback' => 'drush_performance_summary',
- 'description' => "Display the Performance Logging and Monitoring summary entries.",
- 'aliases' => array('perf-sm'),
- 'arguments' => array(
- 'limit' => $limit,
- 'orderby' => "The column name to sort on, defaults to last_access: path, last_access, bytes_max, bytes_avg, ms_max, ms_avg, [query_count_max, query_count_avg, query_timer_max, query_timer_avg] or num_accesses.",
- 'direction' => $direction,
- ),
- 'examples' => array(
- 'performance-summary 25' => 'Retrieve last 25 entries.',
- 'performance-summary 10 path' => 'Retrieve last 10 entries sorted by path, descending.',
- 'performance-summary 40 bytes_avg asc' => 'Retrieve last 40 entries sorted by average size, ascending.',
- ),
- );
- $items['performance-detail'] = array(
- 'callback' => 'drush_performance_details',
- 'description' => "Display the Performance Logging and Monitoring detail entries.",
- 'aliases' => array('perf-dt'),
- 'arguments' => array(
- 'limit' => $limit,
- 'orderby' => "The column name to sort on, defaults to timestamp: pid, timestamp, bytes, ms, [query_count, query_timer], anon or path.",
- 'direction' => $direction,
- ),
- 'examples' => array(
- 'performance-detail 15' => 'Retrieve last 15 entries.',
- 'performance-detail 20 query_count' => 'Retrieve last 20 entries sorted by the number of queries, descending.',
- 'performance-detail 35 bytes asc' => 'Retrieve last 35 entries sorted by size, ascending.',
- ),
- );
- return $items;
- }
- /**
- * Summary page callback.
- * Differs a little from the version in the module because drush_print_table()
- * works differently.
- */
- function drush_performance_summary() {
- $args = func_get_args();
- // Collect arguments.
- $orderby = 'last_access';
- $columns = array('path', 'last_access', 'bytes_max', 'bytes_avg', 'ms_max', 'ms_avg', 'num_accesses');
- if (variable_get(PERFORMANCE_QUERY_VAR, 0)) {
- $columns[] = 'query_count_max';
- $columns[] = 'query_count_avg';
- $columns[] = 'query_timer_max';
- $columns[] = 'query_timer_avg';
- }
- $arguments = drush_performance_parse_args($args, $orderby, $columns);
- // Error thrown, abort.
- if (!is_array($arguments)) {
- return $arguments;
- }
- // Go back no more than 1 hour.
- $arguments['timestamp'] = REQUEST_TIME - 60 * 60;
- // Get actual data.
- $data_list = performance_traverse_cache('drush_performance_get_summary', $arguments);
- $data_list = performance_sort_summary($data_list, $arguments['direction'], $arguments['orderby']);
- if (empty($data_list) && !variable_get('performance_summary', 0)) {
- return drush_set_error(dt('Summary performance log is not enabled. Go to the settings page to enable it.'));
- }
- elseif (empty($data_list)) {
- drush_print("\033[1m" . dt('No log messages available.') . "\033[0m\n", 1);
- drush_print(dt('Possible causes:'), 1);
- drush_print('- ' . dt('no data stored yet'), 2);
- drush_print('- ' . dt('all data stored is older than one hour'), 2);
- return drush_print('- $base_url ' . dt('not properly set: run drush with the --uri parameter'), 2);
- }
- elseif (!variable_get('performance_summary', 0)) {
- drush_print("\033[1;33m" . dt('Summary performance log is not enabled! Showing stored logs.') . "\033[0m\n", 1);
- }
- // Build table header.
- $header = array(
- dt('Path'),
- dt('Last access'),
- dt('# accesses'),
- dt('MB Memory (Max)'),
- dt('MB Memory (Avg)'),
- dt('ms (Max)'),
- dt('ms (Avg)'),
- );
- if (variable_get(PERFORMANCE_QUERY_VAR, 0)) {
- $header[] = dt('Query ms (Max)');
- $header[] = dt('Query ms (Avg)');
- $header[] = dt('Query Count (Max)');
- $header[] = dt('Query Count (Avg)');
- }
- $rows[] = $header;
- // Format data into table.
- $threshold = variable_get('performance_threshold_accesses', 0);
- $total_rows = $shown = $last_max = $total_bytes = $total_ms = $total_accesses = 0;
- $last_min = REQUEST_TIME;
- foreach ($data_list as $data) {
- $total_rows++;
- $last_max = max($last_max, $data['last_access']);
- $last_min = min($last_min, $data['last_access']);
- // Calculate running averages.
- $total_bytes += $data['bytes_sum'] / $data['num_accesses'];
- $total_ms += $data['ms_sum'] / $data['num_accesses'];
- $total_accesses += $data['num_accesses'];
- $row_data = array();
- if ($data['num_accesses'] > $threshold) {
- $shown++;
- $row_data[] = check_plain($data['path']);
- $row_data[] = format_date($data['last_access'], 'small');
- $row_data[] = $data['num_accesses'];
- $row_data[] = number_format($data['bytes_max'] / 1024 / 1024, 2);
- $row_data[] = number_format($data['bytes_avg'] / 1024 / 1024, 2);
- $row_data[] = number_format($data['ms_max'], 1);
- $row_data[] = number_format($data['ms_avg'], 1);
- if (variable_get(PERFORMANCE_QUERY_VAR, 0)) {
- $row_data[] = number_format($data['query_timer_max'], 1);
- $row_data[] = number_format($data['query_timer_avg'], 1);
- $row_data[] = $data['query_count_max'];
- $row_data[] = $data['query_count_avg'];
- }
- }
- $rows[] = $row_data;
- }
- if (!$rows) {
- $rows[] = dt('No statistics available yet.');
- }
- if ($threshold) {
- drush_print("\n" . dt('Showing !shown paths with more than !threshold accesses, out of !total total paths.',
- array('!threshold' => $threshold, '!shown' => $shown, '!total' => $total_rows)));
- }
- else {
- drush_print("\n" . dt('Showing all !total paths.', array('!total' => $total_rows)));
- }
- // Protect against divide by zero.
- if ($total_rows > 0) {
- $mb_avg = number_format($total_bytes / $total_rows / 1024 / 1024, 1);
- $ms_avg = number_format($total_ms / $total_rows, 2);
- }
- else {
- $mb_avg = 'n/a';
- $ms_avg = 'n/a';
- }
- drush_print(dt('Average memory per page: !mb_avg MB', array('!mb_avg' => $mb_avg)));
- drush_print(dt('Average duration per page: !ms_avg ms', array('!ms_avg' => $ms_avg)));
- drush_print(dt('Total number of page accesses: !accesses', array('!accesses' => $total_accesses)));
- drush_print(dt('First access: !access.', array('!access' => format_date($last_min, 'small'))));
- drush_print(dt('Last access: !access.', array('!access' => format_date($last_max, 'small'))) . "\n");
- drush_print("\033[1m" . dt('Performance log summary: !rows entries ordered by !column, !direction', array('!rows' => count($rows) - 1, '!column' => $arguments['orderby'], '!direction' => $arguments['direction'])) . "\033[0m", 1);
- // TODO: add 'running averages' here, like in the Drupal backend.
- drush_print_table($rows, TRUE);
- }
- function drush_performance_details() {
- $header = array(
- dt('#'),
- dt('Date'),
- dt('Path'),
- dt('Memory (MB)'),
- dt('ms (Total)'),
- dt('Anonymous?'),
- );
- if (variable_get(PERFORMANCE_QUERY_VAR, 0)) {
- $header[] = dt('# Queries');
- $header[] = dt('Query ms');
- }
- $rows[] = $header;
- // Collect arguments.
- $args = func_get_args();
- $orderby = 'timestamp';
- $columns = array('pid', 'timestamp', 'bytes', 'ms', 'anon', 'path');
- if (variable_get(PERFORMANCE_QUERY_VAR, 0)) {
- $columns[] = 'query_count';
- $columns[] = 'query_timer';
- }
- $arguments = drush_performance_parse_args($args, $orderby, $columns);
- // Error thrown, abort.
- if (!is_array($arguments)) {
- return $arguments;
- }
- $data_list = drush_performance_get_detail($arguments);
- if (empty($data_list) && !variable_get('performance_detail', 0)) {
- return drush_set_error(dt('Detail performance log is not enabled! Go to the settings page to enable it.'));
- }
- elseif (empty($data_list)) {
- return drush_print("\033[1m" . dt('No log messages available.') . "\033[0m", 1);
- }
- elseif (!variable_get('performance_detail', 0)) {
- drush_print("\033[1;33m" . dt('Detail performance log is not enabled! Showing stored logs.') . "\033[0m\n", 1);
- }
- foreach ($data_list as $data) {
- // Cast to object because of the DB API now returning row objects by default.
- $data = is_array($data) ? (object)$data : $data;
- $row_data = array();
- $row_data[] = $data->pid;
- $row_data[] = format_date($data->timestamp, 'small');
- $row_data[] = check_plain($data->path);
- $row_data[] = number_format($data->bytes/1024/1024, 2);
- $row_data[] = $data->ms;
- $row_data[] = ($data->anon) ? t('Yes') : t('No');
- if (variable_get(PERFORMANCE_QUERY_VAR, 0)) {
- $row_data[] = $data->query_count;
- $row_data[] = $data->query_timer;
- }
- $rows[] = $row_data;
- }
- drush_print("\033[1m" . dt('Performance log details: !rows entries ordered by !column, !direction', array('!rows' => count($rows) - 1, '!column' => $arguments['orderby'], '!direction' => $arguments['direction'])) . "\033[0m", 1);
- drush_print_table($rows, TRUE);
- }
- /**
- * Helper function to parse the arguments which are the same for both commands.
- * Only columns differ.
- */
- function drush_performance_parse_args($args, $orderby, $columns) {
- $arguments = array();
- $default = TRUE;
- // Set limit from arguments or fall back to default.
- $arguments['limit'] = 25;
- if ((count($args) > 2 || count($args) == 1) && isset($args[0])) {
- if (is_numeric($args[0])) {
- $arguments['limit'] = $args[0];
- }
- else {
- return drush_set_error(dt('First argument must be numeric!'));
- }
- }
- else {
- // 1st parameter was most likely omitted, so we prepend the default to the
- // arguments to make the following checks check the right argument :-)
- array_unshift($args, $arguments['limit']);
- }
- // Order by column name.
- $arguments['orderby'] = $orderby;
- if (isset($args[1])) {
- if (in_array($args[1], $columns)) {
- $arguments['orderby'] = $args[1];
- }
- // Let the user know what the options are.
- else {
- return drush_set_error(dt('Unknown column name. Possible values are: !columns', array('!columns' => implode(', ', $columns))));
- }
- }
- // Sort direction.
- $arguments['direction'] = 'desc';
- $options = array('asc', 'desc');
- if (isset($args[2])) {
- if (in_array($args[2], $options)) {
- $arguments['direction'] = $args[2];
- }
- // Let the user know what the options are.
- else {
- return drush_set_error(dt('Unknown sort direction. Possible values are: !options', array('!options' => implode(', ', $options))));
- }
- }
- return $arguments;
- }
- /**
- * Callback used by performance_traverse_cache() for fetching summary data.
- *
- * @param $cache cache object
- * @param $arguments associative array containing limit and timestamp
- * @return the processed data or NULL
- *
- * @see performance_traverse_cache()
- */
- function drush_performance_get_summary($cache, $arguments) {
- static $count = 0;
- if ($cache->data['last_access'] >= $arguments['timestamp'] && $count < $arguments['limit']) {
- $count++;
- return $cache->data;
- }
- return;
- }
- /**
- * Drupal version independant variation of performance_db_get_data() for easy
- * maintenance of the drush commands.
- */
- function drush_performance_get_detail($arguments) {
- $data_list = array();
- $result = drush_db_select('performance_detail', '*', NULL, NULL, 0, $arguments['limit'], $arguments['orderby'], $arguments['direction']);
- if (drush_drupal_major_version() >= 7) {
- foreach ($result as $row) {
- $data_list[] = $row;
- }
- }
- else {
- while ($row = db_fetch_object($result)) {
- $data_list[] = $row;
- }
- }
- return $data_list;
- }
|