各サーバーのログを収集、集約して、集約したログをリアルタイムで閲覧するためのソリューションを調べてまとめてみました。
ログの収集、集約のためのコンポーネント
syslog系列 (ログの収集、集約、保存)
- MSG のフォーマットは、フリーフォーマットなので CEF も使えるが JSON も一行にすれば送る事ができる。
- 各サーバー上の syslog を転送する事で、一つの syslog サーバーにログを集約する事ができる。UDP で送信される。
- logger コマンドで標準入力を syslogd にログを送る事ができる。
- syslogd にログをアプリケーションから送るには、logger コマンドや、各言語毎の関数を使う。C言語の場合は、syslog という関数が準備されている。Java の場合は、Logger クラスが準備されている。
- syslog 単体では、最終的にはファイルか、RDB (rsyslog) に蓄積するので、大量に集まってきたデータをリアルタイムで見るには向いて無いので、どうしても syslog を使いたい場合は、logstash の syslog プラグインなどを使用して ElasticSearch に入れる事になると思う。
syslog のバリエーション
- syslog-ng 1998年に登場。TCP にして通信の確実性を確保。TLS暗号化をサポート。現在ではあまり使われてないようだ。
- rsyslog 2004年に登場。RELP (Reliable Event Logging Protocol) というTCP上で動く信頼性の高いプロトコルをサポート。RELP は Receiver 側がどのメッセージを受け取ったか、"バックチャネル"を使って送信側に通知するので、どこまで送信ができたか確実になる。CentOS, Debian, Ubuntu等、主要な Linux のディストリビューションが採用している。rsyslog の主な機能はこちらにある。出力として、DBへの書き込みも対応している。
- syslog < syslog-ng < rsyslog となるについて、信頼性が高くなる。
fluentd (ログの収集、集約)
- 各サーバーにインストールしてログを収集。さらに各サーバーで収集されたログを集約し、ストレージやデータベースに挿入する所までを行う。
- syslog にアプリケーションがログを吐くにはアプリケーション側で対応する必用があったが、fluentd では、入力を input として分離した。また output もプラグインという形で分離する事で、様々なアプリケーションのログを入力として受けとり、いろいろな出力先を選択できるようになった。
- fulentd が稼働稼働する複数のノードからのログをとりまとめる、Aggregatorノードを構成する事ができる。通常は、Aggregator ノードでログをとりまとめて、Aggregator ノードから S3 やら ElasticSearch にログを出力する。
- ログ収集をより確実にしたい場合は、各ノードでログを集めるのは fluentd で行って、Aggregator ノードに送るよりも Kafka 等に送った方が良い。
- 基本的にはログの欠損はしないように各種設定を行う事ができそう。(但し確実なログの転送確認はパフォーマンスにも影響する)
- fluentd の input / output plugin の一覧はこちら。
logstash (ログの収集、集約)
- グローバルでは、fluentd より一般的らしい。
- 各サーバーにインストールしてログを収集。さらに各サーバーで収集されたログを集約し、ストレージやデータベースに挿入する所までを行う。
- ElasticSearch のデータの受け口として、logstash + ElasticSearch がほぼセットで使われる。
- input / filter (オプション) / output の構成を取る。それぞれが plugin 化されており、ある input を filter して、別の形式の output にする事ができる。
- input の プラグインはたくさんあるが、例として、ファイル (file)、tcp、 udp 、標準入力 (stdin) 等がある。
- output の例として、csv や file、標準出力 (stdout )、ElasticSearch (elasticsearch) 等がある。
- 設定によってはオーバーフローしてログを無くす事もあるようだ。queue の仕組みも持っているので、Persistent Queue でディスクに書き込むようにしてもIOが追いつかないケースがあるようだ。
- Logstash の input plugin 一覧はこちら。output plugin 一覧はこちら。
Apache Kafka (ログの集約)
- Kafka の本来の用途は、メッセージ・キューイングシステム。誰かからメッセージを一時的に受け取り、サーバー内にキューをして、最終的には誰かにメッセージを渡す。バッファー的な役割のシステム。ログを扱う場合はログ = メッセージを意味する。本質的に「ログ」も「メッセージ」も呼び方の問題で同じもの。
- Kafka は、logstash / fluentd 等のサーバーに導入された Agent からログを集約するためのプラットフォームとして使用される。Kafka のサーバーに集約 / キューされたログは、ストレージや DB等に書き出すために、ストレージや DBのインターフェイスとなる logstash / fluentd に向けて排出される。logstash/fluentd だけでも足りるが、ログ転送の確実性を保ちたい場合は、一時的にでもキューをしてくれて全体のトラフィックの流れを和らげてくれる Kafka を使用する。忙しいシステムほど、間にバッファーが無いと臨海に達した時に破綻する。
- メッセージ(ログ)は、Kafka サーバーで Queue し非同期通信にする事で、大量のデータでも裁けるようになっている。非同期と言えども、ほぼリアルタイムなデータ処理。
- Kafka サーバーでは、メッセージ(ログ)の保持しておくキュー(箱)の事を、パーティションと呼ぶ。複数のパーティション(箱)を作って置き、メッセージを仕分けしてパーティションに保管する事ができる。
- Kafkaサーバー (Broker サーバー) を複数立ててクラスターを作る事ができる。耐障害性が上がる。メッセージ(ログ)は、Kafkaサーバー間でレプリカされて保持される。
- クラスタリングを組んだ場合は、そのうちの一台が「Leader」で残りが「Follower」と呼ばれる。Leader に書かれたメッセージ(ログ)が、Follower にレプリケートされる。
- クラスタリングを組むと、メッセージを保管しておく箱であるパーティションも、複数の Kafka サーバーに跨がって存在するイメージになる。そのうち一つだけが Leader で残りは Followerになる。
- Kafka は、一般的に 「Pub / Sub」と呼ばれるアーキテクチャーを取る。情報を Kafka に入れてくる人を Publisher 、Kafka からの情報を受け取る人を Subscriber になる。Kafka では、Publisher / Subscriber を Producer / Consumer と呼び方を変えている。
- Kafka の Producer / Consumer は、Kafka と情報をやり取りするためのアプリケーションで、Kafka 用の Interface を持つ必要がある。Kafka の Producer / Consumer を作るための Java のライブラリが提供されている。Kafka へのデータの出し入れには、プログラムを開発する必用がある。但し fluentd / logstash には Kafka 用のプラグインが存在している。
- fluentd から Kafka にログを output (送る) / input (受け取る) ための certified plugin が存在している。
- logstash から Kafka にログを output (送る)ための plugin と Kafka からログを input (受け取る)ための plugin も存在している。
参考:
- 第26回Elasticsearch勉強会】Logstashとともに振り返る、やっちまった事例ごった煮 logstash で netflow からのログがオーバーフローした話。最終的に1台だった logstash ノードを4台にまで増やして分散させた。
- syslog に書き込んでみる C言語を使って syslog に書き込む
- 【Java入門】Loggerの使い方(ログレベル、出力先の設定も解説) Java で syslog に書き込む
- Fluentd Aggregator NodeをCentOS7に構築する fluentd の aggregator ノードを構成する。
- fluentdでログが欠損する可能性を考える fluentd におけるログ欠損の可能性の考察
- Apache Kafkaについてまとめる ー わかりやすい解説
- Apache Kafkaの概要とアーキテクチャ
ログの蓄積と可視化
Elasticsearch + logstash + Kibana
- Elasticsearch + logstash (ログを受け手 Elasticsearch に挿入) + Kibana (Elasticsearch 用の GUI) でセットとして使われる。
- Elasticsearch は、「全文検索エンジン」と呼ばれる。NoSQL DB と呼ばれるかどうかは議論がある。
開発側のElasticは NoSQL であるかどうかは、"Maybe!"というスタンスで、あくまでメインの データ置き場として使うのログ用途ぐらいで、通常は別のDatabase 等からデータを一時的に持ってきて、データの検索を行う「検索システム」という立場を取っている。一方で、nosql-database.org では、「Document Store」型の NoSQL であると Elastic(search) を扱っている。 - 通常の Elasticsearch の用途は、他のシステムからデータを投入し、そのデータの中から必用な情報を検索する事に使われる。
- Log 等の大量のデータを検索するのに向いているので、Log データの集約先として用いられる。Logの収集の場合は、logstash 経由でデータがドンドン Elasticsearch に投入される事になる。
- RDBの DB、Table、Row に近い、Cluster、Index、Type という概念を持っている
- データは JSON 形式で投入できる。
- データの CRUD 操作は全て REST API を通して行われる。
- ノードを追加する事で、クラスタ構成を作れる。トラフィックの増加、データ量の増加をノードを追加する事で行う事ができる。また、耐障害性を確保するためにレプリカを作成できる。
- Logstach + Elasticsearch + Kibana は、事実上セット製品である。
- Kibana は、ElasticSearch のデータの可視化に特化したGUI。
- Elasticsearch は、Kibana 以外にも 複数の DB に対応したデータの可視化ツールである Glafana も使用できる。Glafana は、ElasticSeach だけでなく、Prometheus (一応 GUI は標準であるがシンプル)や、MySQL 等の RDB のデータも可視化する事ができる。
Nagios Log Server
- Elasticsearch + logstash + Kibana を元に開発されたソリューション。
Splunk
参考:
- Elasticsearchって? Elastic 社の Elasticsearch の解説ページ
- 15分で作る、Logstash+Elasticsearchによるログ収集・解析環境 簡単構築の仕方
- リアルタイムログ監視・ログ管理ツール Nagios Log Server Nagios Log Server の代理店。ジュピター・テクノロジーズの解説ページ
- How to forward events from logstash to Splunk logstash から Splunk にデータを送る方法
- 10分で理解するGrafana
- 10分で理解する Prometheus
- Kafka+Spark Streaming+Elasticserachによるシステム構築と検証の進め方 Kafka や Elasticsearch の構造について非常にクオリティ高く解説されている。
ログ収集とログの欠損
ログの収集の目的は主に、「監視」と「セキュリティ監査」だと思います。
ログ収集にかける情熱はいろんな温度感があって、「ログを絶対に失っては駄目です」という場合から、「ログはたまに欠損しても良い」という場合まで様々です。
前者の例で言うと金融機関の監視システム、後者の例だとネットーワークの監視システムが代表的だと思います。
例えば、金融システムの監視システムでログを失って、それによって障害を見落とすととんでもない事になるのは、理解できます。
一方でネットワークの監視システムの場合は、syslog がメインで使われていることがほとんどですが、「ログはなくなってもすぐにまた同じのが来る」程度の感覚で扱われており、ログ収集のソフトウェアもラフに作られている感じがします(というと怒られるかな)。
これはネットワークの障害は通常、継続的であるので何度も何度もエラーが上がる事が通常であるという事に起因しているのと、ネットワークの監視となると対象が非常に多いので、上がってくるログをまともに収集すると、とんでもない量になりロストするのが当たり前。という感覚があるためだと思っています。
ログのフィルタリングと重複排除
ログを欠損なく収集するには、信頼性の高いログ収集システムを使用する必要があります。これについては、後述します。
ただログは集めれば集めるほど、処理が難しくなります。
リソースは無限にあるわけではないので、収集するログを絞る事が大事です。
例えばネットワークの ping エラーで、1分毎に同じエラーログが来ると仮定します。
あるネットワークのログ監視ソフトでは、1000回の同じエラーログが来たら、1行のログにまとめて、「1000」という数字を回数のカラムに追加するように作成されていました。
ネットワークのエラーログは大量に来るので、そのような形で重複を排除していかないと簡単にログ収集システムがパンクしてしまいます。
ログのフィルタリング・重複排除には
- ログの収集元でログをフィルタリング・重複排除する。
- ログの集約先でログをフィルタリング・重複排除する。
の2通りがありますが、できるだけログの生成元でフィルタリングと重複排除をした方が、システム全体にかける負荷は少なくなります
究極的なログ収集システムは、メッセージ・キューイングシステム
アプリケーションがログを生成し、そのログをネットワーク越しのログ収集サーバー上のストレージに保管さるまで、いろいろな箇所で障害が発生する可能性があります。
TCPで通信していても、アプリケーションサーバーが送ったデータに対して ACK が返ってこなかった場合に、ログ送信者がどのようなアクションを取るべきか確定させる事はできません。
例えば、もう一度データを送信すると、受け手側は二重にデータを受け取る可能性がありますし、かと言って、データを送らなかった場合は、欠損を招く恐れがあります。
ですので、ネットワーク越しにデータを送る場合に、データの重複、欠損の無いやりとりをするには、アプリケーションレイヤーでのデータの送受信確認を作り込む必用があります。
アプリケーションレイヤーで、データの送信、確実に届いたかの確認をする場合、それはコストがかかる処理になるため、パフォーマンスはどうしても出しにくくなります。
そのため同期通信は難しく、こう言った到達を保証しなければいけない環境では、非同期の通信が用いられます。
金融系システムのサーバー間のデータのやりとり
金融系のシステムでは、お金のデータを取り扱うため、絶対にデータの重複、欠損は許されません。
金融系システムでは、システム間のデータのやり取りに、メッセージ・キューイングシステムが用いられています。かなりのケースで IBM の MQ という製品が使われていると思います。
データの送受信の確実性があると言っても、メッセージ・キューイングシステムで確保しているリソース(CPU / Memory / Disk) が枯渇すると、当然新しいメッセージは受け付けられなくなります。
キャパシティをオーバーした時にシステム内部でデータが失われると金融システムではお金が無くなってしまう事を意味するので、システムとしてデータが受け付けられなかった場合は、ユーザーに「処理が受け付けられませんでした」とエラーを返す必用があります。
つまり、データを生成した大元に、「このデータは受け付けられませんでした」とメッセージを送る必用があります。
安定したログ収集システムを目指すには、最終的に Kafka のような Message Queuing システムに行き着きます。
ログ収集にメッセージ・キューイングシステムを使用する
一方で Kafka のようなメッセージ・キューイングシステムをログ収集に使用するとしても、Kafka用に準備されたサーバーの CPU/Memory/Disk の限界があるので、Kafka のリソースの限界を超えたログが入って来た場合は、Kafka はログの生成元にエラーを返す必用があります。
この時にエラーを返す相手は、ログを排出しようとしたアプリケーションになるはずです。
アプリケーションは出したログを引っ込める事はできないので、ファイルに書き出す等して一時的に保存し、暫くして再度ログを Kafka に送信するようにリトライするように作り込まれている必用があります(エラーが続いて一時的にファイルを書き出していたファイルシステムが一杯になる。という事もまれにあります)
金融システムの場合は、数字を入力した担当者向けの UserInterface に「トランザクションが失敗しました」とメッセージを出せば良いですが、そこまで考え抜かれてないシステムの一部のコンポーネントであれば、アプリの処理を失敗した事を伝える相手もいないケースもあり得ます。
Kafka の API を使って Producer としてKafka に直接書き込むようにアプリケーションが作り込まれてない場合は、ログファイルなどを介して Kafka に送信される事になると思います 。
その場合でも、もしアプリケーションがログをはけなかった時に、ログのディスク保管、リトライなどの機能が細かく作り込まれているアプリケーションがあるかと言うと、殆ど存在していないと思います。
ログの送信の確実性について完璧を目指すのであれば、ログを生成するアプリケーションから作り込まれている必用があります。
金融システムで無い限り、システム内に存在する全てのアプリケーションがここまで作り込まれおり、ログシステムのリソース使用状況も綿密に管理されている事を保証する事は大変難しい事です。
ですので、ログの重複、欠損の無い完璧なログ収集システムというのは、いろいろなアプリケーションが存在するオープン系システムでは現実的に難しい。という事を意識する必用があると思います。
IT界では、村上春樹が良く引用される事がありますが、「完璧なログシステムなんて存在しないんだ。完璧な絶望が存在しないようにね」というのが実態で、緻密な作りこみと緻密な運用(想定を超えた使われ方がされてないか正確に監視し、事前に対策を打つ)をする事で、完璧なログ管理システムを目指す事になると思います。