web-dev-qa-db-ja.com

Linuxでのロギングについて理解する

私が理解しているように、Linuxカーネルは/proc/kmsgファイル(主にハードウェア関連のメッセージ)と/dev/logソケットにログを記録しますか?どこか他の?他のアプリケーションも/proc/kmsgまたは/dev/logにメッセージを送信できますか?最後に重要なことですが、これらの2つの場所からのメッセージをチェックして、次のようなさまざまなファイルにメッセージを配布するのは、syslogデーモン(rsyslogsyslog-ng)であることは正しいですか? /var/log/messagesまたは/var/log/kern.logまたは中央のsyslogサーバー?

68
Martin

簡略化すると、多かれ少なかれこのようになります:

カーネルは、メッセージを(printk()関数を使用して)カーネル空間のリングバッファーに記録します。これらのメッセージは、_/proc/kmsg_ファイル(_/proc_がマウントされている場合)と_sys_syslog_ syscallの2つの方法でユーザー空間アプリケーションで利用できるようになります。

カーネルのリングバッファーを読み取る(そしてある程度制御できる)主なアプリケーションは、dmesg(1)klogd(8)の2つです。前者は、リングバッファーの内容を印刷するために、ユーザーがオンデマンドで実行することを目的としています。後者は、_/proc/kmsg_からメッセージを読み取り(または_sys_syslog_がマウントされていない場合は_/proc_を呼び出す)、syslogd(8)またはコンソールにメッセージを送信するデーモンです。それはカーネル側をカバーします。

ユーザー空間にはsyslogd(8)があります。これは、いくつかのUNIXドメインソケット(主に_/dev/log_ですが、他のものも構成できます)をリッスンするデーモンで、オプションでメッセージ用にUDPポート514をリッスンします。また、klogd(8)からメッセージを受信します(syslogd(8)は_/proc/kmsg_を考慮しません)。次に、これらのメッセージを_/log_の一部のファイルまたは名前付きパイプに書き込むか、_/etc/syslog.conf_で構成されているように、それらを(syslogプロトコルを介して、UDPポート514で)リモートホストに送信します。

ユーザー空間アプリケーションは通常、libc関数syslog(3)を使用してメッセージをログに記録します。 libcはこれらのメッセージをUNIXドメインソケット_/dev/log_(syslogd(8)によって読み取られる場所)に送信しますが、アプリケーションがchroot(2)- edされている場合、メッセージが書き込まれる可能性があります他のソケットへ、fi _/var/named/dev/log_に変換します。もちろん、これらのログを送信するアプリケーションとsyslogd(8)がこれらのソケットの場所について合意することは不可欠です。これらの理由により、syslogd(8)は、標準の_/dev/log_以外の追加のソケットをリッスンするように構成できます。

最後に、syslogプロトコルは単なるデータグラムプロトコルです。アプリケーションが任意のUNIXドメインソケットへのsyslogデータグラムの送信を停止することはありません(その資格情報によりソケットを開くことが許可されている場合)、libcsyslog(3)関数を完全にバイパスします。データグラムが正しくフォーマットされている場合、syslogd(8)は、メッセージがsyslog(3)を介して送信されたかのようにそれらを使用できます。

もちろん、上記は「古典的な」ロギング理論のみをカバーしています。他のデーモン(rsyslogや_syslog-ng_など)は、プレーンなsyslogd(8)を置き換えることができ、暗号化されたTCP接続、高解像度のタイムスタンプなどを提供します。また、LinuxのUNIX部分をゆっくりと貪食しているsystemdもあります。systemdには独自のロギングメカニズムがありますが、その話は他の誰かに伝えなければなりません。 :)

* BSDの世界との違い:

* BSDではklogd(8)はなく、_/proc_は存在しない(OpenBSDの場合)か、ほとんど使用されていません(FreeBSDおよびNetBSDの場合)。 syslogd(8)はカーネルデバイスから文字メッセージ_/dev/klog_を読み取り、dmesg(1)は_/dev/kmem_を使用してカーネル名をデコードします。 OpenBSDだけが_/dev/log_を持っています。 FreeBSDは2つのUNIXドメインソケット_/var/run/log_と_var/rub/logpriv_を代わりに使用し、NetBSDは_/var/run/log_を持っています。

85
lcd047

他の答えは、その作者が言うように、Linuxの「クラシックロギング」を説明しています。今日の多くのシステムでは、それはそうではありません。

カーネル

