示例#1
0
/**
 * Collect system stats for display on the "About this system" page
 *
 * @return array
 */
function get_system_stats()
{
    global $evo_charset, $DB, $Settings, $cache_path;
    static $system_stats = array();
    if (!empty($system_stats)) {
        return $system_stats;
    }
    // b2evo config choices:
    $system_stats['mediadir_status'] = system_check_dir('media');
    // If error, then the host is potentially borked
    $system_stats['install_removed'] = system_check_install_removed();
    $system_stats['evo_charset'] = $evo_charset;
    $system_stats['evo_blog_count'] = count(system_get_blog_IDs(false));
    // Caching:
    $system_stats['cachedir_status'] = system_check_dir('cache');
    // If error, then the host is potentially borked
    $system_stats['cachedir_size'] = get_dirsize_recursive($cache_path);
    $system_stats['general_pagecache_enabled'] = $Settings->get('general_cache_enabled');
    $system_stats['blog_pagecaches_enabled'] = count(system_get_blog_IDs(true));
    // Database:
    $system_stats['db_version'] = $DB->get_version();
    // MySQL version
    $system_stats['db_utf8'] = system_check_db_utf8();
    // PHP:
    list($uid, $uname) = system_check_process_user();
    $system_stats['php_uid'] = $uid;
    $system_stats['php_uname'] = $uname;
    // Potential unsecure hosts will use names like 'nobody', 'www-data'
    list($gid, $gname) = system_check_process_group();
    $system_stats['php_gid'] = $gid;
    $system_stats['php_gname'] = $gname;
    // Potential unsecure hosts will use names like 'nobody', 'www-data'
    $system_stats['php_version'] = PHP_VERSION;
    $system_stats['php_reg_globals'] = ini_get('register_globals');
    $system_stats['php_allow_url_include'] = ini_get('allow_url_include');
    $system_stats['php_allow_url_fopen'] = ini_get('allow_url_fopen');
    // TODO php_magic quotes
    $system_stats['php_upload_max'] = system_check_upload_max_filesize();
    $system_stats['php_post_max'] = system_check_post_max_size();
    $system_stats['php_memory'] = system_check_memory_limit();
    // how much room does b2evo have to move?
    $system_stats['php_mbstring'] = extension_loaded('mbstring');
    $system_stats['php_xml'] = extension_loaded('xml');
    $system_stats['php_imap'] = extension_loaded('imap');
    $system_stats['php_opcode_cache'] = get_active_opcode_cache();
    // GD:
    $system_stats['gd_version'] = system_check_gd_version();
    return $system_stats;
}
示例#2
0
/**
 * Outputs debug info, according to {@link $debug} or $force param. This gets called typically at the end of the page.
 *
 * @param boolean true to force output regardless of {@link $debug}
 * @param boolean true to force clean output (without HTML) regardless of {@link $is_cli}
 */
