Example #1
0
/**
 * get_performance_info() pairs up with init_performance_info()
 * loaded in setup.php. Returns an array with 'html' and 'txt'
 * values ready for use, and each of the individual stats provided
 * separately as well.
 *
 * @return array
 */
function get_performance_info()
{
    global $CFG, $PERF, $DB, $PAGE;
    $info = array();
    $info['txt'] = me() . ' ';
    // Holds log-friendly representation.
    $info['html'] = '';
    if (!empty($CFG->themedesignermode)) {
        // Attempt to avoid devs debugging peformance issues, when its caused by css building and so on.
        $info['html'] .= '<p><strong>Warning: Theme designer mode is enabled.</strong></p>';
    }
    $info['html'] .= '<ul class="list-unstyled m-l-1">';
    // Holds userfriendly HTML representation.
    $info['realtime'] = microtime_diff($PERF->starttime, microtime());
    $info['html'] .= '<li class="timeused">' . $info['realtime'] . ' secs</li> ';
    $info['txt'] .= 'time: ' . $info['realtime'] . 's ';
    if (function_exists('memory_get_usage')) {
        $info['memory_total'] = memory_get_usage();
        $info['memory_growth'] = memory_get_usage() - $PERF->startmemory;
        $info['html'] .= '<li class="memoryused">RAM: ' . display_size($info['memory_total']) . '</li> ';
        $info['txt'] .= 'memory_total: ' . $info['memory_total'] . 'B (' . display_size($info['memory_total']) . ') memory_growth: ' . $info['memory_growth'] . 'B (' . display_size($info['memory_growth']) . ') ';
    }
    if (function_exists('memory_get_peak_usage')) {
        $info['memory_peak'] = memory_get_peak_usage();
        $info['html'] .= '<li class="memoryused">RAM peak: ' . display_size($info['memory_peak']) . '</li> ';
        $info['txt'] .= 'memory_peak: ' . $info['memory_peak'] . 'B (' . display_size($info['memory_peak']) . ') ';
    }
    $inc = get_included_files();
    $info['includecount'] = count($inc);
    $info['html'] .= '<li class="included">Included ' . $info['includecount'] . ' files</li> ';
    $info['txt'] .= 'includecount: ' . $info['includecount'] . ' ';
    if (!empty($CFG->early_install_lang) or empty($PAGE)) {
        // We can not track more performance before installation or before PAGE init, sorry.
        return $info;
    }
    $filtermanager = filter_manager::instance();
    if (method_exists($filtermanager, 'get_performance_summary')) {
        list($filterinfo, $nicenames) = $filtermanager->get_performance_summary();
        $info = array_merge($filterinfo, $info);
        foreach ($filterinfo as $key => $value) {
            $info['html'] .= "<li class='{$key}'>{$nicenames[$key]}: {$value} </li> ";
            $info['txt'] .= "{$key}: {$value} ";
        }
    }
    $stringmanager = get_string_manager();
    if (method_exists($stringmanager, 'get_performance_summary')) {
        list($filterinfo, $nicenames) = $stringmanager->get_performance_summary();
        $info = array_merge($filterinfo, $info);
        foreach ($filterinfo as $key => $value) {
            $info['html'] .= "<li class='{$key}'>{$nicenames[$key]}: {$value} </li> ";
            $info['txt'] .= "{$key}: {$value} ";
        }
    }
    if (!empty($PERF->logwrites)) {
        $info['logwrites'] = $PERF->logwrites;
        $info['html'] .= '<li class="logwrites">Log DB writes ' . $info['logwrites'] . '</li> ';
        $info['txt'] .= 'logwrites: ' . $info['logwrites'] . ' ';
    }
    $info['dbqueries'] = $DB->perf_get_reads() . '/' . ($DB->perf_get_writes() - $PERF->logwrites);
    $info['html'] .= '<li class="dbqueries">DB reads/writes: ' . $info['dbqueries'] . '</li> ';
    $info['txt'] .= 'db reads/writes: ' . $info['dbqueries'] . ' ';
    $info['dbtime'] = round($DB->perf_get_queries_time(), 5);
    $info['html'] .= '<li class="dbtime">DB queries time: ' . $info['dbtime'] . ' secs</li> ';
    $info['txt'] .= 'db queries time: ' . $info['dbtime'] . 's ';
    if (function_exists('posix_times')) {
        $ptimes = posix_times();
        if (is_array($ptimes)) {
            foreach ($ptimes as $key => $val) {
                $info[$key] = $ptimes[$key] - $PERF->startposixtimes[$key];
            }
            $info['html'] .= "<li class=\"posixtimes\">ticks: {$info['ticks']} user: {$info['utime']} sys: {$info['stime']} cuser: {$info['cutime']} csys: {$info['cstime']}</li> ";
            $info['txt'] .= "ticks: {$info['ticks']} user: {$info['utime']} sys: {$info['stime']} cuser: {$info['cutime']} csys: {$info['cstime']} ";
        }
    }
    // Grab the load average for the last minute.
    // /proc will only work under some linux configurations
    // while uptime is there under MacOSX/Darwin and other unices.
    if (is_readable('/proc/loadavg') && ($loadavg = @file('/proc/loadavg'))) {
        list($serverload) = explode(' ', $loadavg[0]);
        unset($loadavg);
    } else {
        if (function_exists('is_executable') && is_executable('/usr/bin/uptime') && ($loadavg = `/usr/bin/uptime`)) {
            if (preg_match('/load averages?: (\\d+[\\.,:]\\d+)/', $loadavg, $matches)) {
                $serverload = $matches[1];
            } else {
                trigger_error('Could not parse uptime output!');
            }
        }
    }
    if (!empty($serverload)) {
        $info['serverload'] = $serverload;
        $info['html'] .= '<li class="serverload">Load average: ' . $info['serverload'] . '</li> ';
        $info['txt'] .= "serverload: {$info['serverload']} ";
    }
    // Display size of session if session started.
    if ($si = \core\session\manager::get_performance_info()) {
        $info['sessionsize'] = $si['size'];
        $info['html'] .= $si['html'];
        $info['txt'] .= $si['txt'];
    }
    if ($stats = cache_helper::get_stats()) {
        $html = '<ul class="cachesused list-unstyled m-l-1">';
        $html .= '<li class="cache-stats-heading">Caches used (hits/misses/sets)</li>';
        $text = 'Caches used (hits/misses/sets): ';
        $hits = 0;
        $misses = 0;
        $sets = 0;
        foreach ($stats as $definition => $details) {
            switch ($details['mode']) {
                case cache_store::MODE_APPLICATION:
                    $modeclass = 'application';
                    $mode = ' <span title="application cache">[a]</span>';
                    break;
                case cache_store::MODE_SESSION:
                    $modeclass = 'session';
                    $mode = ' <span title="session cache">[s]</span>';
                    break;
                case cache_store::MODE_REQUEST:
                    $modeclass = 'request';
                    $mode = ' <span title="request cache">[r]</span>';
                    break;
            }
            $html .= '<ul class="cache-definition-stats list-unstyled m-l-1 cache-mode-' . $modeclass . '">';
            $html .= '<li class="cache-definition-stats-heading p-t-1">' . $definition . $mode . '</li>';
            $text .= "{$definition} {";
            foreach ($details['stores'] as $store => $data) {
                $hits += $data['hits'];
                $misses += $data['misses'];
                $sets += $data['sets'];
                if ($data['hits'] == 0 and $data['misses'] > 0) {
                    $cachestoreclass = 'nohits text-danger';
                } else {
                    if ($data['hits'] < $data['misses']) {
                        $cachestoreclass = 'lowhits text-warning';
                    } else {
                        $cachestoreclass = 'hihits text-success';
                    }
                }
                $text .= "{$store}({$data['hits']}/{$data['misses']}/{$data['sets']}) ";
                $html .= "<li class=\"cache-store-stats {$cachestoreclass}\">{$store}: {$data['hits']} / {$data['misses']} / {$data['sets']}</li>";
            }
            $html .= '</ul>';
            $text .= '} ';
        }
        $html .= '</ul> ';
        $html .= "<div class='cache-total-stats row'>Total: {$hits} / {$misses} / {$sets}</div>";
        $info['cachesused'] = "{$hits} / {$misses} / {$sets}";
        $info['html'] .= $html;
        $info['txt'] .= $text . '. ';
    } else {
        $info['cachesused'] = '0 / 0 / 0';
        $info['html'] .= '<div class="cachesused">Caches used (hits/misses/sets): 0/0/0</div>';
        $info['txt'] .= 'Caches used (hits/misses/sets): 0/0/0 ';
    }
    $info['html'] = '<div class="performanceinfo siteinfo">' . $info['html'] . '</div>';
    return $info;
}
Example #2
0
/**
 * get_performance_info() pairs up with init_performance_info()
 * loaded in setup.php. Returns an array with 'html' and 'txt'
 * values ready for use, and each of the individual stats provided
 * separately as well.
 *
 * @return array
 */
