フタなしカンヅメ

徒然なるままに @happytar0

Scribeでログの集約・収集【前編】

前回の記事で静的ファイルを別サーバから配信することにしましたが、今度はアクセスログがサーバ毎に分散してしまうので、少々やっかいだなと思いました。
出来るだけ正確でリアルタイムに近い形でログを収集できればいいなという感じです。

まず、考えていたのは一定期間毎に一つのサーバにログを収集していく方法です。せっかくlsyncdも入れているので、rsyncで収集するのが一番簡単そうです。しかし、lsyncdでそのままログファイルをミラーしてしまうと、ログが書き込まれる度に送信しちゃうわけで。。。この辺りはどうにか出来るとは思いますが、みんなはどうやっているのかちょっと調べてみました。

とりあえず、検索してみたら下記のページが見つかりました。
ログ集約・収集について【syslog - 集約】 - プログラマ 福重 伸太朗 〜基本へ帰ろう〜

どうやら、「集約」と「収集」では意味合いが違う模様。たしかにそうだなと思い、妙に納得してしまうのでありました。こちらに書いてあったのは、syslogやsyslog-ngを使う方法のようです。
「集約」を目的にするとどうしても精度が落ちてしまうらしい、当然に集約するためにログサーバなどに送信するわけで、データが正しく送れる保証はないということです。
それに比べて「収集」は、ローカルに保存されたデータを定期的にログサーバなどに送信するといった感じでしょうか。精度の高いデータを必要する場合は、こちらがいいようです。今回はアクセスログで、ログ解析などを必要とするためにある程度の精度が必要です。

ここでふと思い出したのが、Scribeというものです。知っている方も多いと思いますがFacebookで利用されているログを集約・収集するためのツールです。調べてみた所、けっこういいんじゃないかと思ったので導入してみることにしました。

・中間程度の信頼性がある。通信が失敗したときはローカルに保存し、次に成功したときに自動的に送信してくれる。
・メッセージ構造がシンプル。カテゴリとメッセージ本体のみで保存される。

とりあえず、使ってみることにします。
Thriftというものを使っているらしく、まずこちらを入れてみます。
# ThriftもFacebookが開発したもので、RPCフレームワークらしいです
Apache Thrift

その前にBoost1.36以上に依存しているため新しいものを入れます。今回はRPMで入れる事にしました。yumではインストール出来ませんので、下記サイトを参考にSRPMからインストールします。
Boost 1.37.0のRPMパッケージ作成メモ - torutkの日記

## http://rpm.pbone.net/index.php3/stat/26/dist/32/size/29387914/name/boost-1.37.0-3.fc11.src.rpm からダウンロード
# rpm -ivh boost-1.37.0-3.fc11.src.rpm
## 依存パッケージをインストール
# yum install libicu-devel

## http://www.02.246.ne.jp/~torutk/linux/centos5/packages.html#SEC23 ここにあるファイルで下記ディレクトリのファイルを置き換える
$ /usr/src/redhat/SPECS
$ /usr/src/redhat/SOURCES
# rpmbuild -bb /usr/src/redhat/SPECS/boost.spec
# rpm -Uvh boost-devel-1.37.0-1.i386.rpm boost-1.37.0-1.i386.rpm
## libeventをyumでインストール
## イベント駆動型アーキテクチャを実装するためのライブラリだそうです
# yum install libevent libevent-devel

$ tar zxvf thrift.tgz
$ cd thrift
$ ./bootstrap.sh

## しかし下記のようなエラー
configure.ac:50: error: possibly undefined macro: AC_PROG_MKDIR_P
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.

## autoconfが古いと出るみたいなので2.6以上にします
## http://rpm.pbone.net/index.php3?stat=26&dist=42&size=959985&name=autoconf-2.61-2.el4.pp.noarch.rpm からダウンロード
# rpm -Uvh autoconf-2.61-2.el4.pp.noarch.rpm

## thriftディレクトリで再度実行
$ ./bootstrap.sh
$ ./configure && make
# make install

## Thirftの追加パッケージfb303というにも依存しているらしいので
## fb303もインストールしておきます
$ cd thrift/contrib/fb303
$ ./bootstrap.sh
$ ./configure && make
# make install

次に下記のページからScribe本体をダウンロードします。
Scribe | Free Development software downloads at SourceForge.net

$ tar zxvf scribe-version-2.01.tar.gz
$ cd scribe
$ ./bootstarp.sh
$ ./configure && make
# make install

これでインストール完了です。早速使ってみることにします。

## ビルドしたディレクトリ内にある設定ファイルのサンプルを使って起動
$ /usr/local/bin/scribed examples/example1.conf

## こんなエラーが出ました
/usr/local/bin/scribed: error while loading shared libraries: libthrift.so.0: cannot open shared object file: No such file or directory

## Thriftのライブラリが読み込めていないようです
# echo "/usr/local/lib" >> /etc/ld.so.conf
# /sbin/ldconfig

## 再度実行し、成功すると下記のようなメッセージ
$ /usr/local/bin/scribed examples/example1.conf
Thrift: Thu Jul 30 12:44:18 2009 libevent 1.1a method epoll

この状態ではまだデーモンとして立ち上げず、別のシェル上からログメッセージを送信してみます。Scribeのビルドディレクトリ内のexamplesの中にサンプルのプログラムが入っているみたいです。
scribe_catはメッセージを追記、scribe_ctrlはサーバの状態を確認するもののようです。pythonで出来てました。

## 最後のtestの部分がいわゆるカテゴリ
$ echo "hello japan." | ./examples/scribe_cat test

## するとscribedがこんなメッセージを出力しました
[Thu Jul 30 12:48:30 2009] "Exception < boost::filesystem::create_directory: No such file or directory: "/tmp/scribetest/test" > trying to create directory" 
[Thu Jul 30 12:48:30 2009] "[test] Failed to open file </tmp/scribetest/test/test_00000> for writing" 
[Thu Jul 30 12:48:30 2009] "[test] Opened file </tmp/test/test_00000> for writing" 

## どうやら/tmp/scribetestというディレクトリを作っておく必要があるらしい
## 作ってなかったので、/tmp/test以下に自動保存された
$ mkdir /tmp/scribetest

## 自動的にscribedが認識し自動保存されたログを書き込んだ模様
[Thu Jul 30 12:49:38 2009] "[test] Opened file </tmp/scribetest/test/test_00000> for writing" 
[Thu Jul 30 12:49:38 2009] "[test] Changing state from <DISCONNECTED> to <SENDING_BUFFER>" 
[Thu Jul 30 12:49:38 2009] "[test] successfully read <1> entries from file </tmp/test/test_00000>"

# ちゃんと書き込まれている
$ cat /tmp/scribetest/test/test_current
hello japan.

とりあえず、無事に動いているようでインストール成功しました。長くなりそうなので記事を別けて掲載します。次の記事ではネットワーク経由でログを出力させてみようと思います。