Python logging
파이썬에서 logging을 다루는 방법을 정리

로깅(logging)이란?
개발에서 사용하는 ‘로깅(logging)’의 어원은 실제로 통나무(log)와 관련이 있습니다.
어원의 유래
항해 시대로 거슬러 올라갑니다. 선박의 속도를 측정할 때 ‘로그(log)’라고 불리는 통나무 조각을 밧줄에 묶어서 바다에 던졌습니다. 배가 움직이면서 밧줄이 풀리는 속도로 배의 속력을 계산했죠. 선원들은 이렇게 측정한 항해 정보(속도, 방향, 날씨, 주요 사건 등)를 ‘로그북(logbook)’에 기록했습니다. 이것이 시간순으로 사건을 기록한다는 의미의 ‘log’가 되었습니다.
> 항해 정보를 로그북(logbook) 기록
컴퓨터 과학 초기에 시스템의 활동과 이벤트를 시간순으로 기록하는 개념이 필요했을 때, 항해 일지처럼 “무슨 일이 언제 일어났는지” 기록한다는 의미에서 자연스럽게 ‘logging’이라는 용어를 차용하게 되었습니다.
Python logging: 기본 사용법
파이썬에서는 기본적으로 logging
이라는 표준 라이브러리를 제공합니다. 가장 간단하게 로깅을 설정하는 방법은 logging.basicConfig(
)을 사용하는 방법입니다. 기본 루트 로거(root logger)를 자동으로 구성하며 프로세스당 최초 한 번만 설정이 적용됩니다.
import logging
logging.basicConfig(level=logging.INFO)
logging.info("가장 기본적인 로깅 사용 방법")
로그 레벨(Log Levels)
로그 레벨은 메시지의 중요도를 나타냅니다. 파이썬은 5가지 표준 로그 레벨을 제공합니다. 각 레벨은 중요도에 따라 사용하며, 특정 레벨 이상만 출력하도록 설정할 수 있습니다.
레벨 | 숫자값 | 설명 | 사용 예시 |
---|---|---|---|
DEBUG |
10 | 상세한 진단 정보 | 변수값, 함수 호출 추적 |
INFO |
20 | 일반적인 정보 | 프로그램 시작/종료, 주요 단계 |
WARNING |
30 | 경고 메시지 | 예상치 못한 상황, 향후 문제 가능성 |
ERROR |
40 | 오류 발생 | 예외 처리, 기능 실패 |
CRITICAL |
50 | 심각한 오류 | 프로그램 중단을 야기할 수 있는 오류 |
import logging
# 기본 설정
logging.basicConfig(level=logging.INFO)
# 로그 메시지 출력
logging.debug("이 메시지는 보이지 않습니다 (기본 레벨이 INFO라서)")
logging.info("프로그램이 시작되었습니다")
logging.warning("경고: 메모리 사용량이 높습니다")
logging.error("오류가 발생했습니다")
logging.critical("심각한 오류입니다!")
주요 구성
파이썬 로깅은 4가지 주요 컴포넌트로 구성됩니다.
- Logger: 로그 메시지를 생성하는 객체
- Handler: 로그를 어디로 보낼지 결정
- Formatter: 로그 메시지의 형식 지정
- Filter: 로그를 선택적으로 필터링
로그 포맷 설정
import logging
# 상세한 로그 포맷 설정
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logging.info("포맷이 적용된 로그입니다")
# 출력: 2025-10-16 10:30:45 - root - INFO - 포맷이 적용된 로그입니다
파일에 로그 저장
import logging
# 파일에 로그 저장
logging.basicConfig(
filename='app.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
filemode='a' # 추가 모드 (w: 덮어쓰기)
)
logging.info("이 메시지는 app.log 파일에 저장됩니다")
고급 사용법
1. Logger 객체 사용
import logging
# 로거 생성
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# 핸들러 생성 (콘솔 출력)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# 핸들러 생성 (파일 출력)
file_handler = logging.FileHandler('debug.log')
file_handler.setLevel(logging.DEBUG)
# 포맷터 생성
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# 핸들러에 포맷터 적용
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# 로거에 핸들러 추가
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# 로그 메시지 출력
logger.debug("디버그 메시지 (파일에만 저장)")
logger.info("정보 메시지 (콘솔과 파일 모두)")
logger.error("오류 메시지")
베스트 프랙티스
-
모듈별 로거 사용:
logger = logging.getLogger(__name__)
- 적절한 로그 레벨 사용: 개발 시 DEBUG, 운영 시 INFO 이상
- 구조화된 로그: JSON 형태 또는 일관된 포맷 사용
-
로그 로테이션:
RotatingFileHandler
또는TimedRotatingFileHandler
사용 - 민감 정보 제외: 비밀번호, API 키 등은 로그에 포함하지 않기
- 성능 고려: 문자열 포맷팅은 실제 로그가 출력될 때만 수행