내 파이썬 파일이 잘 돌아가고 있는지 확인하고 싶다면? - 로그 활용하기

한승수·2025년 3월 26일

AI 코딩 팁

목록 보기
10/13
post-thumbnail

안녕하세요! 그루비한 입니다. 이번 포스트는 파이썬에 로그를 활용하는 방법입니다.

파이썬 파일을 10시간 정도 실행시켰는데, 뭔가 코드의 오류로 실행 결과가 저장되지 않는다면 정말 절망적일 수 밖에 없습니다. (실제 경험담..)

그래서 저는 이런 불안감을 잠재우고자 파이썬의 logging을 활용해보기로 하였습니다. print를 사용하는 것보다 터미널에 실행결과가 출력되지는 않지만 로그 파일에 현재 실행되고 있는 상태가 저장이 되어 좀 더 효율적이었습니다.

이렇게 로그를 남겨두는 것은 추후에 파이썬 파일의 실행 경과 (시간, 결과) 등을 확인할 때도 용이하고, 에러 발생 로그를 남겨둘 때도 많이 활용되기 때문에 이번 시간에 간단한 로깅 활용법을 정리해보겠습니다.

1. Logging이란?

Logging(로깅) 은 프로그램 실행 중 발생하는 이벤트, 오류, 상태 변화 등을 기록하는 과정입니다. 이를 통해 프로그램이 어떻게 동작하는지 파악하고, 예상치 못한 버그나 성능 문제를 추적할 수 있습니다.

언제 Logging(로깅)을 활용할까?
📌 디버깅 & 문제 해결: 코드가 예상과 다르게 동작할 때
📌 운영 환경 모니터링: 서버 애플리케이션의 상태를 기록할 때
📌 에러 추적: 예외 발생 시 원인을 빠르게 파악할 때
📌 사용자 행동 분석: 웹 애플리케이션에서 사용자의 요청을 기록할 때

2. Logging 활용법

로그를 기록하기 위해서 파이썬에서는 logging모듈을 제공하고 있습니다.logging 모듈의 Logger, Handler, Formatter 개념을 활용하면 더욱 강력하게 로그를 관리할 수 있습니다.

아래는 기본 예시 입니다.

import logging

# 로그 포맷 설정
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s")

# 콘솔 핸들러 생성 및 포맷 적용
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)

# 로거 생성 및 핸들러 추가
logger = logging.getLogger("example_logger")
logger.setLevel(logging.INFO)
logger.addHandler(console_handler)

# 로그 출력
logger.info("로그 메시지")

로그 생성

self.logger = logging.getLogger(self.logname)
self.logger.setLevel(logging.INFO)
  • getLogger: 로그를 생성합니다.
  • set level: 로그의 유형을 선택합니다.

로그의 유형
사용자가 원하는 로그의 유형을 선택합니다. 로그 저장 시에 어떤 유형의 로그인지 함께 출력됩니다.

유형설명
DEBUG개발 중에 유용한 상세한 정보
INFO일반적인 정보 메시지
WARNING경고 메시지 (잠재적 문제)
ERROR오류 메시지
CRITICAL치명적인 오류

핸들러(Handler)

로그의 출력 위치를 결정합니다. 핸들러에 따라 로그를 콘솔에 출력할지, 파일에 저장할지 등을 선택할 수 있습니다.

  • file_handler = logging.FileHandler(self.dir): 해당 위치에 .log 파일 생성 및 로그 출력
  • logger.addHandler(file_handler): 정의한 로그에 핸들러를 추가합니다.

핸들러의 종류

핸들러설명
StreamHandler콘솔(터미널)에 로그 출력
FileHandler로그를 파일에 저장
RotatingFileHandler일정 크기가 되면 새 파일 생성 (로그 파일 관리에 유용)
TimedRotatingFileHandler일정 시간이 지나면 새 파일 생성 (예: 매일 새로운 로그 파일 생성)
SMTPHandler이메일로 로그 전송
HTTPHandler웹 서버로 로그 전송
SocketHandler네트워크 소켓을 통해 로그 전송

포매팅(Formatting)

로그 메세지의 출력 형식(포맷)을 정의합니다. 핸들러를 통해 출력될 로그에 시간, 파일명, 메세지 등을 포함할 수 있도록 정의합니다.

예시

formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

출력 예시

2025-03-27 14:30:45,678 - my_logger - INFO - 로그 메시지 출력

주요 포맷 코드

포맷 코드설명
%(asctime)s로그 발생 시간
%(name)s로거 이름
%(levelname)s로그 레벨 (DEBUG, INFO, WARNING...)
%(message)s로그 메시지
%(filename)s실행 중인 파일 이름
%(lineno)d로그가 발생한 코드의 줄 번호
%(funcName)s로그가 발생한 함수 이름

로그 메세지

포매터(Formatter)에서 정의한 대로 로그를 출력할 때, 로그 메세지를 입력해줘야 합니다. 이때 각 로그의 유형에 맞춰서 메세지만 입력해주면 되고, 다른 포맷 정보들은 자동으로 입력됩니다.

예시

logger.debug("디버깅 메시지")
logger.info("정보 메시지")
logger.warning("경고 메시지")
logger.error("에러 메시지")
logger.critical("치명적인 오류")

출력 예시
logger.info()에 대한 출력 예시입니다.

2025-03-27 15:00:00,123 - INFO - example_logger - 로그 메시지

실제 활용

제가 실제로 로깅을 활용하기 위해 구현한 클래스입니다. 코드는 해피코더님의 블로그를 참고하였습니다.

import logging

class logSave():
    def __init__(self,dir,logname):
        self.logname = logname #로그 이름
        self.dir = os.path.join(dir,logname) #로그 파일 저장 위치
        self.InitLogger() #로그 정의 함수
	
    #로그를 정의합니다.
    def InitLogger(self):
    	#로거 생성
        self.logger = logging.getLogger(self.logname)
        self.logger.setLevel(logging.INFO)
        
        #핸들러 추가
        file_handler = logging.FileHandler(self.dir)
        
        #포맷 설정
        formatter = logging.Formatter("[%(asctime)s] %(message)s")
        file_handler.setFormatter(formatter)
		
        #핸들러를 로거에 추가
        self.logger.addHandler(file_handler)
        
        #기타
        self.logger.propagate = False #터미널에서 출력되지 않도록 설정
    
    #로그 기록
    def LogTextOut(self,  msg):
        self.logger.info(str(msg))
   
if __name__ == "__main__":
   	log = logSave("./new_real_data","saving.log")
    #(생략)
    log.LogTextOut(f"피쳐 추출 현황 {str(len(new_data))}")

이 코드를 활용하여 저는 피쳐가 잘 추출되고 있는지 로그를 통해 확인할 수 있었습니다. 이제 파이썬 파일이 잘 동작하는지 print()함수가 아닌 로깅(logging)을 써보면 어떨까요?

profile
Grooovy._.Han

0개의 댓글