fluentd 遇到解析器错误时的行为。解析器死信队列
Behavior of fluentd when it gets parser error. Parser dead letter queue
最近我在尝试处理日志消息时在我的 fluentd 实例中收到警告消息。
配置是这样的
<label foo>
<filter foo.log>
@type record_transformer
# Remove all fields other than labels and prettified logs
renew_record
keep_keys level, severity, name, actor, environment, deployment, cluster, hostname, ec2_instance_id, az, log_agent, formatted
enable_ruby
<record>
formatted "[ $${record['level']} ] [$${ record.key?('timestamp')? ' timestamp='+record['timestamp'] : '' }$${ record.key?('request_id')? ' request_id='+record['request_id'].to_s : '' }$${ record.key?('actor_id')? ' actor_id='+record['actor_id'].to_s : '' } ] ($${ record.key?('file')? ' file='+record['file'] : '' }$${ record.key?('module')? ' module='+record['module'] : '' }$${ record.key?('function')? ' function='+record['function'] : '' }$${ record.key?('line')? ' line='+record['line'].to_s : '' } )\n$${ record.key?('message')? ''+record['message'] : '' }"
</record>
</filter>
<match ${environment}-backend-v2.log>
...
</match>
</label>
我收到很多这样的警告信息:
2020-10-01 10:37:27 +0000 [warn]: #0 dump an error event: error_class=RuntimeError error="failed to expand `%Q[[ \#{record['level']} ] [\#{ record.key?('timestamp')? ' timestamp='+record['timestamp'] : '' }\#{ record.key?('request_id')? ' request_id='+record['request_id']
: '' }\#{ record.key?('actor_id')? ' actor_id='+record['actor_id'] : '' } ] (\#{ record.key?('file')? ' file='+record['file'] : '' }\#{ record.key?('module')? ' module='+record['module'] : '' }\#{ record.key?('function')? ' function='+record['function'] :
'' }\#{ record.key?('line')? ' line='+record['line'].to_s : '' } )\n\#{ record.key?('message')? ''+record['message'] : '' }]` : error = no implicit conversion of Integer into String" location="/opt/bitnami/fluentd/gems/fluentd-1.10.4/lib/fluent/plugin/filter_record_transformer.rb:310:in
`rescue in expand'" tag="prd-backend-v2.log" time=2020-10-01 10:37:27.050929974 +0000 record=balbasasasdasd
我有两个问题:
- 如果没有修复解析器逻辑,这个解析器失败的具体行为是什么? fluentd 会丢弃消息吗?
- 我们能否处理这个解析器 error/exception 不顾一切地处理消息,例如将它发送到不同的上游(死信通道)?
最好的,
阿贡
除非您已设置 emit_invalid_record_to_error
,否则此事件将被删除。死信频道可作为 @ERROR
标签使用:https://docs.fluentd.org/filter/parser#emit_invalid_record_to_error
此外,还有多种技巧可以使解析更加健壮:
- 对于multi-format解析,如json日志与明文日志混合,使用
multi-format-parser
插件https://github.com/repeatedly/fluent-plugin-multi-format-parser#for-v10。它将尝试列表中的所有格式,最后一个 format none
是一个指令,用于保留未解析的消息,原样。我在错误跟踪中注意到 record=balbasasasdasd
,您可能希望按原样保留此类消息。
- 对于记录转换器,您可以使用 ruby 运算符来强化它:
formatted ${record['main-field'] || record['backup-field'] || record}
等等。
最近我在尝试处理日志消息时在我的 fluentd 实例中收到警告消息。
配置是这样的
<label foo>
<filter foo.log>
@type record_transformer
# Remove all fields other than labels and prettified logs
renew_record
keep_keys level, severity, name, actor, environment, deployment, cluster, hostname, ec2_instance_id, az, log_agent, formatted
enable_ruby
<record>
formatted "[ $${record['level']} ] [$${ record.key?('timestamp')? ' timestamp='+record['timestamp'] : '' }$${ record.key?('request_id')? ' request_id='+record['request_id'].to_s : '' }$${ record.key?('actor_id')? ' actor_id='+record['actor_id'].to_s : '' } ] ($${ record.key?('file')? ' file='+record['file'] : '' }$${ record.key?('module')? ' module='+record['module'] : '' }$${ record.key?('function')? ' function='+record['function'] : '' }$${ record.key?('line')? ' line='+record['line'].to_s : '' } )\n$${ record.key?('message')? ''+record['message'] : '' }"
</record>
</filter>
<match ${environment}-backend-v2.log>
...
</match>
</label>
我收到很多这样的警告信息:
2020-10-01 10:37:27 +0000 [warn]: #0 dump an error event: error_class=RuntimeError error="failed to expand `%Q[[ \#{record['level']} ] [\#{ record.key?('timestamp')? ' timestamp='+record['timestamp'] : '' }\#{ record.key?('request_id')? ' request_id='+record['request_id']
: '' }\#{ record.key?('actor_id')? ' actor_id='+record['actor_id'] : '' } ] (\#{ record.key?('file')? ' file='+record['file'] : '' }\#{ record.key?('module')? ' module='+record['module'] : '' }\#{ record.key?('function')? ' function='+record['function'] :
'' }\#{ record.key?('line')? ' line='+record['line'].to_s : '' } )\n\#{ record.key?('message')? ''+record['message'] : '' }]` : error = no implicit conversion of Integer into String" location="/opt/bitnami/fluentd/gems/fluentd-1.10.4/lib/fluent/plugin/filter_record_transformer.rb:310:in
`rescue in expand'" tag="prd-backend-v2.log" time=2020-10-01 10:37:27.050929974 +0000 record=balbasasasdasd
我有两个问题:
- 如果没有修复解析器逻辑,这个解析器失败的具体行为是什么? fluentd 会丢弃消息吗?
- 我们能否处理这个解析器 error/exception 不顾一切地处理消息,例如将它发送到不同的上游(死信通道)?
最好的, 阿贡
除非您已设置 emit_invalid_record_to_error
,否则此事件将被删除。死信频道可作为 @ERROR
标签使用:https://docs.fluentd.org/filter/parser#emit_invalid_record_to_error
此外,还有多种技巧可以使解析更加健壮:
- 对于multi-format解析,如json日志与明文日志混合,使用
multi-format-parser
插件https://github.com/repeatedly/fluent-plugin-multi-format-parser#for-v10。它将尝试列表中的所有格式,最后一个format none
是一个指令,用于保留未解析的消息,原样。我在错误跟踪中注意到record=balbasasasdasd
,您可能希望按原样保留此类消息。 - 对于记录转换器,您可以使用 ruby 运算符来强化它:
等等。formatted ${record['main-field'] || record['backup-field'] || record}