현상
Python 프로그램의 로깅을 위해 Logging 모듈을 사용하고 있는데, 테스트하다보니 아래와 같이 같은 로그가 두 번 출력되는 현상을 확인할 수 있었다.
불필요한 중복 로그를 출력하지 않도록 문제를 해결해보자.
현상 재현
먼저 Logger를 편하게 사용하기 위해 다음과 같이 생성 함수를 정의했다.
import logging
def getlogger(title):
logger = logging.getLogger(title)
logger.setLevel(logging.INFO)
formatter = logging.Formatter('[%(asctime)s] [%(module)s.%(funcName)s :%(lineno)d] %(levelname)s:%(message)s')
log_stream_handler = logging.StreamHandler()
log_stream_handler.setFormatter(formatter)
logger.addHandler(log_stream_handler)
return logger
확인해보니 이 함수를 이용해 같은 이름의 Logger를 중복으로 생성했을 때 중복 로깅 현상이 발생하고 있었다.
def func_1():
logger = getlogger('test')
logger.info('hello, func_1')
def func_2():
logger = getlogger('test')
logger.info('hello, func_2')
func_1()
func_2()
즉, 같은 이름의 Logger를 3번 사용하면, 같은 로그가 3번 출력된다…….
원인
Python logging 모듈은 싱글턴 페턴을 사용하고 있다. 즉, logging.getLogger 함수로 Logger를 받을 때 만들고자 하는 Logger의 이름이 이미 존재하는 경우에는 새로운 Logger를 만들지 않고 기존 Logger를 반환한다.
때문에 func_1 함수에서 test라는 이름의 Logger를 사용하고 func_2 함수를 호출하면, func_2 함수에서 test라는 이름의 Logger를 사용할 때 이미 func_1에서 StreamHandler가 추가된 Logger를 사용하게 된다. 따라서 Logger에서 StreamHandler를 추가하면 test Logger는 두 개의 StreamHandler 갖게 되어 로그를 중복으로 출력하는 것이다.
해결
logging.getLogger 함수를 호출한 뒤,
참고 문서
https://5kyc1ad.tistory.com/269