我が家ではRaspberry Piを常時起動してPythonでTwitterのBotを運用したりしています。
問題となるのは、突然のPythonの例外処理などのエラーでコードが正常に実行できなかったときに、それを瞬時に知る手段がないことです。
そのため、我が家ではエラーが起きた瞬間にLINEに通知ようにしています。
また、エラー文が長すぎる場合はPastebinに投稿して、そのURLが通知されるようにしています。
また、万が一通信エラーが生じた場合には、一度LOGに記録し、再起動するようにしています。
例えばhoge.py
が以下のようなコードであったとします。
print(hoge)
エラーは以下のように出ます。
Traceback (most recent call last):
File "hoge.py", line 1, in <module>
print(hoge)
NameError: name 'hoge' is not defined
hoge
が定義されていないと怒られます。当然ですね。
これがLINEに通知されるようにします。
実装
まずhoge.py
を以下のようにします。
import traceback
import notify_traceback
try:
print(hoge)
except Exception:
notify_traceback.send(traceback.format_exc())
例外処理が起きたときに通知してほしい箇所(今回ではprint(hoge)
)をtry・except文で囲います。
tryの中で起きた例外処理をexceptでキャッチし、予めインポートしたnotify_traceback
というライブラリにtraceback内容を渡します。
そして、notify_traceback.py
というライブラリを作成します。これをPythonのライブラリに入れたり、hoge.py
と同じディレクトリに入れます。
import datetime
import os
import requests
import line_notify
from pbwrap import Pastebin
def send(traceback, fail_datetime=None):
traceback = traceback.rstrip()
print(traceback)
try:
if len(traceback) > 1000:
PASTEBIN_API_KEY = ###ここにPastebinのアクセストークン###
PASTE_NAME = str(datetime.datetime.now().replace(microsecond=0))
pb = Pastebin(PASTEBIN_API_KEY)
url = pb.create_paste(traceback, api_paste_private=1, api_paste_name=PASTE_NAME, api_paste_expire_date='1W')
raw_url = url.replace('com/', 'com/raw/', 1)
message = raw_url
else:
message = '\n' + traceback
if fail_datetime:
message = f'{fail_datetime}:\n{message}'
LINE_NOTIFY_ACCESS_TOKEN = ###ここにLINE Notifyのアクセストークン###
client = line_notify.LineNotify(token=LINE_NOTIFY_ACCESS_TOKEN)
res = client.notify(message, time_format=None)
print(res[0])
except requests.exceptions.ConnectionError:
ERROR_FAIL_TEXT_PATH = ###万が一送信できなかった場合のLOGのパス###
with open(ERROR_FAIL_TEXT_PATH, mode='w') as f:
f.write(traceback)
os.system('sudo reboot')
if __name__ == '__main__':
send(f'Traceback (most recent call last):\n File {__file__}, line ∞, in <module>\nAbsolutelyZeroErrors: it\'s just fine')
なお、pypiからpyline-notifyをインストールしておく必要があります。
pip install pyline-notify
LINE通知を使用するためのアクセストークンも必要です。公式サイト、もしくはググってください。
また、pypiからpbwrapもインストールしておく必要があります。
pip install pbwrap
これについても、Pastebinのアクセストークンも必要です。ログインしてからAPIの公式サイトから取得可能です。
結果
これでhoge.py
を実行すると、以下のようにLINEに通知が来ます。
また、エラーが長すぎる場合はこうなります。
渡しの場合、リンクは1週間保持されるようにしましたが、これは設定可能です。
これで、Rasbperry Piに何らかのエラーが起きてもすぐにどんなエラーが起きたか確認できます。
応用
今回はLINEで知らせるようにしましたが、メールで知らせたり、Twitterでツイートにするようにしたりもできますね。