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 來接收后面那一個變量里面的值。