nginx日志切分方案

nginx的日志切分问题一直是运维nginx时需要重点关注的。本文将简单说明下nginx支持的两种日志切分方式。

定时任务切分

所谓的定时任务切分,是指通过定时任务(比如crontab),发送信号给nginx,让其重新打开文件。该方法也是nginx官网上面比较推荐的,原文说明比较清楚,这里在说明下:

发送USR1 信号会让nginx主动重新打开日志文件,故操作如下:

$ mv access.log access.log.0
$ kill -USR1 `cat master.nginx.pid`
$ sleep 1
$ gzip access.log.0    # do something with access.log.0

总结 :优点是思路较为简单,但效果明显,而且对error_log 同样适用;缺点是有外部依赖(比如 crontab)

自切分

自切分是指让nginx自身实现日志切分功能,不依赖crontab等东西。 其主要原理是依赖access_log的强大功能—- 可以用变量定义请求的log路径。

nginx的acess_log 功能非常强大,其完整指令说明如下,这里主要说明定义日志路径的功能;关于syslog还有gzip, buffer等特性,后续再说明。

access_log指令:


    Syntax:    access_log path [format [buffer=size [flush=time]] [if=condition]];
               access_log path format gzip[=level] [buffer=size] [flush=time] [if=condition];
               access_log syslog:server=address[,parameter=value] [format [if=condition]];
               access_log off;
    Default:    access_log logs/access.log combined;
    Context:    http, server, location, if in location, limit_except

注意path部分是支持nignx变量的,这也就意味这我们只要通过配置正确的nginx变量,就可以实现小时等级别的日志自动拆分了。

一个简单的问题就出现了,假设nginx要实现这个机制,那岂不是每打印一个请求log就得打开文件,写日志,关闭文件? 这样显然效率太差了,为了解决这个问题,nginx又引入了一个机制,叫做 open_file_cache,简单的说,这个东西的功能就是会缓存打开的文件,只有满足一定条件的时候才会重新去check当前fd对应的文件是否合法,是否需要重新打开。 open file cache的指令如下:


    Syntax:     open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
                open_log_file_cache off;
    Default:     open_log_file_cache off;
    Context:     http, server, location

open_log_file_cache 里面几个参数的含义为:

  • max : 设置缓存中描述符的最大数量;如果缓存被占满,最近最少使用(LRU)的描述符将被关闭。
  • inactive : 设置缓存文件描述符在多长时间内没有被访问就关闭; 默认为10秒。
  • min_uses : 设置在inactive参数指定的时间里, 最少访问多少次才能使文件描述符保留在缓存中;默认为1。
  • valid :设置一段用于检查超时后文件是否仍以同样名字存在的时间; 默认为60秒。
  • off :禁用缓存。

综上,要让nginx自切分,需要两个步骤,其一,配置合理的access_log;其二,开启open_log_file_cache提升性能; 下面是用实现小时级别日志切分的配置demo


    #提取nginx变量
    if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})")
    {
        set $year $1; 
        set $month $2; 
        set $day $3; 
        set $hour $4; 
        set $minutes $5; 
        set $seconds $6; 
    }


    #配置access_log ;以  hour 为界
    access_log  logs/access.log.$year$month$day$hour;                                                                         

    #配置open_log_file_cache
    open_log_file_cache max=10 inactive=60s valid=1m min_uses=2;

总结 : 自切分可一定程度上面满足日志切分的需求;但是对性能会有一定的影响; 另外,并不支持error_log的切分,个人更推荐产品线采用方式一的方法切。

其他

本文主要阐述了nignx日志切分的方案,希望能够帮助大家提升对nginx的理解。另外nginx的日志管理,还是很多值得学习,注意的点,包括syslog支持,gzip支持(想想protobuf)。

欢迎关注下方“非著名资深码农“公众号进行交流~

发表评论

邮箱地址不会被公开。