thinkphp可通过五种方式集成dstat获取系统资源数据:一、exec()执行并解析命令输出;二、导出csv后读取分析;三、调用独立dstat api服务;四、封装为thinkphp命令行指令;五、结合日志中间件自动采样。

如果您在ThinkPHP项目中需要获取服务器系统资源使用情况,但缺乏直接集成的监控能力,则可能是由于ThinkPHP本身不提供底层系统指标采集功能。Dstat作为独立的Linux命令行工具,可被调用以补充运行时环境的CPU、内存、磁盘、网络等实时数据。以下是将Dstat输出接入ThinkPHP应用的多种实现方式:
一、通过PHP exec()函数执行dstat命令并解析输出
该方法利用PHP的系统调用能力,在ThinkPHP控制器或服务类中直接执行dstat命令,捕获其标准输出,并按列解析为结构化数组。适用于需轻量级集成且对实时性要求较高的场景。
1、确保服务器已安装dstat:sudo apt install dstat(Ubuntu/Debian)或sudo yum install dstat(CentOS/RHEL)。
2、在ThinkPHP控制器中编写执行逻辑:
使用exec()配合超时控制与错误抑制,例如:$output = [];
exec('timeout 3s dstat -cndm 1 1 2>/dev/null', $output, $return_code);
3、过滤首行标题与空行,提取最后一行有效数据:
array_shift($output);
$last_line = end($output);
if ($last_line && preg_match('/\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)/', $last_line, $matches)) { /* 提取CPU用户态、系统态、空闲、等待,内存已用、网络接收、发送、磁盘读 */ }
4、将解析结果封装为JSON响应或存入日志:
return json(['code' => 0, 'data' => ['cpu_usr' => $matches[1], 'cpu_sys' => $matches[2], 'mem_used' => $matches[5], 'net_recv' => $matches[6], 'net_send' => $matches[7]]]);
二、调用dstat导出CSV并由ThinkPHP读取分析
该方法规避了实时终端输出解析的复杂性,借助dstat的--output参数生成结构化CSV文件,再由ThinkPHP使用fgetcsv()逐行读取。适用于需长期记录、批量比对或对接报表模块的场景。
1、创建临时CSV路径并赋予Web服务器写权限:
mkdir -p /runtime/dstat/ && chmod 755 /runtime/dstat/
2、执行带输出的dstat命令:
exec('dstat -cndm --output /runtime/dstat/latest.csv 1 1 >/dev/null 2>&1');
3、在ThinkPHP中打开并跳过表头两行(dstat CSV含2行元信息):
$handle = fopen('/runtime/dstat/latest.csv', 'r');
fgetcsv($handle); fgetcsv($handle); // 跳过版本与字段行
4、读取实际数据行并映射字段:
if (($data = fgetcsv($handle)) !== false) {
$keys = ['time', 'cpu_usr', 'cpu_sys', 'cpu_idl', 'cpu_wai', 'mem_used', 'net_recv', 'net_send', 'dsk_read', 'dsk_writ'];
$row = array_combine($keys, $data);
}
5、关闭句柄并返回清洗后数据:
fclose($handle);
return $row;
三、构建独立Dstat监控API服务供ThinkPHP调用
该方法将dstat运行解耦为独立HTTP服务(如使用Python Flask封装),ThinkPHP仅通过curl发起GET请求获取JSON格式指标。适用于多应用共享监控、权限隔离或容器化部署环境。
1、部署轻量API服务(示例Python脚本):
from flask import Flask, jsonify
import subprocess
app = Flask(__name__)
@app.route('/api/dstat')
def get_dstat():
result = subprocess.run(['dstat', '-cndm', '1', '1'], capture_output=True, text=True)
# 解析逻辑同方法一,返回字典
return jsonify(parsed_metrics)
2、在ThinkPHP中配置CURL客户端:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://localhost:5000/api/dstat');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
3、执行请求并解码JSON:
$response = curl_exec($ch);
curl_close($ch);
$metrics = json_decode($response, true);
4、校验返回状态并注入业务逻辑:
if (isset($metrics['cpu_usr']) && is_numeric($metrics['cpu_usr'])) {
// 触发高负载告警或限流策略
if ($metrics['cpu_usr'] > 85) { Log::warning('High CPU usage detected'); }
}
四、使用ThinkPHP命令行指令封装dstat调用
该方法将dstat集成进ThinkPHP的console组件,通过自定义artisan-style命令统一管理,便于运维人员在部署节点上手动触发诊断或加入定时任务。
1、创建命令类:php think make:command DstatMonitor
2、在handle()方法中嵌入dstat执行逻辑:
$cmd = "dstat -cdngy --noheaders --noupdate 1 1";
$output = shell_exec($cmd);
$this->info('Dstat raw output: ' . $output);
3、添加参数支持以切换指标组合:
$this->addArgument('mode', InputArgument::OPTIONAL, 'Metrics mode: cpu|mem|disk|net', 'all');
4、根据参数动态构造命令:
switch ($this->argument('mode')) {
case 'cpu': $cmd = 'dstat -c 1 1'; break;
case 'mem': $cmd = 'dstat -m 1 1'; break;
default: $cmd = 'dstat -a 1 1';
}
5、注册命令并运行:
php think dstat:monitor cpu
php think dstat:monitor --cron
五、结合ThinkPHP日志中间件自动采集关键指标
该方法在请求生命周期内注入dstat采样,将系统资源快照与HTTP请求日志关联,用于性能归因分析。适用于排查偶发性慢请求是否由底层资源争用引发。
1、在中间件App\Middleware\LogRequest.php的handle()开头插入采样逻辑:
$dstat_sample = shell_exec('dstat -c --noheaders --noupdate 1 1 | tail -n1 2>/dev/null');
2、正则提取CPU空闲率用于判断资源紧张程度:
if (preg_match('/\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)/', $dstat_sample, $cap)) {
$cpu_idle = (float)$cap[3];
if ($cpu_idle 20.0) {
Log::notice('Low CPU idle during request', ['idle_pct' => $cpu_idle, 'url' => $request->url()]);
}
}
3、将指标附加至日志上下文:
$context = array_merge($context, ['dstat_cpu_idle' => $cpu_idle, 'dstat_mem_used' => $mem_used]);
4、确保日志驱动支持结构化字段(如think-log-driver)并启用JSON格式输出。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











