Pythonのlogging.config.fileConfig()でメールを送る例

Pythonのloggingでエラー時にメールを送る設定をしたく、ファイルから設定を読み出すようにしました。
fileConfig()で設定したのですが公式サイトにも完全な例がなく、なかなか苦労したのでメモ。
dictConfig()ならいくつか見かけたので、素直にそちらを使えばよかったかも。

Pythonのバージョンは3.9.1。

サンプル

コード

example.py

from logging import getLogger
from logging.config import fileConfig

fileConfig('./logging.conf')
logger = getLogger(__name__)

logger.info('Output only to the console.')
logger.error('Will also be sent to email.')

設定ファイルはlogging.confとしました。
fileConfig()についての公式リファレンスは以下のリンクより。
fileConfigの公式リファレンス


レベルDEBUG以上をコンソールに表示して、ERROR以上をメールで送る場合の設定です。

logging.conf

[loggers]
keys=root

[handlers]
keys=consoleHandler,emailHandler

[formatters]
keys=consoleFormatter,emailFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler,emailHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=consoleFormatter
args=(sys.stdout,)

[handler_emailHandler]
class=handlers.SMTPHandler
level=ERROR
formatter=emailFormatter
args=(('example.server.com', 465), 'from@example.com', ['to@example.com', ], 'ERROR!', ('username', 'password'), ())

[formatter_emailFormatter]
format=%(asctime)s:%(levelname)s:%(name)s:%(message)s

[formatter_consoleFormatter]
format=%(levelname)s:%(name)s:%(message)s

今回レベルERROR以上でメール送信としたのでloggerがrootだけですが、ログの系統をコンソールとメールで完全に分けたいならloggerも追加で定義してください。

[handler_emailHandler]について

handlerを定義する必要があります。

[handler_emailHandler]
class=handlers.SMTPHandler
level=ERROR
formatter=emailFormatter
args=(('example.server.com', 465), 'from@example.com', ['to@example.com', ], 'ERROR!', ('username', 'password'), ())

となっていますが、argsには

args=((<メールサーバー>, <ポート番号>), <メール送信元>, [<メール宛先1>, <メール宛先2> ... ], <メール件名>, (<ユーザー名>, <パスワード>), (<空のタプルか認証情報>))

を設定します。
最後の空のタプルも必要です。
さらに追加でタイムアウトも設定可能です。

▼ handlers.SMTPHandler
SMTPHandlerの公式リファレンス

[formatter_emailFormatter]について

[formatter_emailFormatter]
format=%(asctime)s:%(levelname)s:%(name)s:%(message)s

カスタムしたログテキストを作成可能です。

よく使いそうなものとしては、

属性名 フォーマット                          説明
asctime %(asctime)s LogRecord が生成された時刻を人間が読める書式で表したもの。デフォルトでは "2003-07-08 16:49:45,896" 形式 (コンマ以降の数字は時刻のミリ秒部分) です。
funcName %(funcName)s ロギングの呼び出しを含む関数の名前。
levelname %(levelname)s メッセージのための文字のロギングレベル ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')。
message %(message)s msg % args として求められた、ログメッセージ。 Formatter.format() が呼び出されたときに設定されます。
name %(name)s ロギングに使われたロガーの名前。

他の属性はこちらの公式リファレンスから。

▼ LogRecord 属性
LogRecord 属性の公式リファレンス

出力

コンソール

INFO:__main__:Output only to the console.
ERROR:__main__:Will also be sent to email.

メール文面:

2021-02-12 23:24:38,484:ERROR:__main__:Will also be sent to email.

GitHubにコードおいてみました。

GitHub - singo-i/example-to-send-an-email-with-fileConfig-of-Python-logging