概要
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)
実装方法
まずは最終的に選択した実装方法を記載します。
こうなりました。
<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_couchbase
にforest
をかぶせて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_norikra
とout_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の起動時にエラーになってしまいます。
(省略)
<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_couchbase
はtag_parts
が使えないからです。
まとめ
- Fluentdのtagに動的な日付と時間を付与する方法を紹介しました。
- 動的日時の生成部分をダブルクォーテーションで囲むとFluentd起動時に固定されてしまうので気を付けましょう。
-
out_couchbase
のbucket指定にはtag_parts
は使えないし、rubyのコードを書いても動的にパラメタ生成はしてくれません。 - 他にもっと良い方法があればコメントお願いします。