104 lines
3.7 KiB
Python
104 lines
3.7 KiB
Python
|
|
from functools import wraps
|
|||
|
|
from flask import request, g
|
|||
|
|
import json
|
|||
|
|
|
|||
|
|
from flask_jwt_extended import current_user
|
|||
|
|
from app.models import OperationHistory, User
|
|||
|
|
|
|||
|
|
from app import db,jwt
|
|||
|
|
|
|||
|
|
def log_operation(func):
|
|||
|
|
@wraps(func)
|
|||
|
|
def decorated(*args, **kwargs):
|
|||
|
|
log_entry = OperationHistory(
|
|||
|
|
api_path=request.path,
|
|||
|
|
http_method=request.method,
|
|||
|
|
ip_address=request.remote_addr,
|
|||
|
|
request_params=None
|
|||
|
|
# 用户信息暂留空
|
|||
|
|
)
|
|||
|
|
# 记录GET参数
|
|||
|
|
if request.method == "GET":
|
|||
|
|
log_entry.request_params = request.args.to_dict()
|
|||
|
|
|
|||
|
|
# 记录POST参数(支持JSON/表单/原始数据)
|
|||
|
|
elif request.method == "POST":
|
|||
|
|
if request.is_json:
|
|||
|
|
res=request.get_json(silent=True) or None
|
|||
|
|
json_str = json.dumps(res,ensure_ascii=False)
|
|||
|
|
log_entry.request_params = json_str
|
|||
|
|
elif request.form:
|
|||
|
|
json_str = json.dumps(request.form.to_dict(),ensure_ascii=False)
|
|||
|
|
log_entry.request_params =json_str
|
|||
|
|
elif request.data:
|
|||
|
|
json_str = json.dumps({"raw_data": request.data.decode('utf-8')[:500]},ensure_ascii=False)
|
|||
|
|
# 原始数据截取前500字符
|
|||
|
|
log_entry.request_params =json_str
|
|||
|
|
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
response = func(*args, **kwargs) # 执行原函数(触发 JWT 验证)
|
|||
|
|
log_entry.user_id = current_user.id # 此时 current_user 已就绪
|
|||
|
|
log_entry.username = current_user.username
|
|||
|
|
log_entry.response_code = response.status_code
|
|||
|
|
return response
|
|||
|
|
except Exception as e:
|
|||
|
|
log_entry.error_message = str(e)
|
|||
|
|
log_entry.operation_result = 0
|
|||
|
|
raise
|
|||
|
|
finally:
|
|||
|
|
db.session.add(log_entry)
|
|||
|
|
db.session.commit()
|
|||
|
|
return decorated
|
|||
|
|
|
|||
|
|
|
|||
|
|
# def log_operation(func):
|
|||
|
|
# @wraps(func)
|
|||
|
|
# def decorated(*args, **kwargs):
|
|||
|
|
# # 初始化日志对象(示例结构)
|
|||
|
|
# log_entry = {
|
|||
|
|
# "path": request.path,
|
|||
|
|
# "method": request.method,
|
|||
|
|
# "ip": request.remote_addr,
|
|||
|
|
# "params": None # 待填充
|
|||
|
|
# }
|
|||
|
|
|
|||
|
|
# try:
|
|||
|
|
# # ---- 核心:记录请求参数 ----
|
|||
|
|
# if request.method == "GET":
|
|||
|
|
# params = request.args.to_dict()
|
|||
|
|
# log_entry["params"] = filter_sensitive_data(params)
|
|||
|
|
|
|||
|
|
# elif request.method == "POST":
|
|||
|
|
# if request.is_json:
|
|||
|
|
# json_data = request.get_json(silent=True) or {}
|
|||
|
|
# log_entry["params"] = filter_sensitive_data(json_data)
|
|||
|
|
# elif request.form:
|
|||
|
|
# form_data = request.form.to_dict()
|
|||
|
|
# log_entry["params"] = filter_sensitive_data(form_data)
|
|||
|
|
# elif request.files:
|
|||
|
|
# log_entry["files"] = [f.filename for f in request.files.values()]
|
|||
|
|
|
|||
|
|
# # ---- 执行原函数 ----
|
|||
|
|
# start_time = time()
|
|||
|
|
# response = func(*args, **kwargs)
|
|||
|
|
# duration = time() - start_time
|
|||
|
|
|
|||
|
|
# # ---- 记录响应 ----
|
|||
|
|
# log_entry["status"] = response.status_code
|
|||
|
|
# log_entry["duration"] = f"{duration:.3f}s"
|
|||
|
|
# return response
|
|||
|
|
|
|||
|
|
# except Exception as e:
|
|||
|
|
# log_entry["error"] = str(e)
|
|||
|
|
# raise
|
|||
|
|
# finally:
|
|||
|
|
# # 实际存储到数据库/文件(此处打印示例)
|
|||
|
|
# current_app.logger.info(json.dumps(log_entry, ensure_ascii=False))
|
|||
|
|
|
|||
|
|
# return decorated
|
|||
|
|
|
|||
|
|
# JWT 用户回调
|
|||
|
|
@jwt.user_lookup_loader
|
|||
|
|
def load_user(jwt_header, jwt_data):
|
|||
|
|
return User.query.get(jwt_data["sub"])
|