なぜこれが起こっているのかわかりません。テストサービスで、10秒ごとにstdoutに任意のテキストを記録しています。これが私のサービスファイル/etc/systemd/system/samplego.service
です。
[Unit]
Description=Sample go app
After=network.target
[Service]
SyslogIdentifier=my-samplego
ExecStart=/opt/samplego/samplego
Restart=on-failure
[Install]
WantedBy=multi-user.target
これはうまく機能し、journalctl
を使用してこれらのログ行を表示できます。
ただし、/etc/systemd/journald.conf
の設定を変更すると、e。 g。 forwardtosyslog=yes
を発行してからsystemctl restart systemd-journald
を発行すると、アプリのロギングが停止し、journalctl -f
が発行されるまでsystemctl restart samplego
に更新が表示されません。 journald
再起動後にすべてのサービスを再起動する必要がありますか?
1990年代中頃のデーモンツールの主要な革新の1つは、信頼できるロギングのアイデアでした。デーモン監督者は、2つのデーモン、mainデーモン、およびlogデーモン。どちらかを呼び出す前にパイプを開き、パイプの書き込み側をmainデーモンプロセスの標準出力として渡し、パイプの読み取り側をlogデーモンプロセスの標準入力。それまた自体も、パイプの両端に開いたファイル記述子を保持していました。そのため、ログデーモンが終了したか、終了してから再起動した場合、パイプに書き込まれたログデータは保持され、ログデーモンの新たに再起動されたインスタンスによって読み取られ、ログに記録されます。これは、パイプが閉じられないためです。
Systemdの設計者は、この設計から学びませんでした。
systemd
は、構成されている場合、生成されたサービスプロセスを調整して、標準出力をソケット経由でジャーナルプロセスに送信します。しかし、daemontoolsの場合のように、パイプを開いて各プロセスがパイプの適切な終端を継承するように調整するのではなく、systemd
はAF_LOCAL
で/run/systemd/journal/stdout
ストリームソケットを使用します。メインプロセスはクライアントとして接続します。ログプロセスはサーバーとしてリッスンします。
つまり、データ接続には、継承されたパイプセマンティクスではなく、クライアント/サーバーソケットセマンティクスがあります。サーバーが停止すると、接続が切断されます。バッファされたログデータはすべて失われ、メインデーモンによって書き込まれたすべてのそれ以上のデータは閉じたソケットに移動して失われます。 (これは、systemdがデフォルトでtrueに設定されているIgnoreSIGPIPE
設定を使用している理由の一部です。ログ出力を閉じたソケットに書き込むまた、カーネルがログを書き込んでいるデーモンを殺そうとします。)
したがって、systemd-journald
プロセスを強制終了すると、プロセス出口は、ログに記録しているすべてのデーモンプロセスへのソケット接続を閉じ、それ以降のすべての出力は失われます。これから回復し、メインプロセスの出力をログプロセスに再接続する方法はありません。すべてのメインプロセスを再起動して、systemd
がnewクライアント接続を(新しく作成された)ログに再度開くようにする必要があります。サーバ。
Systemdの人々は2016年にこの問題を回避するための準備を整えました。これには、プロセスが自分で選択した任意のオープンファイル記述子をプロセス#1にプッシュし、後でプルする機能を追加することが含まれます。 systemd-journald
は、ログに記録しているクライアントへのサーバー側の接続でこれを行うため、ログ記録デーモン自体を再起動してもクライアントは開いたままになります。
このメカニズムの問題は、セキュリティを確保するためにさらに多くの作業が必要であり、今年だけのイベントが実証しているように、セキュリティで保護するものを設計することに関してsystemdの人々は良い実績がないということです。 whoはwhatおよびいくつファイル記述子をプロセス#1にオープンし、どれだけが必要かアクセス制御および制限付き。そうでなければ、可能性のあるエクスプロイトがたくさんあります。 (daemontools設計では、サービスマネージャープロセス自体がファイル記述子を開くものであるため、子プロセスのために開いたままにしているファイル記述子を完全に制御します。だまされたり、悪用されたり、フラッディングされたりすることはありません。)
Laurent Bercotのs6では、s6-svscan
は通常のdaemontoolsをメインサービスとログサービスの間のパイプで実行します。また、任意のファイル記述子を開いたままにするメカニズムも備えています。これは、systemdのように、プロセス#1のサービスマネージャー内でスーパーユーザー権限で実行されているコードでは行われません。これは、サービスマネージャとは別に実行される完全に特権のないプロセスによって行われます。
s6-fdholderd
。 s6。 skarnet.org。