调整格式化nginx日志时间方式

1 需求

    前端在项目的一些页面做了js脚本埋点,以获取用户访问站点的相关信息,比如,用户页面停留时长,用户id,访问的产品id等。然后会从nginx日志里面提取这些信息为json格式,但是nginx 日志时间变量可配置的就两种

第一个时间变量:$time_local   输出格式为:127.0.0.1 - - [03/Nov/2020:14:38:06 +0800] "GET / HTTP/1.1" 200 23 "-" "curl/7.29.0"

第二个时间变量:$time_iso8601  输出格式为: 127.0.0.1 - - [2020-11-03T14:42:53+08:00] "GET / HTTP/1.1" 200 23 "-" "curl/7.29.0" "-"

 

然而希望的时间格式是:  2020-11-03 14:46:44

大概查了下可以实现的方案:

1、修改nginx 日志模块的源码   参考:https://www.cnblogs.com/t-road/p/6868683.html

2、启用lua模块  参考:https://developer.aliyun.com/article/69512

3、python datetime模块转换

4、第一种时间变量格式的值可以用数据库的函数str_to_date转换 str_to_date('%s','%s')   str_to_date('02/Nov/2020:07:07:05','%d/%b/%Y:%H:%i:%s')

 

由于生产是yum方式安装的,前两种方案比较麻烦,且有点小风险,因为需要重新编译。反正都需要对日志做处理的,就用date命令来转换上面的两种格式

 

2 测试date命令转换

2.1 $time_local格式测试

[root@msht-sh-g-test-01 ~]# date -d '03/Nov/2020:14:38:06' "+%Y-%m-%d %H:%M:%S"
date: invalid date ‘03/Nov/2020:14:38:06’
[root@msht-sh-g-test-01 ~]# 

这种格式date命令无法识别

 

2.2 $time_iso8601格式测试

[root@msht-sh-g-test-01 ~]# date -d '2020-11-03T14:45:06+08:00' "+%Y-%m-%d %H:%M:%S"
2020-11-03 14:45:06
[root@msht-sh-g-test-01 ~]# 

这种能达到预期

 

因此,在nginx的日志时间变量定义为$time_iso8601,再用date转换一次就可以,不需要重新编译nginx带来的风险;如果不希望额外用date命令或python来转的话,修改nginx源码更合适。

 

3 模拟脚本里面的操作

[root@msht-sh-g-test-01 ~]# line='127.0.0.1 - - 2020-11-03T14:46:44+08:00 "GET / HTTP/1.1" 200 23 "-" "curl/7.29.0" "-"'
[root@msht-sh-g-test-01 ~]# str_date=$(echo $line|awk '{print $4}')
[root@msht-sh-g-test-01 ~]# format_date=$(date -d $str_date "+%Y-%m-%d %H:%M:%S")
[root@msht-sh-g-test-01 ~]# echo $format_date
2020-11-03 14:46:44
[root@msht-sh-g-test-01 ~]# printf '{"request_time":"%s %s"}\n' $format_date
{"request_time":"2020-11-03 14:46:44"}
[root@msht-sh-g-test-01 ~]# 

 

小提示:由于printf会接收格式参数是以空格分割的,上面格式化后的变量中的值有空格,printf会把2020-11-03当成一个格式化值,另外一部分14:45:06 会重新当成一个值,类似下面这种

[root@msht-sh-g-test-01 ~]# line='127.0.0.1 - - 2020-11-03T14:46:44+08:00 "GET / HTTP/1.1" 200 23 "-" "curl/7.29.0" "-"'
[root@msht-sh-g-test-01 ~]# str_date=$(echo $line|awk '{print $4}')
[root@msht-sh-g-test-01 ~]# format_date=$(date -d $str_date "+%Y-%m-%d %H:%M:%S")
[root@msht-sh-g-test-01 ~]# echo $format_date
2020-11-03 14:46:44
[root@msht-sh-g-test-01 ~]# printf '{"request_time":"%s"}\n' $format_date
{"request_time":"2020-11-03"}
{"request_time":"14:46:44"}
[root@msht-sh-g-test-01 ~]# 
[root@msht-sh-g-test-01 ~]# printf '{"request_time":"%s %s"}\n' $format_date
{"request_time":"2020-11-03 14:46:44"}
[root@msht-sh-g-test-01 ~]# 

 

因此需要写两个 %s 来接收后面那一个变量里面的值。

 

posted @ 2020-11-03 15:56  某某7  阅读(6243)  评论(0编辑  收藏  举报