0
1

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 のlogの使い方 ファイルと画面に出力する/プログラム名を出力する

Last updated at Posted at 2022-06-01
  • pythonのログの機能の覚え書きです。

    • コードをそのまま実行するとログをファイルと画面に出力します。
    • 出力するログのレベル「info debug」などをコントロールするには「logger.setLevel(DEBUG)」を使います。
    • ログの関連情報「出力日時、ソースの場所等」の出力は「LogRecord 属性」を使い「setFormatter(Formatter」で行います。
  • 結局どうする?ラクして無難にPython loggingを使うためのサンプルコードと使用例」を参考にしています。

参考

logレベルの種類

レベル 数値 いつ使うか
DEBUG 10 おもに問題を診断するときにのみ関心があるような、詳細な情報。
INFO 20 想定された通りのことが起こったことの確認。
WARNING 30 想定外のことが起こった、または問題が近く起こりそうである (例えば、'disk space low') ことの表示。
ERROR 40 より重大な問題により、ソフトウェアがある機能を実行できないこと。
CRITICAL 50 プログラム自体が実行を続けられないことを表す、重大なエラー。

LogRecord 属性(setFormatter(Formatterで使う)

属性名

フォーマット

説明

args

このフォーマットを自分で使う必要はないでしょう。

msg に組み合わせて message を生成するための引数のタプル、または、マージに用いられる辞書(引数が一つしかなく、かつそれが辞書の場合)。

asctime

%(asctime)s

LogRecord が生成された時刻を人間が読める書式で表したもの。デフォルトでは "2003-07-08 16:49:45,896" 形式 (コンマ以降の数字は時刻のミリ秒部分) です。

created

%(created)f

LogRecord が生成された時刻 (time.time() によって返される形式で)。

exc_info

このフォーマットを自分で使う必要はないでしょう。

(sys.exc_info 風の) 例外タプルか、例外が起こっていない場合は None

ファイル名

%(filename)s

pathname のファイル名部分。

funcName

%(funcName)s

ロギングの呼び出しを含む関数の名前。

levelname

%(levelname)s

メッセージのための文字のロギングレベル ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')。

levelno

%(levelno)s

メッセージのための数値のロギングレベル (DEBUG, INFO, WARNING, ERROR, CRITICAL)。

lineno

%(lineno)d

ロギングの呼び出しが発せられたソース行番号 (利用できる場合のみ)。

message

%(message)s

msg % args として求められた、ログメッセージ。 Formatter.format() が呼び出されたときに設定されます。

module

%(module)s

モジュール (filename の名前部分)。

msecs

%(msecs)d

LogRecord が生成された時刻のミリ秒部分。

msg

このフォーマットを自分で使う必要はないでしょう。

元のロギングの呼び出しで渡されたフォーマット文字列。 args と合わせて、 message 、または任意のオブジェクトを生成します (任意のオブジェクトをメッセージに使用する 参照)。

name

%(name)s

ロギングに使われたロガーの名前。

pathname

%(pathname)s

ロギングの呼び出しが発せられたファイルの完全なパス名 (利用できる場合のみ)。

process

%(process)d

プロセス ID (利用可能な場合のみ)。

processName

%(processName)s

プロセス名 (利用可能な場合のみ)。

relativeCreated

%(relativeCreated)d

logging モジュールが読み込まれた時刻に対する、LogRecord が生成された時刻を、ミリ秒で表したもの。

stack_info

このフォーマットを自分で使う必要はないでしょう。

現在のスレッドでのスタックの底からこのレコードの生成に帰着したログ呼び出しまでのスタックフレーム情報 (利用可能な場合)。

thread

%(thread)d

スレッド ID (利用可能な場合のみ)。

threadName

%(threadName)s

スレッド名 (利用可能な場合のみ)。

画面とファイルにログを出力するためのfunction(set_log_config)の定義

from logging import StreamHandler, DEBUG, INFO, Formatter
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
import os
 
def set_log_config(logger, dir, filename):
 
    # ---- Prepare log folder ----
    os.makedirs(dir, exist_ok=True) 
    filepath = dir + filename
 
    # ---- handler1: For terminal ----
    handler1 = StreamHandler()
    handler1.setLevel(DEBUG)
    handler1.setFormatter(Formatter("[%(asctime)s][%(levelname)8s][%(name)s][%(filename)s][%(funcName)s][line %(lineno)d] %(message)s"))
    # ---- handler2: For log file ----
    #handler2 = TimedRotatingFileHandler(filename = filepath, when='midnight', backupCount=30, encoding='utf-8') # If you want to rotate file by time, use this
    handler2 = RotatingFileHandler(filename = filepath, maxBytes = 1048576, backupCount = 10, encoding='utf-8', ) # 1MB, keep 10 files
    handler2.setLevel(INFO)
    handler2.setFormatter(Formatter("[%(asctime)s][%(levelname)8s][%(name)s][%(filename)s][%(funcName)s][line %(lineno)d] %(message)s"))
 
    # ---- Set log config ----
    logger.setLevel(INFO)
    logger.addHandler(handler1)
    logger.addHandler(handler2)
    logger.propagate = False
    

logの初期化

#準備
from logging import getLogger
dir = 'Log/'
logger = getLogger('test')
set_log_config(logger, dir, 'main.log' )

テスト1

logger.setLevelがそのままなので、set_log_config内で定義されるINFOがそのまま使われる。
そのため、loglevel info以上のログが出力される

def test_fnc1():
    #set_log_config内でのsetLevelは INFO 
    logger.debug('DEBUG')
    logger.info('INFO')
    logger.warning('WARNING')
    logger.error('ERROR')
    logger.critical('CRITICAL')
    try:
        1/0
    except Exception as e:
        logger.exception('Test: exception')

test_fnc1()

出力

INFO以上(DEBUG以外)が出力される

ython3 log_test.py
[2022-05-31 19:29:14,659][    INFO][test][log_test.py][test_fnc1][line 41] INFO
[2022-05-31 19:29:14,659][ WARNING][test][log_test.py][test_fnc1][line 42] WARNING
[2022-05-31 19:29:14,659][   ERROR][test][log_test.py][test_fnc1][line 43] ERROR
[2022-05-31 19:29:14,659][CRITICAL][test][log_test.py][test_fnc1][line 44] CRITICAL
[2022-05-31 19:29:14,659][   ERROR][test][log_test.py][test_fnc1][line 48] Test: exception
Traceback (most recent call last):
  File "log_test.py", line 48, in test_fnc1
    1/0
ZeroDivisionError: division by zero

テスト2

logger.setLevelをDEBUGにする。
そのため、loglevel DEBUG以上のログが出力される

def test_fnc2():
    #setLevelをDEBUGにする。
    logger.setLevel(DEBUG)

    logger.debug('DEBUG')
    logger.info('INFO')
    logger.warning('WARNING')
    logger.error('ERROR')
    logger.critical('CRITICAL')
    try:
        1/0
    except Exception as e:
        logger.exception('Test: exception')

test_fnc2()

出力

DEBUG以上(全て)が出力される

[2022-05-31 19:29:14,659][   DEBUG][test][log_test.py][test_fnc2][line 56] DEBUG
[2022-05-31 19:29:14,659][    INFO][test][log_test.py][test_fnc2][line 57] INFO
[2022-05-31 19:29:14,659][ WARNING][test][log_test.py][test_fnc2][line 58] WARNING
[2022-05-31 19:29:14,659][   ERROR][test][log_test.py][test_fnc2][line 59] ERROR
[2022-05-31 19:29:14,659][CRITICAL][test][log_test.py][test_fnc2][line 60] CRITICAL
[2022-05-31 19:29:14,660][   ERROR][test][log_test.py][test_fnc2][line 66] Test: exception
Traceback (most recent call last):
  File "log_test.py", line 67, in test_fnc2
    1/0
ZeroDivisionError: division by zero
0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?