OXY NOTES

障害報告・アラート表示・ログのデータベースへの出力と活躍するrsyslogの使い方

カーネル、SSH、Webにメールと、さまざまな形のログに対応したrsyslog

rsyslogとはサーバ上のさまざまなログ収集を一手に引き受けるソフトです。

エラーが起きた時にメールで通知したり、データベースで利用可能な形に変更する事もできます。上手く利用すれば、サーバの管理は劇的に楽になります。


目次

rsyslogとはなにか
rsyslogの動作確認
rsyslogの設定ファイル
グローバル・ディレクティブについて
モジュール・ディレクティブについて
ルールについて
プロパティベースのフィルター
式ベースのフィルター
アクション


rsyslogとはなにか

これについてはRed Hatによる解説が端的で解りやすいので、そのまま引用させてもらいます。


Red Hatによると

rsyslog は sysklogd と同じ機能を持ちながら、強化されたフィルタリング、暗号化で保護されたメッセージのリレー、各種設定オプション、TCP または UDP プロトコルによる転送のサポートにより拡張します。rsyslog と sysklogd は互換性がある点に注意して下さい。

Red Hat ログファイルの表示と管理 より

つまりログ収集と言えばsysklogdでしたが、これからのログ収集はrsyslogで決まり!ということです。


rsyslogの動作確認

まずはインストール済みか確かめるために、バージョンを調べます。

# /sbin/rsyslogd -v
rsyslogd 4.4.2, compiled with:
        FEATURE_REGEXP:                         Yes
        FEATURE_LARGEFILE:                      Yes
        FEATURE_NETZIP (message compression):   Yes
        GSSAPI Kerberos 5 support:              Yes
        FEATURE_DEBUG (debug build, slow code): No
        Atomic operations supported:            Yes
        Runtime Instrumentation (slow code):    No

See http://www.rsyslog.com for more information.

どうやら4.4.2がインストールされているようです。インストールされていない場合は以下のコマンドでインストールしておいてください。(syslogがインストールされている場合は停止して関連ファイルを削除してください)

# yum install rsyslog

rsyslogの設定ファイル

早速設定ファイルを見ていきます。設定ファイルは以下のコマンドで表示することができます。

# cat /etc/rsyslog.conf

設定ファイルは「グローバル・ディレクティブ」「モジュール・ディレクティブ」「ルール」の3つからなっています。それぞれの構文について見ていきます。


グローバル・ディレクティブについて

rsyslog全体の設定をします。ログのタイムアウトに関する調整や、負荷の調整等を行います。

rsyslog.conf」では以下の行から下がグローバル・ディレクティブの設定になります。

#### GLOBAL DIRECTIVES ####

書式

行頭に$を付けて、1行に1つという構成で記述します。

例)rsyslogメッセージキューの最大サイズを指定

$MainMsgQueueSize 50000

別のグローバル指示文についてのマニュアルは以下のディレクトリを参照。

/usr/share/doc/rsyslog-<version-number>/rsyslog_conf_global.html

バージョン4.4.2なら以下のようになる。

/usr/share/doc/rsyslog-4.4.2/rsyslog_conf_global.html

たくさん項目がありますが、普通にログを取るだけならデフォルトの設定で問題ありません。


モジュール・ディレクティブについて

rsyslogは多くのモジュールを使って管理します。
この仕組のお陰で書式の違うログをrsyslogで一元管理することができます。例えば「カーネルのログとメールのログを別のサーバのSQLに出力する」ということも可能です。

rsyslog.conf」では以下の行から下がモジュール・ディレクティブの設定になります。

#### MODULES ####

書式

$ModLoad MODULE_name

モジュールには以下のものがあります。

入力モジュール 様々なソースから情報を収集するモジュール。
Inputの頭文字を取ってinという接頭辞ではじまる。例)imfile や imrelp
出力モジュール データベースへの書き込み、ネットワークを介した書き込みの制御など。
Outputの頭文字を取ってouという接頭辞ではじまる。例)omsnmp や omrelp
フィルタ・モジュール メッセージのフィルタリングをする。接頭辞 fm
パーサモジュール 構文解析などを行う。接頭辞 pm
メッセージ修正モジュール メッセージの内容を変更する。接頭辞 mm
文字列ジェネレーターモジュール メッセージの内容を基にして文字列を生成する。接頭辞 sm
ライブラリモジュール 他のロード可能なモジュールに機能性を提供する。

それぞれのモジュールについて詳しく知りたい方は、公式のモジュールページを参照してください。


ルールについて

どのソースから情報を取得するか、どのフィルターを利用するか、どこにログファイルに書きだすか、などのルールを決定します。
各種フィルターを用いることで必要なログだけを効率的に収集することができるようになります。

rsyslog.conf」では以下の行から下がルールの設定になります。

#### RULES ####

ルールの書式

<FACILITY>.<PRIORITY>

ファシリティー(FACILITY)とはログメッセージを生成するサブシステム。メールであればmail。iptablesであればkernと言った具合にそれぞれソフトで決められています。

