Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@kiyonaga

ラズパイのプロセス監視をslee-Pi3のウォッチドッグタイマで【異常動作検知ー実装編】

今回は、「slee-Pi3」のウォッチドッグタイマを利用したプロセス監視を行います。
前回【異常動作検知による監視】は動作確認でしたが、今回はより実用性を求めてserviceファイルでNice等は与えません
※環境と事前準備はこちらをご覧ください。

[関連ブログ]

slee-Pi3のウォッチドッグタイマを利用したプロセス監視
OOM状態からの即時復帰
正常動作検知による監視
異常動作検知による監視
【異常動作検知-実装】← 本ブログ

[目的と方法]

目的:停止したくないプログラムが停止した場合に、クリーンな状態で再開させたい。
方法:プログラム内にハートビートを組込んでおき、ウォッチドッグタイマが異常検知した際に再起動させる。

[手順1]serviceファイル作成

/etc/systemd/system/test-heartbeat.service
[Unit]
Description=sleepi3 test heartbeat
DefaultDependencies=no 
After=sysinit.target

[Service]
Type=simple
ExecStart=/opt/mtx/test_heartbeat.py ← 実行ファイルのフルパス

[Install]
WantedBy=sysinit.target

シンプルなものを作成します。

※serviceファイル内の記述詳細については下記コマンドでご確認ください。

$ man systemd.service

[手順2]実行プログラム+ハートビートを作成

素数計算中にハートビートを発生させます。
RaspberryPiでよく使うpythonを用います。

#!/usr/bin/python3

import os
import time
import math
from datetime import datetime
from datetime import timedelta

LED_PATH = '/sys/class/leds/sleepi:led0/brightness'
PRIME_PATH = '/var/log/prime-num.log'

class LedBlink():
    def __init__(self,num,dt):
        self.num = num
        self.dt = dt

    def blink(self):
        now = datetime.now()
        if now - self.dt > timedelta(seconds=1):
            with open(LED_PATH,mode="w") as f:
                f.write(self.num)
            self.dt = now
            if self.num == "0":
                self.num = "1"
            else:
                self.num = "0"

def check_files():
    #calculation continue
    if os.path.isfile(PRIME_PATH):
        with open(PRIME_PATH) as f:
            saved_num = f.readline()
    #path lost
    else:
        with open(PRIME_PATH,mode="w") as f:
            f.write("3")
        print("new prime-log created")
    return int(saved_num)

def save_num(PATH,i):
    with open(PATH,mode="w") as f:
         f.write(str(i))

def prime_calc(num,Led):
    i = num
    while True:
        Led.blink()
        j = 3
        flag = 0
        r = math.sqrt(i)
        while j<=r:
            if i%j==0:
                flag = 1
                Led.blink()
                break
            j+=2
        if flag==0:
            save_num(PRIME_PATH,i)
        i+=2

def main():
    Led = LedBlink(num="0",dt=datetime.now())
    num = check_files()
    prime_calc(num,Led)

if __name__ == "__main__":
    main()
else:
    print("FILE NAME ERROR")

[手順3]既存の「sleepi3-heartbeat.service」を停止し、自作ハートビートを起動する

sleePi3-utilsに含まれているserviceです。

$ sudo systemctl disable sleepi3-heartbeat.service
$ sudo systemctl enable test-heartbeat.service
$ sudo systemctl daemon-reload

「test-heartbeat.service」は自作ハートビートのファイル名を入れてください。

[手順4]OOMKiller用プログラム作成と実行

こちらのブログを参考に作成し、実行しました。

[手順5]復帰確認

動作確認編と違い、NiceやOOMScoreAdjustを付与していないのでしばらく生き残りつつ、最終的にはOOMによりハートビート停止→ハードウェアリセットが確認できます。

下記コマンド実行で再起動要因がわかります。

$ sleepi3ctl -g wakeup-flag
watchdog

[まとめ]

今回は、「slee-Pi3」のウォッチドッグタイマによるプロセス監視を行いました。
監視プロセスがOOMKillerにkillされた際に、ハードウェアリセットをかける仕組みです。
ぜひ本製品を使った開発にお役立てください。

1
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
kiyonaga
メカトラックスの中の人です。
mechatrax
メカトラックスはハードウエアの開発/製造を行う会社です。 これらに関連する電子回路/組込ソフト/センサー/機構など 幅広い技術分野に於いて、豊富な実績を有しています。 特に近年は、業務用途でのラズベリーパイ活用に関して、 各種機能拡張モジュールの開発・製造やこれらを組み合わせた プロトタイピング、小ロット製造等にも注力しています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?