Linuxでのロギングを理解する


62

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

回答:


81

簡略化すると、次のようになります。

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

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

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

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

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

もちろん、上記は「古典的な」ロギング理論のみをカバーしています。他のデーモン(rsyslogおよびsyslog-ng、など)はplainを置き換え、syslogd(8)暗号化されたTCP接続を介してリモートホストにメッセージを送信する、高解像度のタイムスタンプを提供するなど、あらゆる種類の気の利いたことを実行できます。またsystemd、LinuxのUNIX部分をゆっくりと貪食しているがあります。 systemd独自のロギングメカニズムがありますが、その話は他の誰かによって語られる必要があります。:)

* BSDの世界との違い:

* BSDにはnoがありklogd(8)/proc存在しないか(OpenBSDの場合)、またはほとんど廃止されています(FreeBSDおよびNetBSDの場合)。 syslogd(8)キャラクターデバイスからカーネルメッセージを読み取り/dev/klog、カーネル名のデコードにdmesg(1)使用/dev/kmemします。OpenBSDのみに/dev/log。FreeBSDは2つのUNIXドメインソケット/var/run/logvar/rub/logpriv使用しますが、代わりにNetBSDには/var/run/log


3
nit:rsyslogがより一般的になり(Fedora、Debianのデフォルト)、個別のklogdを使用しません。syslog-ngも(優先的に)似ていないようです。
sourcejedi

@sourcejedi数年前からLinuxをそれほど詳しく追跡rsyslogしていませんが、IIRC はklogd(8)そのルーツが過去に戻ったためではなく、最近廃止する明示的な決定をしたためではありません。私の記憶は失敗する可能性があります。とにかく、私が言ったように、私は「古典的な」ロギングだけをカバーしようとしていました。
lcd047

1
@ lcd047、@ sourcejedi、返信ありがとうございます!rsyslogd実行中のDebian 7システムと実行中のUbuntu 12.04が1つずつsyslog-ngあり、両方ともファイルが/proc/kmsg開いていました。lsofつまり、klogd使用されていませんでした。私が気づいたもう1つの興味深い点は、/proc/kmsgsyslogデーモンが実行されていない場合にログメッセージがファイルに保存され、たとえばcatテキストエディタでそれらを表示できることです。ただし、これらのメッセージは表示後に消えるため、一度しか表示できません。最後になりましたが、実行dmesgしても/proc/kmsgファイルの内容は消去されません。
マーティン

1
@Martin /proc/kmsgは通常のファイルではなく、「保存」されるものは何もありません。むしろ、カーネルのリングバッファーのビューです。あなたがそれを読むことができますcatあなたは何も持っていないので、正確にklogd(8)(あなたが実行する必要があります実行をklogd(8)cat /proc/kmsgブロックします)。 dmesg(1)から/dev/kmsgではなくからメッセージを読み取ります/proc/kmsg。また、指示があればバッファをクリアすることもできます。
lcd047

1
systemd has its own logging mechanisms, but that story would have to be told by somebody else. :)-教えてください、あなたは才能を得た:-)
フラビウス

51

他の答えは、著者が言うように、Linuxでの「古典的なロギング」を説明しています。それは、今日の多くのシステムで物事がどのように機能するかではありません。

カーネル

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

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

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

/proc/kmsgおよび/dev/kmsg非RFC-5424形式でログデータを提供しています。

用途

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

syslog()メインのGNU Cライブラリの機能は、AF_LOCAL名前の付いたデータグラムソケットに接続し、/dev/logログエントリを書き込みます。(syslog()最近では/var/run/log、BSD Cライブラリの関数はソケット名として使用し、/var/run/logpriv最初に試行します。)もちろん、アプリケーションはこれを直接行う独自のコードを持つことができます。ライブラリ関数は、アプリケーションのプロセスコンテキストで実行される単なるコード(ソケットを開く、接続する、書き込む、閉じる)です。

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

過去20年にわたるデーモンツールの世界からの圧力のおかげで、多くのデーモンはGNU syslog()Cライブラリ関数やUDPソケットを使用せず、ログデータを標準エラーに吐き出すモードでの実行をサポートしています。通常のUnixファッション。

一般的なnoshおよびdaemontoolsファミリーによるログ管理

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

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

そのため、各サービスのログデータが個別に処理される、大部分が分散したログシステムになります。

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

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

noshツールセットはこれを例示しています。1がなくなりできる実行rsyslogd箱から出して、その下に、とだけカーネルの管理、/run/logおよびUDPは古い方法で入力を記録します。それはまた、これらのものをログに記録するより「daemontoolsのネイティブ」な方法を提供します。

  • klogd読み取ったサービス/proc/kmsgと、単にその標準エラー出力にそのログ・ストリームを書き込みます。これはという簡単なプログラムによって行われklog-readます。関連するロギングデーモンは、標準入力のログストリームを/var/log/sv/klogdログディレクトリに送ります。
  • local-syslog-readデータグラムを読み込みサービス/dev/log/run/logBSD系に)単にその標準エラー出力にそのログ・ストリームを書き込みます。これはという名前のプログラムによって行われsyslog-readます。関連するロギングデーモンは、標準入力のログストリームを/var/log/sv/local-syslog-readログディレクトリに送ります。
  • udp-syslog-read単に、UDPのsyslogポートをリッスンし、それに送られるもの読み込み、サービスはその標準エラー出力にそのログ・ストリームを書き込みます。繰り返しますが、プログラムは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-rsyslog1つまたは複数のログディレクトリを監視し(非侵入型ログカーソルのシステムを使用)、指定されたRFC 5426サーバーにネットワーク経由でRFC 5424形式の新しいエントリを送信できるツールも付属しています。

systemdによるログ管理

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

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

このプログラムがクラッシュした場合、またはサービスが停止した場合、システム全体で問題が発生します。

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

これは、klogd、syslogd、syslog-ng、およびrsyslogdを完全に置き換えます。

現在、これらはsystemd固有である必要があります。systemdシステムでは、それらはのサーバー側にはなりません/dev/log。代わりに、2つのアプローチのいずれかを使用します。

  • それらはのサーバー側になり/run/systemd/journal/syslog、(覚えていれば)systemd-journaldジャーナルデータへの接続と書き込みを試みます。数年前には、imuxsockこれを行うためにrsyslogdの入力メソッドを設定していました。
  • バイナリジャーナル形式を理解し、追加される新しいエントリのジャーナルファイルとディレクトリを監視できるsystemd固有のライブラリを使用して、systemdジャーナルから直接読み取ります。最近では、imjournalこれを行うためにrsyslogdの入力メソッドを設定します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.