Pythonのloggingについてどこよりも簡潔に有用な解説をします。
###loggingメインプログラム
import os
import time
import threading
import logging
import logging.handlers
_logger = None
def initLogging(isPrinted: bool):
"""ロギングの初期設定
(ログは指定したフォルダに保管される)
Args:
isPrinted (bool): コンソール画面に表示するときTrue
""" """
ロギング設定
"""
global _logger
_logger = logging.getLogger('App')
_logger.setLevel(logging.INFO)
''' ログファイル保存用のディレクトリ '''
if os.path.exists('./log') == False:
os.makedirs('./log')
''' ログをファイルに出力するための設定 '''
rfh = logging.handlers.RotatingFileHandler(
filename='./log/App.log',
maxBytes=1024*1024,
backupCount=5
)
_logger.addHandler(rfh)
formatter = logging.Formatter('%(asctime)s,%(name)s,%(threadName)s,%(lineno)d,%(levelname)s,%(message)s')
rfh.setFormatter(formatter)
''' ログをコンソールに出力するための設定 '''
if isPrinted:
handler = logging.StreamHandler()
handler.setLevel(logging.INFO)
_logger.addHandler(handler)
handler.setFormatter(formatter)
_logger.info('initLogging fin.')
def func1():
"""Thread 1 Mehotd
"""
while True:
_logger.info("Thread1: Heartbeat...")
time.sleep(1)
def func2():
"""Thread 2 Mehotd
"""
while True:
_logger.info("Thread2: Heartbeat...")
time.sleep(1)
if __name__ == '__main__':
''' ロギング設定の初期化 '''
initLogging(True)
''' ロギング出力テスト '''
_logger.info("INFO")
_logger.warning("WARNING")
_logger.error("ERROR")
_logger.critical("CRITICAL")
''' 読み込み用スレッド '''
thread1 = threading.Thread(target=func1)
thread1.start()
''' 書き込み用スレッド '''
thread2 = threading.Thread(target=func2)
thread2.start()
簡単にプログラムの解説をします。
####RotatingFileHandler
ログファイルの出力と世代管理をします。上記の場合、logフォルダにApp.logというログファイルが生成されます。
filename 出力ファイル名
maxBytes 1ファイルの最大サイズ
backupCount 世代管理数
maxBytesを超えると自動的に「App.log」 -> 「App.log1」 に変換され、以降のログは「App.log」に保存されます
上記の場合、世代管理は5なので、「App.log5」まで行くと古いものから削除されます。
出力形式は Formatter() で設定が可能です。
####StreamHandler
ここではコンソール画面への出力設定をします。出力内容は上記と同じになります。
###getChild()による子ロガー作成
loggingメインプログラムで作成したLogging設定を使って、子ロガーを作成します。
これはPythonプログラムが複数に渡るときに便利です。
以下サンプルプログラムになります。親プログラムは上記とほぼ同じです。
''' ---------------------------
Python Logging Parent
---------------------------'''
import os
import logging
import logging.handlers
_logger = None
def initLogging(isPrinted: bool):
"""ロギングの初期設定
(ログは指定したフォルダに保管される)
Args:
isPrinted (bool): コンソール画面に表示するときTrue
""" """
ロギング設定
"""
global _logger
_logger = logging.getLogger('App')
_logger.setLevel(logging.INFO)
''' ログファイル保存用のディレクトリ '''
if os.path.exists('./log') == False:
os.makedirs('./log')
''' ログをファイルに出力するための設定 '''
rfh = logging.handlers.RotatingFileHandler(
filename='./log/App.log',
maxBytes=1024*1024,
backupCount=1
)
_logger.addHandler(rfh)
formatter = logging.Formatter('%(asctime)s,%(name)s,%(threadName)s,%(lineno)d,%(levelname)s,%(message)s')
rfh.setFormatter(formatter)
''' ログをコンソールに出力するための設定 '''
if isPrinted:
handler = logging.StreamHandler()
handler.setLevel(logging.INFO)
_logger.addHandler(handler)
handler.setFormatter(formatter)
_logger.info('initLogging fin.')
if __name__ == '__main__':
''' ロギング設定の初期化 '''
initLogging(True)
''' ロギング出力テスト '''
_logger.info("INFO")
_logger.warning("WARNING")
_logger.error("ERROR")
_logger.critical("CRITICAL")
''' Childアプリの起動 '''
import LoggerChild
LoggerChild.Start()
続いて、子ロガー側の紹介です。
実はたった1行で子ロガーは親ロガーの設定を引き継いで作成できます。
''' ---------------------------
Python Logging Child
---------------------------'''
import logging
def Start():
''' 子ロガーの設定 '''
_logger = logging.getLogger("App").getChild("Child")
_logger.info("logging child fin.")
Parent側を実行したときの結果です。
出力結果は以下となります。子ロガーの方は、nameが「App.Child」になります。
以上でloggingの解説は終了します。
※実務で利用する場合は、適宜例外処理などは追加してください。