학습 기록

Python 공부 기록 #20 - RotatingFileHandler로 로그 파일 크기와 보관 개수 관리하기

0. 목차

  • 인트로: 로그 파일이 계속 커졌다
  • RotatingFileHandler는 어떤 도구일까?
  • 가장 간단하게 로그 파일 나누기
  • maxBytes와 backupCount 이해하기
  • 크롤링 코드에 연결해 보기
  • 날짜별 로그와 크기별 로그는 언제 다를까?
  • 삽질했던 부분들
  • 아웃트로: 기록은 남기되 폴더는 가볍게

1. 인트로: 로그 파일이 계속 커졌다

지난 글에서는 logging으로 INFO, WARNING, ERROR를 구분해 실행 결과를 남겨봤습니다.

자동 크롤링이나 Excel 저장 코드를 매일 돌리면 로그 한 줄은 짧아도 파일은 계속 커집니다. 처음에는 crawler.log 하나만 있으면 충분해 보였는데, 며칠 뒤 오류 내용을 찾으려고 열어보니 예전 기록까지 길게 이어져 있었습니다.

로그는 남겨야 하지만, 한 파일에 끝없이 쌓이면 확인하기 어려웠습니다.

그래서 이번에는 파일 크기가 일정 수준을 넘으면 새 로그 파일로 자동 교체하는 RotatingFileHandler를 써봤습니다.


2. RotatingFileHandler는 어떤 도구일까?

RotatingFileHandler는 Python logging 안에 들어 있는 로그 저장 도구입니다.

정해 둔 파일 크기에 도달하면 지금 쓰던 파일 이름 뒤에 번호를 붙여 보관하고, 다시 새 로그 파일에 기록을 시작합니다.

예를 들어 crawler.log가 1MB를 넘으면 아래처럼 나뉩니다.

crawler.log
crawler.log.1
crawler.log.2

crawler.log에는 가장 최근 기록이 들어가고, 숫자가 큰 파일일수록 더 이전 기록입니다. 오래된 로그의 개수도 제한할 수 있어서 폴더가 계속 커지는 일을 막을 수 있었습니다.


3. 가장 간단하게 로그 파일 나누기

먼저 로그 폴더를 만들고 핸들러를 준비했습니다.

import logging
from logging.handlers import RotatingFileHandler
from pathlib import Path

log_folder = Path("logs")
log_folder.mkdir(exist_ok=True)

log_file = log_folder / "crawler.log"

handler = RotatingFileHandler(
    log_file,
    maxBytes=1_000_000,
    backupCount=3,
    encoding="utf-8"
)

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[handler]
)

logging.info("크롤링 작업을 시작합니다.")

logging.handlers에서 RotatingFileHandler를 가져왔습니다.

기존에는 basicConfig()에 filename=log_file만 넣었습니다. 이번에는 파일 관리 역할을 하는 handler를 만들어 handlers=[handler]로 전달했습니다. 그러니 로그 형식은 그대로 두면서도 파일 크기를 관리할 수 있었습니다.


4. maxBytes와 backupCount 이해하기

설정에서 가장 중요한 부분은 두 가지였습니다.

maxBytes=1_000_000
backupCount=3

maxBytes는 로그 파일 하나가 가질 수 있는 최대 크기입니다. 위의 1_000_000은 약 1MB입니다. 숫자 사이의 밑줄은 큰 숫자를 읽기 쉽게 적는 Python 문법이라 실제 값은 달라지지 않습니다.

backupCount=3은 이전 로그를 최대 3개까지만 남기겠다는 뜻입니다. 현재 crawler.log까지 포함하면 최대 4개 파일이 생길 수 있습니다.

처음 테스트할 때는 1MB가 너무 커서 로그 교체가 되는지 기다리기 어려웠습니다. 그래서 아래처럼 작은 값으로 확인했습니다.

maxBytes=500
backupCount=2

로그를 여러 줄 출력한 뒤 logs 폴더를 열어 보니 crawler.log.1 파일이 생겼습니다. 이거 되겠는데? 싶었습니다. 실무 코드에는 다시 1MB나 5MB처럼 여유 있는 값으로 바꾸면 됩니다.


5. 크롤링 코드에 연결해 보기

지난 글의 Excel 확인 코드와 합쳐봤습니다.

import logging
import pandas as pd
from logging.handlers import RotatingFileHandler
from pathlib import Path

