如何从nginx生成JSON日志?

Jul*_*éon 50 logging json nginx

我正在尝试从nginx生成JSON日志.

我知道像这样的解决方案,但我想记录的一些字段包括用户生成的输入(如HTTP标头),需要正确转义.

我知道2011年10月和2008年5月的nginx changelog条目说:

*) Change: now the 0x7F-0x1F characters are escaped as \xXX in an
   access_log.
*) Change: now the 0x00-0x1F, '"' and '\' characters are escaped as \xXX
   in an access_log.
Run Code Online (Sandbox Code Playgroud)

但是这仍然没有帮助,因为\xXX在一个JSON字符串无效.

我还查看具有set_quote_json_str指令的HttpSetMiscModule模块,但这似乎只是添加\x22了无效的字符串.

是否有其他解决方案可以从nginx登录JSON格式?

pva*_*pva 97

最后看起来我们有很好的方法可以在没有任何模块的情况下使用vanilla nginx.只需定义:

log_format json_combined escape=json
  '{'
    '"time_local":"$time_local",'
    '"remote_addr":"$remote_addr",'
    '"remote_user":"$remote_user",'
    '"request":"$request",'
    '"status": "$status",'
    '"body_bytes_sent":"$body_bytes_sent",'
    '"request_time":"$request_time",'
    '"http_referrer":"$http_referer",'
    '"http_user_agent":"$http_user_agent"'
  '}';
Run Code Online (Sandbox Code Playgroud)

请注意,在nginx 1.11.8中添加了escape = json. http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format

  • 为了回答我自己的问题,您不想在 JSON 输出中留下裸变量。如果未设置该变量,它将被替换为空字符串,这可能会产生无效的 JSON。在所有数字前加零前缀的明显解决方案是有风险的,因为 JSON 规范官方不允许数字加零前缀(可能是为了避免与八进制/基数 8 数字的常见表示形式混淆)。最好将所有变量用引号引起来,然后解析下游的数字。 (4认同)
  • 我只想补充一点,你需要在access_log定义中指定log_format,例如access_log log_path json_combined; .此外,它不适用于error_log,太糟糕了. (2认同)
  • 也许您还应该注意数据的类型。像 `'"body_bytes_sent": $body_bytes_sent,'` 而不是 `'"body_bytes_sent":"$body_bytes_sent",'` (2认同)

ctr*_*lok 7

您可以尝试使用那个https://github.com/jiaz/nginx-http-json-log - 添加模块用于Nginx.