2021년 10월 3일 일요일

python logger,colored log (컬러 로거 logger)


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


댓글 없음:

댓글 쓰기