Apache日志中的“慢查询”实为响应时间长的HTTP请求,需先配置%{ms}T记录耗时,再用awk筛选超阈值请求,最后联动应用与数据库日志定位根因。

Apache 本身不记录“慢查询”(SQL 层面的慢查询),它只记录 HTTP 请求的处理耗时。所谓“Apache 日志中的慢查询”,实际是指 响应时间长的 HTTP 请求,其背后可能由慢 SQL、应用逻辑卡顿或资源瓶颈引发。要通过监控工具定位这类问题,关键在于:把 Apache 的请求耗时日志作为入口,再联动上下游(应用、数据库)日志与指标,形成可观测闭环。
一、先让 Apache 日志带上耗时字段
没有耗时数据,监控工具就无从判断“慢”。必须在 Apache 配置中启用时间记录:
LogFormat "%h %l %u %t \"%r\" %>s %b %{ms}T \"%{Referer}i\" \"%{User-Agent}i\"" combined_with_time
CustomLog /var/log/apache2/access.log combined_with_time其中 %{ms}T 表示请求总处理时间(毫秒),会追加到每条日志末尾。配置后重启 Apache:
sudo systemctl restart apache2
✅ 验证:
tail -1 /var/log/apache2/access.log应看到类似... "GET /api/user HTTP/1.1" 200 1234 1892—— 最后数字就是耗时(ms)。
二、用轻量级命令行工具快速筛查
无需部署复杂系统,日常排查可直接用 awk + grep 定位异常请求:
-
找出耗时 > 2 秒的请求(含 URL 和耗时):
awk '$NF > 2000 {print $7, $NF}' /var/log/apache2/access.log | sort -k2nr | head -20 -
结合时间段筛选(如今天 14:00–15:00):
Apache Superset Dashboard and SQL Exploration Skill下载Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
awk -v start="14:" -v end="15:" '$4 ~ /\[.*\/Jun\/2026:/ && $4 ~ start "|" end {if ($NF > 2000) print $0}' /var/log/apache2/access.log -
提取慢请求的完整 URL(适配
"GET /path?x=1 HTTP/1.1"格式):awk '$NF > 2000 {match($0, /"([^"]+)"/, arr); print arr[1], $NF}' /var/log/apache2/access.log
三、用 ELK 或 Grafana+Loki 做可视化监控
当流量大、需长期跟踪时,推荐接入日志分析平台:
-
Logstash / Filebeat:解析 access.log,提取
request_time_ms、request_url、status、response_size等字段; - Elasticsearch / Loki:存储结构化日志;
-
Kibana / Grafana:构建看板,例如:
- 慢请求 TOP 10 URL(按平均耗时或 P95);
- 慢请求时间趋势图(识别业务高峰或突增点);
- 耗时与状态码交叉分析(如
500 + 高耗时→ 后端崩溃;200 + 高耗时→ 应用或 DB 瓶颈)。
? 小技巧:在 Kibana 中用
range过滤request_time_ms > 2000,再用terms聚合request_url,就能一眼看出哪几个接口拖慢了整体体验。
四、关联应用与数据库日志确认根因
单看 Apache 日志只能知道“谁慢”,不能知道“为什么慢”。需横向比对:
-
PHP-FPM 慢日志:检查
slowlog中同一时间戳的函数调用栈(如mysqli_query卡住); -
MySQL 慢查询日志:开启
long_query_time = 1,用pt-query-digest分析,匹配 Apache 日志里的 URL 参数与 SQL 中的 WHERE 条件; -
系统指标:用 Prometheus 抓取
node_exporter的 CPU、内存、磁盘 IO,确认是否资源争用导致请求排队。
比如:Apache 日志显示 /api/order/list?user_id=123 耗时 3200ms → 查 MySQL 慢日志发现对应 SELECT * FROM orders WHERE user_id = 123 未走索引 → 执行 EXPLAIN 确认全表扫描 → 加 INDEX(user_id) 解决。
不复杂但容易忽略。

















