私が理解しているように、Linuxカーネルは/proc/kmsg
ファイル(主にハードウェア関連のメッセージ)と/dev/log
ソケットにログを記録しますか?どこか他の?他のアプリケーションも/proc/kmsg
または/dev/log
にメッセージを送信できますか?最後に重要なことですが、これらの2つの場所からのメッセージをチェックして、次のようなさまざまなファイルにメッセージを配布するのは、syslogデーモン(rsyslog、syslog-ng)であることは正しいですか? /var/log/messages
または/var/log/kern.log
または中央のsyslogサーバー?
簡略化すると、多かれ少なかれこのようになります:
カーネルは、メッセージを(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データグラムの送信を停止することはありません(その資格情報によりソケットを開くことが許可されている場合)、libc
のsyslog(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
_を持っています。
他の答えは、その作者が言うように、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の方法でログデータを標準エラーに出力します。
ツールセットの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-read
_サービス。繰り返しますが、プログラムは_syslog-read
_です。関連するロギングデーモンは、標準入力のログストリームを_/var/log/sv/udp-syslog-read
_ログディレクトリに送ります。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-journald
_があります。これは、systemdが管理するサービスとして実行されます。
/dev/kmsg
_を読み取ります。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
入力メソッドを構成していました。imjournal
入力メソッドを設定してこれを行っています。