それぞれのファシリティーコード番号で表現されることもある。対応するコード番号とファシリティーの一覧は以下のとおりです。

コード Facility 意味
0 kern カーネルメッセージ
1 user ユーザーレベルメッセージ
2 mail メール
3 daemon デーモン
4 auth セキュリティ認証
5 syslog syslogサーバメッセージ
6 lpr ランプリター
7 news ネットニューズ
8 uucp UUCP
9 cron クーロンまどクロックデーモン
10 authpriv セキュリティ認証(プライベート)
11 ftp FTP
16~23 local0~7 ローカルの予約(任意の用途で利用可能)

プライオリティー(PRIORITY)は優先度を指定する。

それぞれのコード番号は以下のとおり。

コード PRIORITY 意味
0 emerg 致命的
1 alert 警戒
2 crit 危機的
3 err エラー
4 warning 警告
5 notice 通知
6 info 情報提供
7 debug デバック

ファシリティーとプライオリティを組み合わせた実際の使用例

書式ばかりだと分かりにくいと思うので実際の使用例。

例)kern(カーネル)で書きだされたログの内、優先度debugのログを収集

kern.=debug

例)kern(カーネル)で書きだされた全ての優先順位のログを収集

kern.*

例)kern(カーネル)からinfoとdebugの値を削除したログ

kern.!info,!debug

プロパティベースのフィルター

ルールでは上記のファシリティープライオリティだけでなく、更に細かくプロパティベースのフィルターを使ってログを振り分けることができます。
例えばメールのログの内、特定のホスト宛のログだけ記録したい場合などに利用します。

プロパティベースのフィルターの書式

:<PROPERTY>, [!]<COMPARE_OPERATION>, "<STRING>"

それぞれの構文の意味と指定可能な項目は以下のとおりです。

<PROPERTY>(プロパティ)はログのどの部分から比較する情報を得るかを指定します。メッセージ(msg)ホスト名(hostname)、上で解説したファシリティ(syslogfacility-text)プライオリティ(syslogpriority-text)も指定できます。

プロパティで利用できるマクロ一覧

msg ログメッセージ
hostname ログを出力したホストの名前
fromhost ログを受け取ったホストの名前
programname プログラム名
syslogfacility ファシリティ(数字)
syslogfacility-text ファシリティ(テキスト)
syslogseverity プライオリティ(数字)
syslogseverity-text プライオリティ(テキスト)
syslogpriority syslogseverityと同等
syslogpriority-text syslogseverity-textと同等
timegenerated ログを受け取った日時
timereported ログが出力された日時
timestamp timereportedと同等
$now 現在時刻(書式:YYYY-MM-DD)
$year 現在の年(4けた)
$month 現在の月(2けた)
$day 現在の日(2けた)
$hour 現在の時(24時間表記、2けた)
$minute 現在の分(2けた)

<COMPARE_OPERATION>(コンペアオペレーション)属性は指定した文字列とどのように適合させるかを指定します。
必ず以下のいずれかの比較処理から選ぶ。

contains 指定された文字列が、プロパティにより提供されたテキストの一部にマッチするかどうかを確認します。
isequal 指定された文字列を、プロパティにより提供されたすべてのテキストと比較します。
startswith 指定された文字列が、プロパティにより提供されたテキストの接頭辞にマッチするかどうかを確認します。
regex 指定された POSIX BRE (Basic Regular Expression) 正規表現をプロバティにより提供されたテキストと比較します。
ereregex 指定された POSIX ERE (Extended Regular Expression) 正規表現をプロパティにより提供されたテキストと比較します。

<STRING>属性は比較する文字列を指定します。

例)メッセージの文字列に(接頭辞)IPTABLES PINGDEATHが含まれているもの

:msg, contains, "IPTABLES PINGDEATH"

例)メッセージテキスト内に文字列 errorがあるもの

:msg, contains, "error"

例)正規表現で「fatal .* error」を含まないもの(.*は任意の文字の0回以上の繰り返し。比較処理に!があるので否定になる)

:msg, !regex, "fatal .* error"

式ベースのフィルター

イコールor演算子などを利用してマッチする場合にログを書き出す。比較対象の文字列が動的な場合などに有効。

ルールの書式

if <EXPRESSION> then <ACTION>

<EXPRESSION>属性には式を入れる。先頭に「$」を付けて、プロパティの比較に利用することができる。$msg startswith ‘DEVNAME’$syslogfacility-text == ‘local0’など。
<ACTION>には式がtrueの場合に実行される動作を指定する。

※式ベースのフィルターは条件から動作までを1行で書く必要がある。一致させる文字列はシングルクォートで囲む必要がある。また、正規表現を使った式は利用できない。(その場合はプロパティベースのフィルターでregexを使う)

例)ログの文字列にtestを含まない

if not ( $msg contains 'test' ) then

例)ログの文字列にtestを含み、プライオリティがdebagの場合

if ( $msg contains 'test' ) and ( $syslogseverity-text == 'debag' ) then

アクション

