https://docs.python.org/ko/3/howto/logging-cookbook.html
Python Logging에 대해 제대로 본적이 없어서 평소에 궁금했던 점에 대해 정리한다.
1. Singletone Logger 만들기
https://codeday.me/ko/qa/20190316/1317.html
Python 에서 metaclass를 사용하면 다중 상속이 가능한 Singletone을 만들 수 있다.
class SingletonType(type):
def __call__(cls, *args, **kwargs):
try:
return cls.__instance
except AttributeError:
cls.__instance = super(SingletonType, cls).__call__(*args, **kwargs)
return cls.__instance
class BasicLogger:
logger_level = logging.DEBUG
format = '%(name)s %(levelname)s %(message)s'
class Logger(BasicLogger, metaclass=SingletonType):
_logger = None
def __init__(self):
self._logger = logging.getLogger('BasicLogger')
self._logger.setLevel(self.logger_level)
formatter = logging.Formatter(self.format)
formatter.converter = (datetime.datetime.utcnow() + datetime.timedelta(hours=9)).timetuple()
rotating_handler = TimedRotatingFileHandler('basic.log', when='h', interval=1, backupCount=72)
rotating_handler.setFormatter(formatter)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
self._logger.addHandler(rotating_handler)
self._logger.addHandler(stream_handler)
print('Logger Initialized')
def debug(self, msg):
self._logger.debug(msg)
def info(self, msg):
self._logger.info(msg)
def warning(self, msg):
self._logger.warning(msg)
사용하는 예제로 Single Instance가 생성되었는지 확인해보자.
logger1 = Logger()
logger2 = Logger()
if logger1 == logger2:
print('Same Instance')
logger3 = Logger()
logger1.info("logger1 message")
logger2.info("logger2 message")
logger3.debug("logger3 message")
실행 로그
Logger Initialized
Same Instance
BasicLogger INFO logger1 message
BasicLogger INFO logger2 message
BasicLogger DEBUG logger3 message
2. Custom Logger Format
https://docs.python.org/3/library/logging.html#logrecord-attributes
기본으로 제공하는 format은 위의 Record Attributes를 참고하면 된다.
만약 Custom Format을 만들고 싶으면, LoggerAdapter를 이용한다.
class CustomAdapter(logging.LoggerAdapter):
def process(self, msg, kwargs):
_message = {
'instance_id': self.extra.get('instance_id', ''),
'message_id': self.extra['message_id'],
'module_name': self.extra.get('module_name', ''),
'message': msg,
}
return '[%s] %s' % (self.name, _message), kwargs
호출하는 방법은 CustomAdapter 객체 생성시 logger와 custom parameter를 dict 형태로 넘긴다.
logger = logging.getLogger('test')
logger.setLevel(logging.INFO)
stream_handler = logging.StreamHandler()
logger.addHandler(stream_handler)
logger1 = CustomAdapter(logger, {'instance_id': 'logger1', 'message_id': '1'})
logger1.info("logger1 1 message")
logger2 = logging.getLogger('test')
logger2 = CustomAdapter(logger2, {'instance_id': 'logger2', 'module_name': 'module1', 'message_id': '2'})
logger2.info("logger1 2 message")
실행 로그
[test] {'instance_id': 'logger1', 'message_id': '1', 'module_name': '', 'message': 'logger1 1 message'}
[test] {'instance_id': 'logger2', 'message_id': '2', 'module_name': 'module1', 'message': 'logger1 2 message'}
'자습' 카테고리의 다른 글
click을 이용한 python CLI (0) | 2019.09.08 |
---|---|
pre-commit 활용하기 (0) | 2019.08.31 |
파이썬 클린 코드 CH3. 좋은 코드의 일반적인 특징 (0) | 2019.08.17 |
AWS Lambda@Edge (0) | 2019.08.10 |
AWS S3-Select (0) | 2019.07.20 |