ログ集約・収集について【syslog - 集約】

複数のWebサーバからlighttpdのログを集約・収集することになったが、方法が分からなかったので「サーバ/インフラを支える技術」で学習しました。
サーバ/インフラを支える技術 P295〜302に載っている「Webサーバのログの扱い」の部分はApacheを例に出していますが、lighttpdにも応用できます。
以下、lighttpdのログ集約・収集についてのメモです。


なお、これは、連載のような記事です。

syslog - 集約 <= いまココ

syslog-ng - 集約

syslog-ng - 収集

と見ると一番分かりやすいです。


集約・収集の言葉の定義

まず、集約・収集の言葉の定義・目的を確認します。サーバ/インフラを支える技術の「Webサーバのログの扱い」では、集約・収集を以下のように定義しています。

集約とは

Webサーバが出力するログを常に転送して1つにまとめること。

1つのログサーバにまとめているのがポイントです。

収集とは

各サーバ上に出力されたログを定期的に集め、保存すること。

「普段は【各サーバ上】にあり、定期的に集める」というところがポイントです。


また、目的についても以下のように書かれています。

集約の目的

その時々の状況を把握するためです。瞬間的なPVやユーザ数などを、ざっと集計したりするのに使います。

ネットワーク経由に保存する場合、データが渡されない保障はありません。特に udp で通信していた場合はなおさらです。syslogはudpで通信しますので、保障されません。ただし、syslog-ngはtcpが利用できますので保障はされますが、データを保障する分パフォーマンスが落ちる可能性があります。

収集の目的

おもに集計と解析、そして保存。

「各サーバ」に保存されたログはネットワークを経由して保存されたログより精度が高いため、集計と解析、保存に利用されます。

集約と収集を区別している理由

以下のように書かれています。

結局のところ両方とも1ヶ所にログを集めるのに、ログの集約と収集を区別しているのは、前述のとおり両者のログの精度が異なるからです。Webサーバの場合、アクセスの量に比例して短時間あたりに出力されるログの量も増えます。アクセスが一時的に増大すると、そのすべてのログを集約して漏れなく保存するには、それに見合った性能を持つハードウエアが必要になります。一時的にしか発生しない状況に合わせて高性能なハードウェアを用意するのはコストパフォーマンスの面から好ましくないので、集約するログの制度を求めず、それでは問題になる用途のために、別途各サーバのローカルに出力されたログを収集するわけです。

サーバ/インフラを支える技術 P296「Webサーバのログの扱い」

なお、syslog-ngの集約についてはこちらに、syslog-ngの収集についてはこちらに書いてあります。


では、具体的にsyslogでの集約方法についてみていきましょう。

ログの集約

syslogの役割はUNIX系のOSにおけるログの集約ハブです。

syslogを使ったログの集約

まずは、syslogを使った集約をやってみます。※次の記事でsyslog-ngの集約もやっています。

Apacheはログの出力先として、指定されたファイルに書き込む以外に、別のプログラムを起動して標準入力にログを渡す機能を持っています。ログを渡されたプログラムは、そのプログラムの目的に従ってログを処理します。一方syslogにはloggerというプログラムが付属していて、標準入力から受け取ったログをsyslogに渡すことができます。この2つを組み合わせることで、Apacheのログをsyslogに出力できます。

サーバ/インフラを支える技術 P296「Webサーバのログの扱い」

lighttpd でも同じことができます。
絵で表すと以下のようなイメージになります。


なお、転送元サーバとログサーバの環境は以下です。

$ cat /etc/redhat-release
CentOS release 5 (Final)
ログサーバ(192.168.0.10)の設定

まず、ログ・サーバでは、514/udpポートが待機状態であるか確認します。
確認方法は以下のように、コマンドを入力して表示されればOK。何も表示されない場合は待機状態ではない。

$ netstat -an | grep -i udp | grep 514 
udp        0      0 0.0.0.0:514                 0.0.0.0:*   

こちらの「(2)514/udpを待機させる」に開放の方法が書いてあります。
Red Hat Linux系では、/etc/sysconfig/syslogのSYSLOGD_OPTIONS変数に、-r を追加して、syslog を再起動します。

変更前:
SYSLOGD_OPTIONS="-m 0"
変更後:
SYSLOGD_OPTIONS="-m 0 -r"
修正後、syslogdを再起動させる。
$ sudo /etc/init.d/syslog restart

また、Firewal、iptablesなどで塞がっていないかどうかも確認したほうが良いと思います。


