파이썬에서 print 대신 로깅을 써야 하는 이유
파이썬으로 프로그램을 만들 때 진행 상황을 확인하기 위해 가장 먼저 쓰는 코드는 보통 print() 함수입니다. 간단한 스크립트를 실행할 때는 print만으로도 충분하지만, 코드가 길어지고 자동화 스크립트나 백그라운드 프로그램으로 발전하면 한계에 부딪힙니다. 프로그램이 언제 실행되었는지 시간 정보를 알기 어렵고, 에러가 발생했을 때 어느 함수에서 문제가 생겼는지 추적하기 번거로우며, 터미널 창을 닫는 순간 그동안 출력된 중요한 기록이 모두 사라지기 때문입니다.
[목차]
이 글에서는 실무 환경에서 프로그램의 안정성을 높이고 오류를 빠르게 파악하기 위해 반드시 알아야 할 파이썬 logging 모듈의 기본 패턴을 다룹니다. 로그 레벨 개념부터 포맷 설정, 파일로 기록을 남기는 방법까지 차근차근 살펴보겠습니다.
로그 레벨의 종류와 이해
파이썬의 표준 logging 모듈은 메시지의 중요도에 따라 5가지 단계(Level)를 제공합니다. 상황에 맞는 적절한 레벨을 선택해야 나중에 로그 파일을 분석할 때 필요한 정보만 효율적으로 필터링할 수 있습니다.
- DEBUG: 개발 과정에서 변수 값이나 상세한 흐름을 추적하기 위한 아주 세부적인 정보
- INFO: 프로그램이 정상적으로 작동하고 있음을 알리는 일반적인 실행 정보 (예: ‘데이터 수집 시작’, ‘파일 저장 완료’)
- WARNING: 당장 프로그램이 멈추지는 않지만, 잠재적인 문제나 주의가 필요한 상황 (예: ‘설정 파일이 없어 기본값으로 대체함’)
- ERROR: 특정 기능이나 요청을 처리하는 과정에서 문제가 발생해 실패했을 때
- CRITICAL: 프로그램 자체가 더 이상 실행될 수 없는 심각한 시스템 중단 상황
실무에서 가장 많이 쓰는 기본 설정 패턴
로깅을 사용하려면 먼저 logging.basicConfig() 함수를 이용해 기본 설정을 잡아주어야 합니다. 이 설정은 프로그램 전체에서 최초 한 번만 호출하는 것이 일반적입니다. 로그 출력 형식(format), 저장될 파일 이름(filename), 그리고 출력할 최소 로그 레벨(level)을 지정할 수 있습니다.
아래 코드는 가장 널리 쓰이는 표준적인 로깅 설정 예시입니다.
import logging
# 기본 로깅 설정
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
handlers=[
logging.FileHandler('app.log', encoding='utf-8'),
logging.StreamHandler()
]
)
# 로그 메시지 출력 테스트
logging.debug('디버그 메시지입니다. level이 INFO이므로 출력되지 않습니다.')
logging.info('프로그램이 정상적으로 시작되었습니다.')
logging.warning('주의: 디스크 용량이 부족할 수 있습니다.')
logging.error('파일을 읽어오는 중 에러가 발생했습니다.')
코드 구조화와 모듈별 로거 사용 요령
스크립트 규모가 커지면 단일 설정만으로는 부족합니다. 여러 개의 파이썬 파일을 임포트해서 사용하는 경우, logging.getLogger(__name__) 방식을 사용해 모듈별로 독립된 로거를 생성하는 것이 실무 표준입니다.
이렇게 하면 로그 메시지만 보고도 어떤 파일과 함수에서 발생한 기록인지 정확하게 파악할 수 있습니다.
import logging
# 현재 모듈 이름을 바탕으로 로거 생성
logger = logging.getLogger(__name__)
def process_data(data):
logger.info(f'데이터 처리 시작: {len(data)}건')
try:
# 비즈니스 로직 수행
if not data:
raise ValueError('데이터가 비어 있습니다.')
logger.info('데이터 처리가 성공적으로 완료되었습니다.')
except Exception as e:
logger.error(f'데이터 처리 중 오류 발생: {e}')
if __name__ == '__main__':
# 메인 실행부에서 전체 로깅 환경 설정
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s')
process_data([])
파이썬 logging 설정 시 자주 하는 실수
초보자들이 로깅 모듈을 도입할 때 흔히 겪는 시행착오를 정리했습니다. 코드를 작성하기 전에 아래 항목들을 미리 확인해 보세요.
- print 함수와 혼용하기: 중요한 데이터나 에러 메시지를 여전히 print로 출력하면 로그 파일에 남지 않아 추적이 어렵습니다. 모든 출력은 로거를 통하도록 일원화하는 것이 좋습니다.
- basicConfig 중복 호출:
basicConfig는 프로그램 실행 중 한 번만 적용됩니다. 여러 파일에서 각각 호출하면 나중에 설정이 꼬이거나 원하는 대로 파일 출력이 되지 않을 수 있습니다. - 인코딩 설정 누락: 윈도우 환경에서
filename인자를 통해 파일을 생성할 때encoding='utf-8'을 지정하지 않으면, 한글 로그가 깨지거나UnicodeEncodeError가 발생할 수 있습니다. - 레벨 설정 실수: 개발 단계에서는
DEBUG레벨로 두어 상세히 보다가, 실제 운영(Production) 환경에 배포할 때는INFO나WARNING레벨로 높여 불필요한 로그 용량 증가를 막아야 합니다.
실무 점검 체크리스트
프로그램에 로깅 코드를 완성한 뒤, 배포 전이나 테스트 단계에서 아래 항목을 차례대로 점검해 보세요.
- [ ] 프로그램 전체에서
print()대신logging모듈을 사용하고 있는가? - [ ] 로그 출력 포맷에 타임스탬프(
asctime)와 로그 레벨(levelname)이 포함되어 있는가? - [ ] 운영 환경에 맞는 최소 로그 레벨(INFO 또는 WARNING)이 올바르게 설정되었는가?
- [ ] 로그 파일 저장 시
encoding='utf-8'옵션을 추가하여 한글 깨짐을 방지했는가? - [ ] 대규모 로그 파일이 무한히 커지는 것을 방지할 대책(예: RotatingFileHandler 고려)이 마련되어 있는가?
마무리
파이썬의 logging 모듈은 처음에는 설정 항목이 많아 복잡해 보이지만, 기본 패턴만 익혀두면 프로그램의 신뢰성을 엄청나게 높여주는 강력한 도구입니다. 오늘 소개한 기본 설정과 모듈별 로거 패턴을 실제 프로젝트에 적용해 보시기 바랍니다. 에러 추적 시간이 눈에 띄게 줄어드는 것을 경험하실 수 있을 것입니다.