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; - 多站点、多服务器需要统一采集路径、站点标识和字段类型,才能比较各实例的错误分布。
两类日志分别在哪里?
| 系统 | 访问日志 | 错误日志 |
|---|---|---|
| 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 后,按日志采集配置设置文件路径、source 和 service;访问日志与错误日志格式不同,应分别配置解析规则。用 Pipeline 的 json() 或 grok 提取时间、路径、HTTP 状态码和耗时,再发送测试请求,核对日志查看器中的字段值。
HTTP 状态码建议保存在 http_status_code 等独立字段,日志级别才映射到观测云标准字段 status。确认 500 请求可被检索后,再基于该字段统计 5xx 数量并设置告警阈值;不要用日志级别字段直接比较 HTTP 数值。
总结
Apache 日志体系的核心就两件事:访问日志用 LogFormat 管住"记什么"(推荐直接 JSON),错误日志用 LogLevel 管住"记多细"。多主机分析前,先验证时间、站点、状态码与耗时字段是否一致。
常见问题(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 吗?
需要按实际采集配置确认。可使用 Pipeline 的 json() 提取字段,再解析时间和映射日志级别;common/combined 文本格式可用 grok。两种格式都应先用真实样本验证。
系列阅读:Nginx 日志完全指南 | Caddy 日志配置指南