次に、/etc/syslog.conf の設定例です。以下のようになります。

#kern.*                                                 /dev/console
*.info;mail.none;authpriv.none;cron.none;local6.none    /var/log/messages
authpriv.*                                              /var/log/secure
mail.*                                                  -/var/log/maillog
cron.*                                                  /var/log/cron
*.emerg                                                 *
uucp,news.crit                                          /var/log/spooler
local7.*                                                /var/log/boot.log
# 転送元サーバ(192.168.0.50)のlighttpd log 保存場所
local6.info /var/log/lighttpd/siteA.access.log

設定のポイントは、local6.none で lighttpdのログを /var/log/messages に行かないようにして、local6.info で lighttpdのログを /var/log/lighttpd/siteA.access.log に保存していることです。

設定したら、syslogを再起動(/etc/init.d/syslog restart)します。

これで、ログサーバ側の設定は完了です。
他のWebサーバ用に対応させたい場合は、同じように設定を追加すればOKですので、まずは、192.168.0.50 => 192.168.0.10 のログ転送のみ設定します。

転送元サーバ(192.168.0.50)の設定

ログの転送元となるサーバでは、ログ転送を行うための設定をsyslog.confに追加する必要があります。

まず、/etc/hostsにログ・サーバのホスト名/IPアドレスを追加します。

192.168.0.10 loghost

これは、loghost という名前を解決するためです。DNSサーバに設定しても大丈夫ですが、オススメしません。それはDNSサーバが停止した場合機能しなくなるからです。

つぎに、/etc/syslog.confにログ転送の設定を追加します。facility.priority は local6.info に固定します。また、/var/log/messagesにlighttpdのログが行かないよう local6.none を加えます。

#kern.*                                                 /dev/console
# local6 は lighttpdのログを流すので /var/log/messagesに行かないようにします
*.info;mail.none;authpriv.none;cron.none;local6.none    /var/log/messages
authpriv.*                                              /var/log/secure
mail.*                                                  -/var/log/maillog
cron.*                                                  /var/log/cron
*.emerg                                                 *
uucp,news.crit                                          /var/log/spooler
local7.*                                                /var/log/boot.log
# lighttpdのログは local6.info に固定します
local6.info     @loghost

そして、syslogdを再起動(/etc/init.d/syslog restart)させ、設定を再読み込みさせます。

これで、基本的な設定は完了しました。
転送元サーバで以下のコマンド入力して、ちゃんとログサーバのほうにログが保存されることを確認してください。

logger -p local6.info test

もし、ログがログサーバに現れない場合は、ログサーバで以下のコマンドを実行してみる。

# tcpdump -n -i eth1 udp and dst port 514
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
07:45:12.673781 IP 192.168.0.50.syslog > 192.168.0.10.syslog: SYSLOG user.notice, length: 16

ログサーバ(192.168.0.10)で「tcpdump -n -i eth1 udp and dst port 514」を実行して待ち状態にして、転送元サーバ(192.168.0.50)で 「logger -p local6.info test」 などと実行して、上記のように出力されたら、ログサーバへのアクセスに成功している。
もし、何も変化がない場合、転送元のサーバに問題がある可能性が高いため、設定を見直してみましょう。


ログサーバにログが送れていることが確認できたら、lghttpdの confの設定を行います。
lightpdのアクセスログを ログサーバへ転送させるには、lighttpd の log 出力を logger に渡せばよい。
mod_access_log を利用して、lighttpd.conf のアクセスログが設定してある部分に以下のように記述すればよい。

・
・
accesslog.filename = "|/usr/bin/logger -p local6.info"
・
・

これで、lighttpdアクセスログが loggerに吐かれるようになる。つまり、ログサーバへ吐かれることになります。
同じように他のWebサーバにも設定すれば、ログの集約ができます。

syslogの注意点

ただし、前述したとおり、注意点があります。

syslogは、ログを取りこぼすことがあります。また同じログが連続して出力されるとそれらを1つにまとめます。このため集計などの厳密さが要求される用途には適しませんが、一方で大量のログが出力された時でもディスクへの負荷を押さえることができます。syslogで集約したログはあくまでも、問題が発生したときにどのマシンでそれが発生したのかあたりを付けたり、あるいは現在のサイトのトレンドを観察するために使います。

syslog-ngは udpでの通信でしかできなかったり、出力先のファイル名が1つしか選べないなどの欠点があります。

syslogの欠点を補うのがsyslog-ngです。
次回は syslog-ng で集約をやってみます。