본문으로 건너뛰기

Python Logger

프로그래밍을 하거나 프로그램을 실행했을 때, 원하는 수준으로 진행상황을 텍스트로 출력하여 log파일에 기록하거나 터미널에 출력할 수 있습니다.

쓰레드 안전합니다.

로깅 수준

수준 : NOTSET -> DEBUG -> INFO -> WARNING -> ERROR -> CRITICAL

수준사용
NOTSET0
DEBUG10상세한 정보, 문제 진단
INFO20프로그램 진행 순서
WARNING30경고, 프로그램은 실행 됨
ERROR40에러, 프로그램 기능 중 일부 실행 안됨
CRITICAL50프로그램 오류

포맷

format = '[%(levelname)-8s] %(filename)-10s %(lineno) 4d 행 : %(message)s'
포맷설명
%(created)ftime.time()
%(msecs)dLogRecord가 생성된 시간의 밀리초
%(relativeCreated)dlogging 모듈이 로드된 시간을 기준으로 LogRecord가 생성된 시간의 밀리초
%(pathname)s파일 경로
%(filename)s파일 경로의 파일명 부분
%(module)s파일명의 확장자를 제외한 부분
%(asctime)syyyy-mm-dd hh:mm:ss,sss
%(name)s로거 이름
%(levelname)s로깅 수준
%(levelno)s로깅 수준 값
%(lineno)d로깅 호출 행 번호
%(funcName)s함수 명
%(message)s메시지
%(process)d프로세스 ID
%(processName)s프로세스 이름
%(thread)d쓰레드 ID
%(threadName)s쓰레드 이름

함수

logger = logging.getLogger(name=None)
  • name: 특별한 경우가 아니면 __name__ 설정
    • __name__은 해당 코드의 import 경로입니다. 예를 들어 from a.b import c의 경우 c.py__name__a.b.c입니다.
  • logging.Logger를 반환합니다.
logging.basicConfig(**kwargs)
  • 루트 로거를 설정합니다.
  • kwargs

자식 로거는 자신에게 설정된 수준에 맞춰 부모 로거에게 메시지를 전달합니다.

경고

logging.basicConfig는 로깅이 시작되기 전에 호출해야 유효합니다.

logging.Logger

logger.setLevel(level)
logger.addHandler(handler)
  • 메시지를 처리할 핸들러를 등록합니다.

자식 로거에 핸들러를 추가하는 경우 핸들러와 부모 로거 모두에게 메시지를 보냅니다. 상황에 따라 logger.propagate의 값을 설정해야 합니다.

logger.debug(msg, *args, **kwargs)
logger.info(msg, *args, **kwargs)
logger.warning(msg, *args, **kwargs)
logger.error(msg, *args, **kwargs)
logger.critical(msg, *args, **kwargs)

logging.Formatter

formatter = logging.Formatter(fmt=None, datefmt=None, style='%')

logging.Handler

stream_handler = logging.StreamHandler()
file_handler = logging.FileHandler()

import logging.handlers
http_handler = logging.handlers.HTTPHandler()
queue_handler = logging.handlers.QueueHandler()
handler.setLevel(level)
  • @brief 핸들러가 처리할 수 있는 메시지 수준 설정
handler.setFormatter(formatter)
  • @brief 출력되는 메시지 포맷 설정
  • @param formatter 포맷터

Examples

child.py

import logging

logger = logging.getLogger(__name__)
# logger.setLevel()을 사용하지 않으면 루트 로거의 level을 따름


def child_function():
logger.debug("debug")
logger.info("info")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

main.py

import logging

import child

'''
루트 로거 설정, format만 설정했으므로 StreamHandler 생성
'''
logging.basicConfig(
format='[%(levelname)-8s] %(filename)-10s %(lineno) 4d 행 : %(message)s',
level=logging.ERROR)

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)


def main_function():
logger.debug("debug")
logger.info("info")
logger.warning("warning")
logger.error("error")
logger.critical("critical")


if __name__ == '__main__':

# __main__ 로거
main_function()

# child 로거
child.child_function()

# 루트 로거
logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

결과

$ python3 main.py
[INFO ] main.py 18: info
[WARNING ] main.py 19: warning
[ERROR ] main.py 20: error
[CRITICAL] main.py 21: critical
[ERROR ] child.py 10: error
[CRITICAL] child.py 11: critical
[ERROR ] main.py 36: error
[CRITICAL] main.py 37: criticall