私のCプログラムのすべての出力がstdoutに渡され、Journaldに送信されるのはなぜですか?

私のCプログラムのすべての出力がstdoutに渡され、Journaldに送信されるのはなぜですか?

私はyoctoベースのLinuxディストリビューションに取り組んでいます。私はこれの専門家でもないしsystemd、私でもないsystemd-journald
私のCプログラムはmy_c_program起動時にスクリプトによって起動されますmy_script.sh。ファイルは次のとおりですmy_script.sh

my_c_program &
echo $! > /dev/shm/my_c_program.pid

以前のスクリプトはサービスによって開始されます。サービスの単位ファイルはstart_c_program.service次のとおりです。

[Unit]
Description=Start my_c_program
Requires=...
After=...
Before=...

[Service]
Type=forking
ExecStart=/usr/bin/my_script.sh
PIDFile=/dev/shm/my_c_program.pid

[Install]
WantedBy=multi-user.target

この設定を使用すると、すべてのディレクティブprintf("message")が 。次のように変更するとわかります。my_c_program"message"systemd-journaldmy_script.sh

my_c_program > /dev/null &
echo $! > /dev/shm/my_c_program.pid

のメッセージはjournald表示されませんが、問題は
なぜ私のCプログラムのすべての出力がstdoutに送信されるのでしょうかjournald

ありがとう


たとえば、次のコードを使用してjournaldC命令を使用する必要があるというメッセージを送信したいとします。syslog()

#include<syslog.h>
int main(int argc, char** argv) {
    syslog(LOG_INFO, "Start logging");
}

答え1

Systemd は実行プロセスの標準出力をログにリンクします。標準出力はすべての子プロセスから継承されるため、C プログラムはコンテンツをログに出力します。あなたはそれを使用することができます標準出力=引数はプログラムの標準出力を別の場所にリダイレクトします。

答え2

これはsystemdのデザイン機能であり、実際に最新のソフトウェアでより一般的です。

現代のデザインは、ログを送信する場所を決定するソフトウェアで実行されているプログラム(この場合はsystemd)に何をすべきかを決定する方向に移動しています。ソフトウェア自体はstdoutとstderrに書き込みます。 DockerまたはKubernetesで実行されるコンテナ化されたソフトウェアは、非常に似たパターンを持っています。

多くのプログラムはsyslogに書き込む方法を知らず、stdout / stderrに書くよりも複雑です。 Syslogは完全にユビキタスされておらず、これらのプログラムは以前にstdout / stderrをvarログのログファイルにリダイレクトしている可能性があります。

systemdがプログラムを起動すると、プログラムを実行する前にプロセスのファイルハンドルを置き換えてstdoutとstderrがログにリダイレクトされます。

関連情報