🧐 개요
이번 포스트는 Python 기반의 프레임워크인 FastAPI 내부에 미들웨어를 구성하여 시스템 로그를 관리하는 방법을 설명합니다.
미들웨어(MiddleWare)의 개념
미들웨어(middleware)란? 개념, 종류, 필요성
미들웨어란 운영 체제에서 제공하지 않는 일반적인 서비스와 기능을 애플리케이션에 제공하는 소프트웨어를 뜻하며, 개발자와 운영자가 애플리케이션을 효율적으로 구축하고 배포하도록 지원
www.redhat.com
미들웨어는 클라이언트와 서버 사이에 위치하는 구성 요소입니다. 간략화하여 설명하면, 클라이언트의 요청에 대한 응답이 생성되고 전송되기까지의 과정 사이에서 중간 결과물 및 상태값을 가지고 독립적인 작업을 수행할 수 있습니다.
해당 포스트에서 만든 미들웨어는 FastAPI 서버 동작 도중 발생하는 모든 Internal Server Error의 내용을 로그 파일로 기록하고, 해당 내용을 LINE NOTI로 전송하는 기능을 목적으로 사용하고 있습니다.
🖍️ 미들웨어 클래스 정의하기
FastAPI는 starlette 라는 비동기 웹 프레임워크를 기반으로 개발된 프로젝트입니다. 따라서 FastAPI 내부에 미들웨어를 정의하고 구성하기 위해서는 starlette 모듈을 사용해야 합니다.
from fastapi import HTTPException
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
from starlette.requests import Request
from starlette.responses import Response
import traceback
from time import time
class LoggerMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response:
endpoint_path = request.url.path
.. 반환한 엔드포인트로 로직 수행 (예: 로그 파일명 정의하기) ..
start_time = time()
try:
response = await call_next(request)
return response
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
tb_info = traceback.extract_tb(exc_traceback)[-1]
filename = tb_info.filename
lineno = tb_info.lineno
line = tb_info.line
message = f"Internal Server Error - {endpoint_path} - {filename} - {lineno} - {line} - {str(e)}"
.. 생성한 메세지로 로직 수행 (예: 로그 발생 & LINE NOTI 전송) ..
raise HTTPException(status_code=500, detail="Internal Server Error")
finally:
end_time = time()
elapsed_time = end_time - start_time
message = f"Elapsed Time: {elapsed_time:.2f} seconds"
.. 생성한 메세지로 로직 수행 (예: 로그 발생 & LINE NOTI 전송) ..
클래스 내부에서 정의하는 dispatch 함수는 반드시 해당 이름을 사용해 정의해야 합니다. BaseHTTPMiddleware 미들웨어에서 제공하는 기본 동작들이 dispatch 메서드를 사용하도록 구조화되어 있기 때문입니다.
🛠️ 앱에 미들웨어 추가하기
외부 파일을 통해 생성한 미들웨어는 라우터와 마찬가지로 어플리케이션에 추가해주어야 합니다.
from fastapi import FastAPI
from router import ..
from middleware_c.logger_middleware import LoggerMiddleware
app = FastAPI()
app.add_middleware(LoggerMiddleware)
..
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host='0.0.0.0', port=8000)
모듈 import 부분에서 미들웨어 클래스를 호출하고, 호출한 클래스를 add_middleware() 함수를 통해 입력합니다. 이렇게 추가한 미들웨어는 FastAPI 서버 가동 시 각 엔드포인트 라우터의 동작 도중 비동기적으로 작업을 수행합니다.
📝 마치며
미들웨어는 API 요청 및 응답 과정에서 비동기적으로 작업을 수행하기 때문에 다양한 용도로 활용할 수 있습니다.
'백엔드 이모저모 > FastAPI' 카테고리의 다른 글
[FastAPI] OAuth에 대하여 / 간단한 OAuth 인증 구현해보기 (0) | 2024.01.17 |
---|
발자취를 로그처럼 남기고자 하는 초보 개발자의 블로그