【Python】ログを『ファイルサイズでローテーション』して出力するコード例 RotatingFileHandler

Python の RotatingFileHandlerローテーティング ファイル ハンドラ で、ログをローテーションして出力するコードれいです。

『ログ出力』と『ログのファイルサイズによるローテーション』は、RotatingFileHandler() を使うとできました。

ログファイルを自動で分割しながら、テキストファイルに出力することができました。

古いログも、自動でリネームして、ログファイルをローテーションして、残してくれました。

コマンドプロンプトには何も表示されず、『ファイル』だけに出力できました。

ログのファイルサイズ maxBytes を指定したら、だいたいそのサイズで、自動的に分割してくれました。

ログのファイルサイズは、文字コードによって変わりました。

ログのバックアップのかず backupCount を指定したら、その数だけ、分割後の古いログを残してくれました。

全体のログサイズは『ログサイズ×(最新ログ1個+バックアップN個)』くらいに収まりました。

古いログが『流れて消えていく仕組み』を作ることができました。

ログサイズの設定をデフォルトの maxBytes=0 にしたら、ログが分割されず、どこまでも大きくなっていきました。

ちょうど、普通の FileHandlerファイルハンドラ と同じような動作になりました。

とりあえずは RotatingFileHandler を maxBytes=0 で使っておいて、必要に応じてサイズを指定する、という使い方も便利でした。

使用したライブラリ

Python 公式マニュアルの場所です。

logging モジュール

logging.handlers パッケージ

組み込み機能

コード例

ロガーで、ログファイルをローテーションしながら記録する Python コード例です。

ローテーティングファイルハンドラ RotatingFileHandler() を使います。

※(2020年6月18日 追記)logging.getLogger() で取得したロガー lg は、『グローバル』で持つほうが、便利で適切だと思います。コード例では関数の中に入れたままですが、必ずしもそうする必要は無いと思ったため、補足として追記します。

"""RotatingFileHandlerでログ出力するPythonコード例"""

import logging
import logging.handlers

def main():
    """メイン関数"""

    # ロガーを取得
    lg = logging.getLogger(__name__)
    lg.setLevel(logging.DEBUG)

    # ローテーティングファイルハンドラを作成 & ロガーに追加
    rh = logging.handlers.RotatingFileHandler(
        r'F:\apps\data\rh.log', encoding='utf-8',
        maxBytes=50,
        backupCount=3,
        )
    rh.setLevel(logging.DEBUG)
    lg.addHandler(rh)

    lg.debug('start')

    # (コード例) 架空の気温でログレベルを分けてみる
    temperatures = [20, 25, 30, 35, 40, 45]
    for t in temperatures:
        if t < 24:
            lg.debug(f'debug 気温 {t} ℃')
        elif 24 <= t < 28:
            lg.info(f'info 暑さに注意 {t} ℃')
        elif 28 <= t < 31:
            lg.warning(f'warning 暑さに警戒 {t} ℃')
        elif 31 <= t < 36:
            lg.error(f'error 暑さに厳重警戒 {t} ℃')
        elif 36 <= t:
            lg.critical(f'critical 危険な気温です {t} ℃')

    lg.debug('end')
    return

if __name__ == '__main__':
    main()

ロガーとハンドラには、深刻度しんこくどの低い logging.DEBUG をセットしました。

なので、どのログレベルの出力も記録されるはず。

あと、文字コードは encoding=’utf-8′ で、maxBytes=50 バイト (bytes) をセットしました。

ところで、1文字は何バイトか?

Windows のファイルのプロパティや、テキストエディタの機能で、テキストファイルをチェックしました。

utf-8 では、アルファベットなら1文字1バイト、日本語なら1文字3バイトの計算になりました。

日本語のバイト数は、大抵3バイトでしたが、『utf-8 4バイト 日本語』で検索したところ、例外もあるようでした。

さて、日本語としては、 maxBytes=50 バイトだと、 50 / 3 = 約 16 文字が入る計算です。

とりあえず、ログファイルが分割されて、それらの1つ1つが 50 バイトくらいに収まれば成功です。

実行結果

ログファイルの内容です。

ログの並びは、ローテーションの関係で、Python コードの並びと逆順になりました。

OS は Windows 7 64bit で、出力されたログファイルの改行コードは CR+LF でした。

Web 表示の都合で改行表記を省略しましたが、各行の末尾には、CR+LF の2バイトがくっついていました。

rh は RotatingFileHandler の略です。

rh.log(ファイルサイズ 44 バイト)

critical 危険な気温です 45 ℃
end

rh.log.1(ファイルサイズ 39 バイト)

critical 危険な気温です 40 ℃

rh.log.2(ファイルサイズ 36 バイト)

error 暑さに厳重警戒 35 ℃

rh.log.3(ファイルサイズ 32 バイト)

warning 暑さに警戒 30 ℃

どのログレベルも、ファイルに記録されていました。

あと、それぞれのファイルサイズも、50 バイト以下に収まっていました。

成功です。

maxBytes=0 の実行結果

ログサイズの設定を、デフォルトのゼロ maxBytes=0 にした時の結果です。

Python コード

    rh = logging.handlers.RotatingFileHandler(
        r'F:\apps\data\rh.log', encoding='utf-8',
        maxBytes=0,
        backupCount=3,
        )

実行結果

rh.log(ファイルサイズ 208 バイト)

start
debug 気温 20 ℃
info 暑さに注意 25 ℃
warning 暑さに警戒 30 ℃
error 暑さに厳重警戒 35 ℃
critical 危険な気温です 40 ℃
critical 危険な気温です 45 ℃
end

ログファイルは、分割されなかったです。

古いログが流れて、消えることもなかったです。

1つのファイルに、すべてのログを残すことができました。

スポンサーリンク
Python評価
シェアする(押すとSNS投稿用の『編集ページ』に移動します)
フォローする(RSSフィードに移動します)
スポンサーリンク
シラベルノート
タイトルとURLをコピーしました