Nginx日志文件中的时间格式自定义

Nginx日志文件中时间格式由[18/Oct/2025:07:42:41 +0000]改为YYYY-MM-DD…

默认的配置中,不会有log_format命令:

Nginx
        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;

时间格式

在未指定log_format时,默认日志格式为:

$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"
# 含义如下:(对应变量无值以-表示)
# 请求IP - 请求用户 [dd/month/yyyy:HH:mi:ss 时区] "请求方法 URI HTTP协议" 响应状态码 响应内容大小bytes "请求引用来源" "浏览器UA"

示例日志:

::1 - - [18/Oct/2025:07:42:41 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/8.5.0"
195.178.110.15 - - [18/Oct/2025:08:33:58 +0000] "GET / HTTP/1.1" 400 166 "-" "-"

在日志分析时[18/Oct/2025:07:42:41 +0000]数据不好格式化,需要改为YYYY-MM-DD HH:mi:ss。而nginx内置的二个时间变量格式为:

  • $time_local的格式为08/Nov/2025:13:03:23 +0800
  • $time_iso8601的格式为2025-11-08T13:03:23+08:00

现在的nginx版本中,log_format只能在http块中,不能在server块里,否则报错:"log_format" directive is not allowed here in /etc/nginx/sites-enabled/xxx。而http块里不能使用if来设置变化(if只能在serverlocation中使用),只能使用ngx_http_map_module模块的map指令做变量赋值了,使用格式如下:

Nginx
# 取$int_var值,做比较:如果是value1,则将result1值,赋给$out_var。
map $int_var $out_var {
    value1  result1;
    value2  result2;
    ...
    default default_result;
}

调整 /etc/nginx/nginx.conf

通过map指令,从$time_iso8601取值,整理格式为YYYY-MM-DD HH:mi:ss,再赋值给$time_fmt,后实现log_format

Nginx
        ##
        # Logging Settings
        ##
        log_format main '$remote_addr - $remote_user $time_fmt "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
        map $time_iso8601 $time_fmt {
                "~^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2})" "${year}-${month}-${day} ${hour}:${minutes}:${seconds}";
                default "";
        }

        access_log /var/log/nginx/access.log main;
  • 如果子站点也定义了access_log,需要同步增加main
  • 再配置校验与生效:sudo nginx -t && sudo nginx -s reload
  • 最后观察日志文件:tail -n 10 /var/log/nginx/access.log

如果不考虑人工阅读效率,可以考虑存储为JSON格式,软件在做数据处理时,更方便。

Nginx
        log_format main escape=json '{'
                                        '"remote_addr": "$remote_addr",'
                                        '"remote_user": "$remote_user",'
                                        '"time_fmt": "$time_fmt",'
                                        '"request": "$request",'
                                        '"status": "$status",'
                                        '"body_bytes_sent": "$body_bytes_sent",'
                                        '"http_referer": "$http_referer",'
                                        '"http_user_agent": "$http_user_agent"'
                                    '}';

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注