Skip to content
Takashi Takizawa edited this page Jul 12, 2018 · 12 revisions

正規表現によるログファイル検索Nagiosプラグイン

特徴

  • 検知文字列のパターンを正規表現で指定できます。
  • 検知除外文字列のパターンが指定できます。これも正規表現で指定できます。
  • 複数のログファイルを一括してチェックすることができます。もちろん、ログローテーションされたファイルもチェックできます。
  • ログファイル毎にどこまでチェックしたかを記録するシークファイルを利用しているため、前回チェックからの差分だけをチェックできます。
  • 複数行に渡って同時に出力されたログメッセージを結合してからチェックすることができます。これにより、検知除外文字列の効果が発揮できるでしょう。
  • ログファイルの文字エンコーディングを指定できます。
  • 検知結果をキャッシュすることができます。複数の監視サーバーから監視を行う場合や監視サーバーが再試行を行う場合に役に立ちます。

元々は、このスクリプトは check_log3.pl に触発されていました。現在は、異なるオプションを持っています。

利用例

パターン

文字列を検知したい場合は、-p <pattern> あるいは -P <filename> オプションを追加します。

check_log_ng.py -p 'ERROR' -S /var/spool/check_log_ng -l '/var/log/messages'

あるいは

check_log_ng.py -P /path/to/pattern.txt -S /var/spool/check_log_ng -l '/var/log/messages'
$ cat /path/to/pattern.txt
ERROR
FATAL

除外パターン

検知したくない文字列を指定する場合は、-n <pattern> あるいは -N <filename> を指定します。 If you have character strings not to detect, you can add -n <pattern> or -N <filename> option.

check_log_ng.py -p 'ERROR' -n 'no problem' -S /var/spool/check_log_ng -l '/var/log/messages'

あるいは

check_log_ng.py -P /path/to/pattern.txt -N /path/to/negpattern.txt -S /var/spool/check_log_ng -l '/var/log/messages'
$ cat /path/to/negpattern.txt
no problem
information

大文字小文字の区別なし

大文字小文字を区別しない場合は、 -i オプションを追加します。

check_log_ng.py -i -p 'ERROR' -S /var/spool/check_log_ng -l '/var/log/messages'

複数行

次のように同時に複数行を出力するときには、 -M オプションを追加します。 ログフォーマットがsyslogの形式でない場合は、 -F/--format オプションで形式を指定してください。

2013/12/05 09:36:51,024 jobs-thread-5 ERROR ~ *** Called URI is: https://www.example.com/submit
2013/12/05 09:36:51,024 jobs-thread-5 ERROR ~ *** Response code is: 500
check_log_ng.py -F '^(%Y/%m/%d\s%T,\d+ \S+ \S+) (.*)$' -M -p 'ERROR' -S /var/spool/check_log_ng -l '/var/log/application.log'

これは、次のようなメッセージとして扱われます。

2013/12/05 09:36:51,024 jobs-thread-5 ERROR ~ *** Called URI is: https://www.example.com/submit ~ *** Response code is: 500

複数の監視項目

複数の監視項目がある場合は、シークファイルなどのファイル名の衝突を防ぐために -T <tag> オプションを追加します。

check_log_ng.py -T 'log_error' -p 'ERROR' -S /var/spool/check_log_ng -l '/var/log/messages'
check_log_ng.py -T 'log_block' -p 'BLOCK' -S /var/spool/check_log_ng -l '/var/log/messages'

監視間隔

監視間隔が180秒の場合は、監視間隔内は結果をキャッシュするように --cachetime=180 オプションを追加します。 これは複数の監視サーバーがある場合に役に立ちます。

check_log_ng.py --cachetime=180 -p 'ERROR' -S /var/spool/check_log_ng -l '/var/log/messages'

複数のログファイル

'message.N' や 'message-YYYYMMDD' のようなファイル名のログローテートされたログファイルをチェックする場合は、inode情報を追跡する -I -R オプションを追加できます。

check_log_ng.py -I -R -p 'ERROR' -S /var/spool/check_log_ng -l '/var/log/messages*'

ログローテーションの期間が1週間を超える場合は、 -E <seconds> オプションを追加できます。 この値はログローテーションの期間より長くする必要があります。 1ヶ月の場合は、32日間を意味する -E 2764800 を追加できます。

