HEX
Server: nginx/1.18.0
System: Linux iZj6c1ieg2jrpk1z5tzi19Z 6.3.9-1.el7.elrepo.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Jun 21 22:18:40 EDT 2023 x86_64
User: www (1001)
PHP: 8.2.4
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: /www/wwwroot/www.cytocare.cn/wp-content/plugins/wpjam-basic/components/server-status.php
<?php
/*
Name: 系统信息
URI: https://mp.weixin.qq.com/s/kqlag2-RWn_n481R0QCJHw
Description: 系统信息让你在后台一个页面就能够快速实时查看当前的系统状态。
Version: 2.0
*/
if(!is_admin()){
	return;
}

class WPJAM_Server_Status{
	public static function server_widget(){
		$items[]	= ['title'=>'服务器',		'value'=>gethostname().'('.$_SERVER['HTTP_HOST'].')'];
		$items[]	= ['title'=>'服务器IP',	'value'=>'内网:'.gethostbyname(gethostname())];
		$items[]	= ['title'=>'系统',		'value'=>php_uname('s')];

		if(strpos(ini_get('open_basedir'), ':/proc') !== false){
			if(@is_readable('/proc/cpuinfo')){
				$cpus	= explode("\n\n", trim(file_get_contents('/proc/cpuinfo')));
				$base[]	= count($cpus).'核';
			}
			
			if(@is_readable('/proc/meminfo')){
				$mems	= explode("\n", trim(file_get_contents('/proc/meminfo')));
				$mem	= (int)substr(array_find($mems, fn($m) => str_starts_with($m, 'MemTotal:')), 9);
				$base[]	= round($mem/1024/1024).'G';
			}

			if(!empty($base)){
				$items[]	= ['title'=>'配置',	'value'=>'<strong>'.implode('&nbsp;/&nbsp;', $base).'</strong>'];
			}
		
			if(@is_readable('/proc/meminfo')){
				$uptime		= explode(' ', trim(file_get_contents('/proc/uptime')));
				$items[]	= ['title'=>'运行时间',	'value'=>human_time_diff(time()-$uptime[0])];
			}

			
			$items[]	= ['title'=>'空闲率',		'value'=>round($uptime[1]*100/($uptime[0]*count($cpus)), 2).'%'];
			$items[]	= ['title'=>'系统负载',	'value'=>'<strong>'.implode('&nbsp;&nbsp;',sys_getloadavg()).'</strong>'];
		}

		$items[]	= ['title'=>'文档根目录',	'value'=>$_SERVER['DOCUMENT_ROOT']];
		
		self::output($items);
	}

	public static function php_widget(){
		self::output([['value'=>implode(', ', get_loaded_extensions())]]);
	}

	public static function apache_widget(){
		self::output([['value'=>implode(', ', apache_get_modules())]]);
	}

	public static function version_widget(){
		global $wpdb, $required_mysql_version, $required_php_version, $wp_version,$wp_db_version, $tinymce_version;

		$http_server	= explode('/', $_SERVER['SERVER_SOFTWARE'])[0];

		self::output([
			['title'=>$http_server,	'value'=>$_SERVER['SERVER_SOFTWARE']],
			['title'=>'MySQL',		'value'=>$wpdb->db_version().'(最低要求:'.$required_mysql_version.')'],
			['title'=>'PHP',		'value'=>phpversion().'(最低要求:'.$required_php_version.')'],
			['title'=>'Zend',		'value'=>Zend_Version()],
			['title'=>'WordPress',	'value'=>$wp_version.'('.$wp_db_version.')'],
			['title'=>'TinyMCE',	'value'=>$tinymce_version]
		]);
	}

	public static function opcache_status_widget(){
		self::output(wpjam_map(opcache_get_status()['opcache_statistics'], fn($v, $k) => ['title'=>$k, 'value'=>$v]));
	}

