LoginSignup
2
2

More than 3 years have passed since last update.

【俺的】Pythonロギングまとめ~ログファイル/標準出力

Last updated at Posted at 2019-10-03

Pythonでロギングする際の俺的ベストプラクティス
パターンは以下の通り

  1. ファイル出力(全て同一ログファイルに出力する)
  2. ファイル出力(ログレベルに応じてログファイルを分ける)
  3. 標準出力

基本的に、ログファイル出力と標準出力を併用するケースって少ないと思います。
標準出力のパターンは、コンテナ環境でfluentdドライバなどで外部転送したいケースがあるかなと思います。

参考にさせて頂きました → pythonのlog出力 by
@yopya

ファイル出力(全て同一ログファイルに出力する)

from logging import getLogger, Formatter, handlers, DEBUG


class FileLogger:
    def __init__(self, file='log/app.log'):
        self.logger = getLogger(__name__)
        self.logger.setLevel(DEBUG)
        formatter = Formatter('%(asctime)s %(levelname)s %(name)s: %(message)s')
        handler = handlers.RotatingFileHandler(
            filename=file,
            maxBytes=1048576,
            backupCount=3
        )
        handler.setFormatter(formatter)
        handler.setLevel(DEBUG)
        self.logger.addHandler(handler)

    def debug(self, msg):
        self.logger.debug(msg)

    def info(self, msg):
        self.logger.info(msg)

    def warn(self, msg):
        self.logger.warning(msg)

    def error(self, msg):
        self.logger.error(msg)

    def critical(self, msg):
        self.logger.critical(msg)

ファイル出力(ログレベルに応じてログファイルを分ける)

ERROR以上のレベルの場合にerr.logに出力

from logging import getLogger, Formatter, handlers, DEBUG, ERROR


class FileLogger:
    def __init__(self, debug_file='log/app.log', error_file='log/err.log'):
        self.logger = getLogger(__name__)
        self.logger.setLevel(DEBUG)
        formatter = Formatter('%(asctime)s %(levelname)s %(name)s: %(message)s')
        # DEBUGレベルハンドラ定義
        debug_handler = handlers.RotatingFileHandler(
            filename=debug_file,
            maxBytes=1048576,
            backupCount=3
        )
        debug_handler.setFormatter(formatter)
        debug_handler.setLevel(DEBUG)
        self.logger.addHandler(debug_handler)
        # ERRORレベルハンドラ
        error_handler = handlers.RotatingFileHandler(
            filename=error_file,
            maxBytes=1048576,
            backupCount=3
        )
        error_handler.setFormatter(formatter)
        error_handler.setLevel(ERROR)
        self.logger.addHandler(error_handler)

    def debug(self, msg):
        self.logger.debug(msg)

    def info(self, msg):
        self.logger.info(msg)

    def warn(self, msg):
        self.logger.warning(msg)

    def error(self, msg):
        self.logger.error(msg)

    def critical(self, msg):
        self.logger.critical(msg)

標準出力

from logging import getLogger, Formatter, StreamHandler, DEBUG


class StreamLogger:
    def __init__(self):
        self.logger = getLogger(__name__)
        self.logger.setLevel(DEBUG)
        formatter = Formatter('%(asctime)s %(levelname)s %(name)s: %(message)s')
        handler = StreamHandler()
        handler.setFormatter(formatter)
        handler.setLevel(DEBUG)
        self.logger.addHandler(handler)

    def debug(self, msg):
        self.logger.debug(msg)

    def info(self, msg):
        self.logger.info(msg)

    def warn(self, msg):
        self.logger.warning(msg)

    def error(self, msg):
        self.logger.error(msg)

    def critical(self, msg):
        self.logger.critical(msg)

使い方

logger = StreamLogger()
message = 'hello world!'
logger.info(message)
# => '2019-10-03 12:47:46,667 INFO __main__: hello world!'

FileLoggerの場合は同様のメッセージが/log/app.logに出力されていく

まとめ

「標準出力」に加えて「標準エラー出力」も必要だということに記事書いてて気づいたので後で対応する。

2
2
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
2
2