From e7d5bcaf4bc70a69795edcbcad05f09af4f7f436 Mon Sep 17 00:00:00 2001 From: MingxuanGame Date: Tue, 12 Aug 2025 17:00:01 +0000 Subject: [PATCH] feat(server): add sentry to track error --- .env.example | 3 +++ README.md | 7 ++++++- app/config.py | 3 +++ main.py | 9 +++++++++ pyproject.toml | 1 + uv.lock | 29 +++++++++++++++++++++++++++++ 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 56633c8..1758417 100644 --- a/.env.example +++ b/.env.example @@ -45,6 +45,9 @@ FETCHER_SCOPES=public # 日志设置 LOG_LEVEL="INFO" +# Sentry 设置,为空表示不启用 +SENTRY_DSN + # 游戏设置 ENABLE_OSU_RX=false # 启用 osu!RX 统计数据 ENABLE_OSU_AP=false # 启用 osu!AP 统计数据 diff --git a/README.md b/README.md index 8897b68..fe201e4 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ docker-compose -f docker-compose-osurx.yml up -d | `DEBUG` | 调试模式 | `false` | | `SERVER_URL` | 服务器 URL | `http://localhost:8000` | | `CORS_URLS` | 额外的 CORS 允许的域名列表 (JSON 格式) | `[]` | -| `FRONTEND_URL` | 前端 URL,当访问从游戏打开的 URL 时会重定向到这个 URL,为空表示不重定向 | `` | +| `FRONTEND_URL` | 前端 URL,当访问从游戏打开的 URL 时会重定向到这个 URL,为空表示不重定向 | `(null)` | ### OAuth 设置 | 变量名 | 描述 | 默认值 | @@ -101,6 +101,11 @@ Fetcher 用于从 osu! 官方 API 获取数据,使用 osu! 官方 API 的 OAut |--------|------|--------| | `LOG_LEVEL` | 日志级别 | `INFO` | +### Sentry 设置 +| 变量名 | 描述 | 默认值 | +|--------|------|--------| +| `SENTRY_DSN` | Sentry DSN,为空不启用 Sentry | `(null)` | + ### 游戏设置 | 变量名 | 描述 | 默认值 | |--------|------|--------| diff --git a/app/config.py b/app/config.py index 6ebf646..e99b080 100644 --- a/app/config.py +++ b/app/config.py @@ -84,6 +84,9 @@ class Settings(BaseSettings): # 日志设置 log_level: str = "INFO" + # Sentry 配置 + sentry_dsn: HttpUrl | None = None + # 游戏设置 enable_osu_rx: bool = False enable_osu_ap: bool = False diff --git a/main.py b/main.py index 04603c3..2cd990a 100644 --- a/main.py +++ b/main.py @@ -24,6 +24,7 @@ from app.service.osu_rx_statistics import create_rx_statistics from fastapi import FastAPI, HTTPException, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse +import sentry_sdk @asynccontextmanager @@ -45,6 +46,14 @@ desc = ( "osu! API 模拟服务器,支持 osu! API v2 和 osu!lazer 的绝大部分功能。\n\n" "官方文档:[osu!web 文档](https://osu.ppy.sh/docs/index.html)" ) + +if settings.sentry_dsn is not None: + sentry_sdk.init( + dsn=str(settings.sentry_dsn), + send_default_pii=False, + environment="production" if not settings.debug else "development", + ) + app = FastAPI( title="osu! API 模拟服务器", version="1.0.0", diff --git a/pyproject.toml b/pyproject.toml index d29db87..361860a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ dependencies = [ "python-jose[cryptography]>=3.3.0", "python-multipart>=0.0.6", "redis>=5.0.1", + "sentry-sdk[fastapi,httpx,loguru,sqlalchemy]>=2.34.1", "sqlalchemy>=2.0.23", "sqlmodel>=0.0.24", "uvicorn[standard]>=0.24.0", diff --git a/uv.lock b/uv.lock index 54f2c03..4a700c1 100644 --- a/uv.lock +++ b/uv.lock @@ -830,6 +830,7 @@ dependencies = [ { name = "python-jose", extra = ["cryptography"] }, { name = "python-multipart" }, { name = "redis" }, + { name = "sentry-sdk", extra = ["fastapi", "httpx", "loguru", "sqlalchemy"] }, { name = "sqlalchemy" }, { name = "sqlmodel" }, { name = "uvicorn", extra = ["standard"] }, @@ -864,6 +865,7 @@ requires-dist = [ { name = "python-jose", extras = ["cryptography"], specifier = ">=3.3.0" }, { name = "python-multipart", specifier = ">=0.0.6" }, { name = "redis", specifier = ">=5.0.1" }, + { name = "sentry-sdk", extras = ["fastapi", "httpx", "loguru", "sqlalchemy"], specifier = ">=2.34.1" }, { name = "sqlalchemy", specifier = ">=2.0.23" }, { name = "sqlmodel", specifier = ">=0.0.24" }, { name = "uvicorn", extras = ["standard"], specifier = ">=0.24.0" }, @@ -1275,6 +1277,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6d/4f/d073e09df851cfa251ef7840007d04db3293a0482ce607d2b993926089be/s3transfer-0.13.1-py3-none-any.whl", hash = "sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724", size = 85308, upload-time = "2025-07-18T19:22:40.947Z" }, ] +[[package]] +name = "sentry-sdk" +version = "2.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/38/10d6bfe23df1bfc65ac2262ed10b45823f47f810b0057d3feeea1ca5c7ed/sentry_sdk-2.34.1.tar.gz", hash = "sha256:69274eb8c5c38562a544c3e9f68b5be0a43be4b697f5fd385bf98e4fbe672687", size = 336969, upload-time = "2025-07-30T11:13:37.93Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/3e/bb34de65a5787f76848a533afbb6610e01fbcdd59e76d8679c254e02255c/sentry_sdk-2.34.1-py2.py3-none-any.whl", hash = "sha256:b7a072e1cdc5abc48101d5146e1ae680fa81fe886d8d95aaa25a0b450c818d32", size = 357743, upload-time = "2025-07-30T11:13:36.145Z" }, +] + +[package.optional-dependencies] +fastapi = [ + { name = "fastapi" }, +] +httpx = [ + { name = "httpx" }, +] +loguru = [ + { name = "loguru" }, +] +sqlalchemy = [ + { name = "sqlalchemy" }, +] + [[package]] name = "six" version = "1.17.0"