默认的配置中,不会有log_format命令:
Nginx
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
Contents
hide
时间格式
在未指定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只能在server与location中使用),只能使用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"'
'}';
发表回复