记一次Nginx格式问题导致的Logstash解析失败

  今天22点下班到家,还没进门就收到短信告警,一台Logstash磁盘占用量超过了90%,这挺奇怪的,5年多了从来没有Logstash的磁盘告警。

  赶紧发完版,琢磨了一下这台logstash服务器,一台普通的、用于收集nginx日志的服务器。
  分析一下文件系统,发现是logstash的运行日志满了,打开一看,充斥着这样的记录:

[2024-07-24T23:18:08,695][WARN ][logstash.filters.json    ][main][bcdfb34f2fa4b1a3031d77b9d92cd7465a03438a14c6513f2c87d0a46c305ee7] Error parsing json ... , :exception=>#<LogStash::Json::ParserError: Unrecognized character escape 'x' (code 120)
 at [Source: (byte[])"{"@timestamp":"2024-07-24T23:18:07+08:00","request_method":"POST","scheme":"http" ... ,"referer":"https://servicewechat.com/wx18be1e8f5f465ed2/196/page-frame.html","request":"/xxxxxx/xxxx/qrqm/api/personalized%E2%80%94task/compute","uri":"/xxxxxx/xxxx/qrqm/api/personalized\xE2\x80\x94task/compute","args":"-","size":628,"status": 200,"responsetime":0.195,"upstreamtime":"[truncated 397 bytes]; line: 1, column: 405]>}

  看起来是unicode转义的问题, 应该为\u0000这种格式,而不是\xE2、\x80这样的格式。
  用了url编译工具查看一下是什么接口这么奇葩,于是得到了:

  好家伙!域名里面还带中文破折号的,看来真的不能把研发想的太简单。
  既然不能指望别人,那就自己解决吧,查询了一下Nginx的官方文档,在:

Nginx官网,有明确说明,支持使用escape=json强制解析,照搬就好了。

log_format main escape=json 
             '{"@timestamp":"$time_iso8601",'
             '"@source":"$server_addr",'
             '"hostname":"$hostname",'
             '"ip":"$http_Cdn_Src_Ip",'
             '"client":"$remote_addr",'
             '"request_method":"$request_method",'
             '"scheme":"$scheme",'
             '"domain":"$server_name",'
             '"referer":"$http_referer",'
             '"request":"$request_uri",'
             '"uri":"$uri",'
             '"args":"$args",'
             '"size":$body_bytes_sent,'
             '"status": $status,'
             '"responsetime":$request_time,'
             '"upstreamtime":"$upstream_response_time",'
             '"upstreamaddr":"$upstream_addr",'
             '"http_user_agent":"$http_user_agent",'
             '"https":"$https"'
             '}';

自此问题暂时结束,没有发现新的解析报错了,以待观察。