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")
실행결과
참고할만한 링크