22.4. Rsyslog でのキュー (Queue) を使った操作

キューは、rsyslog のコンポーネント間でコンテンツ (主にsyslog メッセージ) を渡すために使用されます。キューを使うと、rsyslog は複数のメッセージを同時に処理することができ、複数のアクションを単一メッセージに一度に適用できます。rsyslog 内のデータフローは、以下のようになります。
Rsyslog 内のメッセージフロー

図22.1 Rsyslog 内のメッセージフロー

rsyslog はメッセージを受信すると常に、これをプリプロセッサーに渡します。そして、メインメッセージキュー (main message queue) に置きます。メッセージはそこでキューから取り出され、rule processor に渡されるのを待ちます。
rule processor は、分析およびフィルタリングのエンジンです。ここでは、/etc/rsyslog.conf で定義されたルールが適用されます。これらのルールに基づいて、rule processor はどのアクションが実行されるかを評価します。アクションはそれぞれ、独自のアクションキューを持っています。メッセージはこのキューにより各アクションプロセッサーに渡され、これが最終的な出力を作成します。この時点では、1 つのメッセージに関して複数のアクションが同時に実行可能であることに注意してください。このためにメッセージは複製され、複数のアクションプロセッサーに渡されます。
1 アクションにつき、1 つのキューのみが可能です。設定により、メッセージはアクションキューなしですぐにアクションプロセッサーに送信されることもあります。これはダイレクトキュー (direct queues) (下記参照) と呼ばれる動作です。出力アクションが失敗すると、アクションプロセッサーがアクションキューに通知を行い、それにより未処理要素が戻され、しばらくのインターバルの後、アクションが再度試されます。
まとめると、rsyslog では 2 カ所のキュー (rule processor の前にある単一の メインメッセージキュー と、様々なタイプの出力アクションの前にある アクションキュー) に並びます。キューは、メッセージ処理のパフォーマンス向上につながる以下の 2 つの利点を提供します。
  • rsyslog 構造内での decouple のプロデューサーとコンシューマーのバッファーとして機能します。
  • メッセージで実行されるアクションの 並列化 を可能にします。
それ以外では、キューを複数のディレクティブで設定して、システムに最適なパフォーマンスを提供することができます。これらの設定オプションは、以下の項で説明されています。

警告

出力プラグインがメッセージを提供できない場合、メッセージは、先行のメッセージキューに保存されます。キューがいっぱいになると、空きができるまで入力がブロックされます。これにより、ブロックされたキューを使用して新しいメッセーがログに記録されることが回避されます。個別のアクションキューが存在しないため、SSH ロギングが阻止され、SSH アクセスが阻止されるなどの重大な問題が発生することがあります。したがって、ネットワークを介して転送される、またはデータベースに転送される出力専用アクションキューを使用することが推奨されます。

22.4.1. キューの定義

メッセージが保存される場所によって、キューにはいくつかタイプがあります。最もよく使用されるのは、directin-memorydisk、および disk-assisted in-memory のキューです。これらのうちのいずれかを、メインメッセージキューおよびアクションキューに選択できます。以下を /etc/rsyslog.conf に追加します。
object(queue.type=”queue_type”)
これを追加することで、設定を適用できます。
  • メインメッセージキュー: objectmain_queue に置き換える
  • アクションキュー: objectaction に置き換える
  • ルールセット: objectruleset に置き換える
queue_typedirectlinkedlist または fixedarray (インメモリーキュー) または disk のいずれかと置き換えます。
メインメッセージキューのデフォルト設定は、FixedArray queue で 10,000 メッセージの制限があります。アクションキューはデフォルトで、Direct queue に設定されます。

ダイレクトキュー (Direct Queue)

出力をローカルファイルに書き出すなど、多くの単純な操作では、アクションの前にキューを構築することは不要です。キューの使用を回避するには、以下を使用します。
object(queue.type=”Direct”)
objectmain_queueactionruleset のいずれかに置き換え、このオプションをメインメッセージキュー、アクションキュー、またはルールセットにそれぞれ使用します。ダイレクトキューを使用すると、メッセージはプロデューサーからコンシューマーに直ちに直接渡されます。

ディスクキュー (Disk Queue)

