from odoo import models, fields, api import json, ast import logging import requests _logger = logging.getLogger(__name__) class ApiRequestLog(models.Model): _name = 'api.request.log' _description = '接口请求日志' _order = 'id desc' name = fields.Char('接口名称') path = fields.Char('请求路径') method = fields.Char('请求方法') request_data = fields.Text('请求数据') response_data = fields.Text('响应数据') remote_addr = fields.Char('客户端IP') response_time = fields.Float('响应时间(秒)', digits=(16, 6)) status = fields.Integer('状态码') requester = fields.Char('请求方') responser = fields.Char('响应方') @api.model def log_request(self, method, url, name=None, responser=None, **kwargs): # Log the request request_headers = kwargs.get('headers', {}) request_body = kwargs.get('json') or kwargs.get('params') or {} _logger.info(f"Request: {method} {url} Headers: {request_headers} Body: {request_body}") # Make the actual request response = requests.request(method, url, **kwargs) # Log the response response_status = response.status_code response_headers = response.headers response_body = response.text response_time = response.elapsed.total_seconds() _logger.info(f"Response: Status: {response_status} Headers: {response_headers} Body: {response_body}") try: # 如果是字符串,先尝试用 ast.literal_eval 安全地转换成 Python 对象 if isinstance(response_body, str): response_body_obj = json.loads(response_body) else: response_body_obj = response_body # 再使用 json.dumps 转换成标准的 JSON 字符串 response_body = json.dumps(response_body_obj, ensure_ascii=False) except Exception as e: _logger.warning(f"转换 response_body 到标准 JSON 失败: {str(e)}") # 如果转换失败,保持原样 # Save to database self.sudo().create({ 'name': name, 'path': url, 'method': method.upper(), 'request_data': request_body, 'response_data': response_body, 'remote_addr': None, 'response_time': response_time, 'status': response_status, 'requester': '智能工厂', 'responser': responser }) return response