designetwork

ネットワークを軸としたIT技術メモ

LogstashでFluentdのforest+copy同様に複数処理の設定をする

LogstashでFluentd(td-agent)のforestプラグインとcopyを組み合わせたものと同様の設定をしてみる。これにより、ログ種別、送信元が増えていっても出力設定を都度追加することなく、簡素化できる。

また、Logstashは日本語情報が少ないため、少しでも日本のユーザーとして普及に貢献したい。

期待する動作・Fluentdでの設定例

Fluentd(td-agent)でtag変数を元に、forestで処理する汎用的な設定をする。Fluentdでの設定イメージはこちらの通り。Chunk、Bufferなどの最適化は未実装。

ベース設定。個別の設定ファイルをincludeする。検証バージョンはtd-agent 0.12.31

/etc/td-agent/td-agent.conf

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

@include ./conf/*.conf

シンプルにローカルのログファイルを取り込む。ここで設定するtagをElasticsearchのindexなどに使用する。

/etc/td-agent/conf/local_messages.conf

<source>
  @type tail
  path /var/log/messages
  pos_file /var/log/messages.pos
  tag "sys.messages.#{Socket.gethostname}"
  format syslog
</source>

Elasticsearchへの送信設定。バックアップ・長期保存のためにファイルとしても保存する。forest+copyを使用することで、tagを変数として取り込んでindexやファイル名に使用できる。

/etc/td-agent/conf/elasticsearch.conf

<match *.*.**>
  type forest
  subtype copy
  <template>
    <store>
      @type elasticsearch
      host localhost
      port 9200
      logstash_format true
      logstash_prefix ${tag_parts[0]}.${tag_parts[1]}
      type_name ${tag_parts[0]}
      flush_interval 20
    </store>
    <store>
      @type file
      path /var/log/td-agent/${tag_parts[0]}/${tag_parts[1]}.log
      compress gzip
    </store>
  </template>
</match>

forestプラグインはこちら。

これにより、新規のログ種別が増えてもmatchディレクティブの中には追加の設定が不要になる。複数のログを複数のサーバからそれぞれ収集・集約したいときに効率が良い。

Logstashでの設定例

Logstashのバージョンは5.3.0で試験する。

$ /usr/share/logstash/bin/logstash --version
logstash 5.3.0

/etc/logstash/logstash.ymlpath.config: /etc/logstash/conf.dの設定がされていることを確認する。(デフォルトのため問題ないはず)

Logstashでのforest+copyは次のような設定になる。パーツごとに区切って解説するが、設定は/etc/logstash/conf.d/messages.confとして一つのファイルにまとめてよい。

inputでtagsを付与してFluentdと同様にtagで振り分ける。sourceディレクティブに相当する部分。%{host}環境変数を参照するため変更不要。なお、Fluentdに沿ってtagを使用したが、idtypeなど、他のフィールドを使用することもできる。

input {
  file {
    path => "/var/log/messages"
    tags => ["sys", "logstash_messages", "%{host}"]
    type => syslog
  }
}

filterで正規表現によるindex付け、日付の処理をする。FluentdだとSourceディレクティブ内のformatdate_formatに該当する部分。filter単体で動作するため、inputで取り込んだ複数のログに適用される。そのため、ifでフィルタ対象を限定する。

filter {
  if [type] == "syslog" {
    grok {
      match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" }
      add_field => [ "received_at", "%{@timestamp}" ]
      add_field => [ "received_from", "%{host}" ]
    }
    date {
      match => [ "syslog_timestamp", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
    }
  }
}

outputでelasticsearchとfileにそれぞれ出力する。Fluentdのmatchディレクティブに該当する。Logstashではcopy、forestといったプラグインを使用せず、シンプルにoutput内で複数出力、変数使用ができる。同一サーバでElasticsearchを動作させている場合のサンプルのため、環境に合わせてhostsを変更する。

なお、<match <tag1>.<tag2>.*>といった指定をしないため、出力形式を共通化する必要がある。

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "%{tags[0]}.%{tags[1]}-%{+YYYY.MM.dd}"
  }
  file {
    path => "/var/log/logstash/%{tags[0]}/%{tags[1]}.log"
  }
}

出力結果

tags変数が展開されindexとして使用されている。

$ curl http://localhost:9200/sys.logstash_messages-*
{"sys.logstash_messages-2017.04.09":{"aliases":{},"mappings":{"syslog":{"properties":{"@timestamp":{"type":"date"},"@version":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"host":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"message":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"path":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"received_at":{"type":"date"},"received_from":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"syslog_hostname":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"syslog_message":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"syslog_program":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"syslog_timestamp":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"tags":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"type":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}},"settings":{"index":{"creation_date":"1491720002393","number_of_shards":"5","number_of_replicas":"1","uuid":"AO_MMCiqQYqcNIIEG8XmQg","version":{"created":"5020299"},"provided_name":"sys.logstash_messages-2017.04.09"}}}}

ファイルアウトプットも同様、tags変数が展開され、tag情報に基づいてディレクトリ、ログファイルが作成された。

$ tree /var/log/logstash/
/var/log/logstash/
├── logstash-plain.log
└── sys
    └── logstash_messages.log

まとめ - LogstashでFluentdのforest+copy同様に複数処理の設定をする

LogstashでFluentdのforest+copy同様の設定をした。これにより、ログ種別、送信元が増えていっても出力設定を都度追加することなく、簡素化できる。