Some checks failed
Pre-commit / run (ubuntu-latest) (push) Has been cancelled
Deploy Sphinx documentation to Pages / build_en (ubuntu-latest, 3.10) (push) Has been cancelled
Deploy Sphinx documentation to Pages / build_zh (ubuntu-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.12) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.12) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.12) (push) Has been cancelled
117 lines
3.7 KiB
Python
117 lines
3.7 KiB
Python
import logging
|
|
import sys
|
|
|
|
|
|
class _StreamColorizer:
|
|
RESET = "\033[0m"
|
|
C_AI_THINK = "\033[33m" # yellow
|
|
C_INBOUND = "\033[36m" # cyan
|
|
C_OUTBOUND = "\033[32m" # green
|
|
|
|
def __init__(self, stream):
|
|
self.stream = stream
|
|
|
|
def write(self, data):
|
|
if not data:
|
|
return
|
|
out = str(data)
|
|
if "\x1b[" in out:
|
|
self.stream.write(out)
|
|
return
|
|
if "(thinking):" in out:
|
|
out = f"{self.C_AI_THINK}{out}{self.RESET}"
|
|
elif "[收消息]" in out:
|
|
out = f"{self.C_INBOUND}{out}{self.RESET}"
|
|
elif "[发送]" in out:
|
|
out = f"{self.C_OUTBOUND}{out}{self.RESET}"
|
|
self.stream.write(out)
|
|
|
|
def flush(self):
|
|
self.stream.flush()
|
|
|
|
def isatty(self):
|
|
return getattr(self.stream, "isatty", lambda: False)()
|
|
|
|
@property
|
|
def encoding(self):
|
|
return getattr(self.stream, "encoding", "utf-8")
|
|
|
|
|
|
_stream_color_installed = False
|
|
|
|
|
|
def install_stream_colorizer() -> None:
|
|
global _stream_color_installed
|
|
if _stream_color_installed:
|
|
return
|
|
try:
|
|
sys.stdout = _StreamColorizer(sys.stdout)
|
|
sys.stderr = _StreamColorizer(sys.stderr)
|
|
_stream_color_installed = True
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
class _ColorFormatter(logging.Formatter):
|
|
RESET = "\033[0m"
|
|
C_INFO = "\033[36m" # cyan
|
|
C_WARN = "\033[33m" # yellow
|
|
C_ERR = "\033[31m" # red
|
|
C_EVENT = "\033[35m" # magenta
|
|
C_DRAW = "\033[34m" # blue
|
|
C_PRICE = "\033[32m" # green
|
|
|
|
def format(self, record: logging.LogRecord) -> str:
|
|
base = super().format(record)
|
|
msg = str(record.getMessage() or "")
|
|
if msg.startswith("[活动日志]"):
|
|
return f"{self.C_EVENT}{base}{self.RESET}"
|
|
if msg.startswith("[作图]"):
|
|
return f"{self.C_DRAW}{base}{self.RESET}"
|
|
if msg.startswith("[价格]"):
|
|
return f"{self.C_PRICE}{base}{self.RESET}"
|
|
if record.levelno >= logging.ERROR:
|
|
return f"{self.C_ERR}{base}{self.RESET}"
|
|
if record.levelno >= logging.WARNING:
|
|
return f"{self.C_WARN}{base}{self.RESET}"
|
|
return f"{self.C_INFO}{base}{self.RESET}"
|
|
|
|
|
|
def setup_logger() -> logging.Logger:
|
|
install_stream_colorizer()
|
|
logger = logging.getLogger("qingjian_cs")
|
|
if logger.handlers:
|
|
return logger
|
|
logger.setLevel(logging.INFO)
|
|
handler = logging.StreamHandler(sys.stdout)
|
|
formatter = _ColorFormatter("[%(asctime)s] %(levelname)s: %(message)s", "%H:%M:%S")
|
|
handler.setFormatter(formatter)
|
|
logger.addHandler(handler)
|
|
logger.propagate = False
|
|
|
|
# 降低 AgentScope 内部推理/格式器日志噪音,保留本项目活动日志。
|
|
logging.getLogger("agentscope").setLevel(logging.ERROR)
|
|
logging.getLogger("agentscope.formatter").setLevel(logging.ERROR)
|
|
logging.getLogger("agentscope.agent").setLevel(logging.ERROR)
|
|
fmt_logger = logging.getLogger("_openai_formatter")
|
|
fmt_logger.setLevel(logging.CRITICAL)
|
|
fmt_logger.propagate = False
|
|
fmt_logger.disabled = True
|
|
fmt_logger.handlers.clear()
|
|
fmt_logger.addHandler(logging.NullHandler())
|
|
logging.getLogger("_react_agent").setLevel(logging.ERROR)
|
|
logging.getLogger("httpx").setLevel(logging.ERROR)
|
|
logging.getLogger("urllib3").setLevel(logging.ERROR)
|
|
|
|
# 兜底:把当前已注册的同类噪声 logger 一并禁掉
|
|
for name in list(logging.root.manager.loggerDict.keys()):
|
|
if "_openai_formatter" in name:
|
|
lg = logging.getLogger(name)
|
|
lg.setLevel(logging.CRITICAL)
|
|
lg.propagate = False
|
|
lg.disabled = True
|
|
lg.handlers.clear()
|
|
lg.addHandler(logging.NullHandler())
|
|
|
|
return logger
|