function get_performance_info() {
    global $CFG, $PERF, $DB, $PAGE;

    $info = array();
    $info['html'] = '';         // Holds userfriendly HTML representation.
    $info['txt']  = me() . ' '; // Holds log-friendly representation.

    $info['realtime'] = microtime_diff($PERF->starttime, microtime());

    $info['html'] .= '<span class="timeused">'.$info['realtime'].' secs</span> ';
    $info['txt'] .= 'time: '.$info['realtime'].'s ';

    if (function_exists('memory_get_usage')) {
        $info['memory_total'] = memory_get_usage();
        $info['memory_growth'] = memory_get_usage() - $PERF->startmemory;
        $info['html'] .= '<span class="memoryused">RAM: '.display_size($info['memory_total']).'</span> ';
        $info['txt']  .= 'memory_total: '.$info['memory_total'].'B (' . display_size($info['memory_total']).') memory_growth: '.
            $info['memory_growth'].'B ('.display_size($info['memory_growth']).') ';
    }

    if (function_exists('memory_get_peak_usage')) {
        $info['memory_peak'] = memory_get_peak_usage();
        $info['html'] .= '<span class="memoryused">RAM peak: '.display_size($info['memory_peak']).'</span> ';
        $info['txt']  .= 'memory_peak: '.$info['memory_peak'].'B (' . display_size($info['memory_peak']).') ';
    }

    $inc = get_included_files();
    $info['includecount'] = count($inc);
    $info['html'] .= '<span class="included">Included '.$info['includecount'].' files</span> ';
    $info['txt']  .= 'includecount: '.$info['includecount'].' ';

    if (!empty($CFG->early_install_lang) or empty($PAGE)) {
        // We can not track more performance before installation or before PAGE init, sorry.
        return $info;
    }

    $filtermanager = filter_manager::instance();
    if (method_exists($filtermanager, 'get_performance_summary')) {
        list($filterinfo, $nicenames) = $filtermanager->get_performance_summary();
        $info = array_merge($filterinfo, $info);
        foreach ($filterinfo as $key => $value) {
            $info['html'] .= "<span class='$key'>$nicenames[$key]: $value </span> ";
            $info['txt'] .= "$key: $value ";
        }
    }

    $stringmanager = get_string_manager();
    if (method_exists($stringmanager, 'get_performance_summary')) {
        list($filterinfo, $nicenames) = $stringmanager->get_performance_summary();
        $info = array_merge($filterinfo, $info);
        foreach ($filterinfo as $key => $value) {
            $info['html'] .= "<span class='$key'>$nicenames[$key]: $value </span> ";
            $info['txt'] .= "$key: $value ";
        }
    }

    if (!empty($PERF->logwrites)) {
        $info['logwrites'] = $PERF->logwrites;
        $info['html'] .= '<span class="logwrites">Log DB writes '.$info['logwrites'].'</span> ';
        $info['txt'] .= 'logwrites: '.$info['logwrites'].' ';
    }

    $info['dbqueries'] = $DB->perf_get_reads().'/'.($DB->perf_get_writes() - $PERF->logwrites);
    $info['html'] .= '<span class="dbqueries">DB reads/writes: '.$info['dbqueries'].'</span> ';
    $info['txt'] .= 'db reads/writes: '.$info['dbqueries'].' ';

    $info['dbtime'] = round($DB->perf_get_queries_time(), 5);
    $info['html'] .= '<span class="dbtime">DB queries time: '.$info['dbtime'].' secs</span> ';
    $info['txt'] .= 'db queries time: ' . $info['dbtime'] . 's ';

    if (function_exists('posix_times')) {
        $ptimes = posix_times();
        if (is_array($ptimes)) {
            foreach ($ptimes as $key => $val) {
                $info[$key] = $ptimes[$key] -  $PERF->startposixtimes[$key];
            }
            $info['html'] .= "<span class=\"posixtimes\">ticks: $info[ticks] user: $info[utime] sys: $info[stime] cuser: $info[cutime] csys: $info[cstime]</span> ";
            $info['txt'] .= "ticks: $info[ticks] user: $info[utime] sys: $info[stime] cuser: $info[cutime] csys: $info[cstime] ";
        }
    }

    // Grab the load average for the last minute.
    // /proc will only work under some linux configurations
    // while uptime is there under MacOSX/Darwin and other unices.
    if (is_readable('/proc/loadavg') && $loadavg = @file('/proc/loadavg')) {
        list($serverload) = explode(' ', $loadavg[0]);
        unset($loadavg);
    } else if ( function_exists('is_executable') && is_executable('/usr/bin/uptime') && $loadavg = `/usr/bin/uptime` ) {
        if (preg_match('/load averages?: (\d+[\.,:]\d+)/', $loadavg, $matches)) {
            $serverload = $matches[1];
        } else {
            trigger_error('Could not parse uptime output!');
        }
    }
    if (!empty($serverload)) {
        $info['serverload'] = $serverload;
        $info['html'] .= '<span class="serverload">Load average: '.$info['serverload'].'</span> ';
        $info['txt'] .= "serverload: {$info['serverload']} ";
    }

    // Display size of session if session started.
    if ($si = \core\session\manager::get_performance_info()) {
        $info['sessionsize'] = $si['size'];
        $info['html'] .= $si['html'];
        $info['txt'] .= $si['txt'];
    }

    if ($stats = cache_helper::get_stats()) {
        $html = '<span class="cachesused">';
        $html .= '<span class="cache-stats-heading">Caches used (hits/misses/sets)</span>';
        $text = 'Caches used (hits/misses/sets): ';
        $hits = 0;
        $misses = 0;
        $sets = 0;
        foreach ($stats as $definition => $stores) {
            $html .= '<span class="cache-definition-stats">';
            $html .= '<span class="cache-definition-stats-heading">'.$definition.'</span>';
            $text .= "$definition {";
            foreach ($stores as $store => $data) {
                $hits += $data['hits'];
                $misses += $data['misses'];
                $sets += $data['sets'];
                if ($data['hits'] == 0 and $data['misses'] > 0) {
                    $cachestoreclass = 'nohits';
                } else if ($data['hits'] < $data['misses']) {
                    $cachestoreclass = 'lowhits';
                } else {
                    $cachestoreclass = 'hihits';
                }
                $text .= "$store($data[hits]/$data[misses]/$data[sets]) ";
                $html .= "<span class=\"cache-store-stats $cachestoreclass\">$store: $data[hits] / $data[misses] / $data[sets]</span>";
            }
            $html .= '</span>';
            $text .= '} ';
        }
        $html .= "<span class='cache-total-stats'>Total: $hits / $misses / $sets</span>";
        $html .= '</span> ';
        $info['cachesused'] = "$hits / $misses / $sets";
        $info['html'] .= $html;
        $info['txt'] .= $text.'. ';
    } else {
        $info['cachesused'] = '0 / 0 / 0';
        $info['html'] .= '<span class="cachesused">Caches used (hits/misses/sets): 0/0/0</span>';
        $info['txt'] .= 'Caches used (hits/misses/sets): 0/0/0 ';
    }

    $info['html'] = '<div class="performanceinfo siteinfo">'.$info['html'].'</div>';
    return $info;
}
Example #3
0
 public function test_performance_debug()
 {
     global $CFG;
     $this->resetAfterTest(true);
     $CFG->perfdebug = 15;
     $instance = cache_config_testing::instance();
     $applicationid = 'phpunit/applicationperf';
     $instance->phpunit_add_definition($applicationid, array('mode' => cache_store::MODE_APPLICATION, 'component' => 'phpunit', 'area' => 'applicationperf'));
     $sessionid = 'phpunit/sessionperf';
     $instance->phpunit_add_definition($sessionid, array('mode' => cache_store::MODE_SESSION, 'component' => 'phpunit', 'area' => 'sessionperf'));
     $requestid = 'phpunit/requestperf';
     $instance->phpunit_add_definition($requestid, array('mode' => cache_store::MODE_REQUEST, 'component' => 'phpunit', 'area' => 'requestperf'));
     $application = cache::make('phpunit', 'applicationperf');
     $session = cache::make('phpunit', 'sessionperf');
     $request = cache::make('phpunit', 'requestperf');
     // Check that no stats are recorded for these definitions yet.
     $stats = cache_helper::get_stats();
     $this->assertArrayNotHasKey($applicationid, $stats);
     $this->assertArrayHasKey($sessionid, $stats);
     // Session cache sets a key on construct.
     $this->assertArrayNotHasKey($requestid, $stats);
     // Check that stores register misses.
     $this->assertFalse($application->get('missMe'));
     $this->assertFalse($application->get('missMe'));
     $this->assertFalse($session->get('missMe'));
     $this->assertFalse($session->get('missMe'));
     $this->assertFalse($session->get('missMe'));
     $this->assertFalse($request->get('missMe'));
     $this->assertFalse($request->get('missMe'));
     $this->assertFalse($request->get('missMe'));
     $this->assertFalse($request->get('missMe'));
     $endstats = cache_helper::get_stats();
     $this->assertEquals(2, $endstats[$applicationid]['stores']['cachestore_file']['misses']);
     $this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['hits']);
     $this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['sets']);
     $this->assertEquals(3, $endstats[$sessionid]['stores']['cachestore_session']['misses']);
     $this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['hits']);
     $this->assertEquals(1, $endstats[$sessionid]['stores']['cachestore_session']['sets']);
     $this->assertEquals(4, $endstats[$requestid]['stores']['cachestore_static']['misses']);
     $this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['hits']);
     $this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['sets']);
     $startstats = cache_helper::get_stats();
     // Check that stores register sets.
     $this->assertTrue($application->set('setMe1', 1));
     $this->assertTrue($application->set('setMe2', 2));
     $this->assertTrue($session->set('setMe1', 1));
     $this->assertTrue($session->set('setMe2', 2));
     $this->assertTrue($session->set('setMe3', 3));
     $this->assertTrue($request->set('setMe1', 1));
     $this->assertTrue($request->set('setMe2', 2));
     $this->assertTrue($request->set('setMe3', 3));
     $this->assertTrue($request->set('setMe4', 4));
     $endstats = cache_helper::get_stats();
     $this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['misses'] - $startstats[$applicationid]['stores']['cachestore_file']['misses']);
     $this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['hits'] - $startstats[$applicationid]['stores']['cachestore_file']['hits']);
     $this->assertEquals(2, $endstats[$applicationid]['stores']['cachestore_file']['sets'] - $startstats[$applicationid]['stores']['cachestore_file']['sets']);
     $this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['misses'] - $startstats[$sessionid]['stores']['cachestore_session']['misses']);
     $this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['hits'] - $startstats[$sessionid]['stores']['cachestore_session']['hits']);
     $this->assertEquals(3, $endstats[$sessionid]['stores']['cachestore_session']['sets'] - $startstats[$sessionid]['stores']['cachestore_session']['sets']);
     $this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['misses'] - $startstats[$requestid]['stores']['cachestore_static']['misses']);
     $this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['hits'] - $startstats[$requestid]['stores']['cachestore_static']['hits']);
     $this->assertEquals(4, $endstats[$requestid]['stores']['cachestore_static']['sets'] - $startstats[$requestid]['stores']['cachestore_static']['sets']);
     $startstats = cache_helper::get_stats();
     // Check that stores register hits.
     $this->assertEquals($application->get('setMe1'), 1);
     $this->assertEquals($application->get('setMe2'), 2);
     $this->assertEquals($session->get('setMe1'), 1);
     $this->assertEquals($session->get('setMe2'), 2);
     $this->assertEquals($session->get('setMe3'), 3);
     $this->assertEquals($request->get('setMe1'), 1);
     $this->assertEquals($request->get('setMe2'), 2);
     $this->assertEquals($request->get('setMe3'), 3);
     $this->assertEquals($request->get('setMe4'), 4);
     $endstats = cache_helper::get_stats();
     $this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['misses'] - $startstats[$applicationid]['stores']['cachestore_file']['misses']);
     $this->assertEquals(2, $endstats[$applicationid]['stores']['cachestore_file']['hits'] - $startstats[$applicationid]['stores']['cachestore_file']['hits']);
     $this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['sets'] - $startstats[$applicationid]['stores']['cachestore_file']['sets']);
     $this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['misses'] - $startstats[$sessionid]['stores']['cachestore_session']['misses']);
     $this->assertEquals(3, $endstats[$sessionid]['stores']['cachestore_session']['hits'] - $startstats[$sessionid]['stores']['cachestore_session']['hits']);
     $this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['sets'] - $startstats[$sessionid]['stores']['cachestore_session']['sets']);
     $this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['misses'] - $startstats[$requestid]['stores']['cachestore_static']['misses']);
     $this->assertEquals(4, $endstats[$requestid]['stores']['cachestore_static']['hits'] - $startstats[$requestid]['stores']['cachestore_static']['hits']);
     $this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['sets'] - $startstats[$requestid]['stores']['cachestore_static']['sets']);
     $startstats = cache_helper::get_stats();
     // Check that stores register through get_many.
     $application->get_many(array('setMe1', 'setMe2'));
     $session->get_many(array('setMe1', 'setMe2', 'setMe3'));
     $request->get_many(array('setMe1', 'setMe2', 'setMe3', 'setMe4'));
     $endstats = cache_helper::get_stats();
     $this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['misses'] - $startstats[$applicationid]['stores']['cachestore_file']['misses']);
     $this->assertEquals(2, $endstats[$applicationid]['stores']['cachestore_file']['hits'] - $startstats[$applicationid]['stores']['cachestore_file']['hits']);
     $this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['sets'] - $startstats[$applicationid]['stores']['cachestore_file']['sets']);
     $this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['misses'] - $startstats[$sessionid]['stores']['cachestore_session']['misses']);
     $this->assertEquals(3, $endstats[$sessionid]['stores']['cachestore_session']['hits'] - $startstats[$sessionid]['stores']['cachestore_session']['hits']);
     $this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['sets'] - $startstats[$sessionid]['stores']['cachestore_session']['sets']);
     $this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['misses'] - $startstats[$requestid]['stores']['cachestore_static']['misses']);
     $this->assertEquals(4, $endstats[$requestid]['stores']['cachestore_static']['hits'] - $startstats[$requestid]['stores']['cachestore_static']['hits']);
     $this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['sets'] - $startstats[$requestid]['stores']['cachestore_static']['sets']);
 }