check_log_ng.py -I -R -E 2764800 -p 'ERROR' -S /var/spool/check_log_ng -l '/var/log/messages*'

出力の抑制

メッセージを抑制することで出力サイズを削減したいときには、-H/--output-header あるいは -q/--quiet オプションを使います。

抑制しない例

check_log_ng.py -p 'ERROR' -S /var/spool/check_log_ng -l '/var/log/messages'

Outout:

WARNING: Found 1 lines (limit=1/0): Jul 11 06:44:22 hostname app: ERROR Unable to access to 192.0.2.1 at /var/log/messages

-H/--output-header を使う例

check_log_ng.py -p 'ERROR' -H -S /var/spool/check_log_ng -l '/var/log/messages'

Outout:

WARNING: Found 1 lines (limit=1/0, HEADER): Jul 11 06:44:22 hostname app:  at /var/log/messages

-q/--quiet を使う例

check_log_ng.py -p 'ERROR' -Q -S /var/spool/check_log_ng -l '/var/log/messages'

Outout:

WARNING: Found 1 lines (limit=1/0, QUIET): at /var/log/messages

ドライラン

ドライランを行いたいときには、--dry-run オプションを追加します。 シークファイルは更新されなくなり、キャッシュファイルは使われなくなります。 ログフォーマットの指定が正しくないときには、エラーが出力されるようになります。

check_log_ng.py --dry-run -p 'ERROR' -S /var/spool/check_log_ng -l '/var/log/messages'

オプションの解説

状態ファイル用ディレクトリの指定(-S, --state-directory)

-S オプションで状態ファイル(シークファイル、キャッシュファイル、ロックファイル)を格納するディレクトリを指定します。

-S /var/spool/check_log_ng

ログファイルの指定(-l, --logfile)

-l オプションでログファイルを指定します。 ログファイルのファイル名のパターンは絶対パスで指定してください。 また、ファイルの絶対パス名には空白文字を含めることができません。

-l '/var/log/messages'

複数ログファイルの指定

ファイル名のパターンとしてメタキャラクタの *? に対応しています。次の例のように記述できます。 メタキャラクタを指定するときには引用符で囲ってください。

-l '/var/log/messages*'

ただし、ログファイルのファイル名のパターンにはメタキャラクタの []{} は利用できません。使用するとシークファイルのパージ機能が正常に動作しなくなります。

ファイル名は引用符で囲ってスペース区切りでも記述できます。次の例のように記述できます。

-l '/var/log/messages /var/log/messages.????????'

パターンに一致するファイルがたくさんある場合でも、ログファイルのタイムスタンプのチェックも行っているため、-t オプションで指定した時間以降に更新の無いログファイルのチェックを行わずに済みます。 -t オプションの値はデフォルトは86400秒(1日)です。

ログフォーマットの指定(-F, --format)と複数行対応(-M, --multiline)

syslog 以外の複数行出力のあるログファイルの場合については、 -F オプションと -M オプションを指定してください。 これにより、同時に出力された複数行のエラーに対応することができます。 なお、 -F オプションの指定が無い場合は syslog の形式と判断します。 -M オプションがない場合は、1行ごとに処理を行います。

同時に出力されたメッセージを判断するために、タイムスタンプやタグ等の情報を利用しています。 例えば、次のようなログ出力があるときには 2013/12/05 09:36:51,024 jobs-thread-5 ERROR が同じであるため、同時出力されたメッセージと見なすようにします。

2013/12/05 09:36:51,024 jobs-thread-5 ERROR ~ *** Called URI is: https://www.example.com/submit
2013/12/05 09:36:51,024 jobs-thread-5 ERROR ~ *** Response code is: 500

このとき、メッセージの内容を結合して、次のような1行のメッセージと見なしてからパターンのチェックを実施します。

2013/12/05 09:36:51,024 jobs-thread-5 ERROR ~ *** Called URI is: https://www.example.com/submit ~ *** Response code is: 500