上記のプライオリティやファシリティーまたはフィルターを使った一致する条件のことをまとめて「セレクタ」とよびます。そのセレクタの扱いを決めるのが「アクション」です。
ファイルへの書き込み、データベースへの書き込み、メールでの転送、外部サーバへの転送など、さまざまなアクションが用意されています。

アクションの書式

セレクタとアクションの間にはスペースかタブを挟みます。

<セレクタ> <アクション>

ファイル(ディレクトリ)へ書き出す方法

最もよく使う、基本的なアクションです。保存したいファイルをルートから指定します。

例)カーネルのログを/var/log/cron.logに書き出す

cron.* /var/log/cron.log

外部サーバへログデータを書き出す

ログはトラフィックが高くなると負荷が高くなり、サイズも膨大になります。そのためログを外部サーバへ書き出すこともあります。

外部サーバへログデータを書き出す書式

@[(<OPTION>)]<HOST>:[<PORT>]

@(アットマーク)」は1つだとUDP、2つだとTCPで送信する。TCPのほうが正確なログ取得が可能で、安全性が高いため、使用が推奨されている。

<OPTION>属性は「z<NUMBER>」を指定する。ログのzlib圧縮が可能。NUMBERは圧縮レベルを指定する。
<HOST>属性はメッセージの送信先を指定。IPもしくはドメイン名を指定する。
<PORT>属性は送信するポートを指定する。

例)UDPで192.168.0.1へ転送

*.* @192.168.0.1

例)TCPで[2001::1](IPv6)へ圧縮レベル9で転送

*.* @@(z9)[2001::1]

出力チャンネル

ログファイルのローテーションについて指定します。

便利な機能ですがローテートの指定はlogrotate.confがあるので、この機能は廃止予定だそうです。

出力チャンネルの書式

$outchannel <NAME>, <FILE_NAME>, <MAX_SIZE>, <ACTION>

<NAME>属性は、出力チャンネルの名前を指定します。
<FILE_NAME>属性は、出力ファイルの名前を指定します。
<MAX_SIZE>属性は、(<FILE_NAME> 内にある) 指定されたファイルが拡張できる最大サイズを表します。この値は バイト 単位で指定します。
<ACTION>属性は、<MAX_SIZE> で定義される最大サイズに到達した時に取るべき動作を指定します。

例)log_rotationという名前のチャネルを作成。/var/log/test_log.logにログを作成して、サイズが104857600になったら/home/joe/log_rotation_scriptを実行。

$outchannel log_rotation,/var/log/test_log.log, 104857600, /home/joe/log_rotation_script
*.* $log_rotation

特定ユーザーへの転送

複数のユーザーを指定するには、各ユーザー名をカンマ (,) で区切る。
致命的なエラーを特定のユーザーのコンソールに表示するようにしておけばログファイルを解析するまでもなく問題を把握できます。

例)user1とuser2のコンソールに表示

*.* user1,user2

プログラムの実行

プログラムへデータを渡すこともできる。プログラム名にキャレットを付けて実行する。ログを直接シェルスクリプトに渡せば手間を省くことができます。

例)テンプレートの形式で整形され、programへデータを渡す。

*.* ^program;template

※テンプレートについては後述

データベースへの書き込み

直接データベースへ書き込むこともできます。デフォルトではMySQLには対応していないので、モジュールを読み込む必要があります。

# MySQLの場合
$ModLoad ommysql 

# PostgreSQLの場合
$ModLoad ompgsql 

データベースへの書き込む際の書式

:<PLUGIN>:<DB_HOST>,<DB_NAME>,<DB_USER>,<DB_PASSWORD>;[<TEMPLATE>]

<PLUGIN> は、データベースの書き込みを処理する指定プラグインを呼び出します (例えば ommysql プラグイン)。
<DB_HOST> 属性は、データベースのホスト名を指定します。
<DB_NAME> 属性は、データベースの名前を指定します。
<DB_USER> 属性は、データベースのユーザーを指定します。
<DB_PASSWORD> 属性は、前述のデータベースユーザーが使用するパスワードを指定します。
<TEMPLATE> 属性は、オプションである syslog メッセージを修正するテンプレートの使用を指定します。※テンプレートについては後述

テンプレート

テンプレートでログを決まった形式で整えることができます。rsyslogで定義されているマクロを使うことができます。それぞれのマクロを「%」で囲むことで利用できます。ログメッセージの場合は「%msg%」など

テンプレートの書式

$template <TEMPLATE_NAME>,"text %<PROPERTY>% more text", [<OPTION>]

$templateはテンプレートであることを表す書式

<TEMPLATE_NAME>はテンプレートの名前を定義する。

“”」で囲まれた範囲は、テキストの内容を表す。改行や”などを使う場合はエスケープ処理する必要がある。

[<OPTION>]はテンプレートを修正するオプションを指定する。SQLへデータを書き出すsql と stdsqlなど。

例)日時とログの内容を出力する

$template <TEMPLATE_NAME>,"日時:%timegenerated% 内容:%msg%\n"

以上でrsyslogの概要と、基本的な利用方法でした。

次のページでは「rsyslogを利用したログファイル作成と、logrotateを利用したログのローテーション」について解説します。