/**
 * get_performance_info() pairs up with init_performance_info()
 * loaded in setup.php. Returns an array with 'html' and 'txt'
 * values ready for use, and each of the individual stats provided
 * separately as well.
 *
 * @return array
 */
function get_performance_info()
{
    global $CFG, $PERF, $DB, $PAGE;
    $info = array();
    $info['html'] = '';
    // Holds userfriendly HTML representation.
    $info['txt'] = me() . ' ';
    // Holds log-friendly representation.
    $info['realtime'] = microtime_diff($PERF->starttime, microtime());
    $info['html'] .= '<span class="timeused">' . $info['realtime'] . ' secs</span> ';
    $info['txt'] .= 'time: ' . $info['realtime'] . 's ';
    if (function_exists('memory_get_usage')) {
        $info['memory_total'] = memory_get_usage();
        $info['memory_growth'] = memory_get_usage() - $PERF->startmemory;
        $info['html'] .= '<span class="memoryused">RAM: ' . display_size($info['memory_total']) . '</span> ';
        $info['txt'] .= 'memory_total: ' . $info['memory_total'] . 'B (' . display_size($info['memory_total']) . ') memory_growth: ' . $info['memory_growth'] . 'B (' . display_size($info['memory_growth']) . ') ';
    }
    if (function_exists('memory_get_peak_usage')) {
        $info['memory_peak'] = memory_get_peak_usage();
        $info['html'] .= '<span class="memoryused">RAM peak: ' . display_size($info['memory_peak']) . '</span> ';
        $info['txt'] .= 'memory_peak: ' . $info['memory_peak'] . 'B (' . display_size($info['memory_peak']) . ') ';
    }
    $inc = get_included_files();
    $info['includecount'] = count($inc);
    $info['html'] .= '<span class="included">Included ' . $info['includecount'] . ' files</span> ';
    $info['txt'] .= 'includecount: ' . $info['includecount'] . ' ';
    if (!empty($CFG->early_install_lang) or empty($PAGE)) {
        // We can not track more performance before installation or before PAGE init, sorry.
        return $info;
    }
    $filtermanager = filter_manager::instance();
    if (method_exists($filtermanager, 'get_performance_summary')) {
        list($filterinfo, $nicenames) = $filtermanager->get_performance_summary();
        $info = array_merge($filterinfo, $info);
        foreach ($filterinfo as $key => $value) {
            $info['html'] .= "<span class='{$key}'>{$nicenames[$key]}: {$value} </span> ";
            $info['txt'] .= "{$key}: {$value} ";
        }
    }
    $stringmanager = get_string_manager();
    if (method_exists($stringmanager, 'get_performance_summary')) {
        list($filterinfo, $nicenames) = $stringmanager->get_performance_summary();
        $info = array_merge($filterinfo, $info);
        foreach ($filterinfo as $key => $value) {
            $info['html'] .= "<span class='{$key}'>{$nicenames[$key]}: {$value} </span> ";
            $info['txt'] .= "{$key}: {$value} ";
        }
    }
    $jsmodules = $PAGE->requires->get_loaded_modules();
    if ($jsmodules) {
        $yuicount = 0;
        $othercount = 0;
        $details = '';
        foreach ($jsmodules as $module => $backtraces) {
            if (strpos($module, 'yui') === 0) {
                $yuicount += 1;
            } else {
                $othercount += 1;
            }
            if (!empty($CFG->yuimoduledebug)) {
                // Hidden feature for developers working on YUI module infrastructure.
                $details .= "<div class='yui-module'><p>{$module}</p>";
                foreach ($backtraces as $backtrace) {
                    $details .= "<div class='backtrace'>{$backtrace}</div>";
                }
                $details .= '</div>';
            }
        }
        $info['html'] .= "<span class='includedyuimodules'>Included YUI modules: {$yuicount}</span> ";
        $info['txt'] .= "includedyuimodules: {$yuicount} ";
        $info['html'] .= "<span class='includedjsmodules'>Other JavaScript modules: {$othercount}</span> ";
        $info['txt'] .= "includedjsmodules: {$othercount} ";
        if ($details) {
            $info['html'] .= '<div id="yui-module-debug" class="notifytiny">' . $details . '</div>';
        }
    }
    if (!empty($PERF->logwrites)) {
        $info['logwrites'] = $PERF->logwrites;
        $info['html'] .= '<span class="logwrites">Log DB writes ' . $info['logwrites'] . '</span> ';
        $info['txt'] .= 'logwrites: ' . $info['logwrites'] . ' ';
    }
    $info['dbqueries'] = $DB->perf_get_reads() . '/' . ($DB->perf_get_writes() - $PERF->logwrites);
    $info['html'] .= '<span class="dbqueries">DB reads/writes: ' . $info['dbqueries'] . '</span> ';
    $info['txt'] .= 'db reads/writes: ' . $info['dbqueries'] . ' ';
    if (function_exists('posix_times')) {
        $ptimes = posix_times();
        if (is_array($ptimes)) {
            foreach ($ptimes as $key => $val) {
                $info[$key] = $ptimes[$key] - $PERF->startposixtimes[$key];
            }
            $info['html'] .= "<span class=\"posixtimes\">ticks: {$info['ticks']} user: {$info['utime']} sys: {$info['stime']} cuser: {$info['cutime']} csys: {$info['cstime']}</span> ";
            $info['txt'] .= "ticks: {$info['ticks']} user: {$info['utime']} sys: {$info['stime']} cuser: {$info['cutime']} csys: {$info['cstime']} ";
        }
    }
    // Grab the load average for the last minute.
    // /proc will only work under some linux configurations
    // while uptime is there under MacOSX/Darwin and other unices.
    if (is_readable('/proc/loadavg') && ($loadavg = @file('/proc/loadavg'))) {
        list($serverload) = explode(' ', $loadavg[0]);
        unset($loadavg);
    } else {
        if (function_exists('is_executable') && is_executable('/usr/bin/uptime') && ($loadavg = `/usr/bin/uptime`)) {
            if (preg_match('/load averages?: (\\d+[\\.,:]\\d+)/', $loadavg, $matches)) {
                $serverload = $matches[1];
            } else {
                trigger_error('Could not parse uptime output!');
            }
        }
    }
    if (!empty($serverload)) {
        $info['serverload'] = $serverload;
        $info['html'] .= '<span class="serverload">Load average: ' . $info['serverload'] . '</span> ';
        $info['txt'] .= "serverload: {$info['serverload']} ";
    }
    // Display size of session if session started.
    if ($si = \core\session\manager::get_performance_info()) {
        $info['sessionsize'] = $si['size'];
        $info['html'] .= $si['html'];
        $info['txt'] .= $si['txt'];
    }
    if ($stats = cache_helper::get_stats()) {
        $html = '<span class="cachesused">';
        $html .= '<span class="cache-stats-heading">Caches used (hits/misses/sets)</span>';
        $text = 'Caches used (hits/misses/sets): ';
        $hits = 0;
        $misses = 0;
        $sets = 0;
        foreach ($stats as $definition => $stores) {
            $html .= '<span class="cache-definition-stats">';
            $html .= '<span class="cache-definition-stats-heading">' . $definition . '</span>';
            $text .= "{$definition} {";
            foreach ($stores as $store => $data) {
                $hits += $data['hits'];
                $misses += $data['misses'];
                $sets += $data['sets'];
                if ($data['hits'] == 0 and $data['misses'] > 0) {
                    $cachestoreclass = 'nohits';
                } else {
                    if ($data['hits'] < $data['misses']) {
                        $cachestoreclass = 'lowhits';
                    } else {
                        $cachestoreclass = 'hihits';
                    }
                }
                $text .= "{$store}({$data['hits']}/{$data['misses']}/{$data['sets']}) ";
                $html .= "<span class=\"cache-store-stats {$cachestoreclass}\">{$store}: {$data['hits']} / {$data['misses']} / {$data['sets']}</span>";
            }
            $html .= '</span>';
            $text .= '} ';
        }
        $html .= "<span class='cache-total-stats'>Total: {$hits} / {$misses} / {$sets}</span>";
        $html .= '</span> ';
        $info['cachesused'] = "{$hits} / {$misses} / {$sets}";
        $info['html'] .= $html;
        $info['txt'] .= $text . '. ';
    } else {
        $info['cachesused'] = '0 / 0 / 0';
        $info['html'] .= '<span class="cachesused">Caches used (hits/misses/sets): 0/0/0</span>';
        $info['txt'] .= 'Caches used (hits/misses/sets): 0/0/0 ';
    }
    $info['html'] = '<div class="performanceinfo siteinfo">' . $info['html'] . '</div>';
    return $info;
}
Example #5
0
/**
 * get_performance_info() pairs up with init_performance_info()
 * loaded in setup.php. Returns an array with 'html' and 'txt'
 * values ready for use, and each of the individual stats provided
 * separately as well.
 *
 * @global object
 * @global object
 * @global object
 * @return array
 */
