| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: performance.module,v 1.2.2.33 2010/08/04 22:26:53 kbahey Exp $ 3 4 /** 5 * @file 6 * 7 * Logs detailed and/or summary page generation time and memory 8 * consumption for page requests. 9 * 10 * Copyright Khalid Baheyeldin 2008 of http://2bits.com 11 */ 12 13 define('PERFORMANCE_KEY', 'dru-perf:'. $_SERVER['HTTP_HOST'] .':'); 14 define('PERFORMANCE_MEMCACHE_BIN', 'cache_performance'); 15 16 function performance_memcache_enabled() { 17 global $conf; 18 19 if (function_exists('dmemcache_set') && isset($conf['memcache_bins']['cache_performance'])) { 20 return TRUE; 21 } 22 return FALSE; 23 } 24 25 function performance_menu() { 26 $items = array(); 27 28 $items['admin/settings/performance_logging'] = array( 29 'title' => 'Performance logging', 30 'description' => 'Logs performance data: page generation times and memory usage.', 31 'page callback' => 'drupal_get_form', 32 'page arguments' => array('performance_settings'), 33 'access arguments' => array('access administration pages'), 34 ); 35 36 $items['admin/settings/performance_logging/apc_clear'] = array( 37 'title' => 'Clear APC', 38 'description' => 'Clears performance statistics collected in APC.', 39 'page callback' => 'drupal_get_form', 40 'page arguments' => array('performance_clear_apc_confirm'), 41 'access arguments' => array('access administration pages'), 42 ); 43 44 $items['admin/settings/performance_logging/memcache_clear'] = array( 45 'title' => 'Clear Memcache', 46 'description' => 'Clears performance statistics collected in Memcache.', 47 'page callback' => 'drupal_get_form', 48 'page arguments' => array('performance_clear_memcache_confirm'), 49 'access arguments' => array('access administration pages'), 50 ); 51 52 $items['admin/reports/performance_logging_summary'] = array( 53 'title' => 'Performance Logs: Summary', 54 'description' => 'View summary performance logs: page generation times and memory usage.', 55 'page callback' => 'performance_view_summary', 56 'access arguments' => array('access site reports'), 57 ); 58 59 $items['admin/reports/performance_logging_details'] = array( 60 'title' => 'Performance Logs: Details', 61 'description' => 'View detailed, per page, performance logs: page generation times and memory usage.', 62 'page callback' => 'performance_view_details', 63 'access arguments' => array('access site reports'), 64 ); 65 66 return $items; 67 } 68 69 function performance_settings() { 70 $options = array( 71 0 => t('Disabled'), 72 1 => t('Enabled'), 73 ); 74 75 if (function_exists('apc_cache_info')) { 76 drupal_set_message(t('APC is enabled. It is reasonably safe to enable summary logging on live sites.'), 'status', FALSE); 77 } 78 else { 79 drupal_set_message(t('APC is not enabled. It is <strong>not</strong> safe to enable summary logging to the database on live sites.'), 'error', FALSE); 80 } 81 82 $form['mode'] = array( 83 '#type' => 'fieldset', 84 '#title' => t('Logging mode'), 85 '#collapsible' => TRUE, 86 ); 87 88 $form['mode']['performance_detail'] = array( 89 '#type' => 'select', 90 '#title' => t('Detailed logging'), 91 '#default_value' => variable_get('performance_detail', 0), 92 '#options' => $options, 93 '#description' => t('Log memory usage and page generation times for every page. This logging mode is <strong>not</strong> suitable for large sites, as it can degrade performance severly. It is intended for use by developers, or on a test copy of the site.'), 94 ); 95 96 $form['mode']['performance_summary_db'] = array( 97 '#type' => 'select', 98 '#title' => t('Summary logging (DB)'), 99 '#default_value' => variable_get('performance_summary_db', 0), 100 '#options' => $options, 101 '#description' => t('Log summary data, such as average and maximum page generation times and memory usage to the database. This logging mode is <strong>not</strong> suitable for most live sites.'), 102 ); 103 104 $disabled = TRUE; 105 if (function_exists('apc_cache_info')) { 106 $disabled = FALSE; 107 } 108 109 $form['mode']['performance_summary_apc'] = array( 110 '#type' => 'select', 111 '#title' => t('Summary logging (APC)'), 112 '#default_value' => variable_get('performance_summary_apc', 0), 113 '#options' => $options, 114 '#disabled' => $disabled, 115 '#description' => t('Log summary data, such as average and maximum page generation times and memory usage to APC, if installed. The summary will be stored in APC memory, and hence there is no load on the database. This logging to APC is suitable for most live sites, unless the number of unique page accesses is excessively high.'), 116 ); 117 118 $disabled = TRUE; 119 if (performance_memcache_enabled()) { 120 $disabled = FALSE; 121 } 122 123 $form['mode']['performance_summary_memcache'] = array( 124 '#type' => 'select', 125 '#title' => t('Summary logging (Memcached)'), 126 '#default_value' => variable_get('performance_summary_memcache', 0), 127 '#options' => $options, 128 '#disabled' => $disabled, 129 '#description' => t('Log summary data, such as average and maximum page generation times and memory usage to Memcached, if installed. The summary will be stored in Memcached memory, and hence there is no load on the database. This logging to Memcached is suitable for most live sites, unless the number of unique page accesses is excessively high.'), 130 ); 131 132 $form['other'] = array( 133 '#type' => 'fieldset', 134 '#title' => t('Other'), 135 '#collapsible' => TRUE, 136 ); 137 138 $form['other']['dev_query'] = array( 139 '#type' => 'select', 140 '#disabled' => TRUE, 141 '#title' => t('Database Query timing and count'), 142 '#default_value' => variable_get('dev_query', 0), 143 '#options' => $options, 144 '#description' => t('Log database query timing and query count for each page. This is useful to know if the bottleneck is in excessive database query counts, or the time required to execute those queries is high. Enabling this will incurr some memory overhead as query times and the actual query strings are cached in memory as arrays for each page, hence skewing the overall page memory reported. Please note that this settings is enabled or disabled in the settings of the devel module.'), 145 ); 146 147 $form['other']['performance_threshold_accesses'] = array( 148 '#type' => 'select', 149 '#title' => t('Accesses threshold'), 150 '#default_value' => variable_get('performance_threshold_accesses', 0), 151 '#options' => array(0, 1, 2, 5, 10), 152 '#description' => t('When displaying the summary report and using APC, only pages with the number of accesses larger than the specified threshold will be shown. Also, when cron runs, pages with that number of accesses or less will be removed, so as not to overflow APC\'s shared memory. This is useful on a live site with a high volume of hits. On a development site, you probably want this set to 0, so you can see all pages.'), 153 ); 154 155 return system_settings_form($form); 156 } 157 158 function performance_boot() { 159 register_shutdown_function('performance_shutdown'); 160 } 161 162 function performance_shutdown() { 163 global $queries; 164 165 // if ($_GET['q']) { 166 if (isset($_GET['q']) && ($_GET['q'])) { 167 // q= has a value, use that for the path 168 $path = $_GET['q']; 169 } 170 else { 171 // q= is empty, use whatever the site_frontpage is set to 172 $path = variable_get('site_frontpage', 'node'); 173 } 174 175 $params = array( 176 'timer' => timer_read('page'), 177 'path' => $path, 178 ); 179 180 // Memory 181 if (function_exists('memory_get_peak_usage')) { 182 $params['mem'] = memory_get_peak_usage(TRUE); 183 } 184 else { 185 $params['mem'] = 0; 186 } 187 188 // Query time and count 189 $query_count = 0; 190 $query_timer = 0; 191 $sum = 0; 192 if (variable_get('dev_query', 0) && is_array($queries)) { 193 foreach ($queries as $query) { 194 $sum += $query[1]; 195 } 196 $query_count = count($queries); 197 $query_timer = round($sum * 1000, 2); 198 } 199 200 $params['query_count'] = $query_count; 201 $params['query_timer'] = $query_timer; 202 203 $anon = (!empty($data['anon']))? 'Yes' : 'No'; 204 205 $header = array( 206 'path' => $path, 207 'timer' => $params['timer'], 208 'anon' => $anon, 209 ); 210 module_invoke_all('performance', 'header', $header); 211 212 if (variable_get('performance_detail', 0)) { 213 $data = module_invoke_all('performance', 'data'); 214 if (!empty($data[0])) { 215 $params['data'] = $data[0]; 216 } 217 218 performance_log_details($params); 219 } 220 else { 221 module_invoke_all('performance', 'disable'); 222 } 223 224 if (variable_get('performance_summary_db', 0)) { 225 performance_log_summary_db($params); 226 } 227 228 if (variable_get('performance_summary_apc', 0)) { 229 if (function_exists('apc_cache_info')) { 230 performance_log_summary_apc($params); 231 } 232 } 233 234 if (variable_get('performance_summary_memcache', 0)) { 235 if (performance_memcache_enabled()) { 236 performance_log_summary_memcache($params); 237 } 238 } 239 } 240 241 function performance_log_summary_apc($params = array()) { 242 $key = PERFORMANCE_KEY . $params['path']; 243 if ($data = apc_fetch($key)) { 244 $data = array( 245 'path' => $data['path'], 246 'last_access' => time(), 247 'bytes_max' => max($params['mem'], $data['bytes_max']), 248 'bytes_avg' => ($data['bytes_avg'] + $params['mem']) / 2, 249 'ms_max' => max($params['timer'], $data['ms_max']), 250 'ms_avg' => ($data['ms_avg'] + $params['timer']) / 2, 251 'query_timer_max' => max($params['query_timer'], $data['query_timer_max']), 252 'query_timer_avg' => ($data['query_timer_avg'] + $params['query_timer']) / 2, 253 'query_count_max' => max($params['query_count'], $data['query_count_max']), 254 'query_count_avg' => ($data['query_count_avg'] + $params['query_count']) / 2, 255 'num_accesses' => $data['num_accesses'] + 1, 256 ); 257 } 258 else { 259 $data = array( 260 'path' => $params['path'], 261 'bytes_max' => $params['mem'], 262 'bytes_avg' => $params['mem'], 263 'ms_max' => $params['timer'], 264 'ms_avg' => $params['timer'], 265 'query_timer_max' => $params['query_timer'], 266 'query_timer_avg' => $params['query_timer'], 267 'query_count_max' => $params['query_count'], 268 'query_count_avg' => $params['query_count'], 269 'num_accesses' => 1, 270 'last_access' => time(), 271 ); 272 } 273 apc_store($key, $data); 274 } 275 276 function performance_log_summary_memcache($params = array()) { 277 $key = PERFORMANCE_KEY . $params['path']; 278 if ($cache = cache_get($key, PERFORMANCE_MEMCACHE_BIN)) { 279 $type = 'existing'; 280 $values = $cache->data; 281 $values = array( 282 'path' => $params['path'], 283 'last_access' => time(), 284 'bytes_max' => max($params['mem'], $values['bytes_max']), 285 'bytes_avg' => ($values['bytes_avg'] + $params['mem']) / 2, 286 'ms_max' => max($params['timer'], $values['ms_max']), 287 'ms_avg' => ($values['ms_avg'] + $params['timer']) / 2, 288 'query_timer_max' => max($params['query_timer'], $values['query_timer_max']), 289 'query_timer_avg' => ($values['query_timer_avg'] + $params['query_timer']) / 2, 290 'query_count_max' => max($params['query_count'], $values['query_count_max']), 291 'query_count_avg' => ($values['query_count_avg'] + $params['query_count']) / 2, 292 'num_accesses' => $values['num_accesses'] + 1, 293 ); 294 } 295 else { 296 $type = 'new'; 297 // It is a new key 298 $values = array( 299 'path' => $params['path'], 300 'bytes_max' => $params['mem'], 301 'bytes_avg' => $params['mem'], 302 'ms_max' => $params['timer'], 303 'ms_avg' => $params['timer'], 304 'query_timer_max' => $params['query_timer'], 305 'query_timer_avg' => $params['query_timer'], 306 'query_count_max' => $params['query_count'], 307 'query_count_avg' => $params['query_count'], 308 'num_accesses' => 1, 309 'last_access' => time(), 310 ); 311 312 if ($keys_cache = cache_get(PERFORMANCE_KEY, PERFORMANCE_MEMCACHE_BIN)) { 313 $keys_values = $keys_cache->data; 314 } 315 $keys_values[$key] = 1; 316 cache_set(PERFORMANCE_KEY, $keys_values, PERFORMANCE_MEMCACHE_BIN, CACHE_PERMANENT); 317 } 318 cache_set($key, $values, PERFORMANCE_MEMCACHE_BIN, CACHE_PERMANENT); 319 } 320 321 function performance_log_summary_db($params = array()) { 322 $row = db_fetch_object(db_query("SELECT * FROM {performance_summary} WHERE path = '%s'", $params['path'])); 323 if (!empty($row)) { 324 db_query("UPDATE {performance_summary} 325 SET last_access = %d, 326 num_accesses = num_accesses + 1, 327 bytes_max = %d, 328 bytes_avg = %d, 329 ms_max = %d, 330 ms_avg = %d, 331 query_timer_max = %d, 332 query_timer_avg = %d, 333 query_count_max = %d, 334 query_count_avg = %d 335 WHERE path = '%s'", 336 time(), 337 max($params['mem'], $row->bytes_max), 338 ($row->bytes_avg + $params['mem']) / 2, 339 max($params['timer'], $row->ms_max), 340 ($row->ms_avg + $params['timer']) / 2, 341 max($params['query_timer'], $row->query_timer_max), 342 ($row->query_timer_avg + $params['query_timer']) / 2, 343 max($params['query_count'], $row->query_count_max), 344 ($row->query_count_avg + $params['query_count']) / 2, 345 $params['path']); 346 } 347 else { 348 // First time we log this path, write fresh values 349 db_query("INSERT INTO {performance_summary} 350 (path, last_access, num_accesses, 351 bytes_max, bytes_avg, ms_max, ms_avg, 352 query_count_max, query_count_avg, query_timer_max, query_timer_avg) 353 VALUES 354 ('%s', %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", 355 $params['path'], 356 time(), 357 1, 358 $params['mem'], 359 $params['mem'], 360 $params['timer'], 361 $params['timer'], 362 $params['query_count'], 363 $params['query_count'], 364 $params['query_timer'], 365 $params['query_timer'] 366 ); 367 } 368 } 369 370 function performance_log_details($params = array()) { 371 global $user; 372 $anon = ($user->uid) ? FALSE : TRUE; 373 db_query("INSERT INTO {performance_detail} (path, anon, bytes, ms, timestamp, query_timer, query_count, data) VALUES ('%s', %d, %d, %d, %d, %d, %d, '%s')", 374 $params['path'], 375 $anon, 376 $params['mem'], 377 $params['timer'], 378 time(), 379 $params['query_timer'], 380 $params['query_count'], 381 $params['data'] 382 ); 383 } 384 385 function performance_apc_list_all() { 386 $key_list = array(); 387 $list = apc_cache_info('user'); 388 foreach ($list['cache_list'] as $cache_id => $cache_data) { 389 $regex = '/^'. PERFORMANCE_KEY .'/'; 390 if (preg_match($regex, $cache_data['info'])) { 391 $key_list[] = $cache_data['info']; 392 } 393 } 394 return $key_list; 395 } 396 397 /** 398 * Custom sort for summary performance report 399 * 400 * @param $x 401 * @param $y 402 * @return int 403 */ 404 function performance_summary_sort($x, $y) { 405 // This function is not working 406 return 0; 407 } 408 409 function performance_view_summary() { 410 $sum = array(); 411 $data_list = array(); 412 $rows = array(); 413 414 $sum[] = variable_get('performance_summary_db', 0); 415 $sum[] = variable_get('performance_summary_apc', 0); 416 $sum[] = variable_get('performance_summary_memcache', 0); 417 $go = array_sum($sum); 418 419 if (!$go) { 420 return t('Summary performance log is not enabled. Go to the <a href="@link">settings page</a> to enable it.', array('@link' => url('admin/settings/performance_logging'))); 421 } 422 423 $header = array(); 424 425 $header[] = array('data' => t('Path'), 'field' => 'path'); 426 $header[] = array('data' => t('Last access'), 'field' => 'last_access'); 427 $header[] = array('data' => t('# accesses'), 'field' => 'num_accesses'); 428 $header[] = array('data' => t('Max Memory (MB)'), 'field' => 'bytes_max'); 429 $header[] = array('data' => t('Avg Memory (MB)'), 'field' => 'bytes_avg'); 430 $header[] = array('data' => t('ms (Max)'), 'field' => 'ms_max'); 431 $header[] = array('data' => t('ms (Avg)'), 'field' => 'ms_avg'); 432 433 if (variable_get('dev_query', 0)) { 434 $header[] = array('data' => t('Query ms (Max)'), 'field' => 'query_timer_max'); 435 $header[] = array('data' => t('Query ms (Avg)'), 'field' => 'query_timer_avg'); 436 $header[] = array('data' => t('Query Count (Max)'), 'field' => 'query_count_max'); 437 $header[] = array('data' => t('Query Count (Avg)'), 'field' => 'query_count_avg'); 438 } 439 440 $total_rows = $shown = $last_max = $total_bytes = $total_ms = $total_accesses = 0; 441 $last_min = time(); 442 443 $threshold = variable_get('performance_threshold_accesses', 0); 444 445 if (variable_get('performance_summary_memcache', 0) && performance_memcache_enabled()) { 446 $tablesort = tablesort_init($header); 447 // Get the data from memcache 448 if ($keys_cache = cache_get(PERFORMANCE_KEY, PERFORMANCE_MEMCACHE_BIN)) { 449 if ($keys_cache->data) { 450 foreach ($keys_cache->data as $key => $v) { 451 $cache = cache_get($key, PERFORMANCE_MEMCACHE_BIN); 452 $data_list[] = $cache->data; 453 } 454 } 455 } 456 usort($data_list, 'performance_summary_sort'); 457 } 458 else if (variable_get('performance_summary_apc', 0) && function_exists('apc_cache_info')) { 459 $tablesort = tablesort_init($header); 460 // Get the data from the APC cache 461 foreach (performance_apc_list_all() as $key) { 462 $data_list[] = apc_fetch($key) + $tablesort; 463 } 464 usort($data_list, 'performance_summary_sort'); 465 } 466 else { 467 // Get the data form the database table 468 $sql = "SELECT * FROM {performance_summary}"; 469 $tablesort = tablesort_sql($header); 470 $result = pager_query($sql . $tablesort, 50); 471 while ($row = db_fetch_array($result)) { 472 $data_list[] = $row; 473 } 474 } 475 476 foreach ($data_list as $data) { 477 $total_rows++; 478 $last_max = max($last_max, $data['last_access']); 479 $last_min = min($last_min, $data['last_access']); 480 481 // Calculate running averages 482 $total_bytes += $data['bytes_avg']; 483 $total_ms += $data['ms_avg']; 484 $total_accesses += $data['num_accesses']; 485 486 $row_data = array(); 487 488 if ($data['num_accesses'] > $threshold) { 489 $shown++; 490 $row_data[] = check_plain($data['path']); 491 $row_data[] = format_date($data['last_access'], 'small'); 492 $row_data[] = $data['num_accesses']; 493 $row_data[] = number_format($data['bytes_max']/1024/1024, 2); 494 $row_data[] = number_format($data['bytes_avg']/1024/1024, 2); 495 $row_data[] = number_format($data['ms_max'], 1); 496 $row_data[] = number_format($data['ms_avg'], 1); 497 if (variable_get('dev_query', 0)) { 498 $row_data[] = number_format($data['query_timer_max'], 1); 499 $row_data[] = number_format($data['query_timer_avg'], 1); 500 $row_data[] = $data['query_count_max']; 501 $row_data[] = $data['query_count_avg']; 502 } 503 } 504 $rows[] = array('data' => $row_data); 505 } 506 507 if (!$rows) { 508 $rows[] = array(array('data' => t('No statistics available yet.'), 'colspan' => count($header))); 509 } 510 511 $output = ''; 512 if ($threshold) { 513 $output .= t('Showing !shown paths with more than !threshold accesses, out of !total total paths.', 514 array('!threshold' => $threshold, '!shown' => $shown, '!total' => $total_rows)) .'<br/>'; 515 } 516 else { 517 $output .= t('Showing all !total paths.', array('!total' => $total_rows)) .'<br/>'; 518 } 519 520 // Protect against divide by zero 521 if ($total_rows > 0) { 522 $mb_avg = number_format($total_bytes/$total_rows/1024/1024, 1); 523 $ms_avg = number_format($total_ms/$total_rows, 2); 524 } 525 else { 526 $mb_avg = 'n/a'; 527 $ms_avg = 'n/a'; 528 } 529 530 $output .= t('Average memory per page: !mb_avg MB', array('!mb_avg' => $mb_avg)) .'<br/>'; 531 $output .= t('Average ms per page: !ms_avg', array('!ms_avg' => $ms_avg)) .'<br/>'; 532 $output .= t('Total number of page accesses: !accesses', array('!accesses' => $total_accesses)) .'<br/>'; 533 $output .= t('First access: !access.', array('!access' => format_date($last_min, 'small'))) .'<br/>'; 534 $output .= t('Last access: !access.', array('!access' => format_date($last_max, 'small'))) .'<br/>'; 535 536 $output .= theme('table', $header, $rows); 537 $output .= theme('pager', NULL, 50, 0); 538 539 return $output; 540 } 541 542 function performance_view_details() { 543 if (!variable_get('performance_detail', 0)) { 544 return t('Detail performance log is not enabled. Go to the <a href="@link">settings page</a> to enable it.', array('@link' => url('admin/settings/performance_logging'))); 545 } 546 547 $header = array( 548 array('data' => t('#'), 'field' => 'pid', 'sort' => 'desc'), 549 array('data' => t('Date'), 'field' => 'timestamp'), 550 array('data' => t('Path'), 'field' => 'path'), 551 array('data' => t('Memory (MB)'), 'field' => 'bytes'), 552 array('data' => t('ms (Total)'), 'field' => 'ms'), 553 array('data' => t('Anonymous?'), 'field' => 'anon'), 554 ); 555 556 if (variable_get('dev_query', 0)) { 557 $header[] = array('data' => t('# Queries'), 'field' => 'query_count'); 558 $header[] = array('data' => t('Query ms'), 'field' => 'query_timer'); 559 } 560 561 $sql = "SELECT * FROM {performance_detail}"; 562 $tablesort = tablesort_sql($header); 563 $result = pager_query($sql . $tablesort, 50); 564 565 while ($data = db_fetch_array($result)) { 566 $row_data = array(); 567 568 $row_data[] = $data['pid']; 569 $row_data[] = format_date($data['timestamp'], 'small'); 570 $row_data[] = check_plain($data['path']); 571 $row_data[] = number_format($data['bytes']/1024/1024, 2); 572 $row_data[] = $data['ms']; 573 $row_data[] = ($data['anon']) ? t('Yes') : t('No'); 574 575 if (variable_get('dev_query', 0)) { 576 $row_data[] = $data['query_count']; 577 $row_data[] = $data['query_timer']; 578 } 579 580 $rows[] = array('data' => $row_data); 581 } 582 583 if (!$rows) { 584 $rows[] = array(array('data' => t('No log messages available.'), 'colspan' => count($header))); 585 } 586 587 $output = theme('table', $header, $rows); 588 $output .= theme('pager', NULL, 50, 0); 589 590 return $output; 591 } 592 593 function performance_cron() { 594 // One day ago ... 595 $timestamp = time() - 24*60*60; 596 597 performance_cron_db_prune($timestamp); 598 performance_cron_apc_prune($timestamp); 599 } 600 601 function performance_cron_db_prune($timestamp = 0) { 602 // Remove rows which have not been accessed since a certain timestamp 603 db_query("DELETE FROM {performance_summary} WHERE last_access <= %d", $timestamp); 604 605 // Remove performance_detail rows on a daily basis 606 db_query("DELETE FROM {performance_detail} WHERE timestamp <= %d", $timestamp); 607 } 608 609 function performance_cron_apc_prune($timestamp = 0) { 610 if (!function_exists('apc_cache_info')) { 611 // APC not enabled, nothing to do ... 612 return; 613 } 614 615 // Get all entries in APC's user cache 616 $list = performance_apc_list_all(); 617 if (!count($list)) { 618 // Nothing stored yet 619 return; 620 } 621 622 foreach ($list as $key) { 623 if ($data = apc_fetch($key)) { 624 if ($data['last_access'] <= $timestamp) { 625 apc_delete($key); 626 } 627 } 628 } 629 } 630 631 function performance_clear_apc_confirm() { 632 $form['confirm'] = array( 633 '#value' => t('Confirm APC clear'), 634 ); 635 return confirm_form( 636 $form, 637 t('Are you sure you want to clear the APC statistics for this site?'), 638 'admin/settings/performance_logging', 639 t('This will clear all the collected performance statistics stored in APC. This action cannot be undone.'), 640 t('Clear'), 641 t('Cancel')); 642 } 643 644 function performance_clear_apc_confirm_submit($form, &$form_state) { 645 if (!function_exists('apc_cache_info')) { 646 drupal_set_message(t('APC is not enabled. Nothing to do ...'), 'status', FALSE); 647 drupal_goto('admin/settings/performance'); 648 return; 649 } 650 651 $list = performance_apc_list_all(); 652 if (!count($list)) { 653 // Nothing stored yet 654 return; 655 } 656 657 foreach ($list as $key) { 658 if ($data = apc_fetch($key)) { 659 apc_delete($key); 660 } 661 } 662 663 drupal_set_message(t('Performance statistics collected in APC has been cleared.'), 'status', FALSE); 664 drupal_goto('admin/settings/performance'); 665 } 666 667 function performance_clear_memcache_confirm() { 668 $form['confirm'] = array( 669 '#value' => t('Confirm Memcache clear'), 670 ); 671 return confirm_form( 672 $form, 673 t('Are you sure you want to clear the Memcache statistics for this site?'), 674 'admin/settings/performance_logging', 675 t('This will clear all the collected performance statistics stored in Memcache. This action cannot be undone.'), 676 t('Clear'), 677 t('Cancel')); 678 } 679 680 function performance_clear_memcache_confirm_submit($form, &$form_state) { 681 if (!performance_memcache_enabled()) { 682 drupal_set_message(t('Memcache is not enabled. Nothing to do ...'), 'status', FALSE); 683 drupal_goto('admin/settings/performance'); 684 return; 685 } 686 687 // We have to iterate over all entries and delete them, reaching down 688 // the API stack and calling dmemcache_delete directly. 689 // This is suboptimal, but there is no other alternative 690 if ($keys_cache = cache_get(PERFORMANCE_KEY, PERFORMANCE_MEMCACHE_BIN)) { 691 if ($keys_cache->data) { 692 foreach ($keys_cache->data as $key => $v) { 693 dmemcache_delete($key, PERFORMANCE_MEMCACHE_BIN); 694 } 695 dmemcache_delete(PERFORMANCE_KEY, PERFORMANCE_MEMCACHE_BIN); 696 } 697 } 698 699 drupal_set_message(t('Performance statistics collected in Memcache has been cleared.'), 'status', FALSE); 700 drupal_goto('admin/settings/performance'); 701 } 702 703 /** 704 * Implementation of hook_nagios_info(). 705 */ 706 function performance_nagios_info() { 707 return array( 708 'name' => 'Performance logging', 709 'id' => 'PERF', 710 ); 711 } 712 713 /** 714 * Implementation of hook_nagios(). 715 */ 716 function performance_nagios() { 717 $info = performance_nagios_info(); 718 $id = $info['id']; 719 720 // Find out if we have what we need enabled 721 $sum = array(); 722 723 $sum[] = variable_get('performance_summary_db', 0); 724 $sum[] = variable_get('performance_summary_apc', 0); 725 $go = array_sum($sum); 726 727 if (!$go) { 728 return array( 729 $id => array( 730 'status' => NAGIOS_STATUS_UNKNOWN, 731 'type' => 'perf', 732 'text' => t('Performance logging is not enabled'), 733 ), 734 ); 735 } 736 737 // Initialize variables 738 $total_rows = $total_bytes = $total_ms = $total_accesses = $total_query_time = $total_query_count = 0; 739 740 // Check which data store to use 741 if (variable_get('performance_summary_apc', 0) && function_exists('apc_cache_info')) { 742 // Get the data from the APC cache 743 foreach (performance_apc_list_all() as $key) { 744 $data_list[] = apc_fetch($key); 745 } 746 } 747 else { 748 // Get the data form the database table for URLs that have been accessed in the last 15 minutes 749 $result = db_query("SELECT * FROM {performance_summary} WHERE last_access >= %d", time() - 15*60); 750 while (is_array($row = db_fetch_array($result))) { 751 $data_list[] = $row; 752 } 753 } 754 755 foreach ($data_list as $data) { 756 $total_rows++; 757 758 // Calculate running averages 759 $total_bytes += $data['bytes_avg']; 760 $total_ms += $data['ms_avg']; 761 $total_accesses += $data['num_accesses']; 762 $total_query_time += $data['query_timer_avg']; 763 $total_query_count += $data['query_count_avg']; 764 } 765 766 // Protect against divide by zero 767 if ($total_rows > 0) { 768 $ms_avg = number_format($total_ms / $total_rows, 1, '.', ''); 769 $ms_query = number_format($total_query_time / $total_rows, 1, '.', ''); 770 $query_count = number_format($total_query_count / $total_rows, 2, '.', ''); 771 $mb_avg = number_format($total_bytes / $total_rows/1024/1024, 1); 772 } 773 else { 774 $ms_avg = ''; 775 $ms_query = ''; 776 $mb_avg = ''; 777 $query_count = ''; 778 } 779 780 $status = NAGIOS_STATUS_OK; 781 782 return array( 783 'ACC' => array( 784 'status' => $status, 785 'type' => 'perf', 786 'text' => $total_accesses, 787 ), 788 'MS' => array( 789 'status' => $status, 790 'type' => 'perf', 791 'text' => $ms_avg, 792 ), 793 'MMB' => array( 794 'status' => $status, 795 'type' => 'perf', 796 'text' => $mb_avg, 797 ), 798 'QRC' => array( 799 'status' => $status, 800 'type' => 'perf', 801 'text' => $query_count, 802 ), 803 'QRT' => array( 804 'status' => $status, 805 'type' => 'perf', 806 'text' => $ms_query, 807 ), 808 ); 809 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |