Initial commit: Open sourcing all of the Maple Open Technologies code.
This commit is contained in:
commit
755d54a99d
2010 changed files with 448675 additions and 0 deletions
|
|
@ -0,0 +1,454 @@
|
|||
<?php
|
||||
/**
|
||||
* System Information Collector
|
||||
*
|
||||
* Collects detailed system information for diagnosing performance bottlenecks.
|
||||
*
|
||||
* @package MaplePress
|
||||
*/
|
||||
|
||||
class MaplePress_System_Info {
|
||||
|
||||
/**
|
||||
* Get all system information.
|
||||
*
|
||||
* @return array System information array.
|
||||
*/
|
||||
public static function get_all_info() {
|
||||
return array(
|
||||
'php' => self::get_php_info(),
|
||||
'php_fpm' => self::get_php_fpm_info(),
|
||||
'server' => self::get_server_info(),
|
||||
'wordpress' => self::get_wordpress_info(),
|
||||
'database' => self::get_database_info(),
|
||||
'performance' => self::get_performance_info(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PHP configuration information.
|
||||
*
|
||||
* @return array PHP configuration.
|
||||
*/
|
||||
private static function get_php_info() {
|
||||
return array(
|
||||
'version' => PHP_VERSION,
|
||||
'sapi' => php_sapi_name(),
|
||||
'memory_limit' => ini_get( 'memory_limit' ),
|
||||
'max_execution_time' => ini_get( 'max_execution_time' ),
|
||||
'max_input_time' => ini_get( 'max_input_time' ),
|
||||
'post_max_size' => ini_get( 'post_max_size' ),
|
||||
'upload_max_filesize' => ini_get( 'upload_max_filesize' ),
|
||||
'max_input_vars' => ini_get( 'max_input_vars' ),
|
||||
'display_errors' => ini_get( 'display_errors' ),
|
||||
'error_reporting' => ini_get( 'error_reporting' ),
|
||||
'opcache_enabled' => function_exists( 'opcache_get_status' ) && opcache_get_status() !== false,
|
||||
'opcache_status' => function_exists( 'opcache_get_status' ) ? opcache_get_status() : null,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PHP-FPM configuration information.
|
||||
*
|
||||
* @return array PHP-FPM configuration.
|
||||
*/
|
||||
private static function get_php_fpm_info() {
|
||||
$info = array(
|
||||
'is_fpm' => false,
|
||||
'pool_name' => 'N/A',
|
||||
'pm_type' => 'N/A',
|
||||
'max_children' => 'N/A',
|
||||
'start_servers' => 'N/A',
|
||||
'min_spare_servers' => 'N/A',
|
||||
'max_spare_servers' => 'N/A',
|
||||
'max_requests' => 'N/A',
|
||||
'status_url' => 'N/A',
|
||||
'active_processes' => 'N/A',
|
||||
'total_processes' => 'N/A',
|
||||
'idle_processes' => 'N/A',
|
||||
'listen_queue' => 'N/A',
|
||||
'listen_queue_len' => 'N/A',
|
||||
'config_file' => 'N/A',
|
||||
);
|
||||
|
||||
// Check if running under PHP-FPM
|
||||
if ( php_sapi_name() === 'fpm-fcgi' || php_sapi_name() === 'cgi-fcgi' ) {
|
||||
$info['is_fpm'] = true;
|
||||
|
||||
// Try to find PHP-FPM config file
|
||||
$possible_config_paths = array(
|
||||
'/etc/php/' . PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '/fpm/pool.d/www.conf',
|
||||
'/usr/local/etc/php-fpm.d/www.conf',
|
||||
'/etc/php-fpm.d/www.conf',
|
||||
'/etc/php/fpm/pool.d/www.conf',
|
||||
);
|
||||
|
||||
foreach ( $possible_config_paths as $path ) {
|
||||
if ( file_exists( $path ) && is_readable( $path ) ) {
|
||||
$info['config_file'] = $path;
|
||||
$config = self::parse_php_fpm_config( $path );
|
||||
if ( $config ) {
|
||||
$info = array_merge( $info, $config );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to get PHP-FPM status via FastCGI
|
||||
$status = self::get_php_fpm_status();
|
||||
if ( $status ) {
|
||||
$info = array_merge( $info, $status );
|
||||
}
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse PHP-FPM configuration file.
|
||||
*
|
||||
* @param string $config_file Path to config file.
|
||||
* @return array|null Parsed configuration or null.
|
||||
*/
|
||||
private static function parse_php_fpm_config( $config_file ) {
|
||||
$config = array();
|
||||
|
||||
$content = file_get_contents( $config_file );
|
||||
if ( ! $content ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Parse key configuration values (ignore comments after values)
|
||||
$patterns = array(
|
||||
'pool_name' => '/^\[([^\]]+)\]/m',
|
||||
'pm_type' => '/^pm\s*=\s*(\w+)/m',
|
||||
'max_children' => '/^pm\.max_children\s*=\s*(\d+)/m',
|
||||
'start_servers' => '/^pm\.start_servers\s*=\s*(\d+)/m',
|
||||
'min_spare_servers' => '/^pm\.min_spare_servers\s*=\s*(\d+)/m',
|
||||
'max_spare_servers' => '/^pm\.max_spare_servers\s*=\s*(\d+)/m',
|
||||
'max_requests' => '/^pm\.max_requests\s*=\s*(\d+)/m',
|
||||
);
|
||||
|
||||
foreach ( $patterns as $key => $pattern ) {
|
||||
if ( preg_match( $pattern, $content, $matches ) ) {
|
||||
$config[ $key ] = trim( $matches[1] );
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PHP-FPM status from status endpoint.
|
||||
*
|
||||
* @return array|null Status information or null.
|
||||
*/
|
||||
private static function get_php_fpm_status() {
|
||||
// Try common PHP-FPM status URLs
|
||||
$status_urls = array(
|
||||
'http://localhost/fpm-status',
|
||||
'http://127.0.0.1/fpm-status',
|
||||
'http://localhost/status',
|
||||
);
|
||||
|
||||
foreach ( $status_urls as $url ) {
|
||||
$response = wp_remote_get( $url . '?json' );
|
||||
if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) === 200 ) {
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
$data = json_decode( $body, true );
|
||||
if ( $data ) {
|
||||
return array(
|
||||
'pool_name' => $data['pool'] ?? 'N/A',
|
||||
'total_processes' => $data['total processes'] ?? 'N/A',
|
||||
'active_processes' => $data['active processes'] ?? 'N/A',
|
||||
'idle_processes' => $data['idle processes'] ?? 'N/A',
|
||||
'listen_queue' => $data['listen queue'] ?? 'N/A',
|
||||
'listen_queue_len' => $data['listen queue len'] ?? 'N/A',
|
||||
'max_children' => $data['max children reached'] ?? 'N/A',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server information.
|
||||
*
|
||||
* @return array Server information.
|
||||
*/
|
||||
private static function get_server_info() {
|
||||
return array(
|
||||
'software' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : 'Unknown',
|
||||
'os' => PHP_OS,
|
||||
'hostname' => gethostname(),
|
||||
'server_addr' => isset( $_SERVER['SERVER_ADDR'] ) ? $_SERVER['SERVER_ADDR'] : 'Unknown',
|
||||
'document_root' => isset( $_SERVER['DOCUMENT_ROOT'] ) ? $_SERVER['DOCUMENT_ROOT'] : 'Unknown',
|
||||
'cpu_count' => self::get_cpu_count(),
|
||||
'memory_total' => self::get_memory_total(),
|
||||
'memory_available' => self::get_memory_available(),
|
||||
'load_average' => self::get_load_average(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CPU core count.
|
||||
*
|
||||
* @return int|string CPU count or 'Unknown'.
|
||||
*/
|
||||
private static function get_cpu_count() {
|
||||
if ( function_exists( 'shell_exec' ) ) {
|
||||
// Linux
|
||||
$output = shell_exec( 'nproc 2>/dev/null' );
|
||||
if ( $output ) {
|
||||
return (int) trim( $output );
|
||||
}
|
||||
|
||||
// macOS
|
||||
$output = shell_exec( 'sysctl -n hw.ncpu 2>/dev/null' );
|
||||
if ( $output ) {
|
||||
return (int) trim( $output );
|
||||
}
|
||||
}
|
||||
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total system memory in MB.
|
||||
*
|
||||
* @return string Memory in MB or 'Unknown'.
|
||||
*/
|
||||
private static function get_memory_total() {
|
||||
if ( function_exists( 'shell_exec' ) ) {
|
||||
// Linux
|
||||
$output = shell_exec( "free -m | grep Mem | awk '{print $2}'" );
|
||||
if ( $output ) {
|
||||
return trim( $output ) . ' MB';
|
||||
}
|
||||
|
||||
// macOS
|
||||
$output = shell_exec( 'sysctl -n hw.memsize 2>/dev/null' );
|
||||
if ( $output ) {
|
||||
return round( (int) trim( $output ) / 1024 / 1024 ) . ' MB';
|
||||
}
|
||||
}
|
||||
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available system memory in MB.
|
||||
*
|
||||
* @return string Available memory or 'Unknown'.
|
||||
*/
|
||||
private static function get_memory_available() {
|
||||
if ( function_exists( 'shell_exec' ) ) {
|
||||
// Linux
|
||||
$output = shell_exec( "free -m | grep Mem | awk '{print $7}'" );
|
||||
if ( $output ) {
|
||||
return trim( $output ) . ' MB';
|
||||
}
|
||||
}
|
||||
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get system load average.
|
||||
*
|
||||
* @return string Load average or 'Unknown'.
|
||||
*/
|
||||
private static function get_load_average() {
|
||||
if ( function_exists( 'sys_getloadavg' ) ) {
|
||||
$load = sys_getloadavg();
|
||||
return sprintf( '%.2f, %.2f, %.2f', $load[0], $load[1], $load[2] );
|
||||
}
|
||||
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get WordPress information.
|
||||
*
|
||||
* @return array WordPress information.
|
||||
*/
|
||||
private static function get_wordpress_info() {
|
||||
global $wp_version;
|
||||
|
||||
return array(
|
||||
'version' => $wp_version,
|
||||
'multisite' => is_multisite(),
|
||||
'site_url' => get_site_url(),
|
||||
'home_url' => get_home_url(),
|
||||
'debug_mode' => defined( 'WP_DEBUG' ) && WP_DEBUG,
|
||||
'memory_limit' => WP_MEMORY_LIMIT,
|
||||
'max_memory_limit' => WP_MAX_MEMORY_LIMIT,
|
||||
'theme' => wp_get_theme()->get( 'Name' ),
|
||||
'active_plugins' => count( get_option( 'active_plugins', array() ) ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database information.
|
||||
*
|
||||
* @return array Database information.
|
||||
*/
|
||||
private static function get_database_info() {
|
||||
global $wpdb;
|
||||
|
||||
$info = array(
|
||||
'extension' => $wpdb->db_version(),
|
||||
'server' => $wpdb->get_var( 'SELECT VERSION()' ),
|
||||
'client_version' => $wpdb->db_version(),
|
||||
'database_name' => DB_NAME,
|
||||
'database_host' => DB_HOST,
|
||||
'database_charset' => DB_CHARSET,
|
||||
'table_prefix' => $wpdb->prefix,
|
||||
);
|
||||
|
||||
// Get MySQL configuration
|
||||
$variables = array(
|
||||
'max_connections',
|
||||
'max_allowed_packet',
|
||||
'query_cache_size',
|
||||
'innodb_buffer_pool_size',
|
||||
'tmp_table_size',
|
||||
'max_heap_table_size',
|
||||
);
|
||||
|
||||
foreach ( $variables as $var ) {
|
||||
$value = $wpdb->get_var( "SHOW VARIABLES LIKE '$var'" );
|
||||
if ( $value ) {
|
||||
$info[ $var ] = $wpdb->get_var( "SHOW VARIABLES LIKE '$var'", 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// Get current connections
|
||||
$info['current_connections'] = $wpdb->get_var( "SHOW STATUS LIKE 'Threads_connected'" )
|
||||
? $wpdb->get_var( "SHOW STATUS LIKE 'Threads_connected'", 1 )
|
||||
: 'Unknown';
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get performance-related information.
|
||||
*
|
||||
* @return array Performance information.
|
||||
*/
|
||||
private static function get_performance_info() {
|
||||
return array(
|
||||
'object_cache' => wp_using_ext_object_cache() ? 'External' : 'Built-in',
|
||||
'curl_available' => function_exists( 'curl_version' ),
|
||||
'curl_version' => function_exists( 'curl_version' ) ? curl_version()['version'] : 'N/A',
|
||||
'allow_url_fopen' => ini_get( 'allow_url_fopen' ) ? 'Yes' : 'No',
|
||||
'compression' => extension_loaded( 'zlib' ) ? 'Available' : 'Not available',
|
||||
'https_support' => is_ssl() ? 'Yes' : 'No',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format system info as HTML.
|
||||
*
|
||||
* @param array $info System information array.
|
||||
* @return string HTML output.
|
||||
*/
|
||||
public static function format_as_html( $info ) {
|
||||
ob_start();
|
||||
?>
|
||||
<div class="maplepress-system-info">
|
||||
<?php foreach ( $info as $section => $data ) : ?>
|
||||
<div class="system-info-section">
|
||||
<h3 style="margin-top: 0; padding: 10px; background: #f0f0f1; border-left: 4px solid #2271b1;">
|
||||
<?php echo esc_html( ucwords( str_replace( '_', ' ', $section ) ) ); ?>
|
||||
</h3>
|
||||
<table class="widefat" style="margin-top: 0;">
|
||||
<tbody>
|
||||
<?php foreach ( $data as $key => $value ) : ?>
|
||||
<?php
|
||||
// Check if this is the opcache_status field (which contains a large array)
|
||||
$is_opcache_status = ( $key === 'opcache_status' && is_array( $value ) );
|
||||
$field_id = 'maplepress-field-' . sanitize_title( $section . '-' . $key );
|
||||
?>
|
||||
<tr>
|
||||
<td style="width: 250px; font-weight: bold; vertical-align: top;">
|
||||
<?php echo esc_html( ucwords( str_replace( '_', ' ', $key ) ) ); ?>
|
||||
<?php if ( $is_opcache_status ) : ?>
|
||||
<br>
|
||||
<button type="button"
|
||||
class="button button-secondary button-small maplepress-toggle-field"
|
||||
data-target="<?php echo esc_attr( $field_id ); ?>"
|
||||
style="margin-top: 5px;">
|
||||
<span class="dashicons dashicons-visibility" style="vertical-align: middle; font-size: 14px;"></span>
|
||||
<span class="toggle-text">Show</span>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ( $is_opcache_status ) : ?>
|
||||
<div id="<?php echo esc_attr( $field_id ); ?>" style="display: none;">
|
||||
<pre><?php echo esc_html( print_r( $value, true ) ); ?></pre>
|
||||
</div>
|
||||
<span class="opcache-hidden-notice" style="color: #666; font-style: italic;">
|
||||
Click "Show" to view opcache details
|
||||
</span>
|
||||
<?php elseif ( is_array( $value ) ) : ?>
|
||||
<pre><?php echo esc_html( print_r( $value, true ) ); ?></pre>
|
||||
<?php elseif ( is_bool( $value ) ) : ?>
|
||||
<?php echo $value ? '<span style="color: green;">✓ Yes</span>' : '<span style="color: red;">✗ No</span>'; ?>
|
||||
<?php else : ?>
|
||||
<?php echo esc_html( $value ); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.maplepress-system-info .system-info-section {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.maplepress-system-info pre {
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
background: #f9f9f9;
|
||||
border-left: 3px solid #ccc;
|
||||
overflow-x: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
// Toggle field visibility for opcache_status
|
||||
$('.maplepress-toggle-field').on('click', function() {
|
||||
var button = $(this);
|
||||
var targetId = button.data('target');
|
||||
var content = $('#' + targetId);
|
||||
var notice = button.closest('tr').find('.opcache-hidden-notice');
|
||||
var icon = button.find('.dashicons');
|
||||
var text = button.find('.toggle-text');
|
||||
|
||||
if (content.is(':visible')) {
|
||||
content.slideUp(300);
|
||||
notice.show();
|
||||
icon.removeClass('dashicons-hidden').addClass('dashicons-visibility');
|
||||
text.text('Show');
|
||||
} else {
|
||||
content.slideDown(300);
|
||||
notice.hide();
|
||||
icon.removeClass('dashicons-visibility').addClass('dashicons-hidden');
|
||||
text.text('Hide');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue