본문 바로가기

Python

[Python] logging.handlers - TimedRotatingFileHandler

반응형

python에서 제공해주는 logging에선 많 handler를 제공해준다.

https://docs.python.org/ko/3/library/logging.handlers.html

  • logging.handlers — Logging handlers
    • StreamHandler
    • FileHandler
    • NullHandler
    • WatchedFileHandler
    • BaseRotatingHandler
    • RotatingFileHandler
    • TimedRotatingFileHandler
    • SocketHandler
    • DatagramHandler
    • SysLogHandler
    • NTEventLogHandler
    • SMTPHandler
    • MemoryHandler
    • HTTPHandler
    • QueueHandler
    • QueueListener

 

그 중 로깅 파일 설정 시 사용하는 TimedRotatingFileHandler 에 대해서 잠깐 이야기해보고자 한다.

 

보통 로깅을 이용하여 로그 파일을 생성할 때 한개로 처리하는 경우는.. 추천하지않는다.

 

왜냐면 아무리적어도 나중에 부하가 될 경우가 많으며, 디버깅 시 옛날 자료를 찾기도 힘들다.

 

그래서 파일을 나누는 경우가 있는데 그 logging에서 핸들러 중 하나가 TimedRotatingFileHandler 이다.

TimedRotatingFileHandler 이란?

기본 log 파일에 log를 적재를 하다가, 설정한 시간이 될 경우 기존에 있던 파일은 다른 이름으로 만들고,(롤오버)

새로운 파일(최초에 설정한 파일명)에 기록할 수 있도록 주기를 설정

 

기본 옵션

handler 셋팅시 설정

handler = TimedRotatingFileHandler(log_filename, when="midnight", interval=1, backupCount=30, encoding="utf-8")
  • filename: 기본 파일 이름
  • when: 언제 파일을 바꿀지 (예: 'midnight'는 매일 자정)
  • interval: 몇 단위마다 바꿀지
  • backupCount: 옛날 파일 몇 개를 남겨둘지
    • 예를 들어 하루에 한개씩 만드는 경우 30이라고 되어있으면 30개(30일) 까지 보 

추가로 설정

handler.suffix = "%Y-%m-%d.log"
  • suffix: 회전된 파일 이름의 끝에 붙일 날짜 형식

예시보기

일자별 로그

import logging
from logging.handlers import TimedRotatingFileHandler
import re

# 기본 로그 파일 이름 설정
log_filename = "app.log"

# TimedRotatingFileHandler를 생성합니다.
handler = TimedRotatingFileHandler(
    filename=log_filename,   # 로그를 쓸 파일 이름
    when="midnight",         # 자정마다 새 파일을 만듭니다.
    interval=1,              # 1일 간격으로 새 파일로 바꿉니다.
    backupCount=30,          # 최근 30개의 로그 파일을 보관합니다.
    encoding="utf-8"
)

# 회전된 파일에 붙일 suffix를 지정합니다.
handler.suffix = "%Y-%m-%d.log"
# 파일 이름에 날짜가 올바르게 붙도록 하는 정규표현식입니다.
handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}\.log$")

# 로그의 형식(어떤 모양으로 기록될지)을 정합니다.
formatter = logging.Formatter("%(asctime)s | %(levelname)s | %(message)s")
handler.setFormatter(formatter)

# 로거(logger)에 이 핸들러(handler)를 추가합니다.
logger = logging.getLogger("my_logger")
logger.setLevel(logging.INFO)
logger.addHandler(handler)

logger.info("프로그램 시작!")

시간별 로그

import logging
import re
from logging.handlers import TimedRotatingFileHandler

# 로거(logger) 생성 및 레벨 설정
hourly_logger = logging.getLogger("hourly_logger")
hourly_logger.setLevel(logging.INFO)

