Nginx|acccess_log日志通过json格式进行采集

上一节,讲nginx进行tcp代理功能的时候,提到了将日志采集成json格式,方便后面进入ELK分析.既然tcp的都可以,http和https的自然不在话下,本篇就将这个记录一下.

Nginx的access_log默认是以空格分隔的字符串形式记录的,格式如下

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

我们,可以手动将其拼装成json的字符串

log_format  main_json '{"remote_addr":"$remote_addr",'
                      '"remote_user":"$remote_user",'
                      '"time_local":"$time_local",'
                      '"request":"$request",'
                      '"status":"$status",'
                      '"body_bytes_sent":"$body_bytes_sent",'
                      '"http_referer":"$http_referer",'
                      '"http_user_agent":"$http_user_agent",'
                      '"http_x_forwarded_for":"$http_x_forwarded_for"}';

正常这么写基本就ok了,但是你有个问题,如果你的request路径里,有中文的话,会以乱码的形式显示

{
    "remote_addr": "47.75.50.50", 
    "remote_user": "-", 
    "time_local": "23/Apr/2020:20:56:34 +0800", 
    "request": "GET /\xE4\xB8\xAD\xE6\x96\x87 HTTP/1.1",
    "status": "200", 
    "body_bytes_sent": "2", 
    "http_referer": "-",
    "http_user_agent": "curl/7.58.0",
    "http_x_forwarded_for": "-"
}

解决办法就是在log_format加上escape=json

log_format  main_json escape=json '{"remote_addr":"$remote_addr",'
                      '"remote_user":"$remote_user",'
                      '"time_local":"$time_local",'
                      '"request":"$request",'
                      '"status":"$status",'
                      '"body_bytes_sent":"$body_bytes_sent",'
                      '"http_referer":"$http_referer",'
                      '"http_user_agent":"$http_user_agent",'
                      '"http_x_forwarded_for":"$http_x_forwarded_for"}';

验证

{
    "remote_addr": "47.75.50.50", 
    "remote_user": "-", 
    "time_local": "23/Apr/2020:20:56:34 +0800", 
    "request": "GET /中文 HTTP/1.1",
    "status": "200", 
    "body_bytes_sent": "2", 
    "http_referer": "-",
    "http_user_agent": "curl/7.58.0",
    "http_x_forwarded_for": "-"
}

不过要注意escape=json是nginx 1.11.8开始才支持的参数,如果低于这个版本可以考虑使用nginx-http-json-log

变量含义

$remote_addr, $http_x_forwarded_for 记录客户端IP地址
$remote_user 记录客户端用户名称
$request 记录请求的URL和HTTP协议
$request_length 请求的长度(包括请求行,请求头和请求正文)。
$request_time 请求处理时间,单位为秒,精度毫秒;从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$status 记录请求状态
$body_bytes_sent 发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。
$bytes_sent 发送给客户端的总字节数。
$connection 连接的序列号。
$connection_requests 当前通过一个连接获得的请求数量。
$msec 日志写入时间。单位为秒,精度是毫秒。
$pipe 如果请求是通过 HTTP 流水线(pipelined)发送,pipe值为“p”,否则为“.”。
$http_referer 记录从哪个页面链接访问过来的
$http_user_agent 记录客户端浏览器相关信息
$time_iso8601 ISO8601标准格式下的本地时间。
$time_local 通用日志格式下的本地时间。
$request_body 获取请求 body 内容
$cookie_[COOKIE_NAME] 通过 cookie 名字记录 cookie 值
$http_[HEADER_NAME] 通过 header 名字记录 header 值

that's all


相关博文

About rainbird

IOS攻城狮
This entry was posted in ELK, Nginx and tagged , , , , , , . Bookmark the permalink.

发表评论