	public static function opcache_usage_widget(){
		echo '<p>'.wpjam_get_page_button('reset_opcache').'</p>';

		echo '<hr />';

		$status	= opcache_get_status();
		$args 	= ['chart_width'=>150, 'table_width'=>320];

		$labels	= ['used_memory'=>'已用内存', 'free_memory'=>'剩余内存', 'wasted_memory'=>'浪费内存'];
		$counts	= wpjam_map($labels, fn($v, $k) => ['label'=>$v,	'count'=>round($status['memory_usage'][$k]/(1024*1024),2)]);
		$total	= round(array_reduce(array_keys($labels), fn($total, $k) => $total+$status['memory_usage'][$k], 0)/(1024*1024),2);

		wpjam_donut_chart($counts, ['title'=>'内存使用', 'total'=>$total]+$args);

		echo '<hr />';

		$labels	= ['hits'=>'命中', 'misses'=>'未命中'];
		$counts	= wpjam_map($labels, fn($v, $k) => ['label'=>$v,	'count'=>$status['opcache_statistics'][$k]]);
		$total	= array_reduce(array_keys($labels), fn($total, $k) => $total+$status['opcache_statistics'][$k], 0);

		wpjam_donut_chart($counts, ['title'=>'命中率', 'total'=>$total]+$args);

		echo '<hr />';

		$counts	= [
			['label'=>'已用Keys',	'count'=>$status['opcache_statistics']['num_cached_keys']],
			['label'=>'剩余Keys',	'count'=>$status['opcache_statistics']['max_cached_keys']-$status['opcache_statistics']['num_cached_keys']]
		];

		$total	= $status['opcache_statistics']['max_cached_keys'];

		wpjam_donut_chart($counts, ['title'=>'存储Keys','total'=>$total]+$args);

		// echo '<hr />';

		// $labels	= ['used_memory'=>'已用内存', 'free_memory'=>'剩余内存'];
		// $counts	= wpjam_map($labels, fn($v, $k) => ['label'=>$v,	'count'=>round($status['interned_strings_usage'][$k]/(1024*1024),2)]);
		// $total	= round(array_reduce(array_keys($labels), fn($total, $k) => $total+$status['interned_strings_usage'][$k], 0)/(1024*1024),2);

		// wpjam_donut_chart($counts, ['title'=>'临时字符串存储内存','total'=>$total]+$args);
	}

	public static function opcache_configuration_widget(){
		$config = opcache_get_configuration();
		$items	= wpjam_map($config['version'], fn($v, $k) => ['title'=>$k, 'value'=>$v]);
		$items	= array_merge($items,  wpjam_map($config['directives'], fn($v, $k) => ['title'=>str_replace('opcache.', '', $k), 'value'=>$v]));
	
		self::output($items);
	}

	public static function memcached_usage_widget(){
		global $wp_object_cache;

		echo '<p>'.wpjam_get_page_button('flush_mc').'</p>';

		foreach($wp_object_cache->get_stats() as $key => $details){
			echo '<hr />';

			$args	= ['chart_width'=>150,'table_width'=>320];
			$labels	= ['get_hits'=>'命中次数', 'get_misses'=>'未命中次数'];
			$counts	= wpjam_map($labels, fn($v, $k) => ['label'=>$v,	'count'=>$details[$k]]);

			wpjam_donut_chart($counts, ['title'=>'命中率','total'=>$details['cmd_get']]+$args);

			echo '<hr />';

			$counts	= [
				['label'=>'已用内存',	'count'=>round($details['bytes']/(1024*1024),2)],
				['label'=>'剩余内存',	'count'=>round(($details['limit_maxbytes']-$details['bytes'])/(1024*1024),2)]
			];

			$total	= round($details['limit_maxbytes']/(1024*1024),2);

			wpjam_donut_chart($counts, ['title'=>'内存使用','total'=>$total]+$args);
		}
	}

	public static function memcached_status_widget(){
		global $wp_object_cache;

		foreach($wp_object_cache->get_stats() as $key => $details){
			self::output([
				// ['title'=>'Memcached进程ID',	'value'=>$details['pid']],
				['title'=>'Memcached地址',	'value'=>$key],
				['title'=>'Memcached版本',	'value'=>$details['version']],
				['title'=>'启动时间',			'value'=>wpjam_date('Y-m-d H:i:s',($details['time']-$details['uptime']))],
				['title'=>'运行时间',			'value'=>human_time_diff(0,$details['uptime'])],
				['title'=>'已用/分配的内存',	'value'=>size_format($details['bytes']).' / '.size_format($details['limit_maxbytes'])],
				['title'=>'启动后总数量',		'value'=>$details['curr_items'].' / '.$details['total_items']],
				['title'=>'为获取内存踢除数量',	'value'=>$details['evictions']],
				['title'=>'当前/总打开连接数',	'value'=>$details['curr_connections'].' / '.$details['total_connections']],
				['title'=>'命中次数',			'value'=>$details['get_hits']],
				['title'=>'未命中次数',		'value'=>$details['get_misses']],
				['title'=>'总获取请求次数',	'value'=>$details['cmd_get']],
				['title'=>'总设置请求次数',	'value'=>$details['cmd_set']],
				['title'=>'Item平均大小',		'value'=>size_format($details['bytes']/$details['curr_items'])],
			]);
		}
	}

