GeekFactory

int128.hatenablog.com

syslog-ngをmetalog風に使う

以前、システムロガーにmetalogを使っていました。分かりやすいログ配置、分かりやすい設定ファイル、自動ローテーション等の利点があって重宝していましたが、たった一つ欠点がありました。それは他ホストからのsyslogを受信できないことでした。複数のホストを管理し始めると、ログを集約できないと不便です。

syslog-ngにおける標準的なログ配置はだいたいこんな感じと思います。logrotateでローテーションが行われると messages-20091001.gz といった具合に日付が付加されていきます。

  • /var/log/messages
  • /var/log/messages-20091001.gz
  • /var/log/secure
  • /var/log/maillog

metalogにおける標準的なログ配置は下記です。自動で日次ローテーションされるようになっています。

  • /var/log/everything/current
  • /var/log/everything/2009-10-24
  • /var/log/auth/current
  • /var/log/mail/current

どちらがお好みですか?私は後者が好きですね。

metalog風の配置にするにはsyslog-ng.confを書き換えます。

filter everything {
        # everythingに書き出したくない項目
        not filter(mail) and
        not filter(...);
};
filter auth { facility(auth, authpriv); };
filter mail { facility(mail); };

destination everything { file("/var/log/everything/$YEAR-$MONTH-$DAY.log"); };
destination auth { file("/var/log/auth/$YEAR-$MONTH-$DAY.log"); };
destination mail { file("/var/log/mail/$YEAR-$MONTH-$DAY.log"); };

現在のログも日付ファイル名で出力されてしまう(例:2009-10.25.log)ため、currentにシンボリックリンクを張ります。日次で下記のシェルを実行します。

#!/bin/bash
# /etc/cron.daily/syslog-ng-current
current="$(date +%Y-%m-%d)"
find /var/log -type f -name "$current.*" | while read f
do
        cd "$(dirname "$f")"
        original="$(basename "$f")"
        symlink=${original/$current/current}
        [ -L "$symlink" ] && rm -f "$symlink"
        [ -e "$symlink" ] && echo "$0[$$]: file already exists: $symlink"
        ln -s "$original" "$symlink"
done

分かりやすいログ配置に変えておくと、トラブル時の解析が楽になります。metalogと同様にsyslog-ngは単体でログ監視を行えるので活用してみてください。