Files
layoutlmv3_service/classifier_service.py
2026-06-15 09:54:01 +09:00

113 lines
3.4 KiB
Python

import argparse
import gc
import os
import psutil
import uvicorn
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from loguru import logger
from starlette.responses import JSONResponse
from routers import router
from routers import classifier
from utils.classifier_model_store import get_model
app = FastAPI(title="classifier_service")
app.state.request_counter = 0
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(router)
# app.include_router(classifier.router)
# ── 로거 설정 ─────────────────────────────────────
logger.remove()
logger.add(
"logs/{time:YYYY-MM-DD}.log",
level="DEBUG",
rotation="00:00",
retention="30 days",
format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}",
)
# ── 메모리 유틸 ───────────────────────────────────
def log_memory_usage() -> float:
process = psutil.Process(os.getpid())
return process.memory_info().rss / 1024 / 1024
# ── HTTP 미들웨어 ─────────────────────────────────
@app.middleware("http")
async def log_requests(request: Request, call_next):
try:
memory_before = log_memory_usage()
request_counter = getattr(app.state, "request_counter", 0) + 1
app.state.request_counter = request_counter
logger.info(f"request_counter: {request_counter}")
logger.info(f"Received: {request.method} {request.url}")
logger.info(f"Headers: {dict(request.headers)}")
response = await call_next(request)
logger.info(f"Response status: {response.status_code}")
if request_counter % 100 == 0:
logger.info("gc.collect 실행")
gc.collect()
memory_after = log_memory_usage()
logger.info(
f"Memory: Before={memory_before:.2f}MB, "
f"After={memory_after:.2f}MB, "
f"Diff={memory_after - memory_before:.2f}MB"
)
return response
except Exception as e:
logger.exception(f"요청 처리 중 예외 발생: {e}")
return JSONResponse(
status_code=500,
content={"detail": "Internal Server Error", "error": str(e)},
)
@app.get("/", tags=["기타"])
async def root():
return {"message": "document classifier service"}
@app.get("/health", tags=["기타"])
async def health():
m = get_model()
return {
"status": "ok",
"model_loaded": m is not None,
"classes": list(m.classes_) if m else [],
}
# ── 진입점 ────────────────────────────────────────
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-host", default="0.0.0.0")
parser.add_argument("-port", default=10941)
args = parser.parse_args()
logger.info(f"서버 시작: {args.host}:{args.port}")
uvicorn.run(
app,
host=args.host,
port=int(args.port),
limit_concurrency=1000,
timeout_keep_alive=120,
log_level="debug",
)