	public static function memcached_options_widget(){
		global $wp_object_cache;

		$reflector	= new ReflectionClass('Memcached');
		$constants	= wpjam_filter($reflector->getConstants(), fn($v, $k) => str_starts_with($k, 'OPT_'));
		$mc			= $wp_object_cache->get_mc();

		self::output(wpjam_map($constants, fn($v, $k) => ['title'=>$k, 'value'=>$mc->getOption($v)]));
	}

	public static function memcached_efficiency_widget(){
		global $wp_object_cache;

		foreach($wp_object_cache->get_stats() as $key => $details){
			self::output([
				['title'=>'每秒命中次数',		'value'=>round($details['get_hits']/$details['uptime'],2)],
				['title'=>'每秒未命中次数',	'value'=>round($details['get_misses']/$details['uptime'],2)],
				['title'=>'每秒获取请求次数',	'value'=>round($details['cmd_get']/$details['uptime'],2)],
				['title'=>'每秒设置请求次数',	'value'=>round($details['cmd_set']/$details['uptime'],2)],
			]);
		}
	}

	public static function output($items){
		?>
		<table class="widefat striped" style="border:none;">
			<tbody><?php foreach($items as $item){ ?>
				<tr><?php if(!empty($item['title'])){ ?>
					<td><?php echo $item['title'] ?></td>
					<td><?php echo $item['value'] ?></td>
				<?php }else{ ?>
					<td colspan="2"><?php echo $item['value'] ?></td>
				<?php } ?></tr>
			<?php } ?></tbody>
		</table>
		<?php
	}

	public static function get_tabs(){
		$tabs['server']	= ['title'=>'服务器', 'function'=>'dashboard', 'widgets'=>[
			'server'	=> ['title'=>'信息',			'callback'=>[self::class, 'server_widget']],
			'php'		=> ['title'=>'PHP扩展',		'callback'=>[self::class, 'php_widget']],
			'version'	=> ['title'=>'版本',			'callback'=>[self::class, 'version_widget'],	'context'=>'side'],
			'apache'	=> ['title'=>'Apache模块',	'callback'=>[self::class, 'apache_widget'],		'context'=>'side']
		]];

		if(strtoupper(substr(PHP_OS,0,3)) === 'WIN'){
			unset($tabs['server']['widgets']['server']);
		}

		if(!$GLOBALS['is_apache'] || !function_exists('apache_get_modules')){
			unset($tabs['server']['widgets']['apache']);
		}

		if(function_exists('opcache_get_status')){
			$tabs['opcache']	= ['title'=>'Opcache',	'function'=>'dashboard',	'widgets'=>[
				'usage'			=> ['title'=>'使用率',	'callback'=>[self::class, 'opcache_usage_widget']],
				'status'		=> ['title'=>'状态',		'callback'=>[self::class, 'opcache_status_widget']],
				'configuration'	=> ['title'=>'配置信息',	'callback'=>[self::class, 'opcache_configuration_widget'],	'context'=>'side']
			]];

			wpjam_register_page_action('reset_opcache', [
				'title'			=> '重置缓存',
				'button_text'	=> '重置缓存',
				'direct'		=> true,
				'confirm'		=> true,
				'callback'		=> fn() => opcache_reset() ? ['errmsg'=>'缓存重置成功'] : wp_die('缓存重置失败')
			]);
		}

		if(method_exists('WP_Object_Cache', 'get_mc')){
			$tabs['memcached']	= ['title'=>'Memcached',	'function'=>'dashboard',	'widgets'=>[
				'usage'			=> ['title'=>'使用率',	'callback'=>[self::class, 'memcached_usage_widget']],
				'efficiency'	=> ['title'=>'效率',		'callback'=>[self::class, 'memcached_efficiency_widget']],
				'options'		=> ['title'=>'选项',		'callback'=>[self::class, 'memcached_options_widget'], 'context'=>'side'],
				'status'		=> ['title'=>'状态',		'callback'=>[self::class, 'memcached_status_widget']]
			]];

			wpjam_register_page_action('flush_mc', [
				'title'			=> '刷新缓存',
				'button_text'	=> '刷新缓存',
				'direct'		=> true,
				'confirm'		=> true,
				'callback'		=> fn() => wp_cache_flush() ? ['errmsg'=>'缓存刷新成功'] : wp_die('缓冲刷新失败')
			]);
		}

		return $tabs;
	}
}

wpjam_add_menu_page('server-status', [
	'parent'		=> 'wpjam-basic',
	'menu_title'	=> '系统信息',
	'summary'		=> __FILE__,
	'chart'			=> true,
	'order'			=> 9,
	'function'		=> 'tab',
	'capability'	=> is_multisite() ? 'manage_site' : 'manage_options',
	'tabs'			=> ['WPJAM_Server_Status', 'get_tabs']
]);