Files
ecm_sync_system/sync_state_machine/logging.py
T
2026-04-01 16:23:43 +08:00

111 lines
3.3 KiB
Python

from __future__ import annotations
import logging
from pathlib import Path
from typing import Optional
APP_LOGGER_NAME = "sync_state_machine"
class _NodeLogFilter(logging.Filter):
def filter(self, record: logging.LogRecord) -> bool:
message = record.getMessage()
if "node=" in message:
return False
if "节点 " in message and "状态" in message:
return False
return True
def get_app_logger() -> logging.Logger:
return logging.getLogger(APP_LOGGER_NAME)
def get_logger(name: Optional[str] = None) -> logging.Logger:
if not name or name == "__main__":
return get_app_logger()
if name == APP_LOGGER_NAME or name.startswith(f"{APP_LOGGER_NAME}."):
return logging.getLogger(name)
return logging.getLogger(f"{APP_LOGGER_NAME}.{name}")
def clear_app_logger_handlers(logger: Optional[logging.Logger] = None) -> None:
target = logger or get_app_logger()
handlers = list(target.handlers)
for handler in handlers:
target.removeHandler(handler)
try:
handler.close()
except Exception:
pass
target.propagate = True
def init_app_logger(
*,
log_file_path: Optional[str] = None,
level: int = logging.INFO,
mirror_console: bool = True,
replace_handlers: bool = True,
suppress_node_logs: bool = True,
) -> logging.Logger:
logger = get_app_logger()
logger.setLevel(level)
logger.propagate = False
if logger.handlers and not replace_handlers:
return logger
if replace_handlers:
clear_app_logger_handlers(logger)
formatter = logging.Formatter("%(message)s")
node_filter = _NodeLogFilter() if suppress_node_logs else None
if mirror_console:
console_handler = logging.StreamHandler()
console_handler.setLevel(level)
console_handler.setFormatter(formatter)
if node_filter is not None:
console_handler.addFilter(node_filter)
logger.addHandler(console_handler)
if log_file_path:
path = Path(log_file_path)
path.parent.mkdir(parents=True, exist_ok=True)
file_handler = logging.FileHandler(path, mode="w", encoding="utf-8")
file_handler.setLevel(level)
file_handler.setFormatter(formatter)
if node_filter is not None:
file_handler.addFilter(node_filter)
logger.addHandler(file_handler)
return logger
def configure_app_logging(config, *, replace_handlers: bool = False, mirror_console: bool = True) -> logging.Logger:
if not getattr(config, "initialize", True):
return get_app_logger()
if not getattr(config, "file_path", None):
from .config.logging_config import resolve_log_file_path
config.file_path = resolve_log_file_path(config)
return init_app_logger(
log_file_path=config.file_path,
level=config.level,
mirror_console=mirror_console,
replace_handlers=replace_handlers,
suppress_node_logs=config.suppress_node_logs,
)
def ensure_app_logging(config, *, mirror_console: bool = True) -> logging.Logger:
logger = get_app_logger()
if not getattr(config, "initialize", True):
return logger
if logger.handlers:
return logger
return configure_app_logging(config, replace_handlers=False, mirror_console=mirror_console)