そのため、複数行のログメッセージを同時出力と見なすためのキーとなる情報(タイムスタンプ、ホスト名、タグ、プロセスID、スレッドID、ログレベル等)を正規表現の"(式)"の形式でグルーピングしてください。 正規表現の後方参照の1つ目をキーとします 。 さらに、残りのメッセージのパートを (.*) でまとめてグルーピングしてください。 正規表現の後方参照の2つ目をメッセージと見なします 。 他の箇所で括弧 (〜) を使うときには (?:〜) の形式を使って後方参照しないようにしてください。 また、正規表現の他に strftime(3) の次のパターンが利用できます。

%%  文字%
%Y  年(4桁)
%y  年(2桁)
%a  曜日(Sun..Sat)
%b  月(Jan..Dec)
%m  月(01..12)
%d  日(01..31)
%e  日( 1..31)
%H  時(00..23)
%M  分(00..59)
%S  秒(00..60)
%F  %Y-%m-%d
%T  %H:%M:%S

実行時に内部的に正規表現に展開されます。

--dry-run オプションを付与して、ドライランを実行すると、ログフォーマットが正しくないときにはエラーが出力されます。 これにより、ログフォーマットが正しいかを確認することができます。syslog形式以外の場合は必ず確認するようにしてください。

フォーマットの指定例

Apacheのエラーログの例:

[Thu Dec 05 15:03:20 2013] [error] [client ::1] Directory index forbidden by Options directive: /var/www/html/

オプションの指定:

-F '^(\[%a %b %d %T %Y\] \[\S+\]) (.*)'

アプリケーションログの例:

2013/12/05 09:36:51,024 jobs-thread-5 ERROR ~ *** Called URI is: https://www.example.com/submit
2013/12/05 09:36:51,024 jobs-thread-5 ERROR ~ *** Response code is: 500

オプションの指定:

--format='^(%Y/%m/%d %T,\d+ \S+ \S+) (.*)'

※ NRPEの設定ファイル上で $ を用いるとエラーが発生しますので注意しましょう。 なお、ログフォーマットのパターンに一致しない行は前の行に対する継続行と見なされ、前の行に結合されます。

監視パターンの指定

監視パターンの指定(-p, --pattern, -P, --patternfile)

監視文字列のパターンは -p オプションを用いて指定します。 監視文字列が複数あるときには行毎にパターンを書いたファイルを用意して -P オプションの引数としてファイル名を指定します。 パターンは正規表現を用いて指定することができます。

重篤な監視パターンの指定(--critical-pattern, --critical-patternfile)

WARNING ではなく CRITICAL と判定させたい場合は、-p, -P オプションの代わりに --critical-pattern , --critical-patternfile オプションを用いて監視パターンを指定します。

除外パターンの指定(-n, --negpattern, -N, --negpatternfile)

検知を除外する文字列のパターン(ネガティブパターン)があるときには、 -n オプションに正規表現で指定します。 除外文字列が複数あるときには行毎にパターンを書いたファイルを用意して -N オプションでファイル名を指定します。

-n または -N によって除外パターンを指定した場合、 -p または -P で指定した監視パターンにマッチするメッセージが出力されている場合でも、 同時に除外パターンにマッチするメッセージが出力されている場合には、アラートは発報しません。 なお、重篤な監視パターンについては無視をせず、通常通りアラート発報します。

除外パターンを指定するケースについて説明します。 例えば、次のようなログ出力があるとします。

2013/12/05 09:36:51,024 jobs-thread-5 ERROR ~ *** Called URI is: https://www.example.com/submit ~ *** Response code is: 400 ~ *** Reason: expired

ここで、エラーの理由が"expired"の場合には検知を除外したいとします。 この場合は監視パターンに"ERROR"を指定して、除外パターンとして"Reason: expired"を指定すればよいでしょう。

より強力な除外パターンの指定(--critical-negpattern, --critical-negpatternfile)

-n または -N では、 --critical-pattern または --critical-patternfile で指定された監視パターンが存在する場合には、無視をせずアラートを発報します。

--critical-negpattern または --critical-negpatternfile によって除外パターンを指定した場合、 監視パターンにマッチするメッセージが出力されている場合でも、 同時に除外パターンにマッチするメッセージが出力されている場合には、それらを無視してアラートは発報しません。 重篤な監視パターンについても無視します。

大文字小文字を区別しない(-i, --case-insensitive)

-i オプションを指定することで、大文字小文字を区別せずにパターンマッチを指定行います。 このオプションの指定は、監視パターンマッチと除外パターンマッチの両方に適用されます。

