nginx worker process 不生成日志,而是在请求处理结束时按 access_log 指令触发写入:独立执行、支持缓冲与条件记录,通过 ngx_http_log_handler 格式化并写入文件或 syslog。

Nginx 的 Worker Process 不直接“生成”日志,而是按配置在请求生命周期末尾触发日志写入动作——这个动作由事件循环驱动、由 access_log 指令控制,最终交由底层 I/O 机制完成。
Worker Process 在日志处理中的角色
- 日志记录发生在请求处理链的末端:当 location 块中请求处理结束(包括可能的内部重定向后最终匹配的 location),Worker 进程会根据该 location 所属作用域(http/server/location)中配置的
access_log指令,决定是否写入、写到哪、用什么格式。 - 每个 Worker 进程独立执行日志写入:不共享日志文件句柄,但可通过
open_log_file_cache缓存文件描述符,减少重复 open/close 开销。 - 写入行为是同步或带缓冲的:若配置了
buffer=size,日志先暂存内存;满足 buffer 满、flush=time到期、或 worker 退出时才刷盘。启用gzip时,压缩也在 Worker 进程内完成(需编译时含 zlib)。
日志写入的关键触发点
- 请求响应已发送完毕,且 response header 和 body 都已确定(状态码
$status、字节数$body_bytes_sent等变量可用)。 - 当前 location 的
access_log配置生效(上级配置未被off覆盖)。 -
if=condition条件满足(例如只记录非 2xx/3xx 响应):条件表达式在 Worker 处理阶段实时求值。
实际写入过程简述
- Worker 进程调用
ngx_http_log_handler(HTTP 模块的 phase handler),遍历当前作用域所有access_log指令。 - 对每条日志配置:
- 格式化字符串(如
combined或自定义log_format),填充$remote_addr、$request_time等变量; - 若启用了 buffer,尝试写入内存缓冲区;否则直接调用
write()系统调用; - 若路径含变量(如
/var/log/$host-access.log),变量在运行时解析,要求 worker 用户对该路径有写权限; - 若使用
syslog:前缀,则通过 Unix socket 向 syslog daemon 发送消息,不经过文件 I/O。
- 格式化字符串(如
注意事项
- 日志写入失败(如磁盘满、目录无权限)通常不会中断请求,但会记录到 error log 中。
- 多个 worker 同时写同一文件时,依赖操作系统追加写(append)保证行级原子性,不会出现日志错乱。
-
root指令影响变量路径解析:若access_log路径为相对路径,会拼接root值;建议显式指定绝对路径或配套设置root。
日志不是 Worker 的核心职责,而是它在完成请求后顺手执行的一次轻量 I/O 任务——设计上尽量不阻塞事件循环,靠缓冲与异步机制维持高吞吐。











