7.5. ログファイルの名前付きパイプへの置き換え

多くの管理者は、特定のイベントのみを記録するようにアクセスログを設定するなど、ロギングデータに関して特別な設定や操作を行う必要があります。標準の Directory Server ログファイル設定属性を使用してこれを行うことはできませんが、ログデータを名前付きパイプに送信し、別のスクリプトを使用してデータを処理することで可能になります。ログに名前付きパイプを使用すると、以下のような特別なタスクが簡素化されます。

  • 特定のユーザーまたは IP アドレスからのバインドの試みや接続の失敗など、特定イベントをログに記録する
  • 特定の正規表現パターンにマッチするエントリーをログに記録する
  • ログを特定の期間保持する (最後の行番号のみをログに記録する)
  • イベント発生時にメールなどの通知を送信する

ログファイルをパイプに置き換えると、特に操作率が高いサーバーではパフォーマンスが向上します。

ログバッファーでのデータ処理方法により、名前付きパイプは、スクリプトを使用してログからのデータを抽出することとは異なります。

ログがバッファーされると、サーバーのパフォーマンス的には良好ですが、重要なデータがイベントの発生直後にディスク (ログファイル) に書き込まれません。サーバーでクラッシュの問題がある場合は、データがディスクに書き込まれる前にクラッシュし、スクリプトが抽出するためのデータがないことがあります。

ログがバッファーされない場合[1]、書き込みは各操作でディスクにフラッシュされるため、ディスク I/O とパフォーマンスが大幅に低下します。

ログディスクファイルをパイプに置き換えると、バッファーに利点があります。これは、パイプから読み取るスクリプトがメモリー内に受信ログデータをバッファーできるためです (単純なスクリプトでは不可能)。

スクリプトの使用方法およびオプションの詳細は、「ds-logpipe.py」で説明されています。基本的な形式は、ds-logpipe.py/path/to/named_pipe--userpipe_user--maxlinesnumber--serverpidfilefile.pid--serverpidPID--servertimeoutseconds--plugin=/path/to/plugin.pypluginfile.arg=value です。

7.5.1. ロギングへの名前付きパイプの使用

Directory Server インスタンスは、名前付きパイプログスクリプトを実行し、パイプの名前を指定するだけで、ロギングに名前付きパイプを使用できます。(サーバーがすでに実行中の場合は、ログを再度開く必要がありますが、それ以外の設定は必要ありません)。

# ds-logpipe.py /var/log/dirsrv/slapd-example/access

このように ds-logpipe.py を実行することには、実装が簡単であり、Directory Server 設定を変更する必要がない、という利点があります。これは、特に特定のイベントタイプを検索する場合に、高速のデバッグまたはモニタリングに役立ちます。

Directory Server インスタンスがロギング用に実際のファイルではなく名前付きパイプを頻繁に、または永続的に使用する場合には、(デフォルトでログファイルを使用するのと同じように) 名前付きパイプを作成してロギングに使用するようにインスタンスを再設定することができます。

インスタンスのログ設定には、3 つの項目を設定する必要があります。

  • 使用するログファイルをパイプに変更しなければなりません (nsslapd-*log: ここで、*は設定されるログタイプに応じて access、error、または audit[2]のいずれかです)。
  • スクリプトがログエントリーをバッファーするため、バッファーを無効にする必要があります (nsslapd-*log-logbuffering)。
  • サーバーが名前付きパイプのローテーションを試行しないように、ログローテーションを無効にする必要があります (nsslapd-*log-maxlogsperdirnsslapd-*log-logexpirationtime、および nsslapd-*log-logrotationtime)。

これらの設定変更は、Directory Server Console で行うか、ldapmodify を使用して実行できます。

たとえば、これによりアクセスログが access.pipe に切り替わります。

# ldapmodify -D "cn=Directory Manager" -W -p 389 -h server.example.com -x

dn: cn=config
changetype: modify
replace: nsslapd-accesslog
nsslapd-accesslog: /var/log/dirsrv/slapd-instance/access.pipe
-
replace: nsslapd-accesslog-logbuffering
nsslapd-accesslog-logbuffering: off
-
replace: nsslapd-accesslog-maxlogsperdir
nsslapd-accesslog-maxlogsperdir: 1
-
replace: nsslapd-accesslog-logexpirationtime
nsslapd-accesslog-logexpirationtime: -1
-
replace: nsslapd-accesslog-logrotationtime
nsslapd-accesslog-logrotationtime: -1
注記

これらの変更を行うと、サーバーは現在のログファイルを閉じ、即座に名前付きパイプに切り替えます。これは、実行中のサーバーのデバッグや、特定のメッセージのログ出力を移動するのに非常に便利です。

7.5.2. サーバーで名前付きパイプを起動する

インスタンスの init スクリプト設定ファイルを編集して、名前付きパイプを Directory Server インスタンスと共に起動およびシャットダウンできます。

注記

