当前位置: 首页 > news >正文

动态会话日志记录 ngx_stream_log_module

一、引言

在使用 NGINX Stream 模块处理 TCP/UDP 会话时,我们常常需要记录每次连接的关键指标(如客户端 IP、会话时长、收发字节数等),便于后续的审计、监控和故障排查。ngx_stream_log_module 就是专门为此设计的,它允许你以自定义格式记录 TCP/UDP 会话日志,并提供了缓冲写入文件描述符缓存等多种优化手段。

本文将以零基础、一步步的方式,带你从环境准备、模块验证,到配置示例、测试验证,再到常见故障排查,全面掌握 ngx_stream_log_module

二、模块概览

  • 模块名称ngx_stream_log_module

  • 首次引入:NGINX 1.11.4

  • 作用:为 Stream(TCP/UDP)会话写入日志,支持自定义格式、日志缓冲、压缩及条件记录。

  • 核心指令

    • log_format:定义日志格式
    • access_log:开启会话日志并指定格式、路径、缓冲、压缩、条件等
    • open_log_file_cache:为带变量的日志路径缓存文件描述符

三、典型场景

  1. 数据库代理审计
    记录来自各客户端 IP 的 MySQL/TCP 连接时长和流量,用于安全审计。
  2. 实时流量监控
    对 Redis、Kafka 等服务的 TCP 会话进行统计,监测异常流量突增。
  3. 故障定位
    当下游服务异常时,通过 $status$session_time 等指标快速定位问题来源。

四、先决条件

  1. NGINX 支持 Stream 模块
    请确保在编译或安装时包含了 --with-stream 参数。

  2. 确认已编译或加载 ngx_stream_log_module

    nginx -V 2>&1 | grep --color stream_log
    
  3. 日志目录准备
    为防止权限问题,建议提前创建并设置好目录权限:

    sudo mkdir -p /spool/logs
    sudo chown nginx:nginx /spool/logs
    

五、指令详解

1. log_format

log_format name [escape=default|json|none] string ...;
  • name:日志格式名称,用于 access_log 引用。
  • escape:可选 default(转义控制字符)、json(JSON 专用转义)、none(不转义)。
  • string:日志模板,支持内嵌多个变量,如 $remote_addr$session_time 等。

内置变量示例

变量含义
$remote_addr客户端 IP 地址
$time_local本地时间(日志记录时刻)
$protocol会话使用的协议(如 TCP/UDP)
$status连接结束状态码(0 表示正常)
$bytes_sent发送给客户端的总字节数
$bytes_received从客户端接收的总字节数
$session_time会话时长,单位秒(带毫秒精度)

2. access_log

access_log path format [buffer=size] [gzip[=level]] [flush=time] [if=condition];
access_log off;
  • path:日志文件路径,可写死也可包含变量(见 open_log_file_cache)。
  • format:引用 log_format 定义的格式名。
  • buffer:启用缓冲写入,单位字节(如 32k);不超过系统原子写入大小。
  • gzip:启用压缩写入,可选 =1..9 压缩级别;需编译时链接 zlib。
  • flush:最大刷新间隔(如 5m),超时或缓冲满后写盘。
  • if:条件表达式;当条件为“0”或空字符串时,跳过本次日志记录。

3. open_log_file_cache

open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
  • max:缓存的最大文件描述符数量(LRU 关闭最少使用的)。
  • inactive:若某文件在此时长内未被访问,则关闭描述符(默认 10s)。
  • min_uses:在 inactive 时间内最少使用次数,低于则不缓存(默认 1)。
  • valid:每隔该时长检查文件名是否仍指向同一文件(默认 60s)。

六、配置示例(一步一步)

以下示例演示如何在 Stream 模块中记录会话日志,并对日志性能进行优化。

  1. stream { ... } 块外全局定义文件描述符缓存

    stream {# 缓存最多 1000 个文件描述符,20s 不活跃则关闭,文件存在校验 1m,至少访问 2 次才缓存open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;…
    }
    
  2. 定义日志格式

    stream {log_format basic '$remote_addr [$time_local] ''$protocol $status $bytes_sent $bytes_received ''$session_time';…
    }
    
  3. 开启会话日志

    stream {# 将日志缓冲到 32KB,5 分钟或满缓冲时写盘access_log /spool/logs/nginx-access.log basic buffer=32k flush=5m;…
    }
    
  4. 启用压缩(可选)

    stream {# 以 gzip 压缩(级别 2),缓冲同上access_log /spool/logs/nginx-access.log.gz basic gzip=2 buffer=64k flush=5m;…
    }
    
  5. 条件日志(可选)

    stream {# 仅记录时长超过 10 秒的会话access_log /spool/logs/long-sessions.log basic if=$session_time\>10;…
    }
    

