首页 > 解决方案 > 从标准输出读取 JSON 和纯文本

问题描述

我有这个fluentd过滤器:

<filter **>
  @type parser
  @log_level trace
  format json
  key_name log
  hash_value_field fields
</filter>

我正在写一些 JSON stdout,一切都按预期工作。

但是,当我还编写一些普通的非 JSON 文本Debugger listening on ws://0.0.0.0:9229/459316ca-5ec5-43e4-ae5d-d4651eca2c9e时,例如stdout(或stderr),我得到了这个错误:

fluent/log.rb:342:warn: dump an error event: 
error_class=Fluent::Plugin::Parser::ParserError 
error="pattern not match with data 
'Debugger listening on ws://0.0.0.0:9229/459316ca-5ec5-43e4-ae5d-d4651eca2c9e'"

fluentd有没有办法在不出错的情况下解析和转发两者?

甚至可以将纯文本包装在JSON像这样的字符串中{ message: "Debugger listening on ws://0.0.0.0:9229/459316ca-5ec5-43e4-ae5d-d4651eca2c9e" }吗?

根据@Imran 的回答进行更新

这是我的docker.compose.yml

version: "2"

services:

  fluentd:
     build: ../fluentd
     command: /bin/sh -c "/fluentd/config.sh && fluentd -c /fluentd/etc/fluent.conf -v"
     ports:
      - "24224:24224"
     environment: 
      - AWS_REGION
      - AWS_ACCESS_KEY_ID
      - AWS_SECRET_ACCESS_KEY
  service:
    build:
      context: ../service
      args:
        - NPM_TOKEN
    command:  node --inspect=0.0.0.0 index.js
    ports:
       - "3000:80"
    volumes :
      - ../service/:/app
    logging:
      driver: fluentd
      options:
        fluentd-address: localhost:24224
        tag: 'docker.{{.ImageName}}.{{.Name}}.{{.ID}}'

这是我的更新fluent.conf

<source>
  @type forward
  port 24224
</source>

# JSON-Parse
<filter docker.**>
  @type parser
  @log_level trace
  format json
  key_name log
  hash_value_field fields
</filter>

<label @ERROR>
  <match docker.**>
    @type stdout
  </match>
</label>

<match docker.**>
  @type stdout
  @include cw.conf
</match>

这是我的cw.conf

@type cloudwatch_logs
log_group_name dev-logs
log_stream_name dev
auto_create_stream true

将 JSON 写入创建的日志stdout已正确推送到 CloudWatch,但@ERROR条目未推送到 CloudWatch。

但他们现在已正确记录stdout

2019-08-22 19:25:53.000000000 +0000 docker.integration_service.integration_service_1.2db3cc97a71a: {"container_name":"/integration_service_1","source":"stderr","log":"Debugger listening on ws://0.0.0.0:9229/94a655a4-1bbb-49
3e-abcc-f2637c39583d","container_id":"2db3cc97a71aa27c957fa13e29ac4c1c9f8a616c8c2989dcf72ea8f9b666d513"}

我现在如何将它们推送到 CloudWatch?

标签: fluentd

解决方案


我认为这是可能的。默认情况下,所有不匹配的记录都会发送到@ERROR标签。

这样做是因为emit_invalid_record_to_errorflag 设置为 true。

无效的情况是

  1. 密钥不存在
  2. 格式不匹配
  3. 意外的错误

您可以在 @ERROR 标签中挽救意外的格式日志。如果您想忽略这些错误,请设置false.

更多文档在这里。 https://docs.fluentd.org/filter/parser#emit_invalid_record_to_error

在您的情况下,您要捕获格式不匹配的记录。一个示例方式如下所示。

<filter myTag>
  @type parser
  @log_level trace
  key_name log
  hash_value_field fields
</filter>

<label @ERROR>
  <match myTag>
    @type stdout
  </match>
</label>

上面matchlabelinside 以您想要的格式将 JSON 中的数据发送到 STDOUT。

{ 消息:“调试器正在监听 ws://0.0.0.0:9229/459316ca-5ec5-43e4-ae5d-d4651eca2c9e”}

试着让我知道。

重要提示-@ERROR捕获大量内部流式错误和警告,因此为了仅捕获格式不匹配的错误,我特别提供了filter myTagmatch myTag这确保我的过滤器和匹配过程仅处理我的标签记录和错误。我看到您正在使用filter **which 对所有记录执行过滤,所以我想说最好的做法是为等提供正确tagmatchfilter


推荐阅读