ディスクキューは、厳密にメッセージをハードドライブに保存します。こうすることで信頼性は非常に高くなりますが、queuing モードのなかでは一番遅くなります。このモードを使用すると、非常に重要なログデータを失うのを回避できますが、ほとんどのユースケースでは、ディスクキューは推奨されません。ディスクキューを設定するには、/etc/rsyslog.conf に以下を入力します。
object(queue.type=”Disk”)
objectmain_queueaction、または ruleset に置き換え、このオプションをメインメッセージキュー、アクションキュー、またはルールセットにそれぞれ使用します。キューのデフォルトサイズは、以下の設定ディレクティブで変更できます。
object(queue.size=”size”)
ここでは、size はディスクキューの一部の指定サイズを表します。定義されたサイズ制限は限定的なものではなく、rsyslog はキューエントリーがサイズ制限を超えていても、常に 1 つの完全なキューエントリーを書き込みます。ディスクキューの各部分は、個別ファイルに適合します。これらファイルの命名ディレクティブは、以下のとおりです。
object(queue.filename=”name”)
これでファイルに name 接頭辞が設定され、1 で始まる 7 桁の数字が続き、ファイルごとにこれが増加します。
object(queue.maxfilesize=”size”)
ディスクキューは、デフォルトサイズの 1 MB でそれぞれに書き込まれています。別の値を使用する場合は size を使用します。

インメモリーキュー (In-memory Queue)

インメモリーキューでは、キューに格納されたメッセージをメモリーに保持し、プロセスを高速化します。コンピュータの電源を切ってすぐに入れ直すか、シャットダウンが行われると、キューのデータは失われます。ただし、 action (queue.saveonshutdown=”on”) 設定を使用して、シャットダウン前にデータを保存できます。インメモリーキューには 2 種類あります。
  • FixedArray キュー - メインメッセージキューのデフォルトモードで、10,000 要素の制限があります。このタイプのキューは、キュー要素へのポインターを保有する固定かつ事前割り当てのアレイを使用します。これらのポインターのために、キューが空であってもある程度のメモリーが消費されます。しかし、FixedArray は、最善のランタイムパフォーマンスを提供し、比較的少ないキューに登録済みのメッセージと高パフォーマンスを期待する場合に最適なものです。
  • LinkedList キュー - ここではすべての構造物はリンクされたリストに動的に割り当てられるので、メモリーは必要な場合にのみ割り当てられます。LinkedList キューは時折発生するメッセージバーストにもうまく対応します。
一般的に、疑いが残る場合は LinkedList キューを使用してみてください。FixedArray と比べてメモリー消費量が少なく、プロセスオーバヘッドが低くて済みます。
インメモリーキューの設定には、以下の構文を使用します。
object(queue.type=”LinkedList”)
object(queue.type=”FixedArray”)
objectmain_queueaction または ruleset に置き換え、このオプションをメインメッセージキュー、アクションキュー、またはルールセットにそれぞれ使用します。

ディスク補助のインメモリーキュー (Disk-Assisted In-memory Queues)

ディスクとインメモリーキューにはそれぞれ利点があり、rsyslog によってディスク補助のインメモリーキュー でそれらを統合できます。そのためには、通常のインメモリーキューを設定し、queue.filename=”file_name” ディレクティブをブロックに追加してディスク補助のファイル名を定義します。このキューは ディスク補助 となり、インメモリーキューとディスクキューが連携します。
インメモリーキューがいっぱい、もしくはシャットダウン後にも継続する必要がある場合に、ディスクキューがアクティブ化されます。ディスク補助のキューでは、ディスク固有およびインメモリー固有の設定パラメーターの両方を設定できます。このタイプのキューはおそらく最も広く使われているもので、潜在的に長期間実行され、信頼性が低いアクションで特に便利です。
ディスク補助インメモリーキューの機能を指定するには、いわゆるウォーターマークを使用します。
object(queue.highwatermark=”number”)
object(queue.lowwatermark=”number”)
objectmain_queueaction または ruleset に置き換えて、このオプションをメインメッセージキュー、アクションキューまたはルールセットにそれぞれ使用します。number をキューに格納されたメッセージの数に置き換えます。インメモリーキューがハイウォーターマークで定義された数字に到達すると、ディスクへのメッセージの書き込みが開始し、インメモリーキューのサイズがローウォーターマークで定義された数字になるまで続きます。不必要なディスク書き込みを最小限に抑えるため、ウォーターマークを正しく設定します。ただし、ディスクファイルへの書き込みは長いので、メッセージバースト用のメモリースペースを残してください。そのために、ハイウォーターマークは queue.size で設定されているキューのキャパシティ全体より低い必要があります。ハイウォーターマークとキューの全体サイズの差が、メッセージバースト用に確保されたスペアメモリーバッファーです。一方で、ハイウォーターマークを低く設定しすぎると、不必要なディスク補助が頻繁に発生してしまいます。

例22.12 サーバーへのログメッセージの確実な転送