完整示例整合:

stream {# 1. 文件描述符缓存open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;# 2. 日志格式log_format basic '$remote_addr [$time_local] ''$protocol $status $bytes_sent $bytes_received ''$session_time';# 3. 普通日志:32k 缓冲,5m 刷新access_log /spool/logs/nginx-access.log basic buffer=32k flush=5m;# 4. 压缩日志:64k 缓冲,gzip 2,5m 刷新access_log /spool/logs/nginx-access.log.gz basic gzip=2 buffer=64k flush=5m;# 5. 仅记录长会话(>10s)access_log /spool/logs/long-sessions.log basic if=$session_time\>10;server {listen     3306;      # 例如:MySQL 代理proxy_pass backend:3306;}
}

七、测试与验证

  1. 重载配置

    sudo nginx -t && sudo systemctl reload nginx
    
  2. 模拟 TCP 会话
    使用 openssl s_clientnc 建立连接并发送少量数据:

    # 简单测试:连接后等待 2 秒再关闭
    { echo -n ''; sleep 2; } | nc example.com 3306
    
  3. 查看日志

    tail -n20 /spool/logs/nginx-access.log
    

    应看到类似:

    192.168.1.10 [12/May/2025:10:30:00 +0000] tcp 0 0 2.001
    

    表示 IP、协议、状态、字节数与时长。

八、常见问题与排查

问题排查思路
日志不生成- 确认 access_log 是否在 streamserver 上下文中
- 检查 NGINX error.log
缓冲后长时间未写盘- 检查 flush 设置是否过大
- 缓冲区是否未满
- 触发重载时会主动写盘
gzip 日志无法解压- 确认 NGINX 编译时已链接 zlib
- 使用 zcatgunzip -t 测试
带变量路径日志无缓存(频繁打开/关闭)- open_log_file_cache 是否已配置
- min_usesinactive 参数是否合理

九、最佳实践

  1. 预分配缓冲:根据日志量合理设置 buffer,避免频繁写盘。
  2. 压缩归档:对历史日志使用 gzip,节省磁盘空间,并可随时通过 zcat 查看。
  3. 文件描述符缓存:当日志路径含变量时,务必开启 open_log_file_cache,减少系统调用开销。
  4. 条件记录:对关键会话(如长连接、大流量)单独出日志,便于聚焦排查。
  5. 定期清理:通过外部脚本或 logrotate 管理日志文件,避免目录爆满。

十、总结

ngx_stream_log_module 为 NGINX Stream 模块提供了灵活、高性能的会话日志能力。

  • 格式定义日志输出缓冲与压缩、到 文件描述符缓存,覆盖了日志记录的全生命周期。
  • 通过 条件记录压缩归档 等功能,兼顾了性能与可用性。

掌握本篇内容后,你即可在 TCP/UDP 代理、数据库中间件、微服务网关等各类场景中,轻松实现精准、可扩展的会话日志记录。祝部署顺利,运维轻松!

相关文章:

  • 介电测试的基本原理与方法及应用领域
  • 摆脱拖延症的详细计划示例
  • C——五子棋小游戏
  • 坐标系概述
  • 湖北理元理律师事务所:企业债务危机的“止血”与“造血”平衡术
  • spark的处理过程-转换算子和行动算子
  • 视频编码原理讲解一:VCL层和NAL层的讲解
  • 在文档里如何引用在线SVG甘特图
  • 17.three官方示例+编辑器+AI快速学习webgl_buffergeometry_lines
  • NVIDIA Quantum-2 QM9700系列利用400G infinniband扩展数据中心智能交换机 NVIDIA Quantum-2 InfiniBand 交换机系列
  • 服务器带宽基础知识
  • 量子加密通信:守护信息安全的未来之盾
  • 从逻辑学视角探索数学在数据科学中的系统应用:一个整合框架
  • 2024年北理工Python123第六章编程题整理
  • Linux `kill` 指令深度解析与高级应用指南
  • C38-全局变量、局部变量及外部变量
  • 吴恩达机器学习笔记:单变量线性回归
  • 机器学习驱动的智能化电池管理技术与应用
  • 《Python星球日记》 第59天:生成对抗网络(GAN)
  • 《算法导论(第4版)》阅读笔记:p32-p38
  • 摩根士丹利:对冲基金已加码,八成投资者有意近期增配中国
  • 韩国总统选战打响:7人角逐李在明领跑,执政党临阵换将陷入分裂
  • 欧阳娜娜携家人回江西探亲,受聘为江西吉安文化旅游大使
  • 浙江公开征集涉企行政执法问题线索,包括乱收费、乱罚款等
  • 印度外交秘书:印巴军方将于12日再次对话
  • 第三届“老山国际春茶节”活动在云南麻栗坡举办