feat:增加fluent日志

This commit is contained in:
2025-09-25 23:33:50 +08:00
parent 5e3dc21ed1
commit a8fdd04c41
4 changed files with 112 additions and 23 deletions

View File

@@ -1,5 +1,7 @@
FROM python:3.12-slim FROM python:3.12-slim
WORKDIR /app WORKDIR /app
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' > /etc/timezone
COPY ./packages /app/packages COPY ./packages /app/packages
COPY requirements.txt /app/ COPY requirements.txt /app/
RUN pip install --no-cache-dir --no-index --find-links=/app/packages -r requirements.txt RUN pip install --no-cache-dir --no-index --find-links=/app/packages -r requirements.txt

View File

@@ -1,8 +1,15 @@
import atexit
from fluent import sender
from loguru import logger from loguru import logger
from pathlib import Path from pathlib import Path
from config.setting import settings from config.setting import settings
FLUENTD_HOST = '14.103.235.151'
FLUENTD_PORT = 24422
TOPIC_TAG = 'blog-service'
# 日志目录 # 日志目录
LOG_DIR = Path(__file__).parent.parent.parent / "logs" LOG_DIR = Path(__file__).parent.parent.parent / "logs"
LOG_DIR.mkdir(exist_ok=True) LOG_DIR.mkdir(exist_ok=True)
@@ -24,6 +31,40 @@ FILE_FORMAT = (
"{name}:{function}:{line} - {message}" "{name}:{function}:{line} - {message}"
) )
fluent_sender = sender.FluentSender(
tag=TOPIC_TAG,
host=FLUENTD_HOST,
port=FLUENTD_PORT,
buffer_max_size=8 * 1024 * 1024,
timeout=3.0
)
def log_to_fluent(message):
try:
record = message.record
# 构建结构化日志数据
log_data = {
'topic': TOPIC_TAG,
'timestamp': record['time'].timestamp(),
'level': record['level'].name.lower(),
'message': record['message'],
'source': f"{record['file'].path}:{record['line']}",
'module': record['module'],
'function': record['function'],
'process_id': record['process'].id,
'thread_id': record['thread'].id,
**record['extra']
}
if not fluent_sender.emit(TOPIC_TAG, log_data):
print(f"Fluentd 发送失败: {fluent_sender.last_error}")
except Exception as e:
print(f"日志处理异常: {str(e)}")
# 移除默认处理器 # 移除默认处理器
logger.remove() logger.remove()
@@ -34,32 +75,42 @@ logger.add(
format=STDOUT_FORMAT, format=STDOUT_FORMAT,
colorize=True, colorize=True,
backtrace=True, # 显示完整异常堆栈 backtrace=True, # 显示完整异常堆栈
diagnose=True, # 显示详细异常信息 diagnose=True, # 显示详细异常信息
) )
# 添加文件处理器 - 常规日志
logger.add( logger.add(
sink=LOG_DIR / "app.log", log_to_fluent,
level="INFO", level="INFO", # 处理 INFO 及以上级别
format=FILE_FORMAT, format="{message}", # 原始消息(实际使用结构化数据)
rotation="10 MB", # 日志文件大小达到10MB时自动分割 backtrace=True, # 启用堆栈回溯
retention="7 days", # 保留7天的日志 diagnose=True # 显示诊断信息
compression="zip", # 归档时压缩为zip
enqueue=True, # 异步写入
serialize=False, # 不使用JSON格式
) )
# 添加文件处理器 - 错误日志 # # 添加文件处理器 - 常规日志
logger.add( # logger.add(
sink=LOG_DIR / "error.log", # sink=LOG_DIR / "app.log",
level="ERROR", # level="INFO",
format=FILE_FORMAT, # format=FILE_FORMAT,
rotation="10 MB", # rotation="10 MB", # 日志文件大小达到10MB时自动分割
retention="30 days", # retention="7 days", # 保留7天的日志
compression="zip", # compression="zip", # 归档时压缩为zip
enqueue=True, # enqueue=True, # 异步写入
serialize=False, # serialize=False, # 不使用JSON格式
) # )
#
# # 添加文件处理器 - 错误日志
# logger.add(
# sink=LOG_DIR / "error.log",
# level="ERROR",
# format=FILE_FORMAT,
# rotation="10 MB",
# retention="30 days",
# compression="zip",
# enqueue=True,
# serialize=False,
# )
atexit.register(fluent_sender.close)
# 导出配置好的logger # 导出配置好的logger
__all__ = ["logger"] __all__ = ["logger"]

View File

@@ -1 +1 @@
fastapi~=0.115.12 fastapi~=0.115.12

View File

@@ -1108,3 +1108,39 @@ category
2025-09-25 14:59:54.375 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'year': '2025'} 2025-09-25 14:59:54.375 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'year': '2025'}
2025-09-25 15:00:09.535 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10 2025-09-25 15:00:09.535 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 15:00:09.536 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'} 2025-09-25 15:00:09.536 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 22:49:58.584 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/
2025-09-25 22:50:00.691 | WARNING  | middleware.exceptions:global_exception_handler:26 - 响应: 404
2025-09-25 22:50:02.808 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/docs
2025-09-25 22:50:09.497 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/openapi.json
2025-09-25 22:50:16.478 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 22:50:18.553 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 22:50:20.723 | CRITICAL | middleware.exceptions:global_exception_handler:38 - 数据库异常: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'host.docker.internal' ([Errno 11001] getaddrinfo failed)")
(Background on this error at: https://sqlalche.me/e/20/e3q8)
2025-09-25 22:50:51.042 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 22:50:53.126 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 22:50:55.241 | CRITICAL | middleware.exceptions:global_exception_handler:38 - 数据库异常: (pymysql.err.OperationalError) (1045, "Access denied for user 'root'@'localhost' (using password: YES)")
(Background on this error at: https://sqlalche.me/e/20/e3q8)
2025-09-25 22:51:09.586 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 22:51:11.676 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 22:52:58.339 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 22:53:01.352 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 22:54:16.612 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 22:54:16.622 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 22:57:08.357 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 22:57:08.357 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 22:57:58.433 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 22:57:58.433 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 23:03:57.445 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 23:03:57.445 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 23:04:29.198 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 23:04:29.198 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 23:11:27.170 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 23:11:27.171 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 23:17:14.162 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 23:17:14.164 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 23:18:42.029 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 23:18:42.029 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 23:20:09.630 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 23:20:09.668 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}
2025-09-25 23:22:00.941 | INFO  | middleware.exceptions:global_exception_handler:18 - 请求: GET http://127.0.0.1:8082/blog/page?currentPage=1&pageSize=10
2025-09-25 23:22:00.942 | INFO  | middleware.exceptions:global_exception_handler:20 - 查询参数: {'currentPage': '1', 'pageSize': '10'}