"file:" 構成で systemd が管理するサービスログを正しく記録する方法

"file:" 構成で systemd が管理するサービスログを正しく記録する方法

systemdにログを直接ファイルに書き込むように指示するsystemd構成を持つsystemdが管理するサービスがあります(syslogやその他の項目はありません)。

StandardOutput=file:/var/log/foo/my.log

ログ回転ルールがあります

/var/log/foo/*.log
{
        rotate 31
        daily
        missingok
        notifempty
        compress
        delaycompress
        sharedscripts
}

何が起こっているのかは、ログは循環していますが、サービスはまだ以前に循環したファイルに書き込んでいますが、新しいログファイルはまだ空です。

サービスがsyslogに記録する同様のタスク設定があります。 logrotate設定

postrotate
                invoke-rc.d rsyslog rotate > /dev/null

、ログが交換されたことをsyslogに通知します。

問題は、問題がある場合はログがファイルに直接送信されるため、同様のシグナルをsystemdに送信するのか、実際のサービスプロセスに送信するのかを知ることができないことです。

私はcopytruncatelogrotateでこのオプションを見つけて、それが私の問題を解決すると確信していますが、これは理想的なcopytruncateアプローチではありません。

この問題をどのように解決できますか? systemdに信号を送る必要がありますか?サービスプロセスに信号を送る必要がありますか?copytruncatelogrotateで使用する必要がありますか?
重要な場合、サービスはログバックを使用してstdoutに書き込むJavaプロセスです。

答え1

copytruncateこの場合は正解です。ログファイルを再度開くようにシグナルを送信できるデーモンがあるため、ほとんど必要ないため、デフォルトではありません。

別のアプローチは、交換後にスクリプトからサービスを再起動することですが、これは便利ではないか理想的ではないかもしれません。

答え2

systemdで開かれたログは、StandardOutput=file:このサービスによって開きます。これにより確認できます。lsof /var/log/mylog.log

したがって、回転はサービスによって異なります。サービスが特定のシグナルを受信した後にログファイルを再度開くことをサポートしている場合は、単にサービスにシグナルを送信できます。いいえシステムへ

たとえば、ApacheはUSR1またはHUPを受信した後にログファイルを再度開きます。したがって、次のいずれかの信号を送信する必要があります。

サービスの単位ファイルにサービスに適切なシグナルを送信するExecReload行がある場合は、次のコマンドを使用してこれを実行できます。

systemctl reload $service

それ以外の場合は、別の方法を使用する必要があります。

kill -$signal $pid

関連情報