nginx日志按天切割,if ($time_iso8601 ~ “^(\d{4})-(\d{2})-(\d{2})”)未生效

在使用Nginx的时候,为了防止单个日志过大,都要对日志进行切割,一般是按照天、小时或者更细粒度进行切割,配置方式如下:

    server {
        # 其他指令
        if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") {
            set $year $1;
            set $month $2;
            set $day $3;
     }

        access_log /home/$yourdir/log/access-$year-$month-$day.log;
    }

之前我是如上配置的,使用过程中对于绝大部分请求都没问题,但是在清理日志的时候发现,少量请求没有按天打印,而是输出在access-.log中,很明显是$year,$month,$day三个变量没有赋值。观察这些少量请求,发现都是http status=400,猜测是因为在处理400请求时,某些指令影响了if指令的执行,导致上述指令没有执行。查阅nginx资料,官方推荐使用map指令,替换之后,发现可以兼容http status=400的情况,配置如下:

    http {
        include       mime.types;
        default_type  application/octet-stream;

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

        map $time_iso8601 $logdate {
             '~^(?\d{4}-\d{2}-\d{2})' $ymd;
            default    'date-not-found';
        }

        access_log  /var/log/nginx/yeetrack.access-$logdate.log  main;
      ...
    }

配置之后,重新加载./nginx -s reload,注意map指令要配置在http配置块中。
可以使用如下命令进行测试:

    printf foo | nc yeetrack.com 80
    printf foo | nc yeetrack.com 443
版权声明

本站文章、图片、视频等(除转载外),均采用知识共享署名 4.0 国际许可协议(CC BY-NC-SA 4.0),转载请注明出处、非商业性使用、并且以相同协议共享。

© 空空博客,本文链接:https://www.yeetrack.com/?p=1442