프로그래밍/Python

[FastAPI] 요청/응답 로깅하는 법

Lou Park 2025. 1. 20. 18:57

Python 웹서버 프레임워크 FastAPI의 모든 요청과 응답, 응답시간을 로깅하는 미들웨어를 추가하는 코드다.

import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("request_logger")

@app.middleware("http")
async def log_requests(request: Request, call_next):
    start_time = time.time()
    
    # 요청 정보 로깅
    logger.info(f"Request: {request.method} {request.url}")
    logger.info(f"Headers: {request.headers}")
    logger.info(f"Body: {await request.body()}")

    response = await call_next(request)
    
    # 응답 시간 계산
    duration = time.time() - start_time
    logger.info(f"Response status: {response.status_code}")
    logger.info(f"Duration: {duration:.2f}s")
    
    return response

 

실행 결과

INFO:request_logger:Request: POST http://127.0.0.1:8000/workflow/image_generation
INFO:request_logger:Headers: Headers({'host': '127.0.0.1:8000', 'connection': 'keep-alive', 'content-length': '250', 'sec-ch-ua-platform': '"macOS"', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0', 'sec-ch-ua': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"', 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryiWN0DwytsF6aRZEt', 'sec-ch-ua-mobile': '?0', 'accept': '*/*', 'origin': 'http://127.0.0.1:8000', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'http://127.0.0.1:8000/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'ko,en;q=0.9,en-US;q=0.8'})
INFO:request_logger:Body: b'------WebKitFormBoundaryiWN0DwytsF6aRZEt\r\nContent-Disposition: form-data; name="seed"\r\n\r\n0\r\n------WebKitFormBoundaryiWN0DwytsF6aRZEt\r\nContent-Disposition: form-data; name="text"\r\n\r\nspongebob wearing glass\r\n------WebKitFormBoundaryiWN0DwytsF6aRZEt--\r\n'
{'path': 'workflows/workflow_image_generation_api.json', 'text_node_id': '37'}
Request: http://xxx.xxx.xxx.xxx:8188/prompt
INFO:request_logger:Response status: 200
INFO:request_logger:Duration: 0.32s