113 lines
3.4 KiB
Python
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",
|
|
) |