(ラズパイ4)ffmpeg #monit
if cpu > 80% for 2 cycles then alert
if cpu > 95% for 5 cycles then restart
if 3 restarts within 5 cycles then timeout
- if cpu > 80% for 2 cycles then alert
- cpu > 80%:ffmpegプロセスのCPU使用率が80%を超えた場合。
- for 2 cycles:Monitが2回連続してチェックを行った結果、80%を超え続けている場合。Monitの1サイクルはデフォルトで2分です(このサイクル時間は設定で変更可能です)。
- then alert:CPU使用率が80%以上を2回連続で超えたらアラート(メール通知やログへの書き込み)を行う。
- if cpu > 95% for 5 cycles then restart
- cpu > 95%:CPU使用率が95%を超えた場合。
- for 5 cycles:Monitが5回連続でチェックを行い、95%を超えている場合。
- then restart:この条件が満たされた場合、ffmpegプロセスを再起動する。
- if 3 restarts within 5 cycles then timeout
- 3 restarts:プロセスが再起動された回数が3回に達した場合。
- within 5 cycles:Monitが5回チェックを行うサイクル内で、3回再起動されていた場合。
- then timeout:Monitがプロセスの自動再起動を停止し、タイムアウトを発動します。これにより、無限に再起動し続けることを防ぎます。たとえば、根本的な問題がある場合に、無限ループに入るのを避けます。
グローバル設定と個別設定を分けたほうが良いらしい(GTP4o先生)
- グローバル設定ファイル:/etc/monit/monitrc
- 個別の設定ファイル:/etc/monit/conf.d/ ディレクトリ内に個別設定ファイルを作成可能
(グローバル)
sudo micro /etc/monit/monitrc
#Monitがどの頻度で監視を行うか
set daemon 600
#監視対象のプロセス設定は個別ファイルで設定する
include /etc/monit/conf.d/*
(個別)
sudo micro /etc/monit/conf.d/ffmpeg.conf
check process ffmpeg matching "ffmpeg"
start program = "/usr/home/XXXX/procstart.sh"
stop program = "/usr/home/XXXX/ffkill.sh"
# if cpu > 80% for 2 cycles then alert
# if cpu > 95% for 5 cycles then restart
# if 3 restarts within 5 cycles then timeout
(monitの手動起動、リロード、自動起動設定)
sudo monit reload
sudo systemctl start monit
↓ffmpegプロセスはcronで起動したいのでmonitもcronで起動
sudo systemctl enable monit
↑monit.service is not a native service, redirecting to systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable monit
(デバッグ)
sudo journalctl -u monit
sudo tail -f /var/log/monit.log
sudo monit status
sudo systemctl status monit
if does not exist for 5 cycles then exec "/path/to/restart_ffmpeg.sh" の意味は次の通りです:
if does not exist for 5 cycles は、Monitが設定されたポーリングサイクル(デフォルトでは60秒)ごとにFFmpegプロセスをチェックし、5回連続でプロセスが存在しない(ダウンしている)状態が続いた場合にアクションを実行する、という意味です。
exec "/path/to/restart_ffmpeg.sh" は、FFmpegプロセスが5サイクル(300秒間)ダウンした状態が続いた場合に指定されたシェルスクリプト(restart_ffmpeg.sh)を実行するという動作になります。
つまり、この設定は次のように動作します:
MonitがFFmpegプロセスの存在を監視し、5サイクル連続でプロセスが存在しない(FFmpegがダウンしている)ことを検出します。
5サイクル目に、FFmpegがまだダウンしている場合、Monitは指定されたシェルスクリプト(/path/to/restart_ffmpeg.sh)を実行します。
誤解を避けるための説明
この設定は、FFmpegがダウンした瞬間から5サイクル(300秒間)経過後にシェルスクリプトを1度だけ実行するというものです。つまり、「5回シェルの起動を試みる」という意味ではなく、「5サイクルの間プロセスが存在しない状態が続いたら1度だけシェルスクリプトを実行する」という動作です。
ポイント
1サイクルごとにプロセスの存在を確認します(デフォルトは60秒ごと)。
5回連続でダウンしているときにのみ、シェルスクリプトが実行されます。
したがって、MonitがFFmpegプロセスのダウンを検知してから5サイクル(300秒間)の遅延後に1回だけシェルスクリプトが実行される設定になります。
if 3 restarts within 5 cycles then timeout の意味は、Monitが指定されたプロセスを5サイクルの間に3回再起動させた場合、そのプロセスをタイムアウト(停止状態)にするという設定です。
詳細な意味:
5 cycles:Monitのポーリングサイクルです。例えば、グローバル設定で300秒ごとにポーリングするようにしている場合、5サイクルは300秒×5 = 1500秒(25分)になります。
3 restarts:Monitがプロセスを再起動する回数です。ここでは、5サイクルの間に3回再起動が行われた場合を指します。
timeout:Monitがそのプロセスの再起動を諦めて、監視から除外したり、他のアクションを実行しないようにする状態を意味します。タイムアウト後は、手動で再起動するなどの操作が必要になる場合があります。
実際の動作:
Monitはプロセス(ここではFFmpeg)を監視しています。
もしプロセスがダウンしてMonitが再起動を試みると、その回数がカウントされます。
5サイクル(例えば1500秒)以内に3回再起動が行われた場合、Monitはそのプロセスの再起動を諦め、タイムアウト状態にします。この状態では、Monitはそのプロセスを再起動しなくなります。
タイムアウト状態になった場合、手動でプロセスを再起動するか、他の監視ツールや管理者が介入する必要があるかもしれません。
なぜこの設定が有効か:
短期間にプロセスが何度もダウンする場合は、根本的な問題(設定の誤り、リソース不足、システムの不具合など)がある可能性が高いです。
Monitが無限に再起動を試みるのを防ぎ、システムの安定性を確保します。多くの再起動が失敗する場合は、手動での介入やさらなる調査が必要です。
この設定により、プロセスの再起動が3回行われても改善されない場合、Monitはタイムアウトして自動の再起動を止めることになります。
- グローバル設定ファイル:/etc/monit/monitrc
メール通知と個別設定ファイルの指定
set daemon 60
set log /var/log/monit.log
set mailserver www(数字).sakura.ne.jp
username "送信元メールアドレス" password "パスワード"
using tls
with timeout 30 seconds
set mail-format {
from: (送信元メールアドレス)
subject: monit alert -- $EVENT $SERVICE
message: $EVENT Service $SERVICE
Date: $DATE
Action: $ACTION
Host: $HOST
Description: $DESCRIPTION
}
set alert (送信先メールアドレス1)
set alert (送信先メールアドレス2)
set httpd port 2812 and
allow (BASIC認証ユーザ):(同パスワード)
include /etc/monit/conf.d/*
- 個別設定ファイル /etc/monit/conf.d/ffmpeg.conf
- プロセス起動、cpu利用率、アップロード速度について監視
- プロセス再起動はprocrestart.shを叩いているが、本体再起動のsaikidou.shでもよいかも。目的はストリームの長期間維持で、ラズパイ本体の長時間稼働ではないから。
- cpu利用率が80%を超えるとメール通知(のみ)
- アップロード速度が350kB/sを下回るとsaikidou.shでラズパイ再起動
# process
check process ffmpeg matching "ffmpeg"
start program = "/home/xxx/procrestart.sh" as uid 1000 and gid 1000
stop program = "/home/xxx/ffkill.sh" as uid 1000 and gid 1000
if does not exist for 3 cycles then exec "/home/xxx/procrestart.sh" as uid 1000 and gid 1000
if does not exist for 3 cycles then alert
if 3 restarts within 5 cycles then exec "/home/xxx/saikidou.sh" as uid 1000 and gid 1000
if 3 restarts within 5 cycles then alert
# if cpu > 80% for 2 cycles then alert
# if cpu > 95% for 5 cycles then restart
# if 3 restarts within 5 cycles then timeout
# CPU usage
check system RaspberryPi4
if cpu usage > 80% for 2 cycles then alert
# network upload
check program network_upload with path "/usr/local/bin/nw_monitor.sh"
if status != 0 for 10 cycles then exec "/home/xxx/saikidou.sh" as uid 1000 and gid 1000
if status != 0 then alert
- アップロード速度監視用 nw_monitor.sh
- アップロード速度 350kB/s
#!/bin/bash
THRESHOLD=350
UPLOAD=$(ifstat -i eth0 1 1 | awk 'NR==3 {print $2}')
echo "Current upload: $UPLOAD kB/s"
if [ -z "$UPLOAD" ]; then
echo "Error: No upload data retrieved."
exit 1
fi
if (( $(echo "$UPLOAD < $THRESHOLD" | bc -l) )); then
echo "Upload below threshold. Triggering alert."
exit 1
else
echo "Upload above threshold. All is well."
exit 0
fi
monit導入に併せ、crontabも変更
@rebootでffmpegを起動するのではなく、monitから起動するように