Fluentd输出插件:out_elasticsearch用法详解
“ 把日志输出到elasticsearch做业务分析,这大概是最普遍的日志采集用途了”

$ fluent-gem install fluent-plugin-elasticsearch<match my.logs> @type elasticsearch host localhost port 9200 logstash_format true</match>@type
插件类型,取值为 elasticsearch
host
elasticsearch 节点主机名,缺省为 localhost
port
elasticsearch 节点的端口号,缺省为 9200
hosts
节点列表。可使用如下配置指定多个 elasticsearch 节点:
hosts host1:port1,host2:port2,host3:port3# orhosts https://customhost.com:443/path,https://username:password@host-failover.com:443使用 hosts 配置后,上边的 host 和 port 将不再生效。
user, password
登录 elasticsearch 的用户名和密码,缺省为 nil
user fluentpassword mysecretschema
使用 http 还是 https,缺省为 http
index_name
将日志写入 elasticsearch 中的索引名称,缺省为 fluentd。
此参数支持使用占位符。
比如,你可以通过以下配置来将日志按照 tag 写入不同的索引中:
index_name fluentd.${tag}一个更加实用的 index_name 值为 tag 和 时间戳的组合:
index_name fluentd.${tag}.%Y%m%d由于上边这个配置使用了时间占位符,我们需要在 chunk_keys 中同时设置 tag 和 time,并且需要指定 timekey 参数:
<buffer tag, time>timekey 1h # chunks per hours ("3600" also available)</buffer>logstash_format
是否使用常规的 index 命名格式(logstash-%Y.%m.%d)。
缺省为 false,不使用。
此选项可取代 index_name 选项。
logstash_prefix
当 logstash_format 为 true 时,设置索引的前缀,缺省为 logstash
user %{demo+}password %{@secret}hosts https://%{j+hn}:%{passw@rd}@host1:443/elastic/,http://host2user demo+password @secret无法向 elasticsearch 发送日志事件
常见的失败原因为 out_elasticsearch 插件和 elasticsearch 实例版本不兼容。
比如,当前的 td-agent 绑定的是 6.x 系列的 elasticsearch-ruby 库,这意味着你的 elasticsearch 服务器的版本也应该是 6.x 。
可通过以下命令查看你使用的客户端库的版本:
# For td-agent users$ /usr/sbin/td-agent-gem list elasticsearch# For standalone Fluentd users$ fluent-gem list elasticsearch如果你使用的 out_elasticsearch 版本为 v2.11.7 或者更高,可在配置文件中指定是否要检查版本兼容性:
validate_client_version true如果版本不兼容,你会看到如下报错:
Detected ES 5 but you use ES client 6.1.0.Please consider to use 5.x series ES client.无法看到详细的失败日志
这可能是由于插件和 elasticsearch 服务器使用的 ssl 协议版本不兼容导致的。
由于历史原因,out_elasticsearch 配置的 ssl_version 是 TLSv1,而现代 elasticsearch 生态要求 TLSv1.2或更高版本。
这种情况下,out_elasticsearch 会隐藏传输阶段的失败日志。
可通过以下配置开启传输日志:
with_transporter_log true@log_level debug这样,你就会看到如下的失败日志:
2018-10-24 10:00:00 +0900 [error]: #0 [Faraday::ConnectionFailed] SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol (OpenSSL::SSL::SSLError) {:host=>"elasticsearch-host", :port=>80, :scheme=>"https", :user=>"elastic", :password=>"changeme", :protocol=>"https"}
这种情况也会发生在使用了反向代理的场景中。
比如,你的 elasticsearch 服务器位于 nginx 之后,而现代 nginx 也要求使用 TLSv1.2 及之后的 ssl 协议。
为何非法日志总是被无限重复处理?
有时候你可能会使用如下配置:
<match **>@type elasticsearchhost localhostport 9200type_name fluentdlogstash_format truetime_key @timestampinclude_timestamp truereconnect_on_error truereload_on_failure truereload_connections falserequest_timeout 120s</match>这种配置使用了泛型匹配(**),并且没有使用 @label 标签。这通常是一种有问题的配置。
fluentd 处理日志出错时,错误日志会被发送到 @ERROR 标注的配置段中进行处理,并且会打上 fluent.* 标签。
如果使用泛型匹配,则错误日志会被重新提交到 out_elasticsearch 插件的处理流程中,不断重复,造成洪泛现象。
这种情况下,你会看到如下的报错信息:
2018-11-13 11:16:27 +0000 [warn]: #0 dump an error event: error_class=Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchError error="400 - Rejected by Elasticsearch" location=nil tag="app.fluentcat" time=2018-11-13 11:16:17.492985640 +0000 record={"message"=>"\xFF\xAD"}2018-11-13 11:16:38 +0000 [warn]: #0 dump an error event: error_class=Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchError error="400 - Rejected by Elasticsearch" location=nil tag="fluent.warn" time=2018-11-13 11:16:27.978851140 +0000 record={"error"=>"#<Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchError: 400 - Rejected by Elasticsearch>", "location"=>nil, "tag"=>"app.fluentcat", "time"=>2018-11-13 11:16:17.492985640 +0000, "record"=>{"message"=>"\xFF\xAD"}, "message"=>"dump an error event: error_class=Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchError error=\"400 - Rejected by Elasticsearch\" location=nil tag=\"app.fluentcat\" time=2018-11-13 11:16:17.492985640 +0000 record={\"message\"=>\"\\xFF\\xAD\"}"}我们可以通过以下两种方法解决这个问题:
1,使用更加细化的 tag 进行事件路由
<match out.elasticsearch.**>@type elasticsearchhost localhostport 9200type_name fluentdlogstash_format truetime_key @timestampinclude_timestamp truereconnect_on_error truereload_on_failure truereload_connections falserequest_timeout 120s</match>2,使用 @label 进行事件路由
<source>@type forward@label @ES</source><label @ES><match out.elasticsearch.**>@type elasticsearchhost localhostport 9200type_name fluentdlogstash_format truetime_key @timestampinclude_timestamp truereconnect_on_error truereload_on_failure truereload_connections falserequest_timeout 120s</match></label><label @ERROR><match **>@type stdout</match></label>
out_elasticsearch 插件支持很多配置参数,本文只是介绍了其中几个。