多くの場合、Rsyslog は、ログメッセージがネットワークを介してサーバーに転送される中央ロギングシステムを保持するために使用されます。サーバーが利用できない場合にメッセージが失われないように、転送アクションに対するアクションキューを設定することが推奨されます。この場合、送信に失敗したメッセージはサーバーが再び到達可能になるまでローカルに保存されます。このようなキューは UDP プロトコルを使用している接続には設定できないことに注意してください。

手順22.1 単一サーバーへの転送

ログメッセージをシステムからホスト名が example.com のサーバーに転送し、サーバー停止時にメッセージをバッファーするようアクションキューを設定するタスクを考えてみます。このタスクを実行するには、以下の手順を実行します。
  • /etc/rsyslog.conf の以下の設定を使用するか、/etc/rsyslog.d/ ディレクトリーに以下の内容のファイルを作成します。
    *.* action(type=”omfwd”
    queue.type=”LinkedList”
    queue.filename=”example_fwd”
    action.resumeRetryCount="-1"
    queue.saveonshutdown="on"
    arget="example.com" Port="6514" Protocol="tcp")
    ここで、
    • queue.type は LinkedList インメモリーキューを有効にし、
    • queue.filename はディスクストレージを定義します。この場合、バックアップファイルが example_fwd 接頭辞を持つ /var/lib/rsyslog/ ディレクトリーで作成され、
    • action.resumeRetryCount= “-1” 設定は、サーバーの応答がない場合に再接続しようとしたときに rsyslog がメッセージをドロップすることを防止し、
    • rsyslog がシャットダウンしたら、有効化された queue.saveonshutdown がインメモリーデータを保存し、
    • 最後の行は信頼できる TCP デリバリーを使用して受信したすべてのメッセージをロギングサーバーに送ります。ポート指定はオプションです。
    上記の設定では、rsyslog はリモートサーバーが到達不能な場合にメッセージをメモリーに保持します。ディスク上のファイルは、rsyslog で設定済みメモリーキュー領域がなくなった場合、または rsyslog をシャットダウンする必要がある場合 (これによりシステムパフォーマンスが向上) にのみ作成されます。

手順22.2 複数のサーバーへの転送

複数のサーバーにログメッセージを転送するプロセスは前の手順に似ています。
  • 各送信先サーバーでは、個別の転送ルール、アクションキュー指定、ディスク上のバックアップファイルが必要です。たとえば、/etc/rsyslog.conf の以下の設定を使用するか、/etc/rsyslog.d/ ディレクトリーに以下の内容のファイルを作成します。
    *.* action(type=”omfwd”
            queue.type=”LinkedList”
            queue.filename=”example_fwd1”
            action.resumeRetryCount="-1"
            queue.saveonshutdown="on"
            Target="example1.com" Protocol="tcp")
    *.* action(type=”omfwd”
            queue.type=”LinkedList”
            queue.filename=”example_fwd2”
            action.resumeRetryCount="-1"
            queue.saveonshutdown="on"
            Target="example2.com" Protocol="tcp")

22.4.2. rsyslog ログファイルの新しいディレクトリーの作成

rsyslog は、syslogd デーモンとして実行され、SELinux により管理されます。したがって、rsyslog が書き込む必要があるすべてのファイルでは適切な SELinux ファイルコンテキストが設定されている必要があります。

手順22.3 新規作業用ディレクトリーの作成

  1. 作業用ファイルを格納する別のディレクトリーを使用する必要がある場合は、以下のようにディレクトリーを作成します。
    ~]# mkdir /rsyslog
  2. SELinux ポリシーを管理するためにユーティリティーをインストールします。
    ~]# yum install policycoreutils-python
  3. SELinux ディレクトリーコンテキストタイプを /var/lib/rsyslog/ ディレクトリーと同じものに設定します。
    ~]# semanage fcontext -a -t syslogd_var_lib_t /rsyslog
  4. SELinux コンテキストを適用します。
    ~]# restorecon -R -v /rsyslog
    restorecon reset /rsyslog context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:syslogd_var_lib_t:s0
  5. 必要な場合は、以下のように SELinux コンテキストを確認します。
    ~]# ls -Zd /rsyslog
    drwxr-xr-x. root root system_u:object_r:syslogd_var_lib_t:s0   /rsyslog
  6. 必要に応じてサブディレクトリーを作成します。例を以下に示します。
    ~]# mkdir /rsyslog/work/
    サブディレクトリーが親ディレクトリーと同じ SELinux コンテキストで作成されます。
  7. /etc/rsyslog.conf を有効にする直前にそのファイルに次の行を追加します。
    global(workDirectory=”/rsyslog/work”)
    この設定は、設定ファイルを解析するときに次の WorkDirectory ディレクティブが検出されるまで有効になります。

