access_log性能强于error_log,因其采用内存缓冲、异步写入和复用文件描述符应对高频请求;error_log默认低频同步,debug级别则因强制fsync和频繁系统调用导致qps断崖下跌。

access_log 和 error_log 在并发处理时的性能表现差异,核心不在“谁更快”,而在于它们的写入机制、触发频率和系统资源占用方式完全不同。
access_log 是高频批量写入,依赖缓冲与异步落盘
每次 HTTP 请求完成,只要没被 if=condition 过滤掉,就会触发一条 access_log 记录。在万级 QPS 场景下,这意味每秒数千甚至上万次日志写入请求。Nginx 为此做了三重优化:
-
内存缓冲(buffer):默认 64KB 缓存,等攒够再刷盘;配合
flush=1s可强制超时写入,避免延迟累积 - 异步文件操作:底层调用非阻塞 write() + 内核页缓存,worker 进程不等待磁盘 I/O 完成
-
复用文件描述符:只要日志路径是静态字符串(如
/var/log/nginx/access.log),Nginx 启动后就持有 fd,全程无 open/close 开销
所以高并发下 access_log 的吞吐能力极强——瓶颈通常不是 Nginx 本身,而是磁盘带宽或 logrotate 切割时的 rename/fsync 阻塞。
error_log 是低频但同步写入,debug 级别会显著拖慢性能
error_log 不按请求次数计数,而是按“事件”触发:配置加载失败、worker crash、upstream timeout、SSL 握手异常等。多数生产环境设为 warn 或 error 级别,写入极少。
使用tbot机器ID身份文件配合tsh CLI,通过Teleport访问控制SSH登录托管主机或执行远程命令。
但一旦开启 debug 级别,情况剧变:
- 每条 debug 日志都调用
ngx_log_error_core(),内部含完整时间戳、模块名、进程 ID、堆栈上下文等字段生成 - 默认不启用 buffer,每条日志都尝试立即 write(),且部分 debug 场景会强制 fsync
- 大量 debug 日志(如
http模块全开)会导致 worker 进程频繁陷入系统调用,CPU 使用率飙升,QPS 断崖下跌
实测:某 API 网关在 debug 级别下,QPS 从 12000 降至 3500,延迟 P99 从 28ms 涨至 420ms。
关键差异总结:不是“快慢”,而是“要不要让它忙”
二者性能差异的本质是设计定位不同:
- access_log 是“流量镜像”,必须扛住高吞吐,因此靠缓冲+复用+异步来保性能
- error_log 是“事故哨兵”,默认安静,只在真正出事时发声;debug 是诊断开关,不是常态运行模式
- 真正影响并发性能的,往往不是日志本身,而是你是否在 error_log 中打开了不该开的级别,或在 access_log 中漏配 buffer 导致小包狂刷磁盘
上线前检查这两点,比纠结“哪个更耗资源”更实际。










