python logger는 디버깅하는데 기본적인 도구 입니다.
이번에 레벨에 따른 색상을 지원하는 colorlog를 이용하여 기존의 logger를 변경하였습니다.
이 logger 의 특징
파일 저장과 스트림 출력을 동시에 하고 있으며 파일 저장은 파일 갯수와 용량을 이용한 Rotating파일 핸들러도 동시에 동작하고 있습니다.
로그 폴더를 기본으로 정하고 로그 폴더가 없으면 자동을 생성됩니다.
self.logger.handlers.clear() 를 추가함으로서 logger가 생성될때마다 중복 핸들러가 생성되는것을 방지합니다. 이 부분이 없으면 생성될때마다 로그가 여러번 출력되게 됩니다.
예제
여러 파일에서 로거를 어떻게 사용하는지 예제가 있습니다.
컬러를 on/off하는 예제를 포함하고 있습니다.
_17_logger_color.py
import datetime import sys import os import time import logging import colorlog from logging import FileHandler from logging import handlers class CustomLog: def __init__(self): pass def create(self,logfolder='', app_name=__name__, logprefix='log_', NEED_BACKUP_FILE = True, NEED_SCREEN_AND_FILE = True, level=logging.DEBUG, format='[%(asctime)s] %(levelname)s [%(filename)s.%(funcName)s:%(lineno)d] %(message)s', maxBytes=10*1024*1024, backupCount = 10, encoding='utf-8', color=True): LOG_PREFIX = logprefix LOG_FOLDER_NAME = logfolder # 로그 파일 핸들러 now = datetime.datetime.now().isoformat()[:10] logf = LOG_PREFIX + now + ".log" if LOG_FOLDER_NAME!='' and not os.path.exists(LOG_FOLDER_NAME): os.makedirs(LOG_FOLDER_NAME) logf = os.path.join(LOG_FOLDER_NAME, logf) logger = self.getLogger(logf, app_name, NEED_BACKUP_FILE, NEED_SCREEN_AND_FILE, level, format, maxBytes, backupCount, encoding, color) logger.logfilename_ = logf return logger def getLogger(self, filename, app_name, NEED_BACKUP_FILE, NEED_SCREEN_AND_FILE, level, format, maxBytes, backupCount, encoding, color): if color : self.logger = colorlog.getLogger(app_name) else: self.logger = logging.getLogger(app_name) self.logger.handlers.clear() self.logger.propagate = False # log level은 아래 순서에 따른다. setLevel 과 같거나 큰 출력만 나오게 된다. # logger.setLevel(logging.CRITICAL) 인 경우 logger.critical() 만 나온다 # # logger.debug("debug") # logger.info("info") # logger.warning("warning") # logger.error("error") # logger.critical("critical") self.logger.setLevel(level) # 포맷을 결정한다. 좀더 자세한 정보는 다음 링크를 참조한다 # https://docs.python.org/3/library/logging.html#logrecord-attributes if color : logFormatter = colorlog.ColoredFormatter('%(log_color)s'+format) else : logFormatter = logging.Formatter(format) if NEED_BACKUP_FILE == True: rotatingHandler = handlers.RotatingFileHandler(filename=filename, maxBytes=maxBytes, backupCount = backupCount, encoding=encoding) rotatingHandler.setFormatter(logFormatter) self.logger.addHandler(rotatingHandler) else: fileHandler = logging.FileHandler(filename) fileHandler.setFormatter(logFormatter) self.logger.addHandler(fileHandler) # StreamHandler 는 self.logger.critical("critical") 이런 형태의 로그가 화면으로도 나오고 file로도 저장이 되도록 한다 if NEED_SCREEN_AND_FILE == True: streamHandler = logging.StreamHandler() streamHandler.setFormatter(logFormatter) self.logger.addHandler(streamHandler) return self.logger if __name__ == "__main__": logger = CustomLog().create('log') print("test") logger.debug("debug test") logger.info("info test") logger.warning("warning test") logger.error("error test") logger.critical("critical test") ''' # other file import _17_logger_color logger = _17_logger_color.CustomLog().create('log',__name__) if __name__ == "__main__": logger.debug("debug test") logger.info("info test") logger.warning("warning test") logger.error("error test") logger.critical("critical test") '''
_17_logger_color_test.py
import _17_logger_color import _17_logger_color_test_2 logger = _17_logger_color.CustomLog().create('log',__name__) if __name__ == "__main__": _17_logger_color_test_2.noncolor_test() logger.debug("debug test") logger.info("info test") logger.warning("warning test") logger.error("error test") logger.critical("critical test") logger = _17_logger_color.CustomLog().create('log',__name__,color=False) logger.debug("MAIN color false test") logger.info("info test") logger.warning("warning test") logger.error("error test") logger.critical("critical test") _17_logger_color_test_2.noncolor_test()
_17_logger_color_test_2.py
import _17_logger_color logger = _17_logger_color.CustomLog().create('log',__name__,color=False) def noncolor_test(): logger.debug("debug test 2") logger.info("info test 2") logger.warning("warning test 2") logger.error("error test 2") logger.critical("critical test 2")
실행결과
참고할만한 링크
python 멀티 로그 레벨을 가지는 로거(how to set multi setlevel in python logger)
https://swlock.blogspot.com/2021/10/python-how-to-set-multi-setlevel-in.html
댓글 없음:
댓글 쓰기