ログ収集テクニック

ここら辺は教科書がないから知らない人はとことんディフォルトで設定したまま何もしていないと思うので書いてみる。
まるで昔のオレのようだぜwww

ログは容量ではなく、日付ごとにローテートさせる

一版的な logrotare ソフトは容量でログをローテートさせていますが、ログは日付でローテートさせた方が見やすいです。
なぜ日付かというと、人間は日付で物事を考えるからです。
昨日のアクセスログを調べたいとか、月間アクセスログを調べたいとかいう要望はありますが、前回ローテートしてからの100MB分のログを調べたいという要望はなかなかないからです。

もちろん、一日のログ出力がとんでもなく、日付でローテートさせていてはとても間に合わない場合は一日に数回ローテートさせる必要があるかもしれませんが。

まずは、 logrotate.d などのローテートソフトのディフォルトは容量でローテートさせているので、日付でローテートするように修正します。

手元のdebian機だとこんな感じかなぁ。。。

vi /etc/logrotate.d/apache2

/var/log/apache2/*.log {
        daily                  ←毎日ローテートするの
        ifempty                ←サイズが0でもローテートするの!
        missingok              ←ファイルがなくてもいいのよ
        compress
        rotate 52
        delaycompress
##      notifempty             ←これは消さないとダメよ
##      dateext                ←logrotateでは日付をつけないから今回はパス
        create 640 root adm
        sharedscripts
        postrotate
                if [ -f "`. /etc/apache2/envvars ; echo ${APACHE_PID_FILE:-/var/run/apache2.pid}`" ]; then
                        /etc/init.d/apache2 reload > /dev/null
                fi
        endscript
}

logrotate.dのデバッグはこんな感じで -f オプションつけて、実行します。-v オプションもつけると詳細な画面出力がみれます。

logrotate -fv /etc/logrotate.d/apache2

実際にローテートされたかどうか、ディレクトリを見て確認します。

ls -la /var/log/apache2/

-rw-r-----  1 root adm     0 Nov 14 10:14 access.log
-rw-r-----  1 root adm     0 Nov 14 10:14 access.log.1       ←サイズが0でもローテート
-rw-r-----  1 root adm   529 Nov 14 10:14 error.log
-rw-r-----  1 root adm   607 Nov 14 10:14 error.log.1

この後、別のログ収集サーバにcronで転送するときに、日付とマシン名を付与するので、logrotateでは特に設定しません。

ログとバックアップは別サーバに保存する

ローテートしてしばらくしているとログは消えてしまいます。
そこで別のサーバに転送し保存します。
別サーバを使うメリットは以下の2つになります。

  • サーバのトラブルによるデータ消失の回避できます。
  • 別サーバだと、どんなに重いログ解析を走らせても大丈夫になります。

私は、logrotate.d が走った後に cronで別サーバにscpで転送するようにしています。
このとき 日付とマシン名をログに付与します。詳しくはログ命名のところで。

apacheのログテクニック

apacheのログはディフォルトは微妙なのでカスタムして使います。

ディフォルト形式のログには処理にかかった時間が記録されていません。
なぜ処理にかかった時間が必要かというと、システムを見るときに処理速度というのは大きな目安になるからです。
ディフォルトのログでは、なぜか表示されないのでw、LogFormatを利用して追加します。

↓%Tを追加
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %T" combined
LogFormat "%h %l %u %t \"%r\" %>s %b %T" common

LogFormatの書式はこちら
http://httpd.apache.org/docs/2.2/ja/mod/mod_log_config.html

ログ命名

ローテートさせ、最終的にバックアップするときにこんな感じに命名しています。

/backup/2009_11_01/SERVER01_access_mydomain.local.gz
/backup/2009_11_01/SERVER01_access_testdomain.local.gz
/backup/2009_11_01/SERVER01_mysql_slowquery.gz
/backup/2009_11_01/SERVER02_access_mydomain.local.gz
/backup/2009_11_02/SERVER01_access_mydomain.local.gz
/backup/2009_11_02/SERVER01_access_testdomain.local.gz
...

要するに、 YYYY_MM_DD/SERVERNAME_access_ドメイン名.gz または、 YYYY_MM_DD/SERVERNAME_ログ名前.gz です。
YYYY_MM_DD をつける理由は、いつのログか知るためです。ログは毎日ローテートさせているのでつけないとわかんなくなります。
SERVERNAME をつける理由は、複数代のサーバでシステムを構築しているので、どのサーバのログか見分けるためです。
この形式で保存しておくメリットは、以下のような集計が容易になるからです。

//2009年11月の mydomain.local のアクセスを集計する
ログ集計ソフト /backup/2009_11_*/*_access_mydomain.local.gz

//2009年の testdomain.local のアクセスを集計する
ログ集計ソフト /backup/2009_*/*_access_testdomain.local.gz

//2009年11月01日のSERVER01のログのみ集計する
ログ集計ソフト /backup/2009_11_01/SERVER01_*_access_*.local.gz

ログ集計とSLA

apacheのログ集計には analogを使わせてもらってます。
google analystic も便利なんですが、応答時刻の集計ができないので analog が便利です。
ケータイ対応とかしてほしいんですけどね。。。

analogを月初のcronで起動して、ドメインごとに月間のアクセス頻度や処理速度などを集計してメールで送るようにしています。

前月のサーバの状態がどうだったのか一目でわかるようになります。
また、処理速度が簡単に集計できるようになると、それを基にした SLAを構築できるようになると思います。

バッチ処理やダウンロード処理を除く、普通のphp等の処理時間の99.99%は3秒以下であること等の目標を数字で定めることができます。

あとは数字を達成する努力をしていけばシステムは安定化し、ユーザもハッピーになり、評価を得ることができると思います。