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 logging
import uvicorn
import json
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
@ -34,6 +35,9 @@ logging.basicConfig(
)
logger = logging.getLogger("fastapi")
# 配置选项
LOG_REQUEST_BODY = os.environ.get("LOG_REQUEST_BODY", "true").lower() == "true"
# 创建FastAPI应用
app = FastAPI(
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(alltick_router, prefix="/alltick", tags=["AllTick数据"])
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")
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 datetime import timedelta
import logging
from fastapi import Request
router = APIRouter()
@ -116,9 +117,9 @@ class NotifyRequest(BaseModel):
# chain_type: str
@router.post("/notify")
async def notify(request: NotifyRequest, session: Session = Depends(get_db)):
async def notify(notify: NotifyRequest, session: Session = Depends(get_db)):
try:
data = request.data
data = notify.data
# 更新订单状态
subscription_order_manager = SubscriptionOrderManager(session)
subscription_order_manager.update_order_status(data['merchantOrderNo'], 2)

View File

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