Skip to content

Update the log output default style #714

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions backend/common/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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 处理器
Expand All @@ -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
Expand All @@ -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)),
}

# 标准输出文件
Expand Down
9 changes: 5 additions & 4 deletions backend/core/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = (
'<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</> | <lvl>{level: <8}</> | <cyan>{correlation_id}</> | <lvl>{message}</>'
)
# 日志(文件)
LOG_ACCESS_FILE_LEVEL: str = 'INFO'
LOG_ERROR_FILE_LEVEL: str = 'ERROR'
LOG_ACCESS_FILENAME: str = 'fba_access.log'
Expand Down
12 changes: 7 additions & 5 deletions backend/middleware/access_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
1 change: 1 addition & 0 deletions backend/middleware/opera_log_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}')

Expand Down
2 changes: 1 addition & 1 deletion backend/utils/trace_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -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