Apache 访问日志与错误日志详解:位置、格式解读与自定义配置
Apache 的 access.log 和 error.log 各记录什么?Common/Combined 日志格式每个字段什么含义?本文讲解 Apache 日志的默认位置、格式解读、LogFormat 自定义、JSON 结构化与 LogLevel 级别配置,并给出接入观测云实现统一检索与 5xx 告警的实践路径。
Apache 日志是 Apache HTTP Server 记录自身运行状态的文本文件,分为访问日志(Access Log)与错误日志(Error Log)两类:前者记录每个进入请求的处理结果,后者记录请求处理中的错误与诊断信息。 作为至今仍承载大量网站流量的老牌 Web 服务器,读懂这两份日志是排查 Apache 问题的起点。
核心要点速览
- 访问日志记"每个请求"(IP、路径、状态码、字节数),错误日志记"出了什么问题"(模块、级别、错误详情);
- Debian/Ubuntu 默认位置是
/var/log/apache2/,RHEL/CentOS 是/var/log/httpd/; - 访问日志格式由
LogFormat定义、CustomLog启用,推荐直接输出 JSON 以便机器解析; - 错误日志用
ErrorLogFormat控制格式、LogLevel控制详略,生产默认warn; - 多站点、多服务器场景下,用 DataKit 采集到观测云做集中检索、状态码统计与告警,比逐台 tail 高效得多。
两类日志分别在哪里?
| 系统 | 访问日志 | 错误日志 |
|---|---|---|
| Debian / Ubuntu | /var/log/apache2/access.log |
/var/log/apache2/error.log |
| RHEL / CentOS / Fedora | /var/log/httpd/access_log |
/var/log/httpd/error_log |
查看实时流量用 sudo tail -f /var/log/apache2/access.log;按关键词过滤用 grep(如 sudo grep " 500 " access.log 捞 500 错误)。
访问日志格式解读:每个字段是什么?
格式由主配置中的 LogFormat 指令定义。两种预定义格式:
Common Log Format(通用格式):
LogFormat "%h %l %u %t \"%r\" %>s %O" common
一条典型记录及各字段含义:
127.0.0.1 - - [06/Jun/2026:11:26:42 +0800] "GET /index.html HTTP/1.1" 200 3477
| 占位符 | 示例值 | 含义 |
|---|---|---|
%h |
127.0.0.1 | 客户端 IP |
%l / %u |
- | 远程登录名 / 认证用户名(无则为 -) |
%t |
[06/Jun/2026:11:26:42 +0800] | 请求时间 |
%r |
"GET /index.html HTTP/1.1" | 方法、路径、协议 |
%>s |
200 | 最终响应状态码 |
%O |
3477 | 响应字节数 |
Combined Log Format 在 Common 基础上追加 %{Referer}i(来源页)与 %{User-Agent}i(客户端 UA),是多数发行版的默认格式。
如何自定义与启用格式?
在 apache2.conf 中定义一个含响应耗时的自定义格式:
LogFormat "%t %H %m %U %q %I %>s %O %{ms}T" custom
再到虚拟主机配置(如 sites-available/000-default.conf)中启用并重启:
CustomLog ${APACHE_LOG_DIR}/access.log custom
sudo systemctl restart apache2
推荐做法:直接输出 JSON 结构化日志
非结构化文本进分析平台前总要"切割"一次,不如源头就写 JSON:
LogFormat "{ \"time\":\"%t\", \"method\":\"%m\", \"uri\":\"%U\", \"query\":\"%q\", \"status\":%>s, \"bytes_sent\":%O, \"duration_ms\":%{ms}T, \"user_agent\":\"%{User-Agent}i\" }" json
CustomLog ${APACHE_LOG_DIR}/access.log json
每条日志即一个标准 JSON 对象,采集后可免解析直接检索——观测云对 JSON 日志会自动切割字段 。
错误日志怎么配?
ErrorLog ${APACHE_LOG_DIR}/error.log
ErrorLogFormat "[%{u}t] [%l] [pid %P:tid %T] [client %a] %M"
LogLevel warn
LogLevel 从低到高为 trace1-8 → debug → info → notice → warn → error → crit → alert → emerg,指定某级即包含更高严重级;不配置时默认 warn。排障期可临时调到 debug,完事记得调回,避免刷爆磁盘。
多台 Apache 服务器如何统一分析?
观测云落地:在各服务器安装 DataKit,通过磁盘文件采集(logging.conf 中指定 logfiles = ["/var/log/apache2/*.log"] 及 source/service)把访问与错误日志统一上报 。非 JSON 的历史格式可用 Pipeline 的 grok 脚本切割出客户端 IP、状态码、耗时等字段,并务必提取标准字段 time 与 status(status 决定查看器中的级别着色与筛选)。之后在日志查看器里按状态码过滤 4xx/5xx、用聚类分析归并高频错误模式 ;再用**监控器(日志检测)**配置"5xx 错误数超过阈值即告警",经告警策略推送到钉钉/企业微信/飞书 。
总结
Apache 日志体系的核心就两件事:访问日志用 LogFormat 管住"记什么"(推荐直接 JSON),错误日志用 LogLevel 管住"记多细"。单机上 tail + grep 够用;规模化之后交给 DataKit + 观测云,把格式红利转化为检索、统计与告警能力。
常见问题(FAQ)
Q:access.log 里的状态码应该以哪个为准,%s 还是 %>s?
以 %>s 为准。%s 记录的是内部第一次响应的状态,请求经过内部重定向后会失真;%>s 才是返回给客户端的最终状态码。
Q:如何让同一台服务器的不同虚拟主机分开记日志?
在每个 VirtualHost 块内单独配置 CustomLog 和 ErrorLog 指向不同文件即可。注意不要在主配置和虚拟主机中重复定义同一 CustomLog,否则会记双份。
Q:错误日志里 [client x.x.x.x] 后面的错误信息看不懂怎么办?
错误日志格式为"时间 [模块:级别] [pid/tid] [客户端] 消息",消息中的 AH 开头编号是 Apache 官方错误码,可直接在官方文档检索该编号获取解释。
Q:改成 JSON 格式后,观测云还需要 Pipeline 吗?
JSON 日志会被自动解析出字段,通常只需 Pipeline 做少量标准化(如把 time 映射为标准时间字段、按状态码区间设置 status);老的 common/combined 文本格式则需要 grok 完整切割。
系列阅读:Nginx 日志完全指南 | Caddy 日志配置指南