You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Nginx按日期命名日志时access日志生效而error日志无效?

解决Nginx error_log变量未解析的问题

问题原因

Nginx的error_log和access_log初始化时机存在差异:

  • access_log会在第一个请求到达时才打开并写入日志,此时请求相关的变量(如$time_iso8601、map生成的变量)已完成解析,因此能正常生成带日期的文件名。
  • 若error_log配置在http块,它会在Nginx启动阶段就尝试初始化文件,此时尚无请求上下文,请求级别的变量无法被解析,最终直接输出变量名(如error.$year-$month.log)。

解决办法

方法1:将error_log移到server块,用set指令提取日期

在server块内部通过if指令从$time_iso8601中提取日期变量,再配置error_log:

server {
    listen 80;
    server_name example.com;

    # 从$time_iso8601提取年-月(如需按天分割,调整正则为^(\d{4})-(\d{2})-(\d{2}))
    set $log_date "";
    if ($time_iso8601 ~ "^(\d{4})-(\d{2})") {
        set $log_date "$1-$2";
    }

    # 配置带日期的日志文件
    error_log /var/log/nginx/error.$log_date.log;
    access_log /var/log/nginx/access.$log_date.log;

    # 其他server配置...
}

当第一个请求到达该server时,$log_date变量会被解析,error_log会自动创建正确命名的日志文件。

方法2:保留http块的map指令,将error_log移到server块

如果习惯用map统一管理日期变量,只需把error_log的配置从http块移到server块即可:

http {
    # 从$time_iso8601提取年-月变量
    map $time_iso8601 $log_yearmonth {
        ~^(\d{4}-\d{2}) $1;
        default "";
    }

    # 其他http配置...

    server {
        listen 80;
        server_name example.com;

        # 在server块中使用map生成的变量
        error_log /var/log/nginx/error.$log_yearmonth.log;
        access_log /var/log/nginx/access.$log_yearmonth.log;

        # 其他server配置...
    }
}

注意事项

  • 日志文件会在当天第一个请求到来时创建,而非提前生成;若需按天分割,调整正则表达式提取到日即可(如~^(\d{4}-\d{2}-\d{2}) $1)。
  • 确保Nginx进程对日志目录(如/var/log/nginx/)有写入权限。
  • 若有多台server,每台server的error_log会独立生成对应日期的文件;若需全局统一的error日志,可将所有server的error_log指向同一个带变量的路径。

内容的提问来源于stack exchange,提问作者stack92

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 15:55:00