必须启用mod_logio模块并使用%I(接收字节数)和%O(发送总字节数)字段,才能准确记录TCP层真实网络流量;%I包含请求头、体及TLS开销,%O含响应头、压缩后体及分块标记等。
要让 apache 准确记录每个请求实际接收和发送的网络字节数,必须启用 mod_logio 模块,并在 logformat 中使用其提供的专用字段 %i(接收字节数)和 %o(发送总字节数)。这两个值比 %b(仅响应体)或 %b(clf 格式)更真实反映 tcp 层流量,尤其适用于带压缩、分块传输或 https 的场景。
确认并启用 mod_logio 模块
该模块默认不启用,需手动加载:
- 检查当前已加载模块:
httpd -M | grep logio或apache2ctl -M | grep logio - 若未列出,编辑主配置文件(如
httpd.conf或mods-enabled/logio.load),添加一行:LoadModule logio_module modules/mod_logio.so - 重启 Apache 生效:
systemctl restart apache2(Debian/Ubuntu)或systemctl restart httpd(RHEL/CentOS)
在 LogFormat 中使用 %I 和 %O 字段
%I 表示客户端发来的原始字节数(含请求头、请求体、TLS 开销等),%O 表示 Apache 发送给客户端的全部字节数(含响应头、响应体、分块标记、gzip 尾部等):
Apache 2.4.62 官方 tar.gz 源码包是 Linux 及类 Unix 系统构建 Web 服务器的核心基础。通过源码编译安装,开发者能够灵活定制模块、优化性能并精准控制安装路径,满足多样化的业务需求。
- 推荐写法(兼容 JSON 日志):
LogFormat "{ \"@timestamp\": \"%{%Y-%m-%dT%H:%M:%S%z}t\", \"client_ip\": \"%a\", \"method\": \"%m\", \"url\": \"%U%q\", \"status\": %>s, \"bytes_in\": %I, \"bytes_out\": %O, \"request_time_usec\": %D }" io_json - 注意:
%I和%O是数值型,不加引号;避免与%B(仅响应体)混淆 - 若用于传统文本日志,可简化为:
LogFormat "%h %l %u %t \"%r\" %>s %b %I %O \"%{Referer}i\" \"%{User-Agent}i\"" combined_io
验证数据是否准确有效
启用后需实测验证,避免因代理、CDN 或压缩干扰导致数值失真:
- 用
curl -v发送一个简单 GET 请求,观察响应头中的Content-Length和实际传输字节数 - 对比日志中
%O值与curl -w "%{size_download}\n%{size_upload}\n%{speed_download}\n" ...输出的发送/接收字节数 - 对 POST 请求测试大 body(如 1MB 文件),确认
%I接近上传大小 + 头开销(通常多 200–500 字节) - 开启
mod_deflate后,%O应明显小于未压缩时的%B,体现压缩收益
常见问题与注意事项
这些细节直接影响字节数可信度:
-
%I在启用 SSL/TLS 时包含加密层开销(如 record header、padding),并非纯应用层 payload - 若前端有反向代理(如 Nginx),
%a可能是代理 IP,需配合%{X-Forwarded-For}i使用,但%I/%O仍反映 Apache 与代理之间的实际流量 - HTTP/2 多路复用下,
%I和%O仍按单个请求统计,非整个连接总量 - 确保日志文件权限可写,且磁盘空间充足——高并发下 IO 字节数日志体积增长显著

