文字エンコーディングの指定 (--encoding)

ログファイルの文字エンコーディングの指定を行います。 デフォルトはUTF-8です。

検知回数の指定(-w, --warning, -c, --critical)

-w オプションと -c オプションは、 WARNING や CRITICAL になる検知回数を指定します。 デフォルトでは -w が 1 で -c が 0 であるため、検知文字列が見つかれば WARNING となります。 なお、--critical-pattern--critical-patternfile で指定した文字列が検知された場合は、-w-c の設定に関わらず CRITICAL になります。

スキャン期間の指定(-t, --scantime)

複数のログファイルを指定する場合、マッチするすべてのログファイルを毎回検索する必要はありません。更新のないログファイルは検索する必要がないからです。

-t <seconds> オプションを用いることで、指定した期間内に更新がないファイルは検索対象外となります。

シークファイルの管理

inode ベースのシークファイル作成(-I, --trace-inode)

-I オプションを指定することで、シークファイルのファイル名に inode の情報を埋め込みます。 これにより、シークファイルは inode ベースで管理されます。

inode ベースでシークファイルを管理すると、ログローテート後に、他のログファイルで用いていたシークファイルが使いまわされるという問題を回避することができます。 そのため、複数ファイル指定する場合はこのオプションの指定を強く推奨します。

シークファイルの保存期間の指定(-E, --expiration)

シークファイルの保存期間を秒単位で指定します。デフォルトは 691200 秒(8日)です。 この値は、ログローテーション期間より大きい値を指定してください。

なお、後述する -R オプションを指定していない場合、シークファイルは削除されません。

期限切れのシークファイルの削除(-R, --remove-seekfile)

-R を指定することで、期限切れのシークファイルを削除します。 期限の指定は、-E オプションで指定します。

キャッシュの有効期間 (--cachetime)

検知結果をキャッシュする期間を指定します。 監視間隔に合わせてください。

キャッシュを無効にする場合は 0 を指定します。

ロックタイムアウト (--lock-timeout)

同時にこのプラグインが動作した場合にロック待ちを行う時間を指定します。 タイムアウトした場合はUNKNOWNステータスが返ります。

動作要件

  • Python 2.6, 2.7, 3.5 or 3.6.
  • Python 2.6では argparse モジュールが必要です。

インストール

check_log_ng のgitリポジトリから取得します。

$ git clone git@github.com:heartbeatsjp/check_log_ng.git
$ cd check_log_ng

実行権限を付与します。

$ chmod 755 check_log_ng.py

このプラグインをnagiosプラグインのディレクトリにコピーします。

$ sudo cp check_log_ng.py /usr/lib64/nagios/plugins/

キャッシュファイル、ロックファイル、シークファイルを格納するディレクトリを作成します。

$ sudo mkdir /var/spool/check_log_ng

このディレクトリのオーナーをnrpeの実行ユーザーに変更します。

$ sudo chown nrpe: /var/spool/check_log_ng

ログファイルの読み取りにroot権限が必要な場合は、sudoersファイルに次の行を追加します。

Defaults:nrpe !requiretty
nagios ALL=(root) NOPASSWD: /usr/lib64/nagios/plugins/check_log_ng.py

Python 2.6で動かす場合は、argparseモジュールをインストールします。

RHEL6/CentOS6を使っている場合は、次のようにします。

$ sudo yum install python-argparse

以上でインストール完了です。

その他

デバッグする場合は-Oオプションをpythonのオプションとして指定してください。 また、-hまたは--helpを指定することで以下のようにオプション一覧が出力されます。

$ check_log_ng.py -h
usage: check_log_ng.py [options] [-p <pattern>|-P <filename>] -S <directory> -l <filename>

