監視対象が複数ある場合の再検知について

ログ監視について以下の事象が発生しております。

【Version】
◆zabbix_server:2.2.2
◆zabbix_agent:2.2.2

【設定(アイテムのキー)】
◆logrt["/var/log/***/app.log.[0-9]{8}$"]
 ⇒更新間隔:60秒

【環境】
◆監視対象のファイルは「app.log.yyyymmdd」の名称で毎日00:00に作成されます。
◆古いログファイルはcronで毎日00:20に圧縮されます。
◆そのため00:00~00:20は監視対象ファイルがディレクトリに2つ存在します。

【事象】
◆ログの出力元のアプリケーションの仕様上、一連の処理を同一ファイルに書き込むため古いファイル(前日ファイル)に更新がかかる場合があります。
◆前日のファイルを読み込んだ際に先頭行から読み込むため再検知が発生します。

【相談】
◆事情によりアプリ側のログ出力設定の改修は難しい。
◆何か解決策はありますでしょうか。

上記、もし解決策があればご教授頂けますでしょうか。
宜しくお願いします。

コメント表示オプション

お好みのコメント表示方法を選び「設定の保存」をクリックすると変更が反映されます。
ユーザー heya の写真

こういうことですよね?

23:58:40 処理Aの続きのログ → app.log.20170323 に追記
23:59:20 アイテムの値取得・・・app.log.20170323 の続きを読む
00:00:00 app.log.20170324 が作成される
00:00:15 処理Bの最初のログ → app.log.20170324 に書き込む
00:00:20 アイテムの値取得・・・app.log.20170324 を最初から読む
00:00:40 処理Aの続きのログ → app.log.20170323 に追記
00:01:20 アイテムの値取得・・・app.log.20170323 を最初から読んでしまう
00:01:25 処理Bの続きのログ → app.log.20170324 に追記
00:02:20 アイテムの値取得・・・app.log.20170324 を最初から読んでしまう

それで、00:20:00 には app.log.20170323 は app.log.20170323.gz になるのでログ監視の対象にはならなくなると。

この場合、ローテーション後にまた処理Aのログが出たらどうなるんですか?
また app.log.20170323 が作られてそれが監視対象になる?

思いつきですが、これでどうにかなりませんかね(試してはいません)。
・app.log.latest というファイルを作り、これを logrt ではなく log を使って監視する。
 このファイルは最新(※)のファイルのハードリンク。
・手動で app.log.20170323 のハードリンクとして app.log.latest を作る。
・00:20 に app.log.20170323 を圧縮するとき、ついでに app.log.latest を削除して、
 それから改めて app.log.20170324 のハードリンクとして app.log.latest を作る。

この場合、00:20 までは処理Bのログは検知できないので(00:20 の次のログ取得時にまとめて出ることになるのかな)、それが許容できるかどうか。

※自分で「これを最新ということにする」と決めるのです。
例えば、上の例と違って「00:00 を過ぎたら app.log.20170323 はもう見ないぞ」と決めるなら、00:00 の時点で app.log.latest を app.log.20170324 のハードリンクにするのです(00:20 はこれまで通りの圧縮だけ)。

ユーザー logtarou の写真

返信ありがとうございます。

事象についてはheya さんのご認識の通りです。

>この場合、ローテーション後にまた処理Aのログが出たらどうなるんですか?
>また app.log.20170323 が作られてそれが監視対象になる?
すいません、上記についてローテートの条件を間違えておりまして
cronで00:20に圧縮されるのは前々日のログでした。
※つまり00:00~00:20ではなく常に監視対象ファイルは二つ存在する状況
※実際の動作ではログの書き込みが日付をまたぐのはレアケースで、長くとも00:20までには更新が止まる状況です

提案いただいたlogキーによる監視について、検討してみます。
app.log.latestの生成自体もスクリプトで自動化出来れば運用も楽になりそうですね。
>00:20 までは処理Bのログは検知できない
これがやはりネックになりますが、cronで圧縮されるのが前々日のファイルのため、書き込みが20分まで継続しないようであれば期間は短く出来るかもしれません。
アプリが改修できない状況ではこの方法が現実的でしょうか。ありがとうございます。

ちなみに別のアプローチとしてzabbixのバージョンアップによるlogrtの仕様変更にも期待していたのですが、
検証したところうまくいきませんでした。
経緯は以下の通りです。
◆agent2.2.4からlogrtの監視でinode情報を保持するようになったとの記載を確認
 参考:https://www.zabbix.com/documentation/2.2/jp/manual/config/items/itemtypes/log_items
◆監視対象が切り戻った場合でもinode情報とmtimeの情報から以前読んだ箇所をスキップできる?と判断
◆server,agentのバージョンを2.2.2→2.2.4に上げ、2つの監視対象ファイルを交互に更新する検証を行うが、対象が切り替わるたびに先頭行からログを読んでしまう

バージョンアップによって今回のようなケースの再検知が解消する可能性はあるのでしょうか。
logrtの仕様について自分が理解しきれていないのですが、上記についてもしご存知であればご教授ください。

宜しくお願いします。

ユーザー heya の写真

>バージョンアップによって今回のようなケースの再検知が解消する可能性はあるのでしょうか。

個人的意見ですが、たぶん無いと思います。
大前提として、現在ログが書き込まれているファイルは一つであって、logrt はローテーション直後だと前のファイルにまだ読んでない行が残っている可能性があるからそれも読む、というだけなので。あくまでそれは「古いファイル」であって、ローテーション後そこにログが記録されることは想定していないと思います。

もしそういう想定をするなら、ぱっと思いつくだけで二つ不都合があります。

▽ログが記録された順番が分からなくなる
前回のチェック時と比べて、app.log.20170323 は10行増えていて、app.log.20170324 は5行増えていたとします。この15行のログは、どういう順番で来たのか?
一つのファイルなら「後ろの方が新しい」で済みます。
#なので、log や logrt には、「ログファイルは追記されていくものである」という前提もあります。

▽覚えておくべきデータが多すぎる
ファイルのinode番号、何行目まで読んだか、最後に読んだときのファイルサイズを、ローテーションした古いファイルについても全部覚えておかないといけなくなります。ひょっとしたら最後に読んだ時間(ナノ秒単位)も必要かもしれません。
ファイル数が一つ二つならいいですが、(圧縮してなくて)世代数が2000などと設定されていれば、ローテーションしたファイルも含めて2001個のファイル分のデータを覚えることになります。
そしてログをチェックするたびにこれをサーバー-エージェント間で通信し、データベースに読み書きする必要があるのです。これらはレアケースに対応させるためだけに必要な情報なわけで、通常時には非常に無駄な気がします。

ユーザー logtarou の写真

>ローテーション後そこにログが記録されることは想定していないと思います。
やはり、logrtの機能で対応するのは難しいということですか。

ハードリンクを監視対象にする方法を検討してみようと思います。

回答ありがとうございました。

ユーザー mocha の写真

こんな作戦はどうでしょうか

・監視対象ファイルがあるサーバのzabbix_agentdのUserParameterに 監視対象ファイル名を一覧でとってLLD用データを作って返すキーを登録する
 lsなどの結果をawkやsedを使って整形してあげるレベルで実現可能です
・テンプレートに 上記キーで得られたマクロをもとにたlog監視用アイテムのプロトタイプとトリガのプロトタイプを登録する
 登録直後にログを頭から読み込む必要があるので modeパラメタにはskipを指定しないほうが無難です

ログの切り替わり直後はファイルを見つけるまで少し時間(LLDで指定した間隔に依存)がかかりますが その都度監視が必要なファイルを動的にアイテムとして追加して監視するようになります