デーモンではないプログラムをnohupなどから起動する方法で常駐させるのは良いとしても、その出力をログに記録するときには少々問題がある。
そこでプログラムからの出力は名前付きパイプ(FIFO)に対して行い、別のプロセスからログファイルに書き込むようにする。
名前付きパイプ(FIFO)からログを受信しファイルに書き込むスクリプト
#!/bin/sh FIFO=/var/tmp/logpipe PID=/run/receive-log LOG=/var/log/pipe.log if [ -n "$1" ] then LOG=$1 fi echo $$ > ${PID} test -p ${FIFO} || mkfifo ${FIFO} trap receive_SIGHUP 1 trap receive_SIGTERM 15 # --- Functions receive_SIGHUP () { daytime=`date '+%Y-%m-%dT%H:%M:%S%z'` echo "Received SIGHUP" 1>&2 sleep 10 } receive_SIGTERM() { daytime=`date '+%Y-%m-%dT%H:%M:%S%z'` echo "Received SIGTERM" 1>&2 rm ${PID} exit 0 } # --- Main while true do if [ -p ${FIFO} ] then read line <${FIFO} test -n "${line}" && echo ${line} >> ${LOG} else sleep 1 fi done 2>/dev/null
ログ受信スクリプトをsystemdのサービスとして定義するファイル
[Unit] Description="pipe log receiver" Before=pipe.service [Service] Type=simple ExecStart="/usr/local/bin/receive-log" KillMode=process PIDFile=/run/receive-log StandardOutput=syslog StandardError=syslog SyslogIdentifier=receive-log [Install] WantedBy=default.target
ログ出力を確認するためのテスト用ログをパイプに送信するスクリプト
#!/bin/sh FIFO=/var/tmp/logpipe while true do date '+%Y-%m-%dT%H:%M:%S%z' > ${FIFO} sleep 5 done
ログファイルを切り替えないプロセスに対し、logrotateではコピーを作成した後に元のログファイルを空にすることもできる。
ただし、ログ切替時に書き込まれたログは失われる可能性がある。