import functools import json import logging from datetime import datetime from odoo.http import request _logger = logging.getLogger(__name__) def api_log(name=None, requester=None): """记录API请求日志的装饰器""" def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): start_time = datetime.now() # 获取请求信息 try: # 获取请求数据 request_data = json.loads(request.httprequest.data) if request.httprequest.data else {} # 获取请求路径 path = request.httprequest.path # 获取请求方法 method = request.httprequest.method # 获取客户端IP remote_addr = request.httprequest.remote_addr # 执行原始函数 result = func(*args, **kwargs) origin_result = result if isinstance(result, str): result = json.loads(result) # 计算响应时间 end_time = datetime.now() response_time = (end_time - start_time).total_seconds() # 创建日志记录 log_vals = { 'name': name or func.__name__, 'path': path, 'method': method, 'request_data': json.dumps(request_data, ensure_ascii=False), 'response_data': json.dumps(result, ensure_ascii=False), 'remote_addr': remote_addr, 'response_time': response_time, 'status': result.get('code') or result.get('ErrorCode') or 500, 'requester': requester, 'responser': '智能工厂' } # 异步创建日志记录 request.env['api.request.log'].sudo().with_context(tracking_disable=True).create(log_vals) return origin_result except Exception as e: _logger.error(f"API日志记录失败: {str(e)}") # 即使日志记录失败,也要返回原始结果 return func(*args, **kwargs) return wrapper return decorator