function get_performance_info() {
    global $CFG, $PERF, $DB, $PAGE;

    $info = array();
    $info['html'] = '';         // holds userfriendly HTML representation
    $info['txt']  = me() . ' '; // holds log-friendly representation

    $info['realtime'] = microtime_diff($PERF->starttime, microtime());

    $info['html'] .= '<span class="timeused">'.$info['realtime'].' secs</span> ';
    $info['txt'] .= 'time: '.$info['realtime'].'s ';

    if (function_exists('memory_get_usage')) {
        $info['memory_total'] = memory_get_usage();
        $info['memory_growth'] = memory_get_usage() - $PERF->startmemory;
        $info['html'] .= '<span class="memoryused">RAM: '.display_size($info['memory_total']).'</span> ';
        $info['txt']  .= 'memory_total: '.$info['memory_total'].'B (' . display_size($info['memory_total']).') memory_growth: '.$info['memory_growth'].'B ('.display_size($info['memory_growth']).') ';
    }

    if (function_exists('memory_get_peak_usage')) {
        $info['memory_peak'] = memory_get_peak_usage();
        $info['html'] .= '<span class="memoryused">RAM peak: '.display_size($info['memory_peak']).'</span> ';
        $info['txt']  .= 'memory_peak: '.$info['memory_peak'].'B (' . display_size($info['memory_peak']).') ';
    }

    $inc = get_included_files();
    //error_log(print_r($inc,1));
    $info['includecount'] = count($inc);
    $info['html'] .= '<span class="included">Included '.$info['includecount'].' files</span> ';
    $info['txt']  .= 'includecount: '.$info['includecount'].' ';

    $filtermanager = filter_manager::instance();
    if (method_exists($filtermanager, 'get_performance_summary')) {
        list($filterinfo, $nicenames) = $filtermanager->get_performance_summary();
        $info = array_merge($filterinfo, $info);
        foreach ($filterinfo as $key => $value) {
            $info['html'] .= "<span class='$key'>$nicenames[$key]: $value </span> ";
            $info['txt'] .= "$key: $value ";
        }
    }

    $stringmanager = get_string_manager();
    if (method_exists($stringmanager, 'get_performance_summary')) {
        list($filterinfo, $nicenames) = $stringmanager->get_performance_summary();
        $info = array_merge($filterinfo, $info);
        foreach ($filterinfo as $key => $value) {
            $info['html'] .= "<span class='$key'>$nicenames[$key]: $value </span> ";
            $info['txt'] .= "$key: $value ";
        }
    }

     $jsmodules = $PAGE->requires->get_loaded_modules();
     if ($jsmodules) {
         $yuicount = 0;
         $othercount = 0;
         $details = '';
         foreach ($jsmodules as $module => $backtraces) {
             if (strpos($module, 'yui') === 0) {
                 $yuicount += 1;
             } else {
                 $othercount += 1;
             }
             if (!empty($CFG->yuimoduledebug)) {
                 // hidden feature for developers working on YUI module infrastructure
                 $details .= "<div class='yui-module'><p>$module</p>";
                 foreach ($backtraces as $backtrace) {
                     $details .= "<div class='backtrace'>$backtrace</div>";
                 }
                 $details .= '</div>';
             }
         }
         $info['html'] .= "<span class='includedyuimodules'>Included YUI modules: $yuicount</span> ";
         $info['txt'] .= "includedyuimodules: $yuicount ";
         $info['html'] .= "<span class='includedjsmodules'>Other JavaScript modules: $othercount</span> ";
         $info['txt'] .= "includedjsmodules: $othercount ";
         if ($details) {
             $info['html'] .= '<div id="yui-module-debug" class="notifytiny">'.$details.'</div>';
         }
     }

    if (!empty($PERF->logwrites)) {
        $info['logwrites'] = $PERF->logwrites;
        $info['html'] .= '<span class="logwrites">Log DB writes '.$info['logwrites'].'</span> ';
        $info['txt'] .= 'logwrites: '.$info['logwrites'].' ';
    }

    $info['dbqueries'] = $DB->perf_get_reads().'/'.($DB->perf_get_writes() - $PERF->logwrites);
    $info['html'] .= '<span class="dbqueries">DB reads/writes: '.$info['dbqueries'].'</span> ';
    $info['txt'] .= 'db reads/writes: '.$info['dbqueries'].' ';

    if (function_exists('posix_times')) {
        $ptimes = posix_times();
        if (is_array($ptimes)) {
            foreach ($ptimes as $key => $val) {
                $info[$key] = $ptimes[$key] -  $PERF->startposixtimes[$key];
            }
            $info['html'] .= "<span class=\"posixtimes\">ticks: $info[ticks] user: $info[utime] sys: $info[stime] cuser: $info[cutime] csys: $info[cstime]</span> ";
            $info['txt'] .= "ticks: $info[ticks] user: $info[utime] sys: $info[stime] cuser: $info[cutime] csys: $info[cstime] ";
        }
    }

    // Grab the load average for the last minute
    // /proc will only work under some linux configurations
    // while uptime is there under MacOSX/Darwin and other unices
    if (is_readable('/proc/loadavg') && $loadavg = @file('/proc/loadavg')) {
        list($server_load) = explode(' ', $loadavg[0]);
        unset($loadavg);
    } else if ( function_exists('is_executable') && is_executable('/usr/bin/uptime') && $loadavg = `/usr/bin/uptime` ) {
        if (preg_match('/load averages?: (\d+[\.,:]\d+)/', $loadavg, $matches)) {
            $server_load = $matches[1];
        } else {
            trigger_error('Could not parse uptime output!');
        }
    }
    if (!empty($server_load)) {
        $info['serverload'] = $server_load;
        $info['html'] .= '<span class="serverload">Load average: '.$info['serverload'].'</span> ';
        $info['txt'] .= "serverload: {$info['serverload']} ";
    }

    // Display size of session if session started
    if (session_id()) {
        $info['sessionsize'] = display_size(strlen(session_encode()));
        $info['html'] .= '<span class="sessionsize">Session: ' . $info['sessionsize'] . '</span> ';
        $info['txt'] .= "Session: {$info['sessionsize']} ";
    }

/*    if (isset($rcache->hits) && isset($rcache->misses)) {
        $info['rcachehits'] = $rcache->hits;
        $info['rcachemisses'] = $rcache->misses;
        $info['html'] .= '<span class="rcache">Record cache hit/miss ratio : '.
            "{$rcache->hits}/{$rcache->misses}</span> ";
        $info['txt'] .= 'rcache: '.
            "{$rcache->hits}/{$rcache->misses} ";
    }*/

    if ($stats = cache_helper::get_stats()) {
        $html = '<span class="cachesused">';
        $html .= '<span class="cache-stats-heading">Caches interaction by definition then store</span>';
        $text = 'Caches used (hits/misses/sets): ';
        $hits = 0;
        $misses = 0;
        $sets = 0;
        foreach ($stats as $definition => $stores) {
            $html .= '<span class="cache-definition-stats">'.$definition.'</span>';
            $text .= "$definition {";
            foreach ($stores as $store => $data) {
                $hits += $data['hits'];
                $misses += $data['misses'];
                $sets += $data['sets'];
                $text .= "$store($data[hits]/$data[misses]/$data[sets]) ";
                $html .= "<span class='cache-store-stats'>$store: $data[hits] / $data[misses] / $data[sets]</span>";
            }
            $text .= '} ';
        }
        $html .= "<span class='cache-total-stats'>Total Hits / Misses / Sets : $hits / $misses / $sets</span>";
        $html .= '</span> ';
        $info['cachesused'] = "$hits / $misses / $sets";
        $info['html'] .= $html;
        $info['txt'] .= $text.'. ';
    } else {
        $info['cachesused'] = '0 / 0 / 0';
        $info['html'] .= '<span class="cachesused">Caches used (hits/misses/sets): 0/0/0</span>';
        $info['txt'] .= 'Caches used (hits/misses/sets): 0/0/0 ';
    }

    $info['html'] = '<div class="performanceinfo siteinfo">'.$info['html'].'</div>';
    return $info;
}