This commit is contained in:
aaron 2025-06-12 10:16:04 +08:00
parent b5093519bc
commit d91bc39663
3 changed files with 98 additions and 3 deletions

View File

@ -9,6 +9,7 @@ FastAPI应用程序入口
import os import os
import logging import logging
import uvicorn import uvicorn
import json
from fastapi import FastAPI, Request from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
@ -34,6 +35,9 @@ logging.basicConfig(
) )
logger = logging.getLogger("fastapi") logger = logging.getLogger("fastapi")
# 配置选项
LOG_REQUEST_BODY = os.environ.get("LOG_REQUEST_BODY", "true").lower() == "true"
# 创建FastAPI应用 # 创建FastAPI应用
app = FastAPI( app = FastAPI(
title="CryptoAI API", title="CryptoAI API",
@ -58,6 +62,96 @@ app.include_router(crypto_router, prefix="/crypto", tags=["加密货币数据"])
app.include_router(analysis_router, prefix="/analysis", tags=["分析历史"]) app.include_router(analysis_router, prefix="/analysis", tags=["分析历史"])
app.include_router(alltick_router, prefix="/alltick", tags=["AllTick数据"]) app.include_router(alltick_router, prefix="/alltick", tags=["AllTick数据"])
app.include_router(payment_router, prefix="/payment", tags=["支付"]) app.include_router(payment_router, prefix="/payment", tags=["支付"])
# 请求体日志中间件
@app.middleware("http")
async def log_request_body(request: Request, call_next):
"""
记录请求体的中间件
可通过环境变量 LOG_REQUEST_BODY=false 来禁用
"""
# 如果禁用了请求体日志记录,则直接处理请求
if not LOG_REQUEST_BODY:
response = await call_next(request)
return response
# 获取请求的基本信息
method = request.method
url = str(request.url)
client_ip = request.client.host if request.client else "unknown"
# 初始化请求体内容
body_content = ""
# 只记录非 GET 请求的请求体
if method in ["POST", "PUT", "PATCH", "DELETE"]:
try:
# 读取请求体
body = await request.body()
if body:
# 尝试解析为 JSON
try:
body_json = json.loads(body.decode('utf-8'))
# 敏感信息过滤 - 隐藏密码等敏感字段
sensitive_fields = ['password', 'token', 'secret', 'key', 'auth']
filtered_body = body_json.copy()
def filter_sensitive_data(data, fields_to_hide):
if isinstance(data, dict):
for key in data:
if any(sensitive in key.lower() for sensitive in fields_to_hide):
data[key] = "***HIDDEN***"
elif isinstance(data[key], dict):
filter_sensitive_data(data[key], fields_to_hide)
elif isinstance(data[key], list):
for item in data[key]:
if isinstance(item, dict):
filter_sensitive_data(item, fields_to_hide)
filter_sensitive_data(filtered_body, sensitive_fields)
body_content = json.dumps(filtered_body, ensure_ascii=False, indent=2)
except (json.JSONDecodeError, UnicodeDecodeError):
# 如果不是 JSON则显示原始内容限制长度
body_content = body.decode('utf-8', errors='ignore')[:1000]
if len(body) > 1000:
body_content += "... (truncated)"
else:
body_content = "(empty)"
except Exception as e:
body_content = f"(error reading body: {str(e)})"
# 记录请求信息
logger.info(f"""
REQUEST LOG
Method: {method}
URL: {url}
Client IP: {client_ip}
Content-Type: {request.headers.get('content-type', 'N/A')}
User-Agent: {request.headers.get('user-agent', 'N/A')[:100]}
Body:
{body_content}
""")
else:
# GET 请求只记录基本信息
query_params = str(request.query_params) if request.query_params else "(none)"
logger.info(f"""
REQUEST LOG
Method: {method}
URL: {url}
Client IP: {client_ip}
Query Params: {query_params}
User-Agent: {request.headers.get('user-agent', 'N/A')[:100]}
""")
# 处理请求
response = await call_next(request)
return response
# 请求计时中间件 # 请求计时中间件
@app.middleware("http") @app.middleware("http")
async def add_process_time_header(request: Request, call_next): async def add_process_time_header(request: Request, call_next):

View File

@ -12,6 +12,7 @@ from cryptoai.utils.db_manager import get_db
from cryptoai.models.user_subscription import UserSubscriptionManager from cryptoai.models.user_subscription import UserSubscriptionManager
from datetime import timedelta from datetime import timedelta
import logging import logging
from fastapi import Request
router = APIRouter() router = APIRouter()
@ -116,9 +117,9 @@ class NotifyRequest(BaseModel):
# chain_type: str # chain_type: str
@router.post("/notify") @router.post("/notify")
async def notify(request: NotifyRequest, session: Session = Depends(get_db)): async def notify(notify: NotifyRequest, session: Session = Depends(get_db)):
try: try:
data = request.data data = notify.data
# 更新订单状态 # 更新订单状态
subscription_order_manager = SubscriptionOrderManager(session) subscription_order_manager = SubscriptionOrderManager(session)
subscription_order_manager.update_order_status(data['merchantOrderNo'], 2) subscription_order_manager.update_order_status(data['merchantOrderNo'], 2)

View File

@ -29,7 +29,7 @@ services:
cryptoai-api: cryptoai-api:
build: . build: .
container_name: cryptoai-api container_name: cryptoai-api
image: cryptoai-api:0.2.1 image: cryptoai-api:0.2.2
restart: always restart: always
ports: ports:
- "8000:8000" - "8000:8000"