22.4.3. キューの管理

キューはすべてのタイプで、使用中の要件に合致するようにさらなる設定が可能です。複数のディレクティブを使用してアクションキューとメインメッセージキューの両方を修正できます。現時点では、20 以上のキューパラメーターが利用可能です。「オンラインのドキュメント」 を参照してください。これらの設定のいくつかは一般的に使用されており、また、worker thread management のようにキューの動作を密接に管理し、高度なユーザー用に確保されているものもあります。高度な設定では、rsyslog のパフォーマンスやスケジュールキューイングを最適化したり、システムシャットダウン時のキュー動作を修正したりできます。

キューのサイズ制限

キューが保有できるメッセージ数は、以下の設定で制限できます。
object(queue.highwatermark=”number”)
objectmain_queueaction、または ruleset に置き換え、このオプションをメインメッセージキュー、アクションキュー、またはルールセットにそれぞれ使用します。number をキューに格納されたメッセージの数に置き換えます。キューサイズを実際のメモリーサイズではなくメッセージの数として設定します。デフォルトのキューサイズは、メインメッセージキューとルールセットキューの場合は 10,000 メッセージ、アクションキューの場合は 1,000 となります。
ディスク補助キューはデフォルトでは無制限で、このディレクティブでは制限できませんが、以下の設定で物理的なディスク領域をバイト単位で確保することは可能です。
object(queue.maxdiskspace=”number”)
objectmain_queueaction、または ruleset に置き換えます。数によって指定されるサイズ上限に達している場合、キューから取り出されたメッセージによって十分なスペースが解放されるまでメッセージは破棄されます。

メッセージの破棄

キューのメッセージがある数に達すると、重要でないメッセージを破棄して、より優先度が高いエントリーのためにキューのスペースを節約できます。破棄プロセスを開始するしきい値は、discard mark と呼ばれるもので設定できます。
object(queue.discardmark=”number”)
メインメッセージキューにこのオプションを使用する場合は objectMainMsg に、アクションキューに使用する場合は Action に置き換えます。ダイレクトキューでは、メッセージはプロデューサーからコンシューマーに直接かつ即座に渡されます。ここでの number は、破棄プロセスを開始する際のキューにあるメッセージ数です。破棄するメッセージを定義するには、以下を使用します。
object(queue.discardseverity=”number”)
number を、プライオリティーに対応するいずれかの数字に置き換えます (7 (debug)、6 (info)、5 (notice)、4 (warning)、3 (err)、2 (crit)、1 (alert)、0 (emerg))。この設定により、定義されたプライオリティーを下回る、新しく受信したメッセージおよびすでにキューに格納されたメッセージは、破棄マークに到達すると直ちにキューから消去されます。

タイムフレームの使用

特定の時間帯にキューを処理するように rsyslog を設定できます。このオプションを使用すると、たとえば処理をオフピーク時に移すことができます。時間帯を定義するには、以下の構文を使用します。
object(queue.dequeuetimebegin=”hour”)
object(queue.dequeuetimeend=”hour”)
hour では、時間帯を区切る時間を指定します。分は指定せず、24 時間形式を用います。

ワーカースレッドの設定

ワーカースレッドは キューに入っているメッセージに指定されたアクションを実行します。たとえば、メインメッセージキューでは、ワーカーのタスクは、入ってくるメッセージにフィルター論理を適用し、関連のアクションキューに入れることです。メッセージが届くと、ワーカースレッドは自動的に開始します。メッセージ数がある数に達すると、別のワーカースレッドがオンになります。この数字を指定するには、以下を使用します。
object(queue.workerthreadminimummessages=”number”)
number を、補助のワーカースレッドを起動するメッセージ数に置き換えます。たとえば number を 100 に設定すると、100 を超えるメッセージが届いた際に新たなワーカースレッドが起動し、200 を超えるメッセージが届くと 3 つ目のワーカースレッドが起動するようになります。しかし、多くのワーカースレッドが並列して実行すると効果的でなくなるので、以下を使用してこの最大数を制限できます。
object(queue.workerthreads=”number”)
ここでの number は、並列で実行可能なワーカースレッドの最大数になります。メインメッセージキューのデフォルトは、1 スレッドです。ワーカースレッドが一旦起動すると、非アクティブタイムアウトが現れるまで、実行し続けます。タイムアウトを設定するには、以下を入力します。
object(queue.timeoutworkerthreadshutdown=”time”)
time をミリ秒単位の期間設定に置き換えます。新しいメッセージなしの時間を指定すると、ワーカースレッドが閉じます。デフォルトの設定は 1 分です。