名前付きパイプスクリプトは、サーバーの起動時に呼び出す前にインスタンスの dse.ldif ファイルで明示的に設定する必要があります。

  1. サーバーシステムのインスタンス設定ファイルを開きます。

    /etc/sysconfig/dirsrv-instance_name
    警告

    /etc/sysconfig/dirsrv ファイルを編集 しない でください。

  2. ファイルの末尾に、以下という行があります。

    # Put custom instance specific settings below here.

    その行の下に ds-logpipe.py コマンドを挿入し、サーバーの起動時に起動します。以下に例を示します。

    # only keep the last 1000 lines of the error log
    python /usr/bin/ds-logpipe.py /var/log/dirsrv/slapd-example/errors.pipe -m 1000 -u dirsrv -s /var/run/dirsrv/slapd-example.pid > /var/log/dirsrv/slapd-example/errors &
    
    # only log failed binds
    python /usr/bin/ds-logpipe.py /var/log/dirsrv/slapd-example/access.pipe -u dirsrv -s /var/run/dirsrv/slapd-example.pid --plugin=/usr/share/dirsrv/data/failedbinds.py failedbinds.logfile=/var/log/dirsrv/slapd-example/access.failedbinds &
    注記

    -s オプションは、どちらも PID を書き込むサーバー用の .pid ファイルを指定し、サーバープロセスで起動および停止するようにスクリプトを設定します。

7.5.3. 名前付きパイプログでのプラグインの使用

プラグインは、名前付きパイプからログデータを読み取り、操作を実行するために呼び出すことができます。名前付きパイプログスクリプトによりプラグインを使用する場合、いくつかの考慮事項があります。

  • プラグイン関数は、名前付きパイプから読み取られる各行に対して呼び出されます。
  • プラグイン関数は Python スクリプトで、.py で終了する必要があります。
  • プラグインの引数は、コマンドラインで名前付きパイプ ログスクリプトに渡されます。
  • プラグインの読み込みタイミングに関して、事前操作関数を指定できます。
  • スクリプトの終了タイミングに関して、事後操作関数を呼び出すことができます。

7.5.3.1. 名前付きパイプログスクリプトを使用したプラグインの読み込み

プラグインに使用する ds-logpipe.py には、以下の 2 つのオプションがあります。

  • --plugin オプションはプラグインファイル (Python スクリプトで、.py で終了する必要があります) へのパスを提供します。
  • plugin.arg オプションは、プラグイン引数を名前付きパイプログスクリプトに渡します。プラグインファイル名 ( .py 拡張子なし) は plugin で、そのプラグインで許可される任意の引数は arg です。

以下に例を示します。

ds-logpipe.py /var/log/dirsrc/slapd-example/errors.pipe --plugin=/usr/share/dirsrv/data/example-funct.py example-funct.regex="warning" > warnings.txt

同じ引数に複数の値を渡すと、それらはプラグインディクショナリーの値のリストに変換されます。たとえば、このスクリプトでは、arg1 に 2 つの値を指定します。

--plugin=/path/to/pluginname.py pluginname.arg1=foo pluginname.arg1=bar pluginname.arg2=baz

プラグインでは、これは次のように変換されます。

{'arg1': ['foo', 'bar'],
 'arg2': 'baz'}

これは、2 つのキーを持つ Python dict オブジェクトです。最初のキーは文字列 arg1 で、その値は文字列 foobar の 2 つの要素を持つ Python リストオブジェクトです。2 つ目のキーは文字列 arg2 で、その値は文字列 baz です。引数に値が 1 つしかない場合は、単純な文字列のままです。1 つの引数名に対する複数の値が、文字列のリストに変換されます。

7.5.3.2. 名前付きパイプログスクリプトで使用するプラグインの作成

ds-logpipe.py コマンドは、どのプラグインでも最大 3 つの関数 (plugin ()pre ()、および post ()) があることを想定します。

ds-logpipe.py コマンドで使用されるすべてのプラグインは、plugin 関数を指定する必要があります。

plugin () 関数はログデータ内のすべての行に対して実行されますが、pre () および post () 関数は、それぞれスクリプトの開始および停止時に実行されます。

各関数に引数を定義でき、これらの引数は plugin.arg オプションを使用してスクリプトに渡すことができます。さらに、各関数には独自の戻り値とアクションを定義できます。

例7.8 単純な名前付き Pipe ログプラグイン

def pre(myargs):
    retval = True
    myarg = myargs['argname']
    if isinstance(myarg, list): # handle list of values
    else: # handle single value
    if bad_problem:
        retval = False
    return retval

def plugin(line):
    retval = True
    # do something with line
    if something_is_bogus:
        retval = False
    return retval

def post(): # no arguments
    # do something
    # no return value


[1] アクセスログでログバッファリングが無効になっている場合、エラーログでログレベルが変更されている場合、または監査ログでログバッファリングが無効になっている場合、サーバーのパフォーマンスが低下します。
[2] 監査ログはデフォルトでは有効になっていないため、名前付きパイプを使用して置き換える前に、このログを有効にする必要があります。