diff --git a/.env.development b/.env.development index 8a5b05d..429711d 100644 --- a/.env.development +++ b/.env.development @@ -1,9 +1,6 @@ ENVIRONMENT=development # JWT -# 错误日志收集 -SENTRY_DSN=https://cf047260c50340fa8a96f4f198cefa12@o959813.ingest.sentry.io/6128331 - # 数据库 MYSQL_ADDRESS=127.0.0.1:3306 MYSQL_USER=root diff --git a/common/config.py b/common/config.py index e0c92c5..398314e 100644 --- a/common/config.py +++ b/common/config.py @@ -4,7 +4,6 @@ from typing import Dict from typing import Any from pydantic import BaseSettings -from pydantic import HttpUrl from pydantic import validator from pydantic import AnyUrl @@ -35,9 +34,6 @@ class Settings(BaseSettings): ALGORITHM: str = 'HS256' ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 3 - # Sentry - SENTRY_DSN: Optional[HttpUrl] - # 数据库 MYSQL_ADDRESS: str MYSQL_USER: str diff --git a/common/exception.py b/common/exception.py index e69de29..eee9e40 100644 --- a/common/exception.py +++ b/common/exception.py @@ -0,0 +1,41 @@ +from starlette.exceptions import HTTPException +from fastapi.responses import ORJSONResponse + + +async def http_exception(request, exc): + if hasattr(exc, 'detail'): + msg = exc.detail + else: + msg = exc + return ORJSONResponse({"msg": msg}, status_code=exc.status_code) + + +# async def http_404_exception(request, exc): +# return ORJSONResponse({"msg": exc.detail}, status_code=exc.status_code) +# +# +# async def http_500_exception(request, exc): +# return ORJSONResponse({"msg": exc.detail}, status_code=exc.status_code) + + +# 自定义异常 +class UnicornException(Exception): + def __init__(self, name: str): + self.name = name + + +async def unicorn_exception_handler(request, exc: UnicornException): + return ORJSONResponse( + status_code=418, + content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."}, + ) + + +exception_handlers = { + HTTPException: http_exception, + # 404: http_404_exception, + # 500: http_500_exception, + UnicornException: unicorn_exception_handler +} + +__all__ = [exception_handlers] diff --git a/common/logs.py b/common/logs.py index e69de29..d761cdc 100644 --- a/common/logs.py +++ b/common/logs.py @@ -0,0 +1,17 @@ +import sys + +from loguru import logger + +config = { + "handlers": [ + {"sink": sys.stdout, "colorize": True}, + {"sink": "file.log", "enqueue": True, "level": "ERROR", "rotation": "20 MB"} + ] +} +logger.configure(**config) + + +def http(request, response, time_s): + """http请求日志""" + logger.info( + f'{request.method} {request.url.path} {response.status_code} {round(time_s * 1000, 3)} ms') diff --git a/common/middleware.py b/common/middleware.py index 3ef774d..86cd765 100644 --- a/common/middleware.py +++ b/common/middleware.py @@ -1,14 +1,27 @@ -import sentry_sdk -from sentry_sdk.integrations.asgi import SentryAsgiMiddleware -from fastapi.middleware.cors import CORSMiddleware -from common.config import settings +import time -sentry_sdk.init(settings.SENTRY_DSN) +from starlette.middleware import Middleware +from starlette.middleware.cors import CORSMiddleware +from starlette.middleware.base import BaseHTTPMiddleware +from starlette.middleware.base import RequestResponseEndpoint +from starlette.requests import Request +from starlette.responses import Response + +from common.logs import http + + +class HttpLogInfoMiddleware(BaseHTTPMiddleware): + """请求耗时 日志""" + async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response: + start = time.time() + response = await call_next(request) + http(request, response, time.time() - start) + return response middlewares = [ - SentryAsgiMiddleware, - CORSMiddleware(allow_origins=['*'], allow_methods=['*'], allow_headers=['*']) + Middleware(CORSMiddleware, allow_origins=['*']), + Middleware(HttpLogInfoMiddleware) ] diff --git a/main.py b/main.py index 3f0626c..9d8470a 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,15 @@ -from common.config import settings +from fastapi import FastAPI +from fastapi.responses import ORJSONResponse -print(settings.MYSQL_DATABASE_URL) -print(settings.REDIS_URL) \ No newline at end of file +from common.exception import exception_handlers +from common.middleware import middlewares + +app = FastAPI( + middleware=middlewares, + exception_handlers=exception_handlers, + default_response_class=ORJSONResponse +) + +if __name__ == '__main__': + import uvicorn + uvicorn.run("main:app", reload=True) diff --git a/requirements.txt b/requirements.txt index 4b5d217..67af490 100644 --- a/requirements.txt +++ b/requirements.txt @@ -32,7 +32,6 @@ python-dotenv==0.19.2 python-jose==3.3.0 pytz==2021.3 rsa==4.8 -sentry-sdk==1.5.1 six==1.16.0 sniffio==1.2.0 starlette==0.16.0 @@ -42,3 +41,5 @@ typing_extensions==4.0.1 urllib3==1.26.7 uvicorn==0.16.0 win32-setctime==1.0.4 +orjson==3.6.5 +