[Flask] Logging

Alexandria·2023년 12월 21일
0

Python3 Flask

목록 보기
14/14
post-thumbnail

1. Logging

logging 라이브러리를 이용하여 애플리케이션의 동작을 추적하고 디버깅하는 데 사용됩니다.

로그의 레벨은 다음과 같이 구성됩니다.

LevelValue
DEBUG10
INFO20
WARNING30
ERROR40
CRITICAL50

💡 본 글은 예제 코드를 이용하여 설명합니다.

2. 기본 로깅

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")

2.1. 비활성화

로깅을 하지 않더라도 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

3. 파일 로깅

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')
	}
)

3.1. Rotating

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까지만 백업이 됩니다.

그 외 로깅 방법, 포맷팅은 기본 파일 로거와 동일합니다.

profile
IT 도서관

0개의 댓글