diff --git a/backend/common/log.py b/backend/common/log.py index d3013f09..fd0fe738 100644 --- a/backend/common/log.py +++ b/backend/common/log.py @@ -8,8 +8,9 @@ from asgi_correlation_id import correlation_id from loguru import logger -from backend.core import path_conf from backend.core.conf import settings +from backend.core.path_conf import LOG_DIR +from backend.utils.timezone import timezone class InterceptHandler(logging.Handler): @@ -58,11 +59,11 @@ def setup_logging() -> None: # Debug log handlers # logging.debug(f'{logging.getLogger(name)}, {logging.getLogger(name).propagate}') - # 定义 correlation_id 默认过滤函数 + # correlation_id 过滤器 # https://github.com/snok/asgi-correlation-id/issues/7 def correlation_id_filter(record): - cid = correlation_id.get(settings.LOG_CID_DEFAULT_VALUE) - record['correlation_id'] = cid[: settings.LOG_CID_UUID_LENGTH] + cid = correlation_id.get(settings.TRACE_ID_LOG_DEFAULT_VALUE) + record['correlation_id'] = cid[: settings.TRACE_ID_LOG_UUID_LENGTH] return record # 配置 loguru 处理器 @@ -81,13 +82,20 @@ def correlation_id_filter(record): def set_custom_logfile() -> None: """设置自定义日志文件""" - log_path = path_conf.LOG_DIR - if not os.path.exists(log_path): - os.mkdir(log_path) + if not os.path.exists(LOG_DIR): + os.mkdir(LOG_DIR) # 日志文件 - log_access_file = os.path.join(log_path, settings.LOG_ACCESS_FILENAME) - log_error_file = os.path.join(log_path, settings.LOG_ERROR_FILENAME) + log_access_file = os.path.join(LOG_DIR, settings.LOG_ACCESS_FILENAME) + log_error_file = os.path.join(LOG_DIR, settings.LOG_ERROR_FILENAME) + + # 日志压缩回调 + def compression(filepath): + filename = filepath.split(os.sep)[-1] + original_filename = filename.split('.')[0] + if '-' in original_filename: + return os.path.join(LOG_DIR, f'{original_filename}.log') + return os.path.join(LOG_DIR, f'{original_filename}_{timezone.now().strftime("%Y-%m-%d")}.log') # 日志文件通用配置 # https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.add @@ -96,7 +104,7 @@ def set_custom_logfile() -> None: 'enqueue': True, 'rotation': '00:00', 'retention': '7 days', - 'compression': 'tar.gz', + 'compression': lambda filepath: os.rename(filepath, compression(filepath)), } # 标准输出文件 diff --git a/backend/core/conf.py b/backend/core/conf.py index 64b84295..9f011eb0 100644 --- a/backend/core/conf.py +++ b/backend/core/conf.py @@ -143,16 +143,17 @@ class Settings(BaseSettings): IP_LOCATION_REDIS_PREFIX: str = 'fba:ip:location' IP_LOCATION_EXPIRE_SECONDS: int = 60 * 60 * 24 # 1 天 - # 追踪 ID + # 日志(Trace ID) TRACE_ID_REQUEST_HEADER_KEY: str = 'X-Request-ID' + TRACE_ID_LOG_DEFAULT_VALUE: str = '-' + TRACE_ID_LOG_UUID_LENGTH: int = 32 # UUID 长度,必须小于等于 32 - # 日志 - LOG_CID_DEFAULT_VALUE: str = '-' - LOG_CID_UUID_LENGTH: int = 32 # 日志 correlation_id 长度,必须小于等于 32 + # 日志(控制台) LOG_STD_LEVEL: str = 'INFO' LOG_STD_FORMAT: str = ( '{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {correlation_id} | {message}' ) + # 日志(文件) LOG_ACCESS_FILE_LEVEL: str = 'INFO' LOG_ERROR_FILE_LEVEL: str = 'ERROR' LOG_ACCESS_FILENAME: str = 'fba_access.log' diff --git a/backend/middleware/access_middleware.py b/backend/middleware/access_middleware.py index 71f7d697..2fc1b879 100644 --- a/backend/middleware/access_middleware.py +++ b/backend/middleware/access_middleware.py @@ -23,8 +23,7 @@ async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) - path = request.url.path if not request.url.query else request.url.path + '/' + request.url.query if request.method != 'OPTIONS': - log.info(f'--> 请求开始[{path}]') - log.info(f'请求方式:[{request.method}]') + log.debug(f'--> 请求开始[{path}]') perf_time = time.perf_counter() request.state.perf_time = perf_time @@ -37,8 +36,11 @@ async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) - elapsed = (time.perf_counter() - perf_time) * 1000 if request.method != 'OPTIONS': - log.info(f'接口耗时:[{elapsed:.3f}]ms') - log.info(f'接口状态:[{response.status_code}]') - log.info('<-- 请求结束') + log.debug('<-- 请求结束') + + log.info( + f'{request.client.host: <15} | {request.method: <8} | {response.status_code: <6} | ' + f'{path} | {elapsed:.3f}ms' + ) return response diff --git a/backend/middleware/opera_log_middleware.py b/backend/middleware/opera_log_middleware.py index 43eea950..926a5d2f 100644 --- a/backend/middleware/opera_log_middleware.py +++ b/backend/middleware/opera_log_middleware.py @@ -82,6 +82,7 @@ async def dispatch(self, request: Request, call_next: Any) -> Response: username = None # 日志记录 + log.debug(f'接口摘要:[{summary}]') log.debug(f'请求地址:[{request.state.ip}]') log.debug(f'请求参数:{args}') diff --git a/backend/utils/trace_id.py b/backend/utils/trace_id.py index 4f683b9b..0270750a 100644 --- a/backend/utils/trace_id.py +++ b/backend/utils/trace_id.py @@ -12,4 +12,4 @@ def get_request_trace_id(request: Request) -> str: :param request: FastAPI 请求对象 :return: """ - return request.headers.get(settings.TRACE_ID_REQUEST_HEADER_KEY) or settings.LOG_CID_DEFAULT_VALUE + return request.headers.get(settings.TRACE_ID_REQUEST_HEADER_KEY) or settings.TRACE_ID_LOG_DEFAULT_VALUE