一、引言
在传统的 http 日志中,每个请求都会被单独记录,这对于短连接、异步加载等场景非常直观;但在一些需要以“会话”为单位分析用户行为的场景下,如视频点播、多资源并行加载、长轮询等,单个请求日志难以准确反映用户整个会话的生命周期和流量消耗。
ngx_http_session_log_module 模块(商业订阅)针对这一需求推出:它可以将多个请求聚合为一个会话,待会话结束后一次写入日志,方便统计和分析。下面将以零基础、逐步演示的方式,带你掌握该模块。
二、先决条件
- nginx 商业版:确认已包含
ngx_http_session_log_module。 - linux 环境(ubuntu/centos 等),拥有
sudo权限。 - 配置与重载命令:会使用
nginx -t、systemctl reload nginx。
三、模块验证
在终端执行:
nginx -v 2>&1 | grep --color session_log
- 若输出包含
--with-http_session_log_module或session_log,说明模块可用。 - 否则需联系供应商或重新编译 nginx(添加
--add-module=.../ngx_http_session_log_module)。
四、核心指令详解
4.1 session_log_zone
session_log_zone /path/to/log
zone=name:size
[format=format_name]
[timeout=time]
[id=var]
[md5=expr];
/path/to/log:会话日志文件路径。zone=name:size:定义共享内存区name及大小(如1m)。format=format_name(可选):引用由session_log_format定义的格式,默认使用内置的combined。timeout=time(可选,默认 30s):自上一次请求起经过该时间则认为会话结束并写日志。id=var(可选):如果来自客户端的var(例如 cookie)是有效的 md5,会直接作为会话 id。md5=expr:当id不指定或无效时,基于expr(可由多个变量拼接)计算 md5 作为新会话 id。
关键点:同一个会话下的所有请求,在 timeout 时间窗口内都归为同一次日志;超时后才写入并重启新会话。
4.2 session_log_format
session_log_format name string ...;
- name:格式名称,用于
session_log_zone的format=参数。 - string:日志模板,支持所有标准 http 变量,以及
$body_bytes_sent会话内累积值,其他变量取首个请求的值。
常见内置变量:
| 变量 | 含义 |
|---|---|
| $session_log_id | 会话 id(16 字节二进制或 32 字符十六进制) |
| $remote_addr | 首次请求时的客户端 ip |
| $http_user_agent | 用户代理 |
| $session_time | 会话总时长(从首次请求到最后一次请求完成计时) |
| $body_bytes_sent | 会话内所有请求的响应体字节数总和 |
| $request | 首次请求的请求行(如 get /index.html http/1.1) |
4.3 session_log
session_log name | off;
- name:启用对应
session_log_zone中定义的会话日志。 - off:关闭当前级别继承的会话日志。
可在 http、server 或 location 级别使用。
五、一步步配置示例
下面我们以“客户端 ip + user-agent”作为会话标识,统计 /media/ 路径下所有请求的会话日志。
5.1 创建持久化目录
sudo mkdir -p /var/log/nginx/session sudo chown nginx:nginx /var/log/nginx/session
5.2 在 http 块中定义会话日志区
编辑 /etc/nginx/nginx.conf,在 http { ... } 内添加:
# 定义会话日志区,1mb 大小,30s 超时,会话结束写入 /var/log/nginx/session/media.log
# 会话格式使用默认 combined,也可自定义
session_log_zone /var/log/nginx/session/media.log
zone=media_zone:1m
timeout=30s
md5=$binary_remote_addr$http_user_agent;
5.3 自定义日志格式(可选)
如需记录更多字段,可在 http 块继续添加:
session_log_format media_fmt
'$session_log_id '
'$remote_addr [$time_local] '
'"$http_user_agent" '
'bytes_sent=$body_bytes_sent '
'session_time=$session_time';
然后在 session_log_zone 中加上 format=media_fmt。
5.4 在 server/location 启用
server {
listen 80;
server_name example.com;
location /media/ {
# 开启会话级日志
session_log media_zone;
}
# 其他路径不记录
}
5.5 检查与重载
sudo nginx -t && sudo systemctl reload nginx
六、验证与测试
模拟会话在浏览器或命令行中多次请求同一资源,确保连续请求间隔小于 30s:
curl http://example.com/media/video1.ts sleep 5 curl http://example.com/media/video2.ts
查看日志
tail -n20 /var/log/nginx/session/media.log
你将看到类似:
5f2d3a4b... 192.168.1.10 [12/may/2025:14:00:00 +0800] "mozilla/5.0 ..." bytes_sent=1048576 session_time=5.123
其中:
- 第一列 为会话 id;
- bytes_sent 为两次请求的累计发送字节;
- session_time 为首次到最后一次请求的时长。
七、典型应用场景
- 流媒体点播统计聚合一次完整的视频播放会话(多个分片请求),统计总流量与观看时长。
- 长轮询/comet 会话将多次心跳/推送请求归为一次会话,评估用户在线时长。
- api 批量操作若客户端将多次批量操作拆分为多请求,可按会话统计请求总量与数据大小。
八、进阶配置与优化
调整 timeout
- 对于长连接、心跳场景,可将
timeout设置更高(如5m)。
- 对于长连接、心跳场景,可将
指定 id 参数
- 若前端通过 cookie 提供稳定会话 id,可写
id=$cookie_sessionid,避免重复新建。
- 若前端通过 cookie 提供稳定会话 id,可写
日志轮转
- 配合
logrotate工具定期切割/var/log/nginx/session/*.log,防止磁盘占满。
- 配合
性能监控
- 监控共享内存使用情况,若活跃会话数极多,可增大
zone=size。
- 监控共享内存使用情况,若活跃会话数极多,可增大
九、常见问题与排查
| 问题 | 排查建议 |
|---|---|
| 日志文件未生成 | - 确认 session_log_zone 路径可写,且 nginx 进程用户对目录有写权限。 - 检查 session_log 是否已在对应 location 启用。 |
| 会话聚合不生效 | - 请求间隔需小于 timeout。 - md5 表达式要包含能唯一标识会话的变量。 |
| 日志格式缺少字段 | - 自定义 session_log_format 时,确保使用 $body_bytes_sent 而非 $bytes_sent。 |
| 共享内存不足 | - 增加 zone=...:size 中的 size,如 2m、4m。 |
十、总结
通过 ngx_http_session_log_module,你可以:
- 以会话级别代替请求级日志,直观统计用户完整交互。
- 聚合流量与时长,方便流媒体、长轮询、批量 api 等场景分析。
- 灵活配置超时、格式、id 源,满足各种业务需求。
掌握以上配置与调优方法后,即可在 nginx 层为复杂 http 会话提供精准、连贯的日志记录,助力业务监控与数据分析。祝你上手顺利,灵活运维!
到此这篇关于详解ngx_http_session_log_module的使用的文章就介绍到这了,更多相关ngx_http_session_log_module使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论