# TimedRotatingFileHandler 생성 (시간별 로그)
hourly_handler = TimedRotatingFileHandler(
    filename="app_hour.log",   # 기본 로그 파일 이름
    when="H",                  # H: 매시간 회전
    interval=1,                # 1시간마다 회전
    backupCount=24,            # 최근 24시간의 로그 파일 보관 (필요에 따라 조정)
    encoding="utf-8"
)

# 회전된 파일에 붙일 suffix: 날짜와 시간이 들어갑니다.
hourly_handler.suffix = "%Y-%m-%d_%H.log"
# 파일 이름에서 suffix 패턴과 일치하는지 확인하도록 정규표현식을 설정합니다.
hourly_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}_\d{2}\.log$")

# 로그 메시지 포맷 설정
formatter = logging.Formatter("%(asctime)s | %(levelname)s | %(message)s")
hourly_handler.setFormatter(formatter)

# 핸들러를 로거에 추가
hourly_logger.addHandler(hourly_handler)

# 로그 메시지 남기기 (예시)
hourly_logger.info("시간별 로그 파일 예제 - 프로그램 시작!")

 

 

 

요일별

 

  • when="W0", interval=1: W0 => 매주 월요일 자정에 롤오버 실행
    요일 : W0~W6 (W0: 월요일, W1은 화요일…)
  • backupCount: 주 단위 카운트 4 = 4주

 

import logging
import re
from logging.handlers import TimedRotatingFileHandler

# 로거(logger) 생성 및 레벨 설정
weekly_logger = logging.getLogger("weekly_logger")
weekly_logger.setLevel(logging.INFO)

# TimedRotatingFileHandler 생성 (일주일마다 로그 파일 회전)
weekly_handler = TimedRotatingFileHandler(
    filename="app_week.log",  # 기본 로그 파일 이름
    when="W0",                # W0: 매주 월요일 자정에 회전
    interval=1,               # 1주일 간격
    backupCount=4,            # 최근 4주의 로그 파일 보관 (필요에 따라 조정)
    encoding="utf-8"
)

# 회전된 파일에 붙일 suffix: 날짜가 들어갑니다.
weekly_handler.suffix = "%Y-%m-%d.log"
# 파일 이름에서 suffix 패턴과 일치하는지 확인하도록 정규표현식을 설정합니다.
weekly_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}\.log$")

# 로그 메시지 포맷 설정
formatter = logging.Formatter("%(asctime)s | %(levelname)s | %(message)s")
weekly_handler.setFormatter(formatter)

# 핸들러를 로거에 추가
weekly_logger.addHandler(weekly_handler)

# 로그 메시지 남기기 (예시)
weekly_logger.info("일주일마다 로그 파일 예제 - 프로그램 시작!")

참고하면 좋은거?

yyyy-mm-dd 의 기준

TimedRotatingFileHandler는 파일 롤오버 시에 현재 시각이 아닌, 이전 기간(즉, 기록된 로그의 기간)에 해당하는 날짜를 기반으로 suffix를 적용하도록 설계되어 있어 아래와 같이 작동합니다.

예를 들어, 로그가 2025-04-09에 기록되고 자정(2025-04-10 00:00:00)이 되어 롤오버가 일어난다면,
내부에서는 rolloverAt - interval 계산을 통해 실제 로그가 기록된 날짜(2025-04-09)를 받아
app.log 파일을 app.log.2025-04-09.log처럼 이름 변경합니다.
따라서, 로그 파일 안의 기록 시간(2025-04-09)과 롤오버되어 만들어진 백업 파일의 이름에 찍히는 날짜(2025-04-09)는 일치하게 됩니다.
이런 방식은 로그 파일이 언제 롤오버 되었는지(자정)와는 별개로, 백업 파일 이름에 실제 로그가 기록된 날짜를 명시하여 날짜별 로그를 확인하기 쉽게 만들어 줍니다.
이로 인해, 코드에서 handler.suffix = "%Y-%m-%d.log"로 설정했을 때 로그 파일 내부와 백업된 파일 이름에 찍히는 날짜가 일치하며 의도한 대로 동작하게 됩니다.

반응형