feat: 添加日志处理器适配功能,统一第三方库日志输出
This commit is contained in:
@@ -430,6 +430,52 @@ def reconfigure_existing_loggers():
|
|||||||
logger_obj.addHandler(handler)
|
logger_obj.addHandler(handler)
|
||||||
|
|
||||||
|
|
||||||
|
def adopt_library_logger(logger_name: str, handler_names: Optional[set[str]] = None):
|
||||||
|
"""移除第三方库自带 handler,让日志统一走根 logger。"""
|
||||||
|
logger_obj = logging.getLogger(logger_name)
|
||||||
|
|
||||||
|
for handler in logger_obj.handlers[:]:
|
||||||
|
handler_name = getattr(handler, "name", "")
|
||||||
|
if handler_names is not None and handler_name not in handler_names:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if hasattr(handler, "close"):
|
||||||
|
handler.close()
|
||||||
|
logger_obj.removeHandler(handler)
|
||||||
|
|
||||||
|
logger_obj.propagate = True
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_embedded_event_dict(logger, method_name, event_dict):
|
||||||
|
"""将嵌套在 event 字段中的结构化日志还原为可读文本。"""
|
||||||
|
record = event_dict.get("_record")
|
||||||
|
if record is not None and isinstance(getattr(record, "msg", None), dict):
|
||||||
|
embedded_event = record.msg
|
||||||
|
else:
|
||||||
|
embedded_event = event_dict.get("event")
|
||||||
|
|
||||||
|
if not isinstance(embedded_event, dict):
|
||||||
|
return event_dict
|
||||||
|
|
||||||
|
event_text = embedded_event.get("event")
|
||||||
|
if event_text is not None:
|
||||||
|
event_dict["event"] = event_text
|
||||||
|
else:
|
||||||
|
event_dict["event"] = str(embedded_event)
|
||||||
|
|
||||||
|
for field_name in ("logger_name", "module", "lineno", "pathname"):
|
||||||
|
if field_name not in event_dict and field_name in embedded_event:
|
||||||
|
event_dict[field_name] = embedded_event[field_name]
|
||||||
|
|
||||||
|
for key, value in embedded_event.items():
|
||||||
|
if key in {"event", "level", "timestamp", "logger_name", "module", "lineno", "pathname"}:
|
||||||
|
continue
|
||||||
|
if key not in event_dict:
|
||||||
|
event_dict[key] = value
|
||||||
|
|
||||||
|
return event_dict
|
||||||
|
|
||||||
|
|
||||||
def convert_pathname_to_module(logger, method_name, event_dict):
|
def convert_pathname_to_module(logger, method_name, event_dict):
|
||||||
# sourcery skip: extract-method, use-string-remove-affix
|
# sourcery skip: extract-method, use-string-remove-affix
|
||||||
"""将 pathname 转换为模块风格的路径"""
|
"""将 pathname 转换为模块风格的路径"""
|
||||||
@@ -657,6 +703,7 @@ file_formatter = structlog.stdlib.ProcessorFormatter(
|
|||||||
structlog.stdlib.add_logger_name,
|
structlog.stdlib.add_logger_name,
|
||||||
structlog.stdlib.add_log_level,
|
structlog.stdlib.add_log_level,
|
||||||
structlog.stdlib.PositionalArgumentsFormatter(),
|
structlog.stdlib.PositionalArgumentsFormatter(),
|
||||||
|
normalize_embedded_event_dict,
|
||||||
structlog.processors.TimeStamper(fmt="iso"),
|
structlog.processors.TimeStamper(fmt="iso"),
|
||||||
structlog.processors.CallsiteParameterAdder(
|
structlog.processors.CallsiteParameterAdder(
|
||||||
parameters=[structlog.processors.CallsiteParameter.PATHNAME, structlog.processors.CallsiteParameter.LINENO]
|
parameters=[structlog.processors.CallsiteParameter.PATHNAME, structlog.processors.CallsiteParameter.LINENO]
|
||||||
@@ -674,6 +721,8 @@ console_formatter = structlog.stdlib.ProcessorFormatter(
|
|||||||
structlog.stdlib.add_logger_name,
|
structlog.stdlib.add_logger_name,
|
||||||
structlog.stdlib.add_log_level,
|
structlog.stdlib.add_log_level,
|
||||||
structlog.stdlib.PositionalArgumentsFormatter(),
|
structlog.stdlib.PositionalArgumentsFormatter(),
|
||||||
|
normalize_embedded_event_dict,
|
||||||
|
convert_pathname_to_module,
|
||||||
structlog.processors.TimeStamper(fmt=get_timestamp_format(), utc=False),
|
structlog.processors.TimeStamper(fmt=get_timestamp_format(), utc=False),
|
||||||
structlog.processors.StackInfoRenderer(),
|
structlog.processors.StackInfoRenderer(),
|
||||||
structlog.processors.format_exc_info,
|
structlog.processors.format_exc_info,
|
||||||
@@ -715,6 +764,9 @@ def _immediate_setup():
|
|||||||
# 清理重复的handler
|
# 清理重复的handler
|
||||||
remove_duplicate_handlers()
|
remove_duplicate_handlers()
|
||||||
|
|
||||||
|
# maim_message 导入时会给同名 stdlib logger 挂默认 handler,这里统一收口。
|
||||||
|
adopt_library_logger("maim_message", handler_names={"maim_message_default_handler"})
|
||||||
|
|
||||||
# 配置第三方库日志
|
# 配置第三方库日志
|
||||||
configure_third_party_loggers()
|
configure_third_party_loggers()
|
||||||
|
|
||||||
@@ -734,6 +786,8 @@ def get_logger(name: Optional[str]) -> structlog.stdlib.BoundLogger:
|
|||||||
"""获取logger实例,支持按名称绑定"""
|
"""获取logger实例,支持按名称绑定"""
|
||||||
if name is None:
|
if name is None:
|
||||||
return raw_logger
|
return raw_logger
|
||||||
|
if name == "maim_message":
|
||||||
|
adopt_library_logger(name, handler_names={"maim_message_default_handler"})
|
||||||
logger = binds.get(name) # type: ignore
|
logger = binds.get(name) # type: ignore
|
||||||
if logger is None:
|
if logger is None:
|
||||||
logger: structlog.stdlib.BoundLogger = structlog.get_logger(name).bind(logger_name=name)
|
logger: structlog.stdlib.BoundLogger = structlog.get_logger(name).bind(logger_name=name)
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ from maim_message import MessageServer
|
|||||||
import traceback
|
import traceback
|
||||||
import importlib.metadata
|
import importlib.metadata
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import adopt_library_logger, get_logger
|
||||||
from src.common.utils.port_checker import assert_port_available
|
from src.common.utils.port_checker import assert_port_available
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
from .server import get_global_server
|
from .server import get_global_server
|
||||||
|
|
||||||
global_api = None
|
global_api = None
|
||||||
|
adopt_library_logger("maim_message", handler_names={"maim_message_default_handler"})
|
||||||
|
|
||||||
|
|
||||||
def get_global_api() -> MessageServer: # sourcery skip: extract-method
|
def get_global_api() -> MessageServer: # sourcery skip: extract-method
|
||||||
|
|||||||
Reference in New Issue
Block a user