Raspberry Pi で起動、自動終了時のログを残す方法と設定の手順についてまとめておきます。
具体的には、起動時、終了時にログを残す Python のスクリプトを作っておき、これらを Raspberry Pi (Linux) の cron 機能を使って登録することで、起動、終了時に自動でログを残すようにします。
以下の環境で動作確認をしています。
環境: Raspberry Pi 3 model B+、USBカードリーダー、ログ保存用の SDカード
背景
日ごろ、Raspberry Pi を自動起動、自動終了させて定型作業の自動化を進めています。
自動化するにあたり、Raspberry Pi の起動時や、シャットダウン時にログを残しておくと、何か問題があったときにトレースができ、とても便利です。
また、独自の Python のスクリプトを作ったとき、同様に自動実行するよう設定し、ログも保存するようにしておきます。すると、後から、過去のすべての履歴を時系列で確認できます。
起動、終了、自動実行した処理内容のログを残すようにし、数か月運用してみると、ログから、各機能の必要性や実行頻度、重要度を見直すことで、稼働時間の最適化や処理内容の見直しも可能となります。
ということで、まずは、起動時、終了時のスクリプトと設定手順をまとめておくことにします。
他の処理を自動化してログを残す場合も、要領は同じです。
設定方法
起動・終了用のスクリプトの作成
① Raspberry Pi に自動処理用のフォルダを作ってください。
例: /home/pi/auto1/
② ①のフォルダに、”01_start1.py”、”02_shutdown1.py” 等の名前でテキストファイルを作り、下記のサンプルスクリプトをコピー&ペーストして保存してください。
③ ログファイル(log1.txt)は、①のフォルダ内に書き出すようにしています。
フォルダの場所やフォルダ名を変える場合は、②のスクリプト内に記載したパス等を修正してください。
④ ②の2つのファイルは、⑤以下で、cron という機能で自動実行します。以下を参考に、これらのスクリプトに実行権限(-rwx….)を設定してください。
$ cd /home/pi/auto1/
$ ls -al
$ chmod 744 01_start1.py
$ chmod 744 02_shutdown1.py
$ ls -al
※ 実行権限が与えられると、灰色だったファイル名の表示が緑色に変わると思います。
スクリプトを自動で実行するよう設定する ~ cron の設定
⑤ ターミナルを起動し、”crontab -e” と入力し、[enter] キーを押します。
⑥ 起動した cron の編集画面の末尾等に、以下の行を追加します。
@reboot sleep 30
@reboot sudo python /home/pi/auto1/01_start1.py
30 23 * * * sudo python /home/pi/auto1/02_shutdown1.py
⑦ 編集が終わったら、[ctrl] + [x] キーを押します。
編集内容を保存する場合は [y] キーを押します。編集内容を破棄する場合は、[n] キーを押します。
→ スクリプトの設定まで完了です。
・ なお、①でフォルダ名やファイル名を変えた場合は、上記の Python スクリプトのパスなどを修正してください。
・ ”@reboot … ” とした行は、Raspberry Pi を起動した際に実行するコマンドの記載例です。
・ 上の例は、起動時に 30 秒スリープした後、Python のスクリプト 01_start1.py (起動時のログを書き出す)を実行する例です。Raspberry Pi の起動時は、通常、ネットワークの接続や周辺機器の起動に時間を要します。そこで経験的に、上記の程度のウェイトを入れ、システムや周辺機器が安定化してから独自の処理を行うようにしています。
・ 加えて、23:30 になったら、02_shutdown1.py (ログを書き出したあと、シャットダウンを行う)を実行します。設定時刻(23:30)は、必要により修正してください。私の場合、スクリプトの設定中は、動作確認のため、現在時刻の数分後などの時間を設定して自動実行させてみて、うまく動いたら、実際に使う時刻に合わせるというやり方をしています。
・ それぞれのスクリプトでは、起動とシャットダウン時の日時のログを保存するようにしています。
上記の設定により、起動、自動終了する際に、同フォルダ内に時刻つきでログが保存されるようになります。
動作確認 ~ ログが保存されることを確認する
⑧ Raspberry Pi を再起動してみて、上記のフォルダに起動時のログが保存されることを確認してください。
また、⑤で設定した時刻に 02_shutdown1.py が実行され、Raspberry Pi がシャットダウンされることを確認してください。
→ これで動作確認も完了です。
必要により、フォルダの場所や自動終了の時刻などを修正、最適化してください。
なお、ターミナルから 02_shutdown1.py を実行すると(”sudo python /home/pi/auto1/02_shutdown1.py 等)、手動でシャットダウンを実行できます。動作確認をしたいときや、ログを残したいときなどに使えると思います。
うまく動かないとき
・ うまく動かないときは、ターミナル上で以下のコマンドを実行し、cron が動作していることをまずは確認してみてください。
$ sudo /etc/init.d/cron status (ステータス確認)
→ active (running) 等の表示がされたら、cron は正常に動作しています。
以下のコマンドで、cron を、起動、停止、再起動できます。
$ sudo /etc/init.d/cron start (起動)
$ sudo /etc/init.d/cron stop (停止)
$ sudo /etc/init.d/cron restart (再起動)
・ ファイル名やパスにミスタイプがないか確認してみてください。特に、ファイル名やフォルダの場所などを変えた場合、確認をしてみてください。
・ 実行権限の設定も確認してみてください。
・ また、上記の Python のスクリプトをターミナルから手動で実行してみて、ログが書き出せるか、シャットダウンコマンドが実行されるかを確認してみてください。
サンプルコードの説明
・ 2つあるそれぞれのスクリプトで、def write_append1() としたところで、ログを書き出す関数を定義しています。
重複する記載を1つにまとめて呼び出すようにしてもよいですが、わかりやすさのため、2つのスクリプトで同じ関数を定義しています。
・ str1 としたところで、ログに書き出す文字列を作っています。具体的には、日付 + 時刻 + “start” または “shutdown” の文字列を作っています。
・ path1 としたところで、書き出すログのパスを定義しています。書き出す場所を変える場合は、この部分を修正してください。
・ write_append1() 関数を実行し、ログを書き出します。
・ シャットダウンをするスクリプトでは、この後、シャットダウンのコマンド文字列を作って、実行しています。
・ ログは、アペンドモードで記録しています。すなわち、すでに書かれているログは残したまま、末尾にログを追加するようにしています。
うまく動いたら
・ うまく動いたら、実行する時刻やスクリプトの内容を修正するなど、改善・最適化をしてみてください。
・ Python などで便利なスクリプトや自動化したいスクリプトを作った場合、上記の “auto1” フォルダに追加してみてください。上記と同様に cron の設定をすると、自動化が可能となります。
Python のスクリプト内に上記と同様の記載をすることで、スクリプトを実行した日時をログに残すことが可能です。別ファイルに測定データなどを書き出すようにすることで、ログや測定データなどの自動記録が可能になります。
・ 上記のサンプルでは、簡単のため/説明のため、ログは、Raspberry Pi の起動 SD カード内に残すようにしています。
長期間運用する場合は、書き込み回数やデータ量が増えます。この場合、ログやデータを書き込むメディアは、システムを書き込んだメディアとはわけるほうが安全です。
例えば、USB カードリーダーの SD カードに①のフォルダを作成し、外部のメディアにデータやログを書き出すようにしたほうが安全です。
また、ログファイルのファイル名の冒頭に年月を入れると、各月ごとにファイル名を変えて保存することができます。古いログは別のメディアに移すといった運用も可能となります。検討してみてください。
まとめ
起動時のサンプルコードと、シャットダウン時のサンプルコードについてまとめました。
また、これらのスクリプトを Raspberry Pi (Linux) の cron 機能を使って登録し、自動実行する手順をまとめました。
Raspberry Pi のハードウェアの電源の ON/OFF については、下記の関連リンクにまとめています。
これらを組み合わせることで、ハードウェアとソフトウェアの両方で自動化が可能となります。
起動/終了/計測/自動処理などのログのトレースも可能となります。
関連リンク
・ Raspberry Pi を自動で起動、シャットダウンする
・ 指定したフォルダを RAM 上に設定する 【Raspberry Pi】
サンプルコード1: 01_start1.py 起動時のスクリプトの例
import datetime as dt1
def write_append1( file1, str1 ):
with open( file1, "a" ) as f1:
f1.write( str1 + "\n" )
return 0
str1 = dt1.datetime.now().strftime( "%y%m%d %H%M%S" ) + " start "
print( str1 )
path1 = "/home/pi/auto1/"
file1 = path1 + "log1.txt"
write_append1( file1, str1 )
サンプルコード2: 02_shutdown1.py シャットダウン時のスクリプトの例
import datetime as dt1
import subprocess as sp1
import shlex as sl1
def write_append1( file1, str1 ):
with open( file1, "a" ) as f1:
f1.write( str1 + "\n" )
return 0
str1 = dt1.datetime.now().strftime( "%y%m%d %H%M%S" ) + " shutdown "
print( str1 )
path1 = "/home/pi/auto1/"
file1 = path1 + "log1.txt"
write_append1( file1, str1 )
cmd1 = "sudo shutdown -h now"
print( cmd1 )
arg1 = sl1.split( cmd1 )
ret1 = sp1.call( arg1 )