【问题标题】:How to generate a JSON log from nginx?如何从 nginx 生成 JSON 日志?
【发布时间】:2014-09-22 20:28:30
【问题描述】:

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

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

我知道 2011 年 10 月和 2008 年 5 月的 nginx 更改日志条目说:

*) 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.

但这仍然无济于事,因为\xXXinvalid in a JSON string

我还查看了具有 set_quote_json_str 指令的 the HttpSetMiscModule 模块,但这似乎只是在没有帮助的字符串周围添加了 \x22

对于其他从 nginx 以 JSON 格式登录的解决方案有什么想法吗?

【问题讨论】:

  • 您帖子中的链接给了我 HTTP/500 ... 因为它不是 nginx 的核心功能,我假设您是使用第 3 方模块自己从源代码构建的。如果是这种情况,您可以简单地编辑代码并将 \xXX 更改为 \uNNNN,如下所示:github.com/kayrus/nginx/blob/…
  • 您可以查看此链接:blog.logentries.com/2014/08/…,它可能对您有所帮助。

标签: json logging nginx


【解决方案1】:

最后看起来我们有一个很好的方法来使用没有任何模块的 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"'
  '}';

注意 escape=json 是在 nginx 1.11.8 中添加的。 http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format

【讨论】:

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

您可以尝试使用https://github.com/jiaz/nginx-http-json-log - Nginx 的附加模块。

【讨论】:

    【解决方案3】:

    你可以尝试使用:

    PS: The if parameter (1.7.0) enables conditional logging。如果条件评估为“0”或空字符串,则不会记录请求:

    map $status $http_referer{
        ~\xXX  0;
        default 1;
    }
    
    access_log /path/to/access.log combined if=$http_referer;
    

    使用诸如https://github.com/zaach/jsonlint 之类的工具来检查您的 JSON 数据是个好主意。您可以测试新日志格式的输出并确保它是真实且正确的 JSON。

    【讨论】:

      猜你喜欢
      • 2022-12-18
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多