カーネルのメカニズムが変更されました。

カーネルは、メモリ内バッファへの出力を生成します。アプリケーションソフトウェアは、2つの方法でこれにアクセスできます。ロギングサブシステムは通常、_/proc/kmsg_という名前の疑似FIFOとしてアクセスします。このログ情報のソースは、一度しか読み取れないため、ログリーダー間で共有することはできません。複数のプロセスが共有している場合、各プロセスはカーネルログデータストリームの一部のみを取得します。また、読み取り専用です。

これにアクセスするもう1つの方法は、新しい_/dev/kmsg_キャラクターデバイスです。これは、複数のクライアントプロセス間で共有可能な読み書きインターフェイスです。複数のプロセスがそれを共有する場合、それらはすべて、互いに影響を受けずに同じ完全なデータストリームを読み取ります。書き込みアクセスのためにそれを開いた場合、メッセージがカーネルによって生成されたかのように、カーネルのログストリームにメッセージを挿入することもできます。

_/proc/kmsg_および_/dev/kmsg_は、RFC-5424以外の形式でログデータを提供します。

用途

アプリケーションが変更されました。

メインのGNU Cライブラリのsyslog()関数は、_AF_LOCAL_という名前の_/dev/log_データグラムソケットに接続し、そこにログエントリを書き込みます( BSD Cライブラリのsyslog()関数は現在、ソケット名として_/var/run/log_を使用し、_/var/run/logpriv_を最初に試行します。)もちろん、これを行うための独自のコードをアプリケーションで直接作成できます。ライブラリ関数結局のところ、アプリケーション自体のプロセスコンテキストで実行される(ソケットを開く、接続する、書き込む、閉じるための)単なるコードです。

また、マシンの_AF_INET_/_AF_INET6_データグラムソケットでリッスンしている場合、アプリケーションはUDP経由でローカルのRFC 5426サーバーにRFC 5424メッセージを送信できます。

過去20年間にわたるdaemontoolsの世界からのプレッシャーのおかげで、多くのデーモンは、GNU syslog() Cライブラリ関数を使用しないモードでの実行をサポートしています。またはUDPソケットですが、通常のUnixの方法でログデータを標準エラーに出力します。

noshおよびdaemontoolsファミリー一般のログ管理

ツールセットのdaemontoolsファミリーを使用すると、ロギングに多くの柔軟性があります。しかし、一般に、家族全体での考え方は、各「メイン」デーモンには関連する「ロギング」デーモンがあるということです。 「メイン」デーモンは、デーモン以外のプロセスと同じように機能し、ログメッセージを標準エラー(または標準出力)に書き込みます。これは、サービス管理サブシステムがパイプ(ログデータが失われないように開いたままにする)を介して接続するように調整します。サービスの再起動)を「ロギング」デーモンの標準入力に追加します。

すべての「ロギング」デーモンは、ログを記録するプログラムを実行しますどこか。一般に、このプログラムはmultilogまたはcyclogのようなもので、標準入力から読み取り、厳密にサイズが制限され、自動的にローテーションされた排他的書き込みディレクトリに(ナノ秒のタイムスタンプ付きの)ログファイルを書き込みます。一般に、これらのデーモンはすべて、個別の専用の非特権ユーザーアカウントの管理下で実行されます。

したがって、各サービスのログデータが個別に処理される、大規模に分散されたログシステムが作成されます。

1つcanは、daemontools-familyサービス管理下でklogdまたはsyslogdまたはrsyslogdのようなものを実行します。しかし、daemontoolsの世界は何年も前に、「ロギング」デーモンを備えたサービス管理構造が、より単純な方法で物事を行うのに非常にきちんと適していることを認識しました。すべてのログストリームを1つの巨大なマッシュマッシュに扇形に送って、ログデータを解析し、ストリームをファンアウトして別のログファイルに戻す必要はありません。次に、(場合によっては)信頼できない外部ログ回転メカニズムを側面にボルトで固定します。標準のログ管理の一部としてのdaemontools-family構造すでに実行ログのローテーション、ログファイルの書き込み、およびストリームの分離。

さらに、すべてのサービスに共通のツールを使用して特権を削除するチェーンロードモデルでは、ロギングプログラムにスーパーユーザー特権は必要ありません。また、UCSPIモデルは、ストリームとデータグラムのトランスポートなどの違いのみを考慮する必要があることを意味します。

