회사에서 일하다가 logging이 부족한 것 같아서 공부했습니다.
logging을 그냥 사용하면 logging.debug, logging.info, logging.warning, logging.error, logging.critical만 반복적으로 사용하게 됩니다. 하지만 logging.StreamHandler, logging.FileHandler, logging.getLogger, logging.Formatter를 잘 쓰면 전혀 다른 편-안함을 느낄 수 있었습니다. 예시는 아래와 같습니다.
class BlahBlah:
def __init__(self, logger):
self.logger = logger
def say_blah(self, something: str):
logger.debug(f"say {something}")
logger.info(f"say {something}")
logger.warning(f"say {something}")
logger.error(f"say {something}")
logger.critical(f"say {something}")
if __name__ == "__main__":
logger_formatter = logging.Formatter(
fmt="{asctime}\t{name}\t{filename}:{lineno}\t{levelname}\t{message}",
datefmt="%Y-%m-%d-%H:%M:%S",
style="{",
)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(logger_formatter)
stream_handler.setLevel(logging.INFO)
file_handler = logging.FileHandler(filename=f"{__file__}.log", mode="w")
file_handler.setFormatter(logger_formatter)
file_handler.setLevel(logging.DEBUG)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(stream_handler)
logger.addHandler(file_handler)
blah_blah = BlahBlah(logger)
blah_blah.say_blah("yeah")
logging.Formatter
: log가 써지는 포맷을 정해줌.fmt
: 포맷을 지정해주는 인자.asctime
: 시간name
: 기본값은 root라고 뜨는데, logging.getLogger()의 인자로 이름을 지정해줄 수 있다. 여러 파일에서 동시에 로깅을 한 파일로 보낼 때 쓸 수 있음.filename
: 로깅을 호출하는 파일 이름. 계층구조면 계층 아래의 파일 이름도 가져온다.lineno
: 로깅을 호출한 line number.levelname
: 로깅레벨, 즉 DEBUG, INFO, WARNING, ERROR, CRITICAL 중 하나.
- DEBUG: 걍 아무거나. 만든 사람이 디버깅 용으로 보는거.
- INFO: 프로그램 보는 사람이 확인할만한 정보 중 최하위.
- WARNING: 어? 이거 문제있을수도 있는데 일단 넘어갈게? 수준.
- ERROR: 야 이거 큰 문제인데 프로그램 전체가 정지할 정도는 아니야 수준.
- CRITICAL: 이건 안된다. 바로 sys.exit() 해줘라 수준.message
: 로깅에서 지정해준 메시지. 여기선 f"say {something}".datefmt
: asctime의 출력형태.style
: "%", "{", "$" 중 하나라던데, 난 f-string이 좋아서 "{"을 쓴다.
logging.*Handler
: logger에 전달해줄, logger의 여러 무기들.StreamHandler
: 출력해주는 로깅.FileHandler
: 파일로 저장해주는 로깅.*handler.setFormatter
: 위에서 만든 Formatter를 넣어주어서 지정해줌.*handler.setLevel
: 각 핸들러마다 일정 레벨 이상을 출력해주게 정할 수 있음. 디폴트는 INFO인데, 예시에선 파일로 DEBUG까지 저장해주고자 함. 단, 아래 나오는 logger.setLevel에서도 DEBUG로 밑바닥을 뚫어줘야 사용 가능.
logging.getLogger
: logging의 객체형태, 미리 셋팅하고 전달이 가능하니까 그냥 logging만 쓰는 것보다 잘 쓸 수 있음.logger.setLevel
: 각 핸들러의 최하레벨을 셋팅해줘야함. 받는 핸들러 중에서 DEBUG가 있는데 INFO로 이걸 해주면 나오질 않음.logger.addHandler
: Handler를 로거에 추가해줌.
'개발 > 파이썬' 카테고리의 다른 글
일급객체란? (0) | 2022.09.13 |
---|---|
NumPy & Pandas 자주 쓰는 문법 요약 (0) | 2022.09.13 |
Pyreverse, Python 다이어그램 diagram 패키지 (0) | 2022.09.13 |
Radon, Python code metrics 평가 도구 (0) | 2022.09.13 |
댓글