ユーザ用ツール

サイト用ツール


名前付きパイプ_fifo_経由でログを受信するスクリプト

名前付きパイプ(FIFO)経由でログを受信するスクリプト

デーモンではないプログラムをnohupなどから起動する方法で常駐させるのは良いとしても、その出力をログに記録するときには少々問題がある。

  • nohupを使うのでSIGHUPは無視される。
  • 標準出力のリダイレクトでログ出力をしていると、ログのローテーションができない。(TIPS追記)

そこでプログラムからの出力は名前付きパイプ(FIFO)に対して行い、別のプロセスからログファイルに書き込むようにする。

ログ受信スクリプト

名前付きパイプ(FIFO)からログを受信しファイルに書き込むスクリプト

receive-log
#!/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のサービスとして定義するファイル

receive-log.service
[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

テスト用ログ送信スクリプト

ログ出力を確認するためのテスト用ログをパイプに送信するスクリプト

send-log
#!/bin/sh
FIFO=/var/tmp/logpipe
 
while true
do
  date '+%Y-%m-%dT%H:%M:%S%z' > ${FIFO}
  sleep 5
done

TIPS

ログファイルを切り替えないプロセスに対し、logrotateではコピーを作成した後に元のログファイルを空にすることもできる。
ただし、ログ切替時に書き込まれたログは失われる可能性がある。

名前付きパイプ_fifo_経由でログを受信するスクリプト.txt · 最終更新: 2023/09/08 02:02 by Minoru Kijima