input_file = Path("results") / "blog_posts.xlsx"
log_file = Path("logs") / "crawler.log"

log_file.parent.mkdir(parents=True, exist_ok=True)

handler = RotatingFileHandler(
    log_file,
    maxBytes=5 * 1024 * 1024,
    backupCount=5,
    encoding="utf-8"
)

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[handler]
)

try:
    df = pd.read_excel(input_file)
    logging.info("데이터 확인 완료: %s건", len(df))

    if len(df) == 0:
        logging.warning("Excel 파일은 있지만 데이터가 0건입니다.")

except FileNotFoundError:
    logging.error("입력 파일을 찾을 수 없습니다: %s", input_file)

except Exception:
    logging.exception("Excel 파일을 읽는 중 예상하지 못한 오류가 발생했습니다.")

이번에는 5 * 1024 * 1024로 5MB를 지정했습니다. 바이트 단위를 직접 계산하기보다 1KB가 1024바이트라는 기준을 코드에 적어두니 나중에 봐도 이해하기 편했습니다.

또 logging.info()에 f-string 대신 %s를 썼습니다. 로그가 실제로 남길 때 값이 들어가는 방식이라, 반복 실행되는 코드에서는 이런 형태도 자주 보인다고 합니다. 처음에는 낯설었지만, 문자열 뒤에 len(df)를 넣는 순서만 기억하면 됐습니다.


6. 날짜별 로그와 크기별 로그는 언제 다를까?

로그를 나누는 방법에는 날짜 기준도 있습니다. 매일 하나씩 파일을 만들고 싶다면 TimedRotatingFileHandler를 사용할 수 있습니다.

하지만 지금처럼 크롤링 결과나 오류가 갑자기 많이 발생할 수 있는 코드에서는 파일 크기 기준이 더 맞아 보였습니다. 정상적인 날에는 작은 파일 하나만 남고, 오류가 반복돼 로그가 많아져도 파일이 지나치게 커지지 않기 때문입니다.

매일 정해진 보고를 남길 때는 날짜 기준, 실행량이 들쑥날쑥할 때는 크기 기준을 먼저 생각하면 되겠습니다.


7. 삽질했던 부분들

처음에는 RotatingFileHandler만 만들고 logging.basicConfig()에 연결하지 않았습니다.

handler = RotatingFileHandler(log_file)
logging.info("작업 시작")

이렇게 쓰면 만든 handler가 실제 로그 설정에 포함되지 않습니다. handlers=[handler]를 넣어야 했습니다.

또 maxBytes=0으로 둔 경우도 있었습니다. 크기 제한이 없는 설정이라 파일이 교체되지 않았습니다. 테스트할 때는 500처럼 작은 양의 정수를 넣는 편이 결과를 확인하기 좋았습니다.

마지막으로 기존 코드에서 이미 basicConfig()를 실행한 뒤 새 설정을 추가했더니 기대한 형식으로 바뀌지 않았습니다. basicConfig()는 한 프로그램 안에서 처음 호출된 설정이 적용되는 경우가 많았습니다. 그래서 로그 설정 코드는 파일 위쪽에서 한 번만 실행하도록 정리했습니다.


8. 아웃트로: 기록은 남기되 폴더는 가볍게

오늘은 RotatingFileHandler로 로그 파일 크기를 제한하고, 이전 기록의 보관 개수도 정해봤습니다.

핵심 정리

  1. RotatingFileHandler는 파일 크기 기준으로 로그를 나눔
  2. maxBytes로 파일 하나의 최대 크기를 정함
  3. backupCount로 이전 로그 파일의 보관 개수를 제한함
  4. handlers=[handler]로 logging 설정에 연결함
  5. 작은 용량으로 먼저 테스트한 뒤 실제 기준으로 조정함

이제 할 수 있는 것들

  • 자동 실행 로그가 끝없이 커지는 문제 막기
  • 최근 오류 기록을 더 빠르게 찾기
  • 오래된 로그 파일을 자동으로 정리하기
  • 크롤링과 Excel 저장 코드의 실행 기록을 안정적으로 보관하기

다음 포스팅에서는 configparser를 사용해서 파일 경로, 로그 용량, 저장 폴더 같은 설정값을 코드 밖의 .ini 파일로 분리해 보려고 합니다. 코드에서 값을 직접 고치지 않고도 실행 환경을 바꾸는 방법을 공부해 보겠습니다.