웹을 유지보수한다면 하루에 한 번은 살펴보는 것이 로그파일입니다.
유저들이 어느 페이지에 접속해서 버튼을 누르는지, 어떤 데이터를 GET, POST하는지 살펴보기고하고, 에러가 발생할 경우 이에 대응하기에 유용합니다.
그리고 보안적으로도 접속 ip등을 기록하여 증적자료로 사용됩니다.
근래 프로토타입을 Flask 기반으로 두 개정도 개발하면서 외부에 공개할 일이 생겨 혹시 모를 일에 대비하여 로그 파일 생성을 구현하였습니다.
우선 구현 항목은 아래와 같습니다.
1. 실시간으로 로그 기록되어야함.
2. 로그는 연-월-일 시:분:초 format으로 기록될 수 있어야함.
3. 로그는 1일 1로그 파일로 구분되어야함.
4. 사용자가 어떤 GET, POST 요청을 했는지 알 수 있어야함.
from logging.handlers import TimedRotatingFileHandler
파이썬의 logging 라이브러리에서 TimedRotatingFileHandler를 핸들링할 수 있는 메소드를 사용했습니다.
공식 문서에는 다음과 같이 명시되어 있습니다.

해당 메소드를 사용해서 구현를 진행하였습니다.
import logging
from logging.handlers import TimedRotatingFileHandler # 로그 관련 추가
from flask import Flask
app = Flask(__name__)
# 로그 설정 추가
log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
log_handler = TimedRotatingFileHandler('access.log', when='midnight', interval=1)
log_handler.setFormatter(log_formatter)
log_handler.setLevel(logging.INFO)
log_handler.suffix = "%Y-%m-%d"
app.logger.addHandler(log_handler)
app.logger.setLevel(logging.INFO)
# 각 요청 로그 기록
@app.before_request
def log_request_info():
app.logger.info('Request: %s %s %s', request.remote_addr, request.method, request.url)
로그 메시지의 출력 형식을 정의합니다.
asctime : 로그가 기록된 시간
levelname : 로그의 심각도 수준 (INFO, ERROR 등)
message : 로그 메시지 내용
다음과 같이 정의해서 모든 로그 메시지가 일관된 형식으로 출력되도록 설정했습니다.
로그 파일명은 'access.log'로 정의했습니다.
when='midnight', intervel=1를 통해서 자정마다 새로운 로그파일 1개가 생성되게 주기를 설정했습니다.
정의한 log_formatter를 log_handler에 적용시켰습니다.
로그에 기록할 로그 수준을 INFO 이상으로 지정했습니다. DEBUG와 같이 INFO보다 낮은 로그는 무시되게 설정했습니다. 이를 통해 너무 불필요한 로그가 쌓이는걸 방지했습니다.
로그파일이름에 날짜를 추가하도록 설정했습니다.
만약 금일 로그가 저장된다면 access.log.2024-11-22 이런 포맷으로 저장되게 설정했습니다.
app.logger.addHandler(log_handler)
app.logger.setLevel(logging.INFO)
@app.before_request
def log_request_info():
app.logger.info('Request: %s %s %s', request.remote_addr, request.method, request.url)
Flask에서 app.before_request 데코레이터를 통해 HTTP 요청이 처리되기 전에 로깅이 되는 함수 log_request_info를 구현했습니다.
요청이 발생한 IP 주소, HTTP 메소드(GET, POST등) 그리고 요청 URL을 추적하도록 구현했습니다.

위 이미지는 로그 파일 (Access.log)에 기록된 내용입니다.