Langchain-Chatchat/libs/chatchat-server/chatchat/utils.py

135 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from functools import partial
import logging
import os
import time
import typing as t
import loguru
import loguru._logger
from memoization import cached, CachingAlgorithmFlag
from chatchat.settings import Settings
def _filter_logs(record: dict) -> bool:
# hide debug logs if Settings.basic_settings.log_verbose=False
if record["level"].no <= 10 and not Settings.basic_settings.log_verbose:
return False
# hide traceback logs if Settings.basic_settings.log_verbose=False
if record["level"].no == 40 and not Settings.basic_settings.log_verbose:
record["exception"] = None
return True
# 默认每调用一次 build_logger 就会添加一次 hanlder导致 chatchat.log 里重复输出
@cached(max_size=100, algorithm=CachingAlgorithmFlag.LRU)
def build_logger(log_file: str = "chatchat"):
"""
build a logger with colorized output and a log file, for example:
logger = build_logger("api")
logger.info("<green>some message</green>")
user can set basic_settings.log_verbose=True to output debug logs
use logger.exception to log errors with exceptions
"""
loguru.logger._core.handlers[0]._filter = _filter_logs
logger = loguru.logger.opt(colors=True)
logger.opt = partial(loguru.logger.opt, colors=True)
logger.warn = logger.warning
# logger.error = partial(logger.exception)
if log_file:
if not log_file.endswith(".log"):
log_file = f"{log_file}.log"
if not os.path.isabs(log_file):
log_file = str((Settings.basic_settings.LOG_PATH / log_file).resolve())
logger.add(log_file, colorize=False, filter=_filter_logs)
return logger
logger = logging.getLogger(__name__)
class LoggerNameFilter(logging.Filter):
def filter(self, record):
# return record.name.startswith("{}_core") or record.name in "ERROR" or (
# record.name.startswith("uvicorn.error")
# and record.getMessage().startswith("Uvicorn running on")
# )
return True
def get_log_file(log_path: str, sub_dir: str):
"""
sub_dir should contain a timestamp.
"""
log_dir = os.path.join(log_path, sub_dir)
# Here should be creating a new directory each time, so `exist_ok=False`
os.makedirs(log_dir, exist_ok=False)
return os.path.join(log_dir, f"{sub_dir}.log")
def get_config_dict(
log_level: str, log_file_path: str, log_backup_count: int, log_max_bytes: int
) -> dict:
# for windows, the path should be a raw string.
log_file_path = (
log_file_path.encode("unicode-escape").decode()
if os.name == "nt"
else log_file_path
)
log_level = log_level.upper()
config_dict = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"formatter": {
"format": (
"%(asctime)s %(name)-12s %(process)d %(levelname)-8s %(message)s"
)
},
},
"filters": {
"logger_name_filter": {
"()": __name__ + ".LoggerNameFilter",
},
},
"handlers": {
"stream_handler": {
"class": "logging.StreamHandler",
"formatter": "formatter",
"level": log_level,
# "stream": "ext://sys.stdout",
# "filters": ["logger_name_filter"],
},
"file_handler": {
"class": "logging.handlers.RotatingFileHandler",
"formatter": "formatter",
"level": log_level,
"filename": log_file_path,
"mode": "a",
"maxBytes": log_max_bytes,
"backupCount": log_backup_count,
"encoding": "utf8",
},
},
"loggers": {
"chatchat_core": {
"handlers": ["stream_handler", "file_handler"],
"level": log_level,
"propagate": False,
}
},
"root": {
"level": log_level,
"handlers": ["stream_handler", "file_handler"],
},
}
return config_dict
def get_timestamp_ms():
t = time.time()
return int(round(t * 1000))