tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

td-agent(fluentd)でのtail_exの挙動メモ(エラーになったり動かなかったりするパターンに気をつけましょう!)

はじめに

いきなりですが、tailしたいファイルが10とか20あった場合ってどうしましょう。
matchディレクティブのように<match hoge.**>ってワイルドカード指定したいですよね!

そんなときのプラグインがこちらです
Globbing と日時指定書式が使える fluent-plugin-tail-ex の紹介

しかし、ちょっと注意しないとうまくいかない場合があります!
というエントリーになります

※tail_exの使い方が間違っているための現象でしたらご指摘ください(><)
※tail_ex拡張すれば良かったじゃんって方、ごもっともです(><)

挙動を確認する前提

構成

  • td-agent(fluentd)とtail_exプラグインはインストール済み前提で行います

  • configはこんな感じを想定してます。

  • ディレクトリはこんな感じ想定
# pwd
/hoge/fuga/piyo

# tree ./
./
|-- aclog
|-- out
|-- pos
`-- slink

挙動確認のパターン

パターンはこんな感じでやってみます

  1. tailするファイル(2パターン)
    1. 実ファイル
    2. 実ファイルのシンボリックリンク
      1. リンク先の実ファイル有り
      2. リンク先の実ファイル無し
  2. tailするファイルの作成タイミング(2パターン)
    1. td-agentの起動
    2. td-agentの起動

の積算の6パターンにおいて各操作して挙動を確認します。
[パターン]
1.1×2.1
1.1×2.2

1.2.1×2.1
1.2.1×2.2

1.2.2×2.1
1.2.2×2.2

また、各操作については下記に続きます

各操作における結果について

上記のパターンの状態それぞれについて、下記の操作とその結果を検証してみます
検証結果はわかりやすく、表形式でOKNGかで書きました

OKとなる各操作の条件はこんな感じで設定しました

操作 OKとなる結果
td-agent起動 正常に起動できる
json出力① tailするファイルに出力したらout_fileに出力
実ファイル消す 起動中に消してもtd-agentは正常に動作する
json出力② tailするファイルに出力したらout_fileに出力

NGとなる場合はその状況や原因を記載します

やってみる

1.1 × 2.1
【パターンの状態】
  • tailするファイル = 実ファイル
  • tailするファイルの作成タイミング = td-agentの起動

ってことで、
「運用ではなく」確認の場合はこれが一番オーソドックスなパターンでしょうか。
「運用ではなく」と強調したのは、実運用の場合はこんな流れのほうが多いかなーと思うからです

環境構築(td-agentの導入、起動)

アプリケーションがファイルを出力

td-agentの起動前からファイルがある場合は少なそうですよね

【結果】
操作 結果
td-agent起動 OK
json出力① OK
実ファイル消す OK
json出力② OK

すべて問題なく動作しました  

1.1 × 2.2
パターンの状態
  • tailするファイル = 実ファイル
  • tailするファイルの作成タイミング = td-agentの起動
結果
操作 結果
td-agent起動 OK
json出力① NG
実ファイル消す OK
json出力② NG

tail_exで*指定をしていますが、td-agent起動後にファイルを作成してもtailされません
これはよく考えれば当たり前なんですが、こちらを見るとわかるかと。。

# pwd
/hoge/fuga/piyo/pos

# ls
aclog.pos

# cat aclog.pos
※中身はカラ

posファイルはtd-agent起動時に作成され、
①ファイルinodeと②読み込んだ位置を記録していますが
②は更新されるものの、①が新たに追加されないので起動時にないファイル(ポインタ)はtailされません

詳細は以前書いた記事を参考にどうぞ
td-agent(fluentd)のposファイルの作成タイミングとかその他もろもろもメモ

1.2.xやる前に

ここからはシンボリックリンクを指定するのでこんな感じにconfigを変えておきます

日付入りファイルをシンボリックリンクにするエントリは
以前書いたこちらを参考にしてください
td-agent(fluentd)で日付指定のログをtailする①-シンボリックリンクでやる

1.2.1 × 2.1
パターンの状態
  • tailするファイル = 実ファイルのシンボリックリンク(実ファイル有り)
  • tailするファイルの作成タイミング = td-agentの起動

ここで一応posファイルの中身をみてシンボリックリンクがtailされているか確認します

# pwd
/hoge/fuga/piyo/pos

# cat aclog.pos
/hoge/fuga/piyo/slink/aclog.login.log        0000000000000000        015e28fd
/hoge/fuga/piyo/slink/aclog.point.log        0000000000000000        015e28fc

slinkディレクトリにあるファイルをtailしている

結果
操作 結果
td-agent起動 OK
json出力① OK
実ファイル消す OK
json出力② OK

さきほどのNGを理解していれば簡単ですが、
tailするファイルへのinode(シンボリックリンクの)は存在しているので途中で実ファイルを消しても問題ありません

1.2.1×2.2
パターンの状態
  • tailするファイル = 実ファイルのシンボリックリンク(実ファイル有り)
  • tailするファイルの作成タイミング = td-agentの起動
結果

json出力がNGですがこれは1.1 × 2.2と同じ理由です

操作 結果
td-agent起動 OK
json出力① NG
実ファイル消す OK
json出力② NG
1.2.2×2.1
パターンの状態
  • tailするファイル = 実ファイルのシンボリックリンク(実ファイル無し)
  • tailするファイルの作成タイミング = td-agentの起動
結果
操作 結果
td-agent起動 NG
json出力① -
実ファイル消す -
json出力② -

※起動できないのでそれ以降の操作はできない

このパターンは一番ダメパターンでしょうか
td-agent起動前にtailするシンボリックリンクだけ作成してあって
リンク先の実ファイルが無い場合、

td-agentの起動の直後にこんなエラーで落ちてしまいます

# cat /var/log/td-agent/td-agent.log
2014-05-16 10:22:35 +0900 [error]: fluent/engine.rb:213:rescue in run: unexpected error error_class=Errno::ENOENT error=#<Errno::ENOENT: No such file or directory - /hoge/fuga/piyo/slink/aclog.login.log>
2014-05-16 10:22:35 +0900 [error]: fluent/engine.rb:214:rescue in run: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluent-plugin-tail-ex-0.1.1/lib/fluent/plugin/in_tail_ex.rb:58:in `initialize'

