refactor(log): refactor the whole project

format: {time:YYYY-MM-DD HH:mm:ss} [{level}] | {name} | {message}
{name} is:
- Uvicorn: log from uvicorn server (#228B22)
- Service: log from class of `app.service` (blue)
- Fetcher: log from fetchers (magenta)
- Task: log from `app.tasks` (#FFD700)
- System: log from `system_logger` (red)
- Normal: log from `log(name)` (#FFC1C1)
- Default: the module name of caller

if you are writing services or tasks, you can just call `logger.`, we will pack it with name `Service` or `Task`
if you want to print fetcher logs, system-related logs, or normal logs, use `logger = (fetcher_logger / system_logger / log)(name)`
This commit is contained in:
MingxuanGame
2025-10-03 11:44:47 +00:00
parent fce88272b5
commit d23f32f08d
27 changed files with 210 additions and 174 deletions

View File

@@ -22,7 +22,7 @@ from app.database.statistics import UserStatistics
from app.dependencies.database import Database, Redis
from app.dependencies.geoip import GeoIPService, IPAddress
from app.dependencies.user_agent import UserAgentInfo
from app.log import logger
from app.log import log
from app.models.extended_auth import ExtendedTokenResponse
from app.models.oauth import (
OAuthErrorResponse,
@@ -44,6 +44,8 @@ from fastapi.responses import JSONResponse
from sqlalchemy import text
from sqlmodel import exists, select
logger = log("Auth")
def create_oauth_error_response(error: str, description: str, hint: str, status_code: int = 400):
"""创建标准的 OAuth 错误响应"""
@@ -360,9 +362,7 @@ async def oauth_token(
await LoginSessionService.mark_session_verified(
db, redis, user_id, token_id, ip_address, user_agent, web_uuid
)
logger.debug(
f"[Auth] New location login detected but email verification disabled, auto-verifying user {user_id}"
)
logger.debug(f"New location login detected but email verification disabled, auto-verifying user {user_id}")
else:
# 不是新设备登录,正常登录
await LoginLogService.record_login(
@@ -505,7 +505,7 @@ async def oauth_token(
)
# 打印jwt
logger.info(f"[Auth] Generated JWT for user {user_id}: {access_token}")
logger.info(f"Generated JWT for user {user_id}: {access_token}")
return TokenResponse(
access_token=access_token,

View File

@@ -14,7 +14,7 @@ from app.database.user import User
from app.dependencies.database import Database, Redis
from app.dependencies.fetcher import Fetcher
from app.dependencies.storage import StorageService
from app.log import logger
from app.log import log
from app.models.multiplayer_hub import PlaylistItem as HubPlaylistItem
from app.models.room import MatchType, QueueMode, RoomCategory, RoomStatus
from app.utils import utcnow
@@ -27,6 +27,7 @@ from sqlalchemy import update
from sqlmodel import col, select
router = APIRouter(prefix="/_lio", include_in_schema=False)
logger = log("LegacyIO")
async def _ensure_room_chat_channel(

View File

@@ -16,7 +16,7 @@ from app.database.user import User
from app.dependencies.database import Database, Redis
from app.dependencies.param import BodyOrForm
from app.dependencies.user import get_current_user
from app.log import logger
from app.log import log
from app.models.notification import ChannelMessage, ChannelMessageTeam
from app.router.v2 import api_v2_router as router
from app.service.redis_message_system import redis_message_system
@@ -33,6 +33,9 @@ class KeepAliveResp(BaseModel):
silences: list[UserSilenceResp] = Field(default_factory=list)
logger = log("Chat")
@router.post(
"/chat/ack",
name="保持连接",

View File

@@ -14,7 +14,7 @@ from app.dependencies.database import (
with_db,
)
from app.dependencies.user import get_current_user_and_token
from app.log import logger
from app.log import log
from app.models.chat import ChatEvent
from app.models.notification import NotificationDetail
from app.service.subscribers.chat import ChatSubscriber
@@ -26,6 +26,8 @@ from fastapi.websockets import WebSocketState
from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession
logger = log("NotificationServer")
class ChatServer:
def __init__(self):
@@ -285,10 +287,10 @@ async def _listen_stop(ws: WebSocket, user_id: int, factory: DBFactory):
await ws.close(code=1000)
break
except WebSocketDisconnect as e:
logger.info(f"[NotificationServer] Client {user_id} disconnected: {e.code}, {e.reason}")
logger.info(f"Client {user_id} disconnected: {e.code}, {e.reason}")
except RuntimeError as e:
if "disconnect message" in str(e):
logger.info(f"[NotificationServer] Client {user_id} closed the connection.")
logger.info(f"Client {user_id} closed the connection.")
else:
logger.exception(f"RuntimeError in client {user_id}: {e}")
except Exception:

View File

@@ -39,7 +39,7 @@ from app.dependencies.database import Database, Redis, get_redis, with_db
from app.dependencies.fetcher import Fetcher, get_fetcher
from app.dependencies.storage import StorageService
from app.dependencies.user import ClientUser, get_current_user
from app.log import logger
from app.log import log
from app.models.beatmap import BeatmapRankStatus
from app.models.room import RoomCategory
from app.models.score import (
@@ -73,6 +73,7 @@ from sqlmodel import col, exists, func, select
from sqlmodel.ext.asyncio.session import AsyncSession
READ_SCORE_TIMEOUT = 10
logger = log("Score")
async def _process_user_achievement(score_id: int):

View File

@@ -15,7 +15,7 @@ from app.dependencies.database import Database, Redis, get_redis
from app.dependencies.geoip import IPAddress
from app.dependencies.user import UserAndToken, get_client_user_and_token
from app.dependencies.user_agent import UserAgentInfo
from app.log import logger
from app.log import log
from app.service.login_log_service import LoginLogService
from app.service.verification_service import (
EmailVerificationService,
@@ -254,7 +254,7 @@ async def fallback_email(
user_agent,
)
if not success:
logger.error(
f"[Email Fallback] Failed to send fallback email to user {current_user.id} (token: {token_id}): {message}"
log("Verification").error(
f"Failed to send fallback email to user {current_user.id} (token: {token_id}): {message}"
)
return VerifyMethod()

View File

@@ -19,7 +19,7 @@ from app.database.user import SEARCH_INCLUDED
from app.dependencies.api_version import APIVersion
from app.dependencies.database import Database, get_redis
from app.dependencies.user import get_current_user
from app.log import logger
from app.log import log
from app.models.score import GameMode
from app.models.user import BeatmapsetType
from app.service.asset_proxy_helper import process_response_assets
@@ -336,7 +336,7 @@ async def get_user_beatmapsets(
try:
await cache_service.cache_user_beatmapsets(user_id, type.value, resp, limit, offset)
except Exception as e:
logger.error(f"Error caching user beatmapsets for user {user_id}, type {type.value}: {e}")
log("Beatmapset").error(f"Error caching user beatmapsets for user {user_id}, type {type.value}: {e}")
background_task.add_task(cache_beatmapsets)