logging 라이브러리를 이용하여 애플리케이션의 동작을 추적하고 디버깅하는 데 사용됩니다.
로그의 레벨은 다음과 같이 구성됩니다.
Level | Value |
---|---|
DEBUG | 10 |
INFO | 20 |
WARNING | 30 |
ERROR | 40 |
CRITICAL | 50 |
💡 본 글은 예제 코드를 이용하여 설명합니다.
flask/source/my_app/__init__.py를 살펴봅니다.
Flask에서 기본 로그는 Flask 객체의 logger
를 통해 사용할 수 있습니다.
app_logger_test()라는 함수를 살펴보면 DEBUG부터 CRITICAL까지의 로그 레벨별 로그를 기록합니다.
def app_logger_test(app:Flask):
app.logger.debug(msg="debug log1")
app.logger.info(msg="info log1")
app.logger.warn(msg="warn log1")
app.logger.warning(msg="warning log1")
app.logger.error(msg="error log1")
app.logger.critical(msg="critical log1")
위의 코드가 실행되면 콘솔에서는 다음과 같이 출력됩니다.
flask | [2023-12-21 05:47:01,916] WARNING in __init__: warn log1
flask | [2023-12-21 05:47:01,916] WARNING in __init__: warning log1
flask | [2023-12-21 05:47:01,916] ERROR in __init__: error log1
flask | [2023-12-21 05:47:01,916] CRITICAL in __init__: critical log1
DEBUG와 INFO 레벨의 로그는 출력되지 않는 것을 확인할 수 있습니다. 그 이유는 기본 로그 레벨이 WARNING이기 때문입니다.
setLevel()을 통해 로그를 기록할 수 있는 레벨을 지정할 수 있습니다.
아래의 예제는 로그 레벨을 DEBUG로 바꾸어 DEBUG와 INFO 레벨의 로그까지 기록될 수 있습니다.
def app_logger_test(app:Flask):
# 코드 생략
app.logger.setLevel(logging.DEBUG)
app.logger.debug(msg="debug log2")
app.logger.info(msg="info log2")
로깅을 하지 않더라도 Flask는 기본적으로 클라이언트의 요청이 이루어질 때마다, 다음과 같이 콘솔에 로그를 출력합니다.
flask | 192.168.61.1 - - [21/Dec/2023 06:00:20] "GET /board/ HTTP/1.1" 200 -
flask | 192.168.61.1 - - [21/Dec/2023 06:00:20] "GET /static/css/style.css HTTP/1.1" 304 -
werkzeug
라는 이름의 로거를 비활성화하면 Flask 로그는 생성되지 않습니다.
logging.getLogger("werkzeug").disabled = True
flask/source/my_app/__init__.py를 살펴봅니다.
사용자 정의 로그를 생성하고, 이를 파일로 관리해보겠습니다. 먼저, 로거를 생성합니다.
logger = logging.getLogger("myLogger")
이후, FileHandler
를 생성합니다.
handler = logging.FileHandler(filename=log_path, mode="a", encoding="utf-8")
로그가 기록될 때의 포맷을 사용자가 지정할 수 있습니다.
asctime은 로그가 기록될 때의 시간이며, datefmt인자를 이용하여 시간의 형식을 지정할 수 있습니다.
levelname은 로그가 기록될 때의 로그 레벨입니다.
message는 로그가 기록될 때의 로그 메시지 입니다.
기타 추가적으로 필드를 지정하고 싶다면 %(변수 명)형식 지정자로 지정하면 됩니다.
handler.setFormatter(fmt=logging.Formatter('[%(asctime)s] [%(levelname)s] [%(remote_addr)s] \"%(method)s %(url)s %(version)s\" : %(message)s', datefmt='%Y-%m-%d %H:%M:%S'))
이후, 생성한 로거에 FileHandler를 추가하고 로그 레벨을 지정해봅니다.
logger.addHandler(handler)
logger.setLevel(logging.INFO)
flask/source/my_app/views/index.py를 살펴보면 생성한 로거를 이용하여 로깅하는 예제를 확인할 수 있습니다.
logger.info(
msg=f"Login Success : {user.username}",
extra={
"remote_addr": request.remote_addr,
"method": request.method,
"url": request.path,
"version": request.environ.get('SERVER_PROTOCOL')
}
)
flask/source/my_app/__init__.py를 살펴봅니다.
파일 로거를 통해 로깅만 하면 파일의 사이즈가 커져서 로그를 확인하기 힘들 수 있습니다.
그럴 때는 최대 크기와 백업 개수를 지정하여 관리하는 파일 로테이팅이 필요합니다.
handler = logging.handlers.RotatingFileHandler(filename=log_path, mode="a", encoding="utf-8", maxBytes=200, backupCount=3)
백업 파일은 로그 파일 명.숫자로 백업이 되며 backupCount가 3이면 로그 파일 명.3까지만 백업이 됩니다.
그 외 로깅 방법, 포맷팅은 기본 파일 로거와 동일합니다.