バッチのデキュー

複数のメッセージを同時にデキューするように rsyslog を設定して、パフォーマンスを高めることができます。このデキューの最大値を設定するには、以下を使用します。
$object(queue.DequeueBatchSize= ”number”)
number を同時にデキュー可能な最大数に置き換えます。この数字を高く設定して、許可されるワーカースレッドの結果を大きくすると、メモリー消費量が大きくなることに注意してください。

キューの終了

メッセージを含んでいるキューを終了する際には、ワーカースレッドがキューの処理を完了する間隔を指定することで、データ損失を最小限に抑えることができます。
object(queue.timeoutshutdown=”time”)
time をミリ秒で指定します。この期間の後にまだキューに入っているメッセージがある場合、ワーカーは現在のデータ要素を完了してから終了します。このため、未処理のメッセージは失われます。ワーカーが最終要素を完了する間隔も設定できます。
object(queue.timeoutactioncompletion=”time”)
このタイムアウトが切れると、残りのワーカーはシャットダウンします。シャットダウン時にデータを保存するには、以下を使用します。
object(queue.saveonshutdown=”on”)
これが設定されていると、rsyslog の終了前にすべてのキュー要素がディスクに保存されます。

22.4.4. rsyslog キューの新規構文の使用

rsyslog 7 で利用可能な新規構文では、キューは /etc/rsyslog.conf で個別に使用、またはルールセット内部で使用できる action() オブジェクト内で定義されます。アクションキューの形式は以下のようになります。
action(type="action_type "queue.size="queue_size" queue.type="queue_type" queue.filename="file_name"
action_type を、アクションを実行するモジュールの名前に置き換え、queue_size を、キューに含めることができるメッセージの最大数に置き換えます。queue_type には、disk を選択するか、インメモリーキュー (directlinkedlist、または fixedarray) のいずれかを選択します。file_name には、パスではなくファイル名のみを指定します。ログファイルを保持する新規ディレクトリーを作成する場合は、SELinux コンテキストを設定する必要があることに注意してください。設定例は 「rsyslog ログファイルの新しいディレクトリーの作成」 を参照してください。

例22.13 アクションキューの定義

出力アクションで、最大 10,000 メッセージを保持できる非同期リンクリストベースのアクションキューを設定するには、以下のようにコマンドを入力します。
action(type="omfile" queue.size="10000" queue.type="linkedlist" queue.filename="logfile")
直接アクションキューの rsyslog 7 構文は以下のとおりです。
*.* action(type="omfile" file="/var/lib/rsyslog/log_file
     )
複数のパラメーターがアクションキュー用 rsyslog 7 構文は以下のように記述できます。
*.* action(type="omfile"
              queue.filename="log_file"
              queue.type="linkedlist"
              queue.size="10000"
     )
デフォルトの作業ディレクトリー、または最後に設定した作業ディレクトリーが使用されます。別の作業ディレクトリーを使用する必要がある場合は、アクションキューの前に以下の行を追加します。
global(workDirectory="/directory")

例22.14 新規構文を使用した単一サーバーへの転送

以下の例は 手順22.1「単一サーバーへの転送」 の手順に基づき、従来の構文と rsyslog 7 の構文の違いを示しています。omfwd プラグインは、UDP または TCP を介した転送を提供するために使用されます。デフォルト値は UDP です。プラグインは組み込まれているため、ロードする必要がありません。
/etc/rsyslog.conf の以下の設定を使用するか、/etc/rsyslog.d/ ディレクトリーに以下の内容のファイルを作成します。
*.* action(type="omfwd"
      queue.type="linkedlist"
      queue.filename="example_fwd"
      action.resumeRetryCount="-1"
      queue.saveOnShutdown="on"
      target="example.com" port="6514" protocol="tcp"
     )
ここで、
  • queue.type="linkedlist" は LinkedList インメモリーキューを有効にします。
  • queue.filename はディスクストレージを定義します。バックアップファイルは、先行するグローバルな workDirectory ディレクティブで指定された作業ディレクトリーに example_fwd プレフィックスで作成されます。
  • action.resumeRetryCount -1 設定は、サーバーが応答しない場合に接続を再試行するときに rsyslog がメッセージを破棄しないようにします。
  • queue.saveOnShutdown="on" が有効な場合に、rsyslog がシャットダウンすると、インメモリーデータが保存されます。
  • 最後の行は、受信されたすべてのメッセージをロギングサーバーに転送します。ポートの指定はオプションです。