PHP CLI脚本实时处理top命令输出:监控高CPU进程
PHP CLI 实时监控CPU使用率方案
核心问题解答
PHP能否实时处理top的持续数据流?
能。PHP CLI模式下可通过proc_open()函数创建子进程,实时读取其标准输出流,无需等待子进程终止就能逐行处理输出,完全满足实时监控需求。10年前的Stack Overflow代码是否仍适用?
那篇代码的核心逻辑(用proc_open()处理子进程输出)至今依然有效,但部分细节需调整:比如不同Linux发行版的top输出格式、参数略有差异,原代码的流读取逻辑可适配现代PHP版本优化,但proc_open()的底层支持一直稳定,核心思路没问题。
实战脚本示例
以下是适配需求的PHP CLI脚本,实时捕获top输出,仅记录CPU占用超20%的进程:
#!/usr/bin/env php <?php // 脚本不超时 set_time_limit(0); // 开启实时输出刷新 ob_implicit_flush(true); ob_end_flush(); // top命令:批处理模式,每5秒更新,按CPU使用率排序 // 不同系统参数可能有差异,Ubuntu可替换为 'top -bn-1 -d5 -o %CPU' $cmd = 'top -b -d 5 -o %CPU'; // 定义进程通信管道 $descriptorspec = [ 0 => ['pipe', 'r'], // 标准输入(无需写入,留空) 1 => ['pipe', 'w'], // 标准输出(读取流) 2 => ['pipe', 'w'] // 标准错误 ]; $process = proc_open($cmd, $descriptorspec, $pipes); if (!is_resource($process)) { die('无法启动top进程'); } // 关闭标准输入 fclose($pipes[0]); // 实时读取输出流 while (!feof($pipes[1])) { $line = fgets($pipes[1]); static $headerFound = false; // 识别表头行,避免处理冗余内容 if (str_contains($line, '%CPU') && str_contains($line, 'PID')) { $headerFound = true; echo $line; continue; } if (!$headerFound) { continue; } // 分割进程数据列(处理top的空格分隔格式) $columns = preg_split('/\s+/', trim($line)); if (count($columns) < 9) { continue; } $cpuUsage = (float)$columns[8]; // %CPU列的索引需根据系统输出调整 if ($cpuUsage > 20.0) { $logLine = date('[Y-m-d H:i:s]') . ' ' . $line; // 实时打印 echo $logLine; // 追加到日志文件 file_put_contents('/var/log/cpu_high.log', $logLine, FILE_APPEND); } } // 清理资源 fclose($pipes[1]); fclose($pipes[2]); proc_close($process); ?>
使用说明
- 给脚本添加执行权限:
chmod +x cpu_monitor.php - 直接运行:
./cpu_monitor.php,或放入screen会话后台执行 - 注意调整
top参数:不同发行版的top参数有差异,需根据实际系统修改 - 可根据
top实际输出调整%CPU列的索引,确保数据读取准确
内容的提问来源于stack exchange,提问作者pkSML
相关产品推荐
相关产品推荐

