chore: initialize insar management system v2
This commit is contained in:
@@ -0,0 +1,510 @@
|
||||
# 系统日志管理分析与优化方案(2026-03-05)
|
||||
|
||||
## 当前日志分布情况
|
||||
|
||||
### 1. 根目录日志(❌ 不规范)
|
||||
|
||||
```
|
||||
Z:\Code\Insar_management_system_v2\
|
||||
├── unpacker_activity.log (34KB) - 解包活动日志
|
||||
└── unpacker_log.json (8.6KB) - 解包结构化日志
|
||||
```
|
||||
|
||||
**来源**:`scripts/unpack_archives.py`
|
||||
**问题**:
|
||||
- 直接保存在项目根目录,不专业
|
||||
- 与代码文件混在一起
|
||||
- 不便于管理和清理
|
||||
- 可能被误提交到 Git
|
||||
|
||||
---
|
||||
|
||||
### 2. IDL/ENVI 工作日志
|
||||
|
||||
```
|
||||
backend/runtime/idl_worker/
|
||||
├── 20260225_022409_dinsar_custom.log
|
||||
├── 20260225_051527_dinsar_custom.log
|
||||
├── 20260304_091723_import.log
|
||||
├── 20260304_091854_import.log
|
||||
└── dinsar_custom_progress.log
|
||||
```
|
||||
|
||||
**来源**:ENVI 工作流执行日志
|
||||
**状态**:✅ 已规范化(在 `backend/runtime/` 下)
|
||||
|
||||
---
|
||||
|
||||
### 3. SARscape 工作日志
|
||||
|
||||
```
|
||||
.idl/sarmap/sarscape-3-6_1_0-idl_8_8/
|
||||
├── hwConfig.log
|
||||
└── sarscape_work/
|
||||
├── Process.log
|
||||
├── Process_20260226165004.log
|
||||
├── Process_20260226210207.log
|
||||
└── Process_20260227091802.log
|
||||
```
|
||||
|
||||
**来源**:SARscape 软件自动生成
|
||||
**状态**:✅ 可接受(第三方软件日志)
|
||||
|
||||
---
|
||||
|
||||
### 4. 应用日志(缺失)
|
||||
|
||||
**问题**:
|
||||
- ❌ 没有统一的应用日志目录
|
||||
- ❌ 没有日志轮转机制
|
||||
- ❌ 没有日志级别配置
|
||||
- ❌ 没有结构化日志
|
||||
|
||||
---
|
||||
|
||||
## 日志用途分析
|
||||
|
||||
### unpacker_activity.log
|
||||
|
||||
**用途**:记录解包脚本的活动日志(文本格式)
|
||||
|
||||
**内容示例**:
|
||||
```
|
||||
2026-03-04 20:53:15 - INFO - 开始扫描归档文件...
|
||||
2026-03-04 20:53:15 - INFO - 找到 5 个归档文件
|
||||
2026-03-04 20:53:16 - INFO - 解包完成: archive1.zip
|
||||
```
|
||||
|
||||
**问题**:
|
||||
- 保存在根目录
|
||||
- 无日志轮转(会无限增长)
|
||||
- 无日志级别控制
|
||||
|
||||
---
|
||||
|
||||
### unpacker_log.json
|
||||
|
||||
**用途**:记录解包脚本的结构化日志(JSON 格式)
|
||||
|
||||
**内容示例**:
|
||||
```json
|
||||
{
|
||||
"timestamp": "2026-03-04T20:53:15",
|
||||
"level": "INFO",
|
||||
"message": "解包完成",
|
||||
"archive": "archive1.zip",
|
||||
"files_extracted": 123,
|
||||
"duration_seconds": 5.2
|
||||
}
|
||||
```
|
||||
|
||||
**问题**:
|
||||
- 保存在根目录
|
||||
- 与 activity.log 重复
|
||||
- 无清理机制
|
||||
|
||||
---
|
||||
|
||||
## 系统中的其他日志
|
||||
|
||||
### 1. 数据库日志
|
||||
- **位置**:PostgreSQL 数据目录
|
||||
- **管理**:由 PostgreSQL 管理
|
||||
|
||||
### 2. Nginx 日志
|
||||
- **位置**:`nginx/logs/` (如果配置了)
|
||||
- **管理**:由 Nginx 管理
|
||||
|
||||
### 3. 任务日志
|
||||
- **位置**:数据库 `system_task` 表的 `logs` 字段
|
||||
- **管理**:通过 API 查询
|
||||
|
||||
### 4. 进度文件
|
||||
- **位置**:`backend/runtime/idl_worker/job_{job_id}_progress.json`
|
||||
- **管理**:任务完成后自动清理
|
||||
|
||||
---
|
||||
|
||||
## 日志管理问题
|
||||
|
||||
### 问题 1:日志分散
|
||||
|
||||
**现状**:
|
||||
- 根目录:unpacker 日志
|
||||
- backend/runtime/:ENVI 日志
|
||||
- .idl/:SARscape 日志
|
||||
- 数据库:任务日志
|
||||
|
||||
**影响**:
|
||||
- 难以统一查看
|
||||
- 难以统一清理
|
||||
- 难以统一备份
|
||||
|
||||
---
|
||||
|
||||
### 问题 2:无日志轮转
|
||||
|
||||
**现状**:
|
||||
- unpacker_activity.log 会无限增长
|
||||
- ENVI 日志会累积(每次执行生成新文件)
|
||||
|
||||
**影响**:
|
||||
- 磁盘空间浪费
|
||||
- 日志文件过大影响性能
|
||||
|
||||
---
|
||||
|
||||
### 问题 3:无统一日志框架
|
||||
|
||||
**现状**:
|
||||
- unpacker 使用自定义日志
|
||||
- 后端使用 print() 输出
|
||||
- 没有统一的日志级别
|
||||
|
||||
**影响**:
|
||||
- 日志格式不一致
|
||||
- 难以过滤和搜索
|
||||
- 难以集成日志分析工具
|
||||
|
||||
---
|
||||
|
||||
## 优化方案
|
||||
|
||||
### 方案 A:统一日志目录结构(推荐)
|
||||
|
||||
```
|
||||
Z:\Code\Insar_management_system_v2\
|
||||
├── logs/ # 统一日志目录
|
||||
│ ├── app/ # 应用日志
|
||||
│ │ ├── backend.log # 后端主日志
|
||||
│ │ ├── backend.log.1 # 轮转日志
|
||||
│ │ ├── backend.log.2
|
||||
│ │ └── ...
|
||||
│ ├── tasks/ # 任务日志
|
||||
│ │ ├── envi/ # ENVI 工作流日志
|
||||
│ │ │ ├── 20260304_091723_import.log
|
||||
│ │ │ └── ...
|
||||
│ │ └── unpacker/ # 解包任务日志
|
||||
│ │ ├── unpacker_20260304.log
|
||||
│ │ └── ...
|
||||
│ ├── access/ # 访问日志
|
||||
│ │ ├── nginx_access.log
|
||||
│ │ └── api_access.log
|
||||
│ └── error/ # 错误日志
|
||||
│ ├── nginx_error.log
|
||||
│ └── api_error.log
|
||||
├── backend/
|
||||
└── frontend/
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- 所有日志集中管理
|
||||
- 便于备份和清理
|
||||
- 便于配置 .gitignore
|
||||
|
||||
---
|
||||
|
||||
### 方案 B:使用 Python logging 模块
|
||||
|
||||
**配置文件**:`backend/app/logging_config.py`
|
||||
|
||||
```python
|
||||
import logging
|
||||
import logging.handlers
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# 日志根目录
|
||||
LOG_ROOT = Path(__file__).parent.parent.parent / "logs"
|
||||
LOG_ROOT.mkdir(exist_ok=True)
|
||||
|
||||
# 应用日志目录
|
||||
APP_LOG_DIR = LOG_ROOT / "app"
|
||||
APP_LOG_DIR.mkdir(exist_ok=True)
|
||||
|
||||
# 任务日志目录
|
||||
TASK_LOG_DIR = LOG_ROOT / "tasks"
|
||||
TASK_LOG_DIR.mkdir(exist_ok=True)
|
||||
|
||||
# 日志配置
|
||||
LOGGING_CONFIG = {
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
"formatters": {
|
||||
"default": {
|
||||
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||
"datefmt": "%Y-%m-%d %H:%M:%S",
|
||||
},
|
||||
"detailed": {
|
||||
"format": "%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s",
|
||||
"datefmt": "%Y-%m-%d %H:%M:%S",
|
||||
},
|
||||
"json": {
|
||||
"()": "pythonjsonlogger.jsonlogger.JsonFormatter",
|
||||
"format": "%(asctime)s %(name)s %(levelname)s %(message)s",
|
||||
},
|
||||
},
|
||||
"handlers": {
|
||||
"console": {
|
||||
"class": "logging.StreamHandler",
|
||||
"level": "INFO",
|
||||
"formatter": "default",
|
||||
"stream": "ext://sys.stdout",
|
||||
},
|
||||
"file": {
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"level": "DEBUG",
|
||||
"formatter": "detailed",
|
||||
"filename": str(APP_LOG_DIR / "backend.log"),
|
||||
"maxBytes": 10 * 1024 * 1024, # 10MB
|
||||
"backupCount": 5,
|
||||
"encoding": "utf-8",
|
||||
},
|
||||
"error_file": {
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"level": "ERROR",
|
||||
"formatter": "detailed",
|
||||
"filename": str(APP_LOG_DIR / "error.log"),
|
||||
"maxBytes": 10 * 1024 * 1024, # 10MB
|
||||
"backupCount": 5,
|
||||
"encoding": "utf-8",
|
||||
},
|
||||
},
|
||||
"loggers": {
|
||||
"": { # root logger
|
||||
"level": "INFO",
|
||||
"handlers": ["console", "file", "error_file"],
|
||||
},
|
||||
"uvicorn": {
|
||||
"level": "INFO",
|
||||
"handlers": ["console", "file"],
|
||||
"propagate": False,
|
||||
},
|
||||
"sqlalchemy": {
|
||||
"level": "WARNING",
|
||||
"handlers": ["file"],
|
||||
"propagate": False,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
def setup_logging():
|
||||
"""初始化日志配置"""
|
||||
import logging.config
|
||||
logging.config.dictConfig(LOGGING_CONFIG)
|
||||
```
|
||||
|
||||
**使用方式**:
|
||||
|
||||
```python
|
||||
# backend/app/main.py
|
||||
from .logging_config import setup_logging
|
||||
|
||||
setup_logging()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
logger.info("应用启动")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 方案 C:修复 unpacker 日志位置
|
||||
|
||||
**修改文件**:`scripts/unpack_archives.py`
|
||||
|
||||
```python
|
||||
# 修改前
|
||||
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
|
||||
LOG_FILE = os.path.join(PROJECT_ROOT, "unpacker_log.json")
|
||||
ACTIVITY_LOG = os.path.join(PROJECT_ROOT, "unpacker_activity.log")
|
||||
|
||||
# 修改后
|
||||
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
|
||||
LOG_DIR = os.path.join(PROJECT_ROOT, "logs", "tasks", "unpacker")
|
||||
os.makedirs(LOG_DIR, exist_ok=True)
|
||||
|
||||
# 使用日期命名,便于清理
|
||||
from datetime import datetime
|
||||
log_date = datetime.now().strftime("%Y%m%d")
|
||||
LOG_FILE = os.path.join(LOG_DIR, f"unpacker_{log_date}.json")
|
||||
ACTIVITY_LOG = os.path.join(LOG_DIR, f"unpacker_{log_date}.log")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 方案 D:添加日志清理机制
|
||||
|
||||
**定期清理脚本**:`scripts/cleanup_logs.py`
|
||||
|
||||
```python
|
||||
import os
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
PROJECT_ROOT = Path(__file__).parent.parent
|
||||
LOG_ROOT = PROJECT_ROOT / "logs"
|
||||
|
||||
# 清理策略
|
||||
CLEANUP_RULES = {
|
||||
"logs/app/*.log.*": 30, # 应用日志保留 30 天
|
||||
"logs/tasks/envi/*.log": 7, # ENVI 日志保留 7 天
|
||||
"logs/tasks/unpacker/*.log": 7, # 解包日志保留 7 天
|
||||
}
|
||||
|
||||
def cleanup_old_logs():
|
||||
"""清理过期日志"""
|
||||
now = time.time()
|
||||
for pattern, days in CLEANUP_RULES.items():
|
||||
max_age = days * 86400 # 转换为秒
|
||||
for log_file in LOG_ROOT.glob(pattern):
|
||||
if log_file.is_file():
|
||||
age = now - log_file.stat().st_mtime
|
||||
if age > max_age:
|
||||
print(f"删除过期日志: {log_file} (已存在 {age/86400:.1f} 天)")
|
||||
log_file.unlink()
|
||||
|
||||
if __name__ == "__main__":
|
||||
cleanup_old_logs()
|
||||
```
|
||||
|
||||
**添加到定时任务**:
|
||||
```python
|
||||
# backend/app/main.py
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
|
||||
scheduler = AsyncIOScheduler()
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
# 每天凌晨 3 点清理日志
|
||||
scheduler.add_job(cleanup_old_logs, "cron", hour=3, minute=0)
|
||||
scheduler.start()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 实施步骤
|
||||
|
||||
### 第一步:创建日志目录结构
|
||||
|
||||
```bash
|
||||
cd Z:\Code\Insar_management_system_v2
|
||||
mkdir -p logs/app
|
||||
mkdir -p logs/tasks/envi
|
||||
mkdir -p logs/tasks/unpacker
|
||||
mkdir -p logs/access
|
||||
mkdir -p logs/error
|
||||
```
|
||||
|
||||
### 第二步:移动现有日志
|
||||
|
||||
```bash
|
||||
# 移动 unpacker 日志
|
||||
mv unpacker_activity.log logs/tasks/unpacker/unpacker_20260304.log
|
||||
mv unpacker_log.json logs/tasks/unpacker/unpacker_20260304.json
|
||||
|
||||
# 移动 ENVI 日志(已经在正确位置)
|
||||
# backend/runtime/idl_worker/ 保持不变
|
||||
```
|
||||
|
||||
### 第三步:修改 unpacker 脚本
|
||||
|
||||
修改 `scripts/unpack_archives.py`,使用新的日志路径。
|
||||
|
||||
### 第四步:配置 Python logging
|
||||
|
||||
创建 `backend/app/logging_config.py`,配置统一日志。
|
||||
|
||||
### 第五步:更新 .gitignore
|
||||
|
||||
```gitignore
|
||||
# 日志文件
|
||||
logs/
|
||||
*.log
|
||||
*.log.*
|
||||
|
||||
# 但保留日志目录结构
|
||||
!logs/.gitkeep
|
||||
!logs/app/.gitkeep
|
||||
!logs/tasks/.gitkeep
|
||||
```
|
||||
|
||||
### 第六步:添加日志清理
|
||||
|
||||
创建 `scripts/cleanup_logs.py`,配置定时清理。
|
||||
|
||||
---
|
||||
|
||||
## 推荐配置
|
||||
|
||||
### 日志级别
|
||||
|
||||
```python
|
||||
# 开发环境
|
||||
LOG_LEVEL = "DEBUG"
|
||||
|
||||
# 生产环境
|
||||
LOG_LEVEL = "INFO"
|
||||
|
||||
# 错误追踪
|
||||
ERROR_LOG_LEVEL = "ERROR"
|
||||
```
|
||||
|
||||
### 日志轮转
|
||||
|
||||
```python
|
||||
# 按大小轮转
|
||||
maxBytes = 10 * 1024 * 1024 # 10MB
|
||||
backupCount = 5 # 保留 5 个备份
|
||||
|
||||
# 按时间轮转
|
||||
when = "midnight" # 每天午夜轮转
|
||||
interval = 1 # 每 1 天
|
||||
backupCount = 30 # 保留 30 天
|
||||
```
|
||||
|
||||
### 日志保留
|
||||
|
||||
```python
|
||||
# 应用日志:30 天
|
||||
# 任务日志:7 天
|
||||
# 错误日志:90 天
|
||||
# 访问日志:30 天
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
### 当前问题
|
||||
1. ❌ unpacker 日志保存在根目录(不专业)
|
||||
2. ❌ 日志分散在多个位置
|
||||
3. ❌ 无统一日志框架
|
||||
4. ❌ 无日志轮转和清理机制
|
||||
|
||||
### 推荐方案
|
||||
1. ✅ 创建统一的 `logs/` 目录
|
||||
2. ✅ 使用 Python logging 模块
|
||||
3. ✅ 配置日志轮转(按大小或时间)
|
||||
4. ✅ 添加定时清理机制
|
||||
5. ✅ 更新 .gitignore
|
||||
|
||||
### 优先级
|
||||
- **P0(立即)**:移动 unpacker 日志到 logs/ 目录
|
||||
- **P1(本周)**:配置 Python logging 模块
|
||||
- **P2(两周)**:添加日志轮转和清理
|
||||
- **P3(一个月)**:集成日志分析工具(如 ELK)
|
||||
|
||||
---
|
||||
|
||||
## 下一步
|
||||
|
||||
需要我开始实施日志管理优化吗?我可以:
|
||||
1. 创建日志目录结构
|
||||
2. 修改 unpacker 脚本
|
||||
3. 配置 Python logging
|
||||
4. 添加日志清理脚本
|
||||
|
||||
还是你想先看看这个方案,再决定是否实施?
|
||||
Reference in New Issue
Block a user