LoginSignup
2
5

More than 5 years have passed since last update.

Fluentdのtagに動的な日付と時間を付与する

Last updated at Posted at 2017-01-09

概要

Norikra -> Fluentd -> Couchbase
という構成でNorikraで集計した結果をCouchbaseに入れてます。

システムの都合上、CouchbaseのBucket名に動的に日付と時間をbucketname_yyyymmddhhの形式で付与する必要がありました。

その実装方法メモ。

システム環境

  • OS: CentOS release 6.8 (Final)
  • Norikra: norikra (1.0.4 java)
  • rbenv(Norikra): jruby-1.7.26
  • td-agent: 2.3.4-0.el6
  • Couchbase: 4.0.0-4051 Community Edition (build-4051)

fluent-plugin

  • fluent-plugin-couchbase (0.0.2)
  • fluent-plugin-forest (0.3.3)
  • fluent-plugin-norikra (0.4.2)
  • fluent-plugin-record-reformer (0.8.2)

実装方法

まずは最終的に選択した実装方法を記載します。
こうなりました。

/etc/td-agent/td-agent.conf
<source>
  type    norikra
  norikra localhost:26571
  <fetch>
    method     event
    target     target_query
    tag        query_name
    tag_prefix norikra.query
    interval 3m
  </fetch>
</source>

<match norikra.query.*>
  type record_reformer
  tag #{Time.now.strftime('%Y%m%d%H')}.${tag}
</match>

<match *.norikra.query.*>
  type forest
  subtype couchbase
  <template>
    hostname couchbase.example.com
    port 8091
    pool default
    bucket bucketname_${tag_parts[0]}
    ttl 0
    include_ttl false
  </template>
</match>

解説

要件的なところ

  • Norikraからfetchした当該時間帯の日付と時間がsuffixとしてついたCouchbaseのBucketに集計結果を入れたい。
  • 動的な日付と時間の生成はFluentdで完結させたい(ログの送信元であるアプリケーション側で生成してtag指定で送るとかはやりたくない)。

ポイントざっくり

confを見ればわかると思いますが、ポイントは以下2点です。

  • record_reformerのtagにrubyのコードを埋め込んで動的にyyyymmddhhを生成して先頭につける。
  • out_couchbaseforestをかぶせてtag_partsを使えるようにする。

細かいところ

ダブルクォーテーションにご注意

record_reformerのtagの値をダブルクォーテーションで囲むとFluentd起動時の日付と時間で固定されてしまうので今回の場合はNGです。

OK

ログを処理するたびに当該時間帯のyyyymmddhhが付与されます。

#{Time.now.strftime('%Y%m%d%H')}.${tag}

NG

Fluentd起動時のyyyymmddhhで固定されます。

"#{Time.now.strftime('%Y%m%d%H')}.${tag}"

record_reformerを挟む理由

confを見てわざわざin_norikraout_couchbaseの間にrecord_reformerを挟む必要はないのでは?と思う方もいらっしゃるかもしれません。

私も最初はこう書きました。

<match norikra.query.*>
  type couchbase
  hostname couchbase.example.com
  port 8091
  pool default
  bucket bucketname_#{Time.now.strftime('%Y%m%d%H')}
  ttl 0
  include_ttl false
</match>

でもこれだとFluentdの起動時にエラーになってしまいます。

/var/log/td-agent/td-agent.log
(省略)
  <match norikra.query.*>
    type couchbase
    hostname couchbase.example.com
    port 8091
    pool default
    bucket bucketname_#{Time.now.strftime('%Y%m%d%H')}
    ttl 0
    include_ttl false
  </match>
</ROOT>
2017-01-09 05:13:22 +0000 [error]: unexpected error error_class=Couchbase::Error::BucketNotFound error=#<Couchbase::Error::BucketNotFound: bootstrap error, The bucket requested does not exist (error=0x19)>

ログがThe bucket requested does not existと言っていますが、Couchbaseにbucketname_2017010905を作ってもダメです。

多分bucketname_#{Time.now.strftime('%Y%m%d%H')}を作ってあげるといけると思いますがCouchbaseのBucket名に#{}は使えません。

out_couchbaseにforestをかぶせる理由

上で少し触れているので蛇足かもしれませんが、out_couchbasetag_partsが使えないからです。

まとめ

  • Fluentdのtagに動的な日付と時間を付与する方法を紹介しました。
  • 動的日時の生成部分をダブルクォーテーションで囲むとFluentd起動時に固定されてしまうので気を付けましょう。
  • out_couchbaseのbucket指定にはtag_partsは使えないし、rubyのコードを書いても動的にパラメタ生成はしてくれません。
  • 他にもっと良い方法があればコメントお願いします。
2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5