プログラムを書くのが難しいlogstashのfile inputプラグインの実現分析
前言
プログラムを書くのは本当に難しいことがあります.いろいろなことを考えなければなりません.
実行中に適用すると、ログファイルが生成され続けます.ログ収集ツールを実装するには、他の分析機能を考慮せずに収集だけを考慮し、どのような面を考慮しますか?
まず、一般的なlogフレームワークがログを出力する方法を見てみましょう.
a.log.1、 a.log.2,a.log.3,a.log.4,a.log.5サイクル出力;
a.2014-5-5.log、a.2014-5-6.log、a.2014-5-7.log、毎日1つのログファイルを生成します.
log.outは、再起動するたびに新しいlog.outを生成し、古いファイルを上書きします.
では、私たちはどのような面で実現し、注意しなければならないのでしょうか.は、正規またはglobs方式のワイルドカードを提供する. ファイルが新しいかどうかを判断できるようにします. ファイルが更新されたかどうかをどう判断しますか? ファイルの読み込みの進捗状況をどのように保存しますか? ファイルを読み込むときにファイルが削除されたらどうなりますか? ファイルの読み取り中にプロセスが停止した場合、読み取りの進捗はタイムリーに保存されていますか? ファイルの進捗状況を保存するときに、保留した場合、再起動してファイルの進捗状況を正しく復元できますか? 読み取った内容が重複しないことを保証できますか? ログファイルがすぐに生成され、すぐに削除された場合、漏らさないことを保証できますか? ログファイルがソフトリンクであれば、正しく処理できますか? ファイルシステムのinodeがリサイクルされますが、これを処理できますか? メモリに読み込まれたデータのサイズを制御し、メモリの消費を防止していますか?
logstashの実装
次に、logstashが上記の問題をどのように実現し、処理するかを説明します.
次のようなglobsスタイルのマッチングをサポートするpathパラメータ(Array)を構成できます.
excludeパラメータ(Array)を設定し、不要なファイルを除外できます.たとえば、次のようにします.
新しいファイルを識別するにはinodeを使用します
logstashは、いわゆるsincedbに進捗状況を保存します.実際には、ホームディレクトリの下にデフォルトで置かれているテキストファイルです.
.sincedb_e794081d6134aace51b759aea8cc3be2
.sincedb_f7a0c8a0def03e0c572511ceea0b9f63
後ろはログファイル、すなわちpathのhash値です.これにより、異なるファイル名のログファイルの進捗保存の問題が区別されます.
sincedbファイルには、次のような内容があります.
6511055 0 2051 118617881 5495516 0 2051 155859036 6348913 0 2051 148511449
上の4列はそれぞれ:
inode, major number, minor number, pos.
ここでmajor numberとminor numberはデバイスに関する数字です.参考:http://unix.stackexchange.com/questions/73988/linux-major-and-minor-device-numbers
inodeはファイルシステムがファイルに割り当てた番号です.参考:http://zh.wikipedia.org/wiki/Inode
したがってlogstashは、デバイス、ファイル名、ファイルの異なるバージョンを区別します.
ここで新しい問題を引き出して、inodeでファイルの異なるバージョンを判断して、十分に正確ですか?inodeはリサイクルされるので.
たとえば、次のコマンドを順次実行すると、2つのファイルのinodeは同じです.
しかしlogstashはcloseが落ちていないため、inodeをずっと持っているので、新しい同名のログファイルには新しいinodeがあります.
そのため、logstashが監視しているログファイルが削除された場合、削除したファイルの内容を処理し続けることができます.
inodeという特性を利用して、mysqlのファイルをうっかり削除したり、データdumpを出したりすることができます.mysqlプロセスはデータファイルのinodeを持っているからです.
また、logstashのデフォルトでは、1秒ごとにファイルの新しい内容の読み取りを試み、デフォルトでは15秒でスキャンし、新しいファイルがあるかどうかをチェックします.対応stat_intervalとdiscover_intervalパラメータ.
詳細は次のとおりです.
例えば、最大16394バイトのデータを読み取り専用で取り出し、メモリの消費量が多すぎることを防止し、5秒ごとに新しいposを保存する必要があるかどうかを判断します.
ログファイルが削除されるとsincedbファイルも削除されます.
renameを利用してposを原子的に保存する
新しいファイルの内容を読み込むとposが増加し、新しいposをsincedbに保存する場合、logstashは一時ファイルの方法を採用します.
まず一時ファイルを作成し、新しいコンテンツを書き込み、オペレーティングシステムが提供するremane関数を呼び出し、元のsincedbファイルを原子的に置き換えます.
これは実際によく使われるテクニックで、redisもそうしています.
重複せず、データを失わないことを保証できますか?
残念ながら、分散トランザクションでない限り、データが失われたり、繰り返し送信されたりする可能性はありません.ログ収集ソフトウェアまたはメッセージキューソフトウェアはすべてそうです.
実装コード
具体的な実装コードは貼らないで、比較的に読みやすいため、logstashはfilewatchというライブラリを使って、gemでインストールすることができます.関連コードはオンラインで表示されます.
https://github.com/elasticsearch/logstash/blob/v1.4.1/lib/logstash/inputs/file.rb
https://github.com/jordansissel/ruby-filewatch/tree/master/lib/filewatch
とfluentdのin_tailプラグイン比較
fluentdもポピュラーなログ収集ツールです.
簡単にfluentdのin_を見てみましたtailプラグインには、メモリの消費を防ぐための独自の提案があることがわかりました.)
https://github.com/fluent/fluentd/blob/master/lib/fluent/plugin/in_tail.rb
if
lines
.
size
>=
MAX_LINES_AT_ONCE
# not to use too much memory in case the file is very large
read_more
=
true
すなわち,最大1000行ずつデータをコミットしposを保存する.
fluentdのin_tailプラグインの原理とlogstashのfile inputは差が少なく、ファイルが更新されているかどうかをinodeで区別しています.
しかしfluentdはinodeとposしか保存されておらず、logstashのように設備を考慮していない.
またfluentdでposを保存する場合は、ファイル追加で保存されますが、logstashのようにrenameファイルで新しいファイルに保存されることはありません.明らかにlogstashの実現はより合理的である.
遠くに行くと、logstashの配置はfluentdより便利です.どちらもrubyで書かれていますが、logstashのデフォルトはjrubyで、JVMさえあれば走ることができます.fluentdはruby環境をインストールするのは面倒です.
他にもいくつかあります
logstashには江湖の勢いがあるが、この言葉はどこで見たか忘れてしまった.github上のlogstashのstartは2000以上あります.
logstash + elasticsearch + Kibanaのログ収集、検索、一貫したサービスが流行しています.
参照先:
http://unix.stackexchange.com/questions/73988/linux-major-and-minor-device-numbers
http://zh.wikipedia.org/wiki/Inode
https://github.com/elasticsearch/logstash/blob/v1.4.1/lib/logstash/inputs/file.rb
プログラムを書くのは本当に難しいことがあります.いろいろなことを考えなければなりません.
実行中に適用すると、ログファイルが生成され続けます.ログ収集ツールを実装するには、他の分析機能を考慮せずに収集だけを考慮し、どのような面を考慮しますか?
まず、一般的なlogフレームワークがログを出力する方法を見てみましょう.
a.log.1、 a.log.2,a.log.3,a.log.4,a.log.5サイクル出力;
a.2014-5-5.log、a.2014-5-6.log、a.2014-5-7.log、毎日1つのログファイルを生成します.
log.outは、再起動するたびに新しいlog.outを生成し、古いファイルを上書きします.
では、私たちはどのような面で実現し、注意しなければならないのでしょうか.
logstashの実装
次に、logstashが上記の問題をどのように実現し、処理するかを説明します.
次のようなglobsスタイルのマッチングをサポートするpathパラメータ(Array)を構成できます.
path => [ "/var/log/messages", "/var/log/*.log" ]
excludeパラメータ(Array)を設定し、不要なファイルを除外できます.たとえば、次のようにします.
exclude => "*.gz"
新しいファイルを識別するにはinodeを使用します
logstashは、いわゆるsincedbに進捗状況を保存します.実際には、ホームディレクトリの下にデフォルトで置かれているテキストファイルです.
.sincedb_e794081d6134aace51b759aea8cc3be2
.sincedb_f7a0c8a0def03e0c572511ceea0b9f63
後ろはログファイル、すなわちpathのhash値です.これにより、異なるファイル名のログファイルの進捗保存の問題が区別されます.
sincedbファイルには、次のような内容があります.
6511055 0 2051 118617881 5495516 0 2051 155859036 6348913 0 2051 148511449
上の4列はそれぞれ:
inode, major number, minor number, pos.
ここでmajor numberとminor numberはデバイスに関する数字です.参考:http://unix.stackexchange.com/questions/73988/linux-major-and-minor-device-numbers
inodeはファイルシステムがファイルに割り当てた番号です.参考:http://zh.wikipedia.org/wiki/Inode
したがってlogstashは、デバイス、ファイル名、ファイルの異なるバージョンを区別します.
ここで新しい問題を引き出して、inodeでファイルの異なるバージョンを判断して、十分に正確ですか?inodeはリサイクルされるので.
たとえば、次のコマンドを順次実行すると、2つのファイルのinodeは同じです.
touch test
stat test
rm test
touch test
stat test
しかしlogstashはcloseが落ちていないため、inodeをずっと持っているので、新しい同名のログファイルには新しいinodeがあります.
そのため、logstashが監視しているログファイルが削除された場合、削除したファイルの内容を処理し続けることができます.
inodeという特性を利用して、mysqlのファイルをうっかり削除したり、データdumpを出したりすることができます.mysqlプロセスはデータファイルのinodeを持っているからです.
また、logstashのデフォルトでは、1秒ごとにファイルの新しい内容の読み取りを試み、デフォルトでは15秒でスキャンし、新しいファイルがあるかどうかをチェックします.対応stat_intervalとdiscover_intervalパラメータ.
詳細は次のとおりです.
例えば、最大16394バイトのデータを読み取り専用で取り出し、メモリの消費量が多すぎることを防止し、5秒ごとに新しいposを保存する必要があるかどうかを判断します.
ログファイルが削除されるとsincedbファイルも削除されます.
renameを利用してposを原子的に保存する
新しいファイルの内容を読み込むとposが増加し、新しいposをsincedbに保存する場合、logstashは一時ファイルの方法を採用します.
まず一時ファイルを作成し、新しいコンテンツを書き込み、オペレーティングシステムが提供するremane関数を呼び出し、元のsincedbファイルを原子的に置き換えます.
これは実際によく使われるテクニックで、redisもそうしています.
重複せず、データを失わないことを保証できますか?
残念ながら、分散トランザクションでない限り、データが失われたり、繰り返し送信されたりする可能性はありません.ログ収集ソフトウェアまたはメッセージキューソフトウェアはすべてそうです.
実装コード
具体的な実装コードは貼らないで、比較的に読みやすいため、logstashはfilewatchというライブラリを使って、gemでインストールすることができます.関連コードはオンラインで表示されます.
https://github.com/elasticsearch/logstash/blob/v1.4.1/lib/logstash/inputs/file.rb
https://github.com/jordansissel/ruby-filewatch/tree/master/lib/filewatch
とfluentdのin_tailプラグイン比較
fluentdもポピュラーなログ収集ツールです.
簡単にfluentdのin_を見てみましたtailプラグインには、メモリの消費を防ぐための独自の提案があることがわかりました.)
https://github.com/fluent/fluentd/blob/master/lib/fluent/plugin/in_tail.rb
if
lines
.
size
>=
MAX_LINES_AT_ONCE
# not to use too much memory in case the file is very large
read_more
=
true
すなわち,最大1000行ずつデータをコミットしposを保存する.
fluentdのin_tailプラグインの原理とlogstashのfile inputは差が少なく、ファイルが更新されているかどうかをinodeで区別しています.
しかしfluentdはinodeとposしか保存されておらず、logstashのように設備を考慮していない.
またfluentdでposを保存する場合は、ファイル追加で保存されますが、logstashのようにrenameファイルで新しいファイルに保存されることはありません.明らかにlogstashの実現はより合理的である.
遠くに行くと、logstashの配置はfluentdより便利です.どちらもrubyで書かれていますが、logstashのデフォルトはjrubyで、JVMさえあれば走ることができます.fluentdはruby環境をインストールするのは面倒です.
他にもいくつかあります
logstashには江湖の勢いがあるが、この言葉はどこで見たか忘れてしまった.github上のlogstashのstartは2000以上あります.
logstash + elasticsearch + Kibanaのログ収集、検索、一貫したサービスが流行しています.
参照先:
http://unix.stackexchange.com/questions/73988/linux-major-and-minor-device-numbers
http://zh.wikipedia.org/wiki/Inode
https://github.com/elasticsearch/logstash/blob/v1.4.1/lib/logstash/inputs/file.rb