Noshツールセットはこれを例示しています。一方、canその下でrsyslogdをそのまま実行し、カーネル、_/run/log_、およびUDPログ入力を古い方法で管理します。 it alsoこれらのことをログに記録する「daemontoolsネイティブ」な方法を提供します。

  • _/proc/kmsg_から読み取り、そのログストリームを標準エラーに書き込むklogdサービス。これは、_klog-read_という名前の単純なプログラムによって行われます。関連するロギングデーモンは、標準入力のログストリームを_/var/log/sv/klogd_ログディレクトリに送ります。
  • _local-syslog-read_サービスは、_/dev/log_(BSDでは_/run/log_)からデータグラムを読み取り、そのログストリームを標準エラーに書き込むだけです。これは、_syslog-read_という名前のプログラムによって行われます。関連するロギングデーモンは、標準入力のログストリームを_/var/log/sv/local-syslog-read_ログディレクトリに送ります。
  • uDP syslogポートで待機し、送信されたものを読み取り、そのログストリームを標準エラーに書き込む_udp-syslog-read_サービス。繰り返しますが、プログラムは_syslog-read_です。関連するロギングデーモンは、標準入力のログストリームを_/var/log/sv/udp-syslog-read_ログディレクトリに送ります。
  • (BSDの場合)_local-priv-syslog-read_からデータグラムを読み取り、そのログストリームを標準エラーに書き込むだけの_/run/logpriv_サービス。繰り返しますが、プログラムは_syslog-read_です。関連するロギングデーモンは、標準入力のログストリームを_/var/log/sv/local-priv-syslog-read_ログディレクトリに送ります。

ツールセットには_export-to-rsyslog_ツールも付属しており、1つまたは複数のログディレクトリを監視し(非侵入型のシステムログカーソルを使用)、RFC 5424形式で新しいエントリをネットワークに送信できます。指定されたRFC 5426サーバー。

systemdによるログ管理

systemdには単一のモノリシックログ管理プログラム_systemd-journald_があります。これは、systemdが管理するサービスとして実行されます。

  • カーネルログデータの場合は_/dev/kmsg_を読み取ります。
  • GNU Cライブラリのsyslog()関数からアプリケーションログデータの_/dev/log_(_/run/systemd/journal/dev-log_へのシンボリックリンク)を読み取ります。
  • _AF_LOCAL_の_/run/systemd/journal/stdout_ストリームソケットで、systemd管理サービスからのログデータをリッスンします。
  • _AF_LOCAL_の_/run/systemd/journal/socket_データグラムソケットをリッスンして、systemd固有のジャーナルプロトコルを話すプログラムからのログデータを受信します(つまり、sd_journal_sendv() et al。)。
  • これらをすべて混ぜ合わせます。
  • _/run/log/journal/_または_/var/log/journal/_で、システム全体およびユーザーごとのジャーナルファイルのセットに書き込みます。
  • (クライアントとして)_AF_LOCAL_の_/run/systemd/journal/syslog_データグラムソケットに接続できる場合、syslogへの転送が構成されていれば、そこにジャーナルデータを書き込みます。
  • 構成されている場合、書き込み可能な_/dev/kmsg_メカニズムを使用して、カーネルデータをカーネルバッファーに書き込みます。
  • 構成されている場合は、端末とコンソールデバイスにもジャーナルデータを書き込みます。

このプログラムがクラッシュしたり、サービスが停止したりすると、システム全体で悪いことが起こります。

systemd自体は、(一部の)サービスの標準出力とエラーが_/run/systemd/journal/stdout_ソケットに接続されるように調整します。したがって、通常の方法で標準エラーにログを記録するデーモンは、その出力をジャーナルに送信します。

これは、klogd、syslogd、syslog-ng、およびrsyslogdに完全に取って代わります。

これらは、systemd固有である必要があります。 systemdシステムでは、_/dev/log_のサーバーエンドになることはできません。代わりに、次の2つの方法のいずれかを使用します。

  • これらは、_/run/systemd/journal/syslog_のサーバー側になり、_systemd-journald_はジャーナルデータへの接続と書き込みを試みます(覚えている場合)。数年前、これを行うためにrsyslogdのimuxsock入力メソッドを構成していました。
  • それらは、バイナリジャーナル形式を理解し、追加される新しいエントリのジャーナルファイルとディレクトリを監視できるsystemd固有のライブラリを使用して、systemdジャーナルから直接読み取ります。最近では、rsyslogdのimjournal入力メソッドを設定してこれを行っています。
58
JdeBP