・・・省略・・・

2014-05-16 10:22:35 +0900 [info]: fluent/engine.rb:216:run: shutting down fluentd
2014-05-16 10:22:35 +0900 [info]: fluent/supervisor.rb:186:supervise: process finished code=0
2014-05-16 10:22:35 +0900 [warn]: fluent/supervisor.rb:189:supervise: process died within 1 second. exit.

※pos見てみる
# cat /hoge/fuga/piyo/slink/aclog.pos
/hoge/fuga/piyo/slink/aclog.login.log        0000000000000000        00000000

※td-agentのstatus見てみる
# /etc/init.d/td-agent status
td-agent dead but pid file exists

もちろん実ファイルを作成してから再度起動しなおすとOKです

1.2.2×2.2
パターンの状態
  • tailするファイル = 実ファイルのシンボリックリンク(実ファイル無し)
  • tailするファイルの作成タイミング = td-agentの起動
結果
操作 結果
td-agent起動 OK
json出力① NG
実ファイル消す OK
json出力② NG

このNGも1.2.1×2.2と同じです

やってみる番外編

上記を踏まえてこんな事例でやってみます

日付変わったとき想定(実ファイル編)

日付が変わってtailしていた実ファイルはtgzや移動され、新しい日付のファイルができる場合の想定です

手順
  1. tailする実ファイルがある状態でtd-agent起動
    ここで正常にtailされている状態
  2. 日付指定ファイルを一度消す
  3. 新しい日付でファイル作成&jsonログ出力

※configは実ファイル用

結果
操作 結果
手順1 OK
手順2 OK
手順3 NG

ここでのNGは落ちたとかではなく、
新しい日付で作成したファイルにログを出力してもtailされない
と、いうことです。

ここまでで何度か出てきたパターンと同じです。
posファイルに新しいファイルへのinodeが追記されないのでtailされません

日付変わったとき想定(シンボリックリンク編)

日付が変わって実ファイルはtgzや移動されるものの、tailしていたシンボリックリンクはそのまま、というパターンです

手順
  1. tailするシンボリックリンク、またそのリンク先の実ファイルがある状態でtd-agent起動
    ここで正常にtailされている状態
  2. 日付指定の実ファイルを一度消す
  3. 新しい日付でファイル作成&jsonログ出力
    ここではシンボリックリンクは前日のファイルを参照のまま
  4. リンクを貼りなおす
  5. 新しい日付でファイル作成&jsonログ出力

※configはシンボリックリンク

結果
操作 結果
手順1 OK
手順2 OK
手順3 OK※2
手順4 OK
手順4 OK

【※2】
3の手順としては正常に実ファイルにjsonログが出力されますが、 リンクが貼りなおされていないのでout_fileまでは行きません。 挙動としては想定どおりと言う意味でOKにしてます

まとめ

ポイント

tail_exを使ってこんな指定

path /hoge/fuga/piyo/slink/aclog.*

で書いておけば、新しく作成されたファイルまでtailしてくれるわけではありません。

こんな感じで使ったらどうでしょう例

ってことで 日付入りの複数ログファイルをtail_exしたい場合はこんな感じが良いのかな、と

最後に

tail_exでaclog.*aclog.*.%Y-%m-%dなんかで指定しておくと
日付が変わった後もtailしてくれるもんだと思ってハマりました(><)

恥ずかしい事例ですが、
似たようなことを思った他の方の参考になればと思い書いてみました!

どなたかの参考になれば幸いです\(^o^)/