【问题标题】:Read JSON and plain text from stdout从标准输出读取 JSON 和纯文本
【发布时间】:2019-08-20 03:03:34
【问题描述】:

我有这个fluentd 过滤器:

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

我正在向stdout 写入一些 JSON,一切正常。

但是,当我还在编写一些普通的非 JSON 文本时,例如 Debugger listening on ws://0.0.0.0:9229/459316ca-5ec5-43e4-ae5d-d4651eca2c9estdout(或 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


    【解决方案1】:

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

    之所以这样做,是因为 emit_invalid_record_to_error 标志设置为 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>
    

    label 内的match 以上将 JSON 中的数据以您想要的格式发送到 STDOUT。

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

    试着让我知道。

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

    【讨论】:

    • 谢谢,我试过了,但看起来我仍然缺少一些东西。我更新了问题。
    • @AlexanderZeitler 我看到过滤器下的标签(&lt;filter docker.**&gt;)与标签下的匹配(&lt;match docker.** *&gt;)之间存在差异。这只是一个错字吗?你能让它们同步并再试一次吗?。
    • 现在我只是将流式事件导入 CloudWatch,不再从服务容器中输出。
    • @AlexanderZeitler 奇怪。当我在上面仅使用@stdout 进行测试时,它适用于不匹配的记录。我对你在同一场比赛中同时使用@stdout@include 有点困惑。有可能吗,你可以只保留@include 吗?此外,由于match **,您的最终匹配正在捕获所有事件,也许您想修改以仅匹配您的标记事件。
    • &lt;label @ERROR&gt; 部分中将@type stdout 替换为@include cw.conf 时,它可以工作。但现在我有 fields.message 用于 JSON 和 log 用于纯文本。我可以同时获得fields.message 吗?
    【解决方案2】:

    您可以使用可以解析不同格式的multi-format parser plugin。这样你可以指定format jsonformat none等多个模式,所有日志都转发到同一个目的地,所以你不必担心通过@ERROR处理一些日志。

    【讨论】:

    • 谢谢,去看看。
    猜你喜欢
    • 2019-09-01
    • 1970-01-01
    • 2013-02-24
    • 2016-12-30
    • 2016-03-14
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多