NGINX 日志在 Stackdriver 中没有 jsonPayload 字段

NGINX Logs have no jsonPayload field in Stackdriver

我有一个基本的 nginx 部署在 GKE 集群上提供静态内容 运行ning。我已经按照说明 here (I enabled logging for an existing cluster), and I also enabled the Stackdriver Kubernetes Monitoring feature explained here 为集群配置了 Stackdriver Logging。日志记录本身似乎工作正常,因为我可以在 Stackdriver 中看到来自 nginx 的日志。

我正在尝试创建一些基于日志的指标,例如已完成的 2xx 请求的数量,但我在 Stackdriver 的日志条目中得到的只是 textPayload 字段。据我了解,在集群上启用 Stackdriver Monitoring 会启动一些 Fluentd 代理(如果我 运行 kubectl get pods -n kube-system 我可以看到),并且它们应该默认启用 nginx 日志解析器(根据文档here)。但是,Stackdriver 中显示的 none 日志条目具有结构化日志应存在的 jsonPayload 字段。

我正在为 nginx 使用默认的 log_format 配置,并且我已经验证默认的 nginx 解析器能够解析我的应用程序正在写入的日志(我复制了 default Fluentd nginx parser plugin regular expression and a log entry from my application to this tool 和它能够解析条目)

我确定我一定遗漏了什么,但我不知道是什么。

编辑:

作为参考,这是我的 NGINX 日志格式:

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

到目前为止我已经尝试了以下方法:

到目前为止,none个已经解决了。

你是 运行 Kubernetes 1.11.4 吗?这是 Beta release 1.11.4. The fix is available in Beta Update (Kubernetes 1.11.6) 的一个已知问题。 请确认您的版本。

在与 Google 云支持联系后,我们能够设计出解决此问题的方法,但根本原因仍然未知。

解决方法是将 NGINX 日志格式本身定义为 JSON 字符串。这将允许 Google-Fluentd 解析器将有效负载正确解析为 JSON 对象。这是迄今为止唯一对我有用的解决方案。

供参考,我使用的日志格式是:

log_format json_combined escape=json
'{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request_method":"$request_method",'
'"request":"$request",'
'"status": "$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"http_referrer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.log json_combined;

我们正在以 Cloud Logging 可以直接理解的方式格式化日志,如下所示:

        log_format json_combined escape=json
          '{'
            '"httpRequest":{'
              '"requestMethod":"$request_method",'
              '"requestUrl":"$scheme://$host$request_uri",'
              '"requestSize":$request_length,'
              '"status":$status,'
              '"responseSize":$bytes_sent,'
              '"userAgent":"$http_user_agent",'
              '"remoteIp":"$remote_addr",'
              '"referer":"$http_referer",'
              '"latency":"${request_time}s",'
              '"protocol":"$server_protocol",'
              '"request":"$request",'
              '"remoteUser":"$remote_user"'
            '}'
          '}';

这样你就不需要使用 fluentd。在这里你可以找到参考:https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#HttpRequest