# -*- coding: utf-8 -*- import logging import sys from odoo import models, fields, api, SUPERUSER_ID _logger_db = logging.getLogger('yuthon.db_log') class SystemLogs(models.Model): _name = 'system.logs' _description = '系统日志' _order = 'date desc' name = fields.Char(string="标题") date = fields.Datetime(string="时间", default=fields.Datetime.now) level = fields.Char(string="级别") logger_name = fields.Char(string="来源") content = fields.Text(string="内容") class OdooDBLogHandler(logging.Handler): """将日志写入 system.logs 模型""" def emit(self, record): if record.levelno < logging.INFO: return try: import odoo db_name = getattr(odoo.tools.config, 'db_name', None) if not db_name: return db = odoo.sql_db.db_connect(db_name) with db.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) msg = record.getMessage() or '' env['system.logs'].create({ 'name': msg[:80], 'date': fields.Datetime.now(), 'level': record.levelname, 'logger_name': record.name, 'content': msg, }) cr.commit() except Exception as e: # 写 DB 失败时 fallback 到 stderr,避免静默吞掉 sys.stderr.write(f"[system.logs] DB write failed: {e}\n") # 注册 Handler(只注册一次) _handler_key = 'odoo_db_log_handler' _root_logger = logging.getLogger() if not any(getattr(h, 'name', None) == _handler_key for h in _root_logger.handlers): handler = OdooDBLogHandler() handler.name = _handler_key handler.setLevel(logging.INFO) _root_logger.addHandler(handler) sys.stderr.write("[system.logs] Handler registered\n")