ククログ

株式会社クリアコード > ククログ > LogstashとFluentdの連携方法

LogstashとFluentdの連携方法

はじめに

LogstashFluentdはどちらもログ収集を行うソフトウェアです。 この二つのソフトウェアの内部で扱われているデータのエンコード方法が異なるため、どちらかでデータ形式の変換を行わないといけません。 この記事はLogstashとFluentdの連携方法のうち、Logstash側で変換を行い、連携する方法を解説します。

Logstashのプラグイン

LogstashもFluentdと同じくプラグイン機構を持っています。

  • input

  • output

  • filter

  • codec

の4種のプラグインが作成できるようになっています。

実際に接続する

Fluentd から Logstashへ

FluentdのforwardプロトコルはHALOやHANDSHAKEを省略することもできるTCPの上に乗っているプロトコルです。 そのため、TCPで待ち受けることができます。この時に、msgpackをデコードできる必要があります。

下図では、Fluentdの out_forward プラグインからLogstashのinputプラグインの一つのtcpプラグインで受け取り、 codecプラグインのlogstash-codec-fluentプラグインにより、Forwardプロトコルで規定されたmsgpackをデコードします。

+---------------------+                             +----------------------+
|                     |                             |                      |
|                     |out_forward             input/tcp + fluent codec    |
|     Fluentd         +----------------------------->       Logstash       |
|                     |         tcp/24224           |                      |
|                     |                             |                      |
+---------------------+                             +----------------------+

この時、FluentdとLogstashの設定ファイルはそれぞれ次のようになります。

fluent-out.conf
<source>
  @type dummy
  @id dummy_input
  tag my.logs
</source>

<match my.logs>
  @type forward
  time_as_integer true
  <server>
    host localhost
  </server>
  <buffer>
    flush_interval 1s
  </buffer>
</match>

この時、 time_as_integer true の設定をしていることに注意してください。 これは、logstash-code-fluentのissueにしてありますが、 Fluentdがmsgpackのエンコードで使用している EventTime 拡張が扱えないことによるものです。

logstash-in.conf
input {
  tcp {
    codec => fluent
    port => 24224
  }
}
output {
  stdout { codec => json }
}

実際に接続する

実際に接続するには、それぞれ別の端末から設定ファイルを読み込んで実行するようにします。

$ logstash -f logstash-in.conf
$ bundle exec fluentd -c fluent-out.conf

logstash側のターミナルで

[2018-01-24T10:52:15,914][INFO ][logstash.pipeline        ] Pipeline started {"pipeline.id"=>"main"}
[2018-01-24T10:52:16,009][INFO ][logstash.agent           ] Pipelines running {:count=>1, :pipelines=>["main"]}
<snip>
{"message":"dummy","tags":["my.logs"],"@timestamp":"2018-01-24T01:54:08.000Z","host":"localhost","@version":"1","@metdata":{"ip_address":"0:0:0:0:0:0:0:1"},"port":55571}

の表示が出たら成功です。

Logstash から Fluentd へ
+---------------------+                             +----------------------+
|                     |                             |                      |
|                     |output/tcp            in_forward                    |
|     Logstash        +----------------------------->       Fluentd        |
|                     |         tcp/24224           |                      |
|                     |                             |                      |
+---------------------+                             +----------------------+

この時、FluentdとLogstashの設定ファイルはそれぞれ次のようになります。

fluent-in.conf
<source>
  @type forward
</source>

<match log>
  @type stdout
</match>
logstash-out.conf
input {
    generator {
    lines => [
      "line 1",
      "line 2",
      "line 3"
    ]
    count => 3 
  }
}
output {
  tcp {
    codec => fluent
    host => localhost
    port => 24224
  }
}

ここで、Logstash側ではtagの指定をしていないことに注意してください。 現在執筆しているときにリリースされているlogstash-codec-fluent v3.1.5ではユーザー定義のタグを使用するとFluentd側に受け渡せないバグがあります。 このバグについても開発元に報告しました。

実際に接続する

実際に接続するには、それぞれ別の端末から設定ファイルを読み込んで実行するようにします。

$ bundle exec fluentd -c fluent-in.conf
$ logstash -f logstash-out.conf

Fluentd側のターミナルで

2018-01-24 12:21:53.000000000 +0900 log: {"message":"line 3","@timestamp":"2018-01-24T03:21:53.008Z","host":"<hostname>.local","@version":"1","sequence":2}
2018-01-24 12:21:53.000000000 +0900 log: {"message":"line 2","@timestamp":"2018-01-24T03:21:53.006Z","host":"<hostname>.local","@version":"1","sequence":0}
2018-01-24 12:21:53.000000000 +0900 log: {"message":"line 1","@timestamp":"2018-01-24T03:21:53.007Z","host":"<hostname>.local","@version":"1","sequence":1}
2018-01-24 12:21:53.000000000 +0900 log: {"message":"line 3","@timestamp":"2018-01-24T03:21:53.007Z","host":"<hostname>.local","@version":"1","sequence":1}
2018-01-24 12:21:52.000000000 +0900 log: {"message":"line 1","@timestamp":"2018-01-24T03:21:52.980Z","host":"<hostname>.local","@version":"1","sequence":0}
2018-01-24 12:21:53.000000000 +0900 log: {"message":"line 2","@timestamp":"2018-01-24T03:21:53.007Z","host":"<hostname>.local","@version":"1","sequence":1}
2018-01-24 12:21:53.000000000 +0900 log: {"message":"line 2","@timestamp":"2018-01-24T03:21:53.008Z","host":"<hostname>.local","@version":"1","sequence":2}
2018-01-24 12:21:53.000000000 +0900 log: {"message":"line 3","@timestamp":"2018-01-24T03:21:53.007Z","host":"<hostname>.local","@version":"1","sequence":0}
2018-01-24 12:21:53.000000000 +0900 log: {"message":"line 1","@timestamp":"2018-01-24T03:21:53.007Z","host":"<hostname>.local","@version":"1","sequence":2}

の表示が出たら成功です。

まとめ

FluentとLogstashを連携してデータのやり取りをする方法を解説しました。 LogstashのプラグインはFluentdとは異なる種類のものが開発が活発であり、CPUやメモリ使用量の傾向が異なります。 Logstashにしかない機能を使いたいけれども柔軟に設定が可能なFluentdも引き続き使用したい時には、 この記事のようにLogstashからFluentdへのデータを受け渡す方法を試してみてはいかがでしょうか。