A log file regular expression-based parser plugin for Nagios.

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --dry-run             Do dry run. The seek files are not updated and cache
                        file is not used. If log format is not correct, it
                        prints an error message.
  -l <filename>, --logfile <filename>
                        The file names of log files to be scanned. The
                        metacharacters * and ? are available. To set multiple
                        files, set a space between file names. See also
                        --scantime.
  -F <format>, --format <format>
                        Regular expression for log format. It requires two
                        groups in format of '^(HEADER)(.*)$'. HEADER includes
                        TIMESTAMP, HOSTNAME, TAG and so on. Also, it may use
                        %%, %Y, %y, %a, %b, %m, %d, %e, %H, %M, %S, %F and %T
                        of strftime(3). (default: regular expression for
                        syslog.
  -s <filename>, --seekfile <filename>
                        Deprecated. Use -S option instead. The file name of
                        the file to store the seek position of the last scan.
  -S <directory>, --state-directory <directory>, --seekfile-directory <directory>
                        The directory to store seek files, cache file and lock
                        file. '--seekfile-directory' is for backwards
                        compatibility.
  -T <tag>, --tag <tag>, --seekfile-tag <tag>
                        Add a tag in the file names of state files, to prevent
                        names collisions. Useful to avoid maintaining many
                        '-S' directories when you check the same files several
                        times with different args. '--seekfile-tag' is for
                        backwards compatibility.
  -I, --trace-inode     If set, trace the inode of the log file. After log
                        rotatation, you can trace the log file.
  -p <pattern>, --pattern <pattern>
                        The regular expression to scan for in the log file.
  -P <filename>, --patternfile <filename>
                        The file name of the file containing regular
                        expressions, one per line.
  --critical-pattern <pattern>
                        The regular expression to scan for in the log file. If
                        found, return CRITICAL.
  --critical-patternfile <filename>
                        The file name of the file containing regular
                        expressions, one per line. If found, return CRITICAL.
  -n <pattern>, --negpattern <pattern>
                        The regular expression which all will be skipped
                        except as critical pattern in the log file.
  -N <filename>, -f <filename>, --negpatternfile <filename>
                        The file name of the file containing regular
                        expressions which all will be skipped except as
                        critical pattern, one per line. '-f' is for backwards
                        compatibility.
  --critical-negpattern <pattern>
                        The regular expression which all will be skipped in
                        the log file.
  --critical-negpatternfile <filename>
                        The file name of the file containing regular
                        expressions which all will be skipped, one per line.
  -i, --case-insensitive
                        Do a case insensitive scan.
  --encoding <encoding>
                        Specify the character encoding in the log file.
                        (default: utf-8)
  -w <number>, --warning <number>
                        Return WARNING if at least this many matches found.
                        (default: 1)
  -c <number>, --critical <number>
                        Return CRITICAL if at least this many matches found.
                        i.e. don't return critical alerts unless specified
                        explicitly. (default: 0)
  -t <seconds>, --scantime <seconds>
                        The range of time to scan. The log files older than
                        this time are not scanned. (default: 86400)
  -E <seconds>, --expiration <seconds>
                        The expiration of seek files. This must be longer than
                        the log rotation period. The expired seek files are
                        deleted with -R option. (default: 691200)
  -R, --remove-seekfile
                        Remove expired seek files. See also --expiration.
  -M, --multiline       Treat multiple lines outputted at once as one message.
                        If the log format is not syslog, set --format option.
                        See also --format.
  --cachetime <seconds>
                        The period to cache the result. To disable this cache
                        feature, set '0'. (default: 60)
  --lock-timeout <seconds>
                        The period to wait for if another process is running.
                        If timeout occurs, UNKNOWN is returned. (default: 3)
  -H, --output-header   HEADER mode: Suppress the output of the message on
                        matched lines. Only HEADER(TIMESTAMP, HOSTNAME, TAG
                        etc) is outputted. If the log format is not syslog,
                        set --format option. See also --format.
  -q, --quiet           QUIET mode: Suppress the output of matched lines.

修正履歴

  • 2018-07-12 2.0.8 Add --output-header, --quiet, --dry-run
  • 2018-01-31 2.0.0 Add --cachetime, --lock-timeout, --encoding
  • 2015-01-14 1.0.8 Refactor for PEP8, pyflake8.
  • 2014-06-18 1.0.7 Fix bugs.
  • 2014-03-31 1.0.6 Add --critical-negpattern options.
  • 2014-03-11 1.0.5 Add ---multiline options.
  • 2014-03-05 1.0.4 Add --trace-inode options.
  • 2013-12-27 1.0.3 Change an OK message.
  • 2013-12-20 1.0.2 Revise version processing and fix a help message.
  • 2013-12-20 1.0.1 Fix check argc and parse logformat variable.
  • 2013-12-05 1.0.0 Initial release.
Clone this wiki locally