0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonの例外処理のエラー内容をLINEに通知する方法

Last updated at Posted at 2021-12-01

我が家ではRaspberry Piを常時起動してPythonでTwitterのBotを運用したりしています。
問題となるのは、突然のPythonの例外処理などのエラーでコードが正常に実行できなかったときに、それを瞬時に知る手段がないことです。
そのため、我が家ではエラーが起きた瞬間にLINEに通知ようにしています。
また、エラー文が長すぎる場合はPastebinに投稿して、そのURLが通知されるようにしています。
また、万が一通信エラーが生じた場合には、一度LOGに記録し、再起動するようにしています。

例えばhoge.pyが以下のようなコードであったとします。

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を以下のようにします。

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と同じディレクトリに入れます。

notify_traceback.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に通知が来ます。
image.png

また、エラーが長すぎる場合はこうなります。
mosaic_20220331200201.png
渡しの場合、リンクは1週間保持されるようにしましたが、これは設定可能です。

これで、Rasbperry Piに何らかのエラーが起きてもすぐにどんなエラーが起きたか確認できます。

応用

今回はLINEで知らせるようにしましたが、メールで知らせたり、Twitterでツイートにするようにしたりもできますね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?