nginx 直接向 logstash 发送 JSON 格式日志

通过 nginx 的 log_format 指令可以很容易直接就在 nginx 这里就生成(几乎是)JSON 格式的消息发送到 logstash

log_format  logstash '{"@timestamp":"$time_iso8601",'
                     '"@version":"1",'
                     '"host":"$server_addr",'
                     '"client":"$remote_addr",'
                     '"size":$body_bytes_sent,'
                     '"domain":"$host",'
                     '"method":"$request_method",'
                     '"url":"$uri",'
                     '"status":"$status",' # status 有可能会是以0开头,比如“009”这样的状态码,因此不能以数值形式保存,需要加括号存为字符串
                     '"referer":"$http_referer",'
                     '"user_agent":"$http_user_agent",'
                     '"real_ip":"$http_x_real_ip",'
                     '"forwarded_for":"$http_x_forwarded_for",'
                     '"responsetime":$request_time,'
                     '"upstream":"$upstream_addr",'
                     '"upstream_response_time":"$upstream_response_time",'
                     '"cache_fetch":"$srcache_fetch_status",' # 统计srcahe缓存命中率
                     '"cache_store":"$srcache_store_status"}';

但是这个还是会有问题,因为中文字符编码的原因,有时候 url 或者 referer 头里面可能会出现”\x”这样的跳脱字符,导致 JSON 解析失败,这个时候需要在 logstash 的 filter 里面再加上配置

filter {
  if [type] == "nginx-access-syslog" {
    mutate {
      gsub => [
        # replace '\x' with '\\x', or json parser will fail
        "message", "\\x", "\\\\x"
      ]
    }
  }
}

把”\x”替换为”\\x”。(这个方法不通用,只对”\x”做了处理,但一般应该也只有”\x”会出现了。。。)
然后我们可以用 kibana 画图了,以上收集的参数还算比较丰富了,可以做出很不错的 dashboard 了