array('access site reports'), 'file' => 'bench_chart_charts.inc', 'page callback' => 'bench_chart_charts', 'title' => 'Hooks', 'type' => MENU_LOCAL_TASK ); $items['admin/settings/hook_chart'] = array( 'access arguments' => array('access site reports'), 'file' => 'bench_chart_conf.inc', 'page callback' => 'bench_chart_conf', 'title' => 'Hook Chart', 'type' => MENU_LOCAL_TASK ); return $items; } /** * Callback of register_shutdown_function() */ function bench_chart_shutdown() { bench_chart_my_hook(array('(exit)', 'end')); bench_chart_save_to_db(); timer_stop('bench_chart'); } function bench_chart_save_to_db() { global $hooks_run; $menu = function_exists('menu_get_item') ? menu_get_item() : NULL; // get alias to the current menu (if menu is already loaded) $path = !empty($menu['path']) ? $menu['path'] : $_GET['q']; // set alias, if doesn't exist, get path directly $totaltime = (float)0; foreach ($hooks_run as $hook_name => $hook) { // for each executed hook $calc_time = (float)0; $count = 0; if (isset($hook['start']) && is_array($hook['start'])) { foreach ($hook['start'] as $key => $time) { // for each calculated time $count++; if (isset($hook['end'])) { $calc_time += ($hook['end'][$key] - $hook['start'][$key]); $lasttime = $hook['end'][$key]; } } $totaltime += $calc_time; db_query("REPLACE INTO {bench_chart} (hook, count, time, totaltime, path) VALUES ('%s', '%d', '%f', '%f', '%s')", $hook_name, $count, $calc_time, $totaltime, $path); if ($calc_time>1000) { // TODO bench_chart_run_hook($hook_name); } } } //$time_rest = ($totaltime - ($lasttime - $hooks_run['(before boot)']['start'][0])); //db_query("INSERT INTO {bench_chart} (hook, count, time, totaltime, path) VALUES ('%s', '%s', '%s', '%s', '%s')", '(other)', 1, $time_rest, $totaltime, $path); } /** * Implementation of each hook * */ function bench_chart_my_hook() { $args = func_get_args(); // get function arguments $hook = $args[0]; // get first parameter list($hook, $type) = array($args[0][0], $args[0][1]); // explode our first function argument unset($args[0]); global $hooks_run, $bench_chart_run; // prepare globals if ($type == 'start' && $bench_chart_run) { // if hook already run, don't start another one (recurency not supported)... return; // ...just do exit } else { $bench_chart_run = FALSE; } $timer = timer_read('bench_chart'); $hooks_run[$hook][$type][] = (float)$timer; $hooks_run[$hook]['#args'][] = $args; switch ($hook) { case 'exit': $hooks_run['(exit)']['start'][] = (float)$timer; break; } } /* * Get the last argument from the path * * @version 11/12/2008 * @author kenorb@gmail.com */ function bench_chart_get_last_path_arg() { if (module_exists('path')) { // if path module exist, translate url from alias $path = drupal_get_path_alias($_GET['q']); $arg = explode('/',drupal_get_path_alias($path)); } else { $arg = arg(); // otherwise use standard one } return $arg[count($arg)-1]; // get last argument of URI path } /** * Implementation of each hook * */ function bench_chart_run_hook() { global $bench_chart_run; // prepare global variables $args = func_get_args(); // get function arguments $hook = $args[0]; // get and set first parameter unset($args[0]); // and remove it from argument list $hook_timer = array(); // reset hook timer $menu = menu_get_item(); // get alias to the current menu $path = !empty($menu['path']) ? $menu['path'] : $_GET['q']; // set alias, if doesn't exist, get path directly timer_start("hook_$hook"); // start timer foreach (module_implements($hook) as $module) { $function = $module .'_'. $hook; if (function_exists($function)) { timer_start("hook_${module}_$hook"); // start timer $result = call_user_func_array($function, $args); $hook_timer_stop = timer_stop("hook_${module}_$hook"); // end timer $hook_timer[$module] = $hook_timer_stop['time']; // calculate the time of executed hook $hook_total_time[$module] = timer_read("hook_$hook"); // end timer } } foreach($hook_timer as $module => $time) { db_query("REPLACE INTO {bench_chart} (hook, count, time, totaltime, path) VALUES ('%s', '%d', '%f', '%f', '%s')", "${module}_$hook", 0, $time, $hook_total_time[$module], $path); } }