最近接到一个奇葩的需求,要求把某些规则的Nginx的日志写入到指定文件夹下,要求记录为json格式,按分钟为粒度切割文件。
吓得我抓紧去查阅了Nginx的日志参数。众所周知,lua写入的日志都是写入到errlog中的,且会有前后环境的描述文本,没法实现定制化,只可以设置级别。accesslog 可以设置格式以及支持if指令。
Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
Default:
access_log logs/$host.access.log combined;
Context: http, server, location, if in location, limit_except
从上述的语法可以看出,支持if逻辑判断
access_log logs/$host.access.log if=$logable;
我们尝试重启之后发现提示$abtest变量未定义。那么我们需要下面一个逻辑块。
//不记录2XX 和 3XX的记录
map $status $loggable {
~^[23] 0;
default 1;
}
再次尝试重启就可以了。
接下来我们需要控制按分钟切割日志文件。看到路径支持自定义变量,其实就很简单了。
set_by_lua $minute 'return os.date("%Y%m%d%H%M",os.time())';
access_log /var/logs/log.$minute server_log if=$loggable;
剩下的任务就是json了,json也很简单,就是实现起来有点啰嗦.
log_format server_log escape=json '{'
' "logable":$loggable ' #这个地方的变量也需要在map中声名
'}';
剩下的就是一些业务逻辑了,只需要在lua中改变对应的值就行了。
ngx.var.loggable = 1
TIP:
如果在 rewrite_by_lua_file 内控制变量需要加上 rewrite_by_lua_no_postpone on; 来提前执行该流程
网友评论