function debug_info($force = false, $force_clean = false)
{
    global $debug, $debug_done, $debug_jslog, $debug_jslog_done, $Debuglog, $DB, $obhandler_debug, $Timer, $ReqHost, $ReqPath, $is_cli;
    global $cache_imgsize, $cache_File;
    global $Session;
    global $db_config, $tableprefix, $http_response_code, $disp, $disp_detail, $robots_index, $robots_follow, $content_type_header;
    /**
     * @var Hit
     */
    global $Hit;
    // Detect content-type
    $content_type = NULL;
    foreach (headers_list() as $header) {
        if (stripos($header, 'content-type:') !== false) {
            // content type sent
            # "Content-Type:text/html;charset=utf-8" => "text/html"
            $content_type = trim(array_shift(explode(';', array_pop(explode(':', $header, 2)))));
            break;
        }
    }
    // ---- Print AJAX Log
    if (empty($debug_jslog_done) && ($debug || $debug_jslog) && $content_type == 'text/html') {
        // Display debug jslog once
        global $rsc_url, $app_version;
        echo '<script type="text/javascript" src="' . $rsc_url . 'js/debug_jslog.js"></script>';
        echo '<script type="text/javascript" src="' . $rsc_url . 'js/jquery/jquery.cookie.min.js"></script>';
        $jquery_ui_css_url = url_add_param($rsc_url . 'css/jquery/smoothness/jquery-ui.css', 'v=' . $app_version);
        echo '<link href="' . $jquery_ui_css_url . '" type="text/css" rel="stylesheet" />';
        $jslog_style_cookies = param_cookie('jslog_style', 'string');
        $jslog_styles = array();
        if (!empty($jslog_style_cookies)) {
            // Get styles only from cookies
            $jslog_style_cookies = explode(';', $jslog_style_cookies);
            foreach ($jslog_style_cookies as $jsc => $style) {
                if (strpos($style, 'height') !== false) {
                    // Unset the height param from defined styles ( and the display param if jslog is disabled )
                    unset($jslog_style_cookies[$jsc]);
                }
            }
            $jslog_styles[] = implode(';', $jslog_style_cookies);
        } else {
            if (!is_logged_in()) {
                // Align top when evobar is hidden
                $jslog_styles[] = 'top:0';
            }
            if ($debug_jslog) {
                // Display the jslog
                $jslog_styles[] = 'display:block';
            }
        }
        $jslog_styles = count($jslog_styles) > 0 ? ' style="' . implode(';', $jslog_styles) . '"' : '';
        $close_url = url_add_param($_SERVER['REQUEST_URI'], 'jslog');
        echo '<div id="debug_ajax_info" class="debug"' . $jslog_styles . '>';
        echo '<div class="jslog_titlebar">AJAX Debug log' . get_manual_link('ajax_debug_log') . action_icon(T_('Close'), 'close', $close_url, NULL, NULL, NULL, array('class' => 'jslog_switcher')) . '</div>';
        echo '<div id="jslog_container"></div>';
        echo '<div class="jslog_statusbar">' . '<a href="' . $_SERVER['REQUEST_URI'] . '#" class="jslog_clear">' . T_('Clear') . '</a>' . '</div>';
        echo '</div>';
        // Make sure debug jslog output only happens once:
        $debug_jslog_done = true;
    }
    // ----
    if (!$force) {
        if (!empty($debug_done)) {
            // Already displayed!
            return;
        }
        if (empty($debug)) {
            // No debug output desired:
            return;
        }
        // Do not display, if no content-type header has been sent or it's != "text/html" (debug > 1 skips this)
        if ($debug < 2) {
            if ($content_type != 'text/html') {
                return;
            }
        }
    }
    //Make sure debug output only happens once:
    $debug_done = true;
    // clean output:
    $clean = $is_cli || $force_clean;
    $printf_format = '| %-45s | %-5s | %-7s | %-5s |';
    $table_headerlen = 73;
    /* This calculates the number of dashes to print e. g. on the top and
    	 * bottom of the table and after the header, making the table look
    	 * better (looks like the tables of the mysql command line client).
    	 * Normally, the value won't change, so it's hardcoded above. If you
    	 * change the printf() format above, this might be useful.
    	preg_match_all( '#\d+#', $printf_format, $table_headerlen );
    	$table_headerlen = array_sum( $table_headerlen[0] ) +
    									strlen( preg_replace( '#[^ \|]+#', '',
    												$printf_format ) ) - 2;
    	*/
    $ReqHostPathQuery = $ReqHost . $ReqPath . (empty($_SERVER['QUERY_STRING']) ? '' : '?' . $_SERVER['QUERY_STRING']);
    echo "\n\n\n";
    echo $clean ? '*** Debug info ***' . "\n\n" : '<div class="debug" id="debug_info"><h2>Debug info</h2>';
    if (!$obhandler_debug) {
        // don't display changing items when we want to test obhandler
        // ---------------------------
        echo '<div class="log_container"><div>';
        echo 'HTTP Response code: ' . $http_response_code;
        echo $clean ? "\n" : '<br />';
        echo '$content_type_header: ' . $content_type_header;
        echo $clean ? "\n" : '<br />';
        echo '$disp: ' . $disp . ' -- detail: ' . $disp_detail;
        echo $clean ? "\n" : '<br />';
        echo '$robots_index: ' . $robots_index;
        echo $clean ? "\n" : '<br />';
        echo '$robots_follow: ' . $robots_follow;
        echo $clean ? "\n" : '<br />';
        echo '</div></div>';
        // ================================== DB Summary ================================
        if (isset($DB)) {
            echo '<div class="log_container"><div>';
            echo $DB->num_queries . ' SQL queries executed in ' . $Timer->get_duration('SQL QUERIES') . " seconds\n";
            if (!$clean) {
                echo ' &nbsp; <a href="' . $ReqHostPathQuery . '#evo_debug_queries">scroll down to details</a><p>';
            }
            echo '</div></div>';
        }
        // ========================== Timer table ================================
        $time_page = $Timer->get_duration('total');
        $timer_rows = array();
        foreach ($Timer->get_categories() as $l_cat) {
            if ($l_cat == 'sql_query') {
                continue;
            }
            $timer_rows[$l_cat] = $Timer->get_duration($l_cat);
        }
        // Don't sort to see orginal order of creation
        // arsort( $timer_rows );
        // ksort( $timer_rows );
        // Remove "total", it will get output as the last one:
        $total_time = $timer_rows['total'];
        unset($timer_rows['total']);
        $percent_total = $time_page > 0 ? number_format(100 / $time_page * $total_time, 2) : '0';
        if ($clean) {
            echo '== Timers ==' . "\n\n";
            echo '+' . str_repeat('-', $table_headerlen) . '+' . "\n";
            printf($printf_format . "\n", 'Category', 'Time', '%', 'Count');
            echo '+' . str_repeat('-', $table_headerlen) . '+' . "\n";
        } else {
            echo '<table class="debug_timer"><thead>' . '<tr><td colspan="4" class="center">Timers</td></tr>' . '<tr><th>Category</th><th>Time</th><th>%</th><th>Count</th></tr>' . '</thead>';
            // Output "total":
            echo "\n<tfoot><tr>" . '<td>total</td>' . '<td class="right red">' . $total_time . '</td>' . '<td class="right">' . $percent_total . '%</td>' . '<td class="right">' . $Timer->get_count('total') . '</td></tr></tfoot>';
            echo '<tbody>';
        }
        $table_rows_collapse = array();
        foreach ($timer_rows as $l_cat => $l_time) {
            $percent_l_cat = $time_page > 0 ? number_format(100 / $time_page * $l_time, 2) : '0';
            if ($clean) {
                $row = sprintf($printf_format, $l_cat, $l_time, $percent_l_cat . '%', $Timer->get_count($l_cat));
            } else {
                $row = "\n<tr>" . '<td>' . $l_cat . '</td>' . '<td class="right">' . $l_time . '</td>' . '<td class="right">' . $percent_l_cat . '%</td>' . '<td class="right">' . $Timer->get_count($l_cat) . '</td></tr>';
            }
            // Maybe ignore this row later, but not for clean display.
            if (!$clean && $percent_l_cat < 1) {
                // Hide everything that tool less tahn 5% of the time
                $table_rows_collapse[] = $row;
            } else {
                echo $row . "\n";
            }
        }
        $count_collapse = count($table_rows_collapse);
        // Collapse ignored rows, allowing to expand them with Javascript:
        if ($count_collapse > 5) {
            echo '<tr><td colspan="4" class="center" id="evo-debuglog-timer-long-header">';
            echo '<a href="" onclick="var e = document.getElementById(\'evo-debuglog-timer-long\'); e.style.display = (e.style.display == \'none\' ? \'\' : \'none\'); return false;">+ ' . $count_collapse . ' queries &lt; 1%</a> </td></tr>';
            echo '</tbody>';
            echo '<tbody id="evo-debuglog-timer-long" style="display:none;">';
        }
        echo implode("\n", $table_rows_collapse) . "\n";
        if ($clean) {
            // "total" (done in tfoot for html above)
            echo sprintf($printf_format, 'total', $total_time, $percent_total . '%', $Timer->get_count('total'));
            echo '+' . str_repeat('-', $table_headerlen) . '+' . "\n\n";
        } else {
            echo "\n</tbody></table>";
            // add jquery.tablesorter to the "Debug info" table.
            global $rsc_uri;
            echo '
			<script type="text/javascript" src="' . $rsc_uri . 'js/jquery/jquery.tablesorter.min.js"></script>
			<script type="text/javascript">
			(function($){
				var clicked_once;
				jQuery("table.debug_timer th").click( function(event) {
					if( clicked_once ) return; else clicked_once = true;
					jQuery("#evo-debuglog-timer-long tr").appendTo(jQuery("table.debug_timer tbody")[0]);
					jQuery("#evo-debuglog-timer-long-header").remove();
					// click for tablesorter:
					jQuery("table.debug_timer").tablesorter();
					jQuery(event.currentTarget).click();
				});
			})(jQuery);
			</script>';
        }
        // ================================ Opcode caching ================================
        echo '<div class="log_container"><div>';
        echo 'Opcode cache: ' . get_active_opcode_cache();
        echo $clean ? "\n" : '<p>';
        echo '</div></div>';
        // ================================ Memory Usage ================================
        echo '<div class="log_container"><div>';
        foreach (array('memory_get_usage' => array('display' => 'Memory usage', 'high' => 8000000), 'memory_get_peak_usage' => array('display' => 'Memory peak usage', 'high' => 8000000)) as $l_func => $l_var) {
            if (function_exists($l_func)) {
                $_usage = $l_func();
                if ($_usage > $l_var['high']) {
                    echo $clean ? '[!!] ' : '<span style="color:red; font-weight:bold">';
                }
                echo $l_var['display'] . ': ' . bytesreadable($_usage, !$clean);
                if (!$clean && $_usage > $l_var['high']) {
                    echo '</span>';
                }
                echo $clean ? "\n" : '<br />';
            }
        }
        echo 'Len of serialized $cache_imgsize: ' . strlen(serialize($cache_imgsize));
        echo $clean ? "\n" : '<br />';
        echo 'Len of serialized $cache_File: ' . strlen(serialize($cache_File));
        echo $clean ? "\n" : '<br />';
        echo '</div></div>';
    }
    // DEBUGLOG(s) FROM PREVIOUS SESSIONS, after REDIRECT(s) (with list of categories at top):
    if (isset($Session) && ($sess_Debuglogs = $Session->get('Debuglogs')) && !empty($sess_Debuglogs)) {
        $count_sess_Debuglogs = count($sess_Debuglogs);
        if ($count_sess_Debuglogs > 1) {
            // Links to those Debuglogs:
            if ($clean) {
                // kind of useless, but anyway...
                echo "\n" . 'There are ' . $count_sess_Debuglogs . ' Debuglogs from redirected pages.' . "\n";
            } else {
                echo '<p>There are ' . $count_sess_Debuglogs . ' Debuglogs from redirected pages: ';
                for ($i = 1; $i <= $count_sess_Debuglogs; $i++) {
                    echo '<a href="' . $ReqHostPathQuery . '#debug_sess_debuglog_' . $i . '">#' . $i . '</a> ';
                }
                echo '</p>';
            }
        }
        foreach ($sess_Debuglogs as $k => $sess_Debuglog) {
            $log_categories = array('error', 'note', 'all');
            // Categories to output (in that order)
            if ($clean) {
                $log_container_head = "\n" . '== Debug messages from redirected page (#' . ($k + 1) . ') ==' . "\n" . 'See below for the Debuglog from the current request.' . "\n";
                echo format_to_output($sess_Debuglog->display(array('container' => array('string' => $log_container_head, 'template' => false), 'all' => array('string' => '= %s =' . "\n\n", 'template' => false)), '', false, $log_categories, '', 'raw', false), 'raw');
            } else {
                $log_container_head = '<h3 id="debug_sess_debuglog_' . ($k + 1) . '" style="color:#f00;">Debug messages from redirected page (#' . ($k + 1) . ')</h3>' . '<p><a href="' . $ReqHostPathQuery . '#debug_debuglog">See below for the Debuglog from the current request.</a></p>';
                $log_cats = array_keys($sess_Debuglog->get_messages($log_categories));
                // the real list (with all replaced and only existing ones)
                $log_head_links = array();
                foreach ($log_cats as $l_cat) {
                    $log_head_links[] .= '<a href="' . $ReqHostPathQuery . '#debug_redir_' . ($k + 1) . '_info_cat_' . str_replace(' ', '_', $l_cat) . '">' . $l_cat . '</a>';
                }
                $log_container_head .= implode(' | ', $log_head_links);
                echo format_to_output($sess_Debuglog->display(array('container' => array('string' => $log_container_head, 'template' => false), 'all' => array('string' => '<h4 id="debug_redir_' . ($k + 1) . '_info_cat_%s">%s:</h4>', 'template' => false)), '', false, $log_categories), 'htmlbody');
            }
        }
        // Delete logs since they have been displayed...
        // EXCEPT if we are redirecting, because in this case we won't see these logs in a browser (only in request debug tools)
        // So in that case we want them to move over to the next page...
        if ($http_response_code < 300 || $http_response_code >= 400) {
            // This is NOT a 3xx redirect, assume debuglogs have been seen & delete them:
            $Session->delete('Debuglogs');
        }
    }
    // CURRENT DEBUGLOG (with list of categories at top):
    $log_categories = array('error', 'note', 'all');
    // Categories to output (in that order)
    $log_container_head = $clean ? "\n" . '== Debug messages ==' . "\n" : '<h3 id="debug_debuglog">Debug messages</h3>';
    if (!empty($sess_Debuglogs)) {
        // link to first sess_Debuglog:
        if ($clean) {
            $log_container_head .= 'See above for the Debuglog(s) from before the redirect.' . "\n";
        } else {
            $log_container_head .= '<p><a href="' . $ReqHostPathQuery . '#debug_sess_debuglog_1">See above for the Debuglog(s) from before the redirect.</a></p>';
        }
    }
    if (!$clean) {
        $log_cats = array_keys($Debuglog->get_messages($log_categories));
        // the real list (with all replaced and only existing ones)
        $log_head_links = array();
        foreach ($log_cats as $l_cat) {
            $log_head_links[] .= '<a href="' . $ReqHostPathQuery . '#debug_info_cat_' . str_replace(' ', '_', $l_cat) . '">' . $l_cat . '</a>';
        }
        $log_container_head .= implode(' | ', $log_head_links);
        echo format_to_output($Debuglog->display(array('container' => array('string' => $log_container_head, 'template' => false), 'all' => array('string' => '<h4 id="debug_info_cat_%s">%s:</h4>', 'template' => false)), '', false, $log_categories), 'htmlbody');
        echo '<h3 id="evo_debug_queries">DB</h3>';
    } else {
        echo format_to_output($Debuglog->display(array('container' => array('string' => $log_container_head, 'template' => false), 'all' => array('string' => '= %s =' . "\n\n", 'template' => false)), '', false, $log_categories, '', 'raw', false), 'raw');
        echo "\n" . '== DB ==' . "\n\n";
    }
    if ($db_config) {
        if (!$clean) {
            echo '<pre>';
        }
        echo 'Config DB Username: '******'user'] . "\n" . 'Config DB Database: ' . $db_config['name'] . "\n" . 'Config DB Host: ' . (isset($db_config['host']) ? $db_config['host'] : 'unset (localhost)') . "\n" . 'Config DB tables prefix: ' . $tableprefix . "\n" . 'Config DB connection charset: ' . $db_config['connection_charset'] . "\n";
        echo $clean ? "\n" : '</pre>';
    }
    if (!isset($DB)) {
        echo 'No DB object.' . ($clean ? "\n" : '');
    } else {
        echo '<pre>Current DB charset: ' . $DB->connection_charset . "</pre>\n";
        $DB->dump_queries(!$clean);
    }
    if (!$clean) {
        echo '</div>';
    }
}
示例#3
0
    // fp>TODO: explain what we need it for. Is it a problem or not.
    // furthermore I think xmlrpc does dynamic loading (or has it been removed?), in which case this should be tested too.
    // dh> You mean the deprecated dl() loading? (fp>yes) We might just try this then here also before any warning.
} else {
    disp_system_check('ok');
}
// IMAP extension
$imap_loaded = extension_loaded('imap');
init_system_check('PHP IMAP extension', $imap_loaded ? T_('Loaded') : T_('Not loaded'));
if (!$imap_loaded) {
    disp_system_check('warning', T_('You will not be able to use the Post by Email feature and the Return Path email processing of b2evolution. Enable the IMAP extension in your php.ini file or ask your hosting provider about it.'));
} else {
    disp_system_check('ok');
}
// Opcode cache
$opcode_cache = get_active_opcode_cache();
init_system_check('PHP opcode cache', $opcode_cache);
if ($opcode_cache == 'none') {
    disp_system_check('warning', T_('Using an opcode cache allows all your PHP scripts to run faster by caching a "compiled" (opcode) version of the scripts instead of recompiling everything at every page load. Several opcode caches are available. We recommend APC.'));
} else {
    disp_system_check('ok');
}
// pre_dump( get_loaded_extensions() );
$block_item_Widget->disp_template_raw('block_end');
/*
 * GD Library
 * windows: extension=php_gd2.dll
 * unix: ?
 * fp> Note: I'm going to use this for thumbnails for now, but I plan to use it for other things like small stats & status graphics.
 */
$block_item_Widget->title = T_('GD Library (image handling)');