125 lines
3.0 KiB
Markdown
125 lines
3.0 KiB
Markdown
# 日志系统
|
||
|
||
:::tip 说明
|
||
项目通过 Python 标准库 `logging` 实现结构化日志,支持控制台 + 文件双输出,日志文件按大小自动轮转。配置入口位于 `src/core/logger.py`。
|
||
:::
|
||
|
||
## 配置入口
|
||
|
||
日志配置位于 `src/core/logger.py`:
|
||
|
||
```python
|
||
import logging
|
||
import sys
|
||
from logging.handlers import RotatingFileHandler
|
||
from pathlib import Path
|
||
|
||
# 日志目录
|
||
LOG_DIR = Path(__file__).resolve().parents[2] / "logs"
|
||
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
||
|
||
# 日志格式
|
||
_FORMAT = "%(asctime)s | %(levelname)-7s | %(name)s | %(message)s"
|
||
|
||
# 轮转配置
|
||
LOG_MAX_BYTES = 10 * 1024 * 1024 # 10MB
|
||
LOG_BACKUP_COUNT = 5
|
||
```
|
||
|
||
## setup_logging()
|
||
|
||
```python
|
||
def setup_logging(level: int = logging.INFO, log_file: str = "app.log") -> None:
|
||
"""
|
||
配置全局日志:root logger 输出到控制台与文件
|
||
|
||
Args:
|
||
level: 日志级别(默认 INFO)
|
||
log_file: 日志文件名(位于 logs/ 目录下)
|
||
"""
|
||
```
|
||
|
||
### 控制台输出
|
||
|
||
```python
|
||
console = logging.StreamHandler(sys.stdout)
|
||
console.setFormatter(formatter)
|
||
root.addHandler(console)
|
||
```
|
||
|
||
### 文件输出(按大小轮转)
|
||
|
||
```python
|
||
file_handler = RotatingFileHandler(
|
||
LOG_DIR / log_file,
|
||
maxBytes=LOG_MAX_BYTES, # 单文件上限 10MB
|
||
backupCount=LOG_BACKUP_COUNT, # 保留 5 份备份
|
||
encoding="utf-8",
|
||
)
|
||
```
|
||
|
||
## 日志轮转
|
||
|
||
当日志文件达到 10MB 时自动轮转:
|
||
|
||
```
|
||
logs/app.log ← 当前日志
|
||
logs/app.log.1 ← 最近一次轮转
|
||
logs/app.log.2 ← 倒数第二次
|
||
logs/app.log.3
|
||
logs/app.log.4
|
||
logs/app.log.5 ← 最早的备份(超过自动删除)
|
||
```
|
||
|
||
## 日志格式
|
||
|
||
```
|
||
2025-03-06 14:30:25,123 | INFO | modules.system.user.service | 用户登录成功
|
||
```
|
||
|
||
格式说明:
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `asctime` | 时间戳 |
|
||
| `levelname` | 日志级别(右对齐7字符) |
|
||
| `name` | 模块名称 |
|
||
| `message` | 日志内容 |
|
||
|
||
## 使用方式
|
||
|
||
在各模块中获取 logger:
|
||
|
||
```python
|
||
import logging
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
logger.info("操作成功")
|
||
logger.warning("配置缺失")
|
||
logger.error(f"异常信息: {str(e)}")
|
||
```
|
||
|
||
## 框架日志集成
|
||
|
||
Flask 和 SQLAlchemy 的默认日志统一走 root logger:
|
||
|
||
```python
|
||
for name in ("flask", "sqlalchemy"):
|
||
lg = logging.getLogger(name)
|
||
lg.handlers.clear()
|
||
lg.propagate = True
|
||
```
|
||
|
||
:::tip 温馨提示
|
||
`setup_logging()` 会检查是否已添加 handler(通过 `_djangoadmin` 标记),避免重复添加。可在应用启动时调用一次。
|
||
:::
|
||
|
||
## 操作日志
|
||
|
||
除了应用日志外,还通过 `src/middleware/operation_log.py` 中间件自动记录用户的写操作日志,存储到数据库 `flask_operation_log` 表中。详见 [操作日志](/zh/volume4/core/operation-log) 章节。
|
||
|
||
## 总结
|
||
|
||
日志系统通过 `RotatingFileHandler` 实现按大小轮转,单文件上限 10MB 保留 5 份备份,防止日志无限增长撑爆磁盘。控制台和文件双输出,格式统一包含时间戳、级别、模块名和消息内容。
|