refactor(docs): reorganize documentation directory structure

- Create user/ - User guides and configuration documentation
- Create features/ - Feature specifications and business flows
- Create debugging/ - Debug guides and quick references
- Create testing/ - Test infrastructure, reports, and plans
- Create internal/ - Internal plans, analyses, and templates
- Move cleaner/*.md to cleaner/ directory
- Move LOGGING_*.md to developer/guides/

Add docs/README.md as documentation index with category navigation
and quick lookup guide.

The reorganized structure makes it easier for users and developers
to quickly locate relevant documentation.
This commit is contained in:
Misaka_Company
2026-04-14 12:15:09 +08:00
parent 0c6bb85e67
commit 681f3ba517
32 changed files with 137 additions and 0 deletions

View File

@@ -0,0 +1,547 @@
# ERPAuto 日志查询指南
## 概述
> 本指南用于帮助运维和开发人员使用日志系统快速排查问题。
>
> **P0 升级**:日志系统已增强 requestId 追踪、性能监控、完整错误上下文。
---
## 日志字段说明
### 新增核心字段P0 升级)
| 字段 | 类型 | 说明 | 示例 |
| --------------- | ------- | ------------------------- | ---------------------------------------- |
| `requestId` | string | 请求唯一标识符UUID v4 | `"f833980c-7b11-4c13-9c39-7c8890eb8b2f"` |
| `userId` | string | 执行操作的用户 ID | `"admin"` |
| `operation` | string | 操作类型 | `"extract"`, `"clean"`, `"validate"` |
| `duration` | number | 操作耗时(毫秒) | `1523` |
| `slow` | boolean | 是否为慢操作(> 阈值) | `true` |
| `batchId` | string | 批次 ID | `"B20260404-001"` |
| `tableName` | string | 数据库表名 | `"DiscreteMaterialPlan"` |
| `operationType` | string | 数据库操作类型 | `"INSERT"`, `"DELETE"`, `"UPDATE"` |
| `recordCount` | number | 记录数 | `150` |
| `fileSize` | number | 文件大小(字节) | `1048576` |
### 业务上下文字段
| 字段 | 场景 | 说明 |
| ------------------------ | ----------------- | ---------------------------------- |
| `orderNumbers` | Extractor/Cleaner | 订单号列表 |
| `materialCodes` | Cleaner | 物料代码列表 |
| `downloadDir` | Extractor | 下载目录路径 |
| `dryRun` | Cleaner | 是否为干运行模式 |
| `mode` | Validation | 验证模式(`database_filtered` 等) |
| `useSharedProductionIds` | Validation | 是否使用共享 Production ID |
| `configPath` | Config | 配置文件路径 |
| `isDev` | Config | 是否为开发环境 |
| `version` | Update | 应用版本号 |
| `channel` | Update | 更新通道(`stable`/`preview` |
---
## 日志查询工具与脚本
### PowerShell 查询脚本
#### 1. 按 requestId 追踪完整请求链路
```powershell
# 查找特定 requestId 的所有日志
$requestId = "f833980c-7b11-4c13-9c39-7c8890eb8b2f"
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\app-*.log" |
ConvertFrom-Json |
Where-Object { $_.requestId -eq $requestId } |
Sort-Object timestamp |
Format-Table timestamp, level, message, context -AutoSize
```
**用途**:完整追踪一个请求的所有操作
---
#### 2. 查找慢操作(> 2 秒)
```powershell
# 查找所有慢操作
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\app-*.log" |
ConvertFrom-Json |
Where-Object { $_.duration -gt 2000 } |
Format-Table timestamp, operation, duration, message -AutoSize
```
**用途**:识别性能瓶颈
---
#### 3. 查找特定用户的所有操作
```powershell
# 按 userId 筛选日志
$userId = "admin"
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\app-*.log" |
ConvertFrom-Json |
Where-Object { $_.userId -eq $userId } |
Sort-Object timestamp |
Format-Table timestamp, operation, level, message -AutoSize
```
**用途**:审计用户操作
---
#### 4. 查找特定时间段内的错误
```powershell
# 查找最近 1 小时的错误
$startTime = (Get-Date).AddHours(-1)
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\error-*.log" |
ConvertFrom-Json |
Where-Object { [datetime]::Parse($_.timestamp) -gt $startTime } |
Format-Table timestamp, message, error -AutoSize
```
**用途**:故障排查
---
#### 5. 按 operation 统计操作频率
```powershell
# 统计各 operation 的执行次数
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\app-*.log" |
ConvertFrom-Json |
Where-Object { $_.operation } |
Group-Object operation |
Sort-Object Count -Descending |
Format-Table Name, Count -AutoSize
```
**用途**:了解系统使用情况
---
### Linux/Mac Bash 查询
```bash
# 按 requestId 过滤
cat app-*.log | jq 'select(.requestId == "f833980c-7b11-4c13-9c39-7c8890eb8b2f")'
# 查找错误日志
cat error-*.log | jq '.'
# 查找慢操作
cat app-*.log | jq 'select(.duration > 2000)'
# 统计 operation 频率
cat app-*.log | jq -r '.operation' | sort | uniq -c | sort -rn
```
---
## 常见故障排查场景
### 场景 1数据提取失败
**症状**:用户报告 "提取任务失败"
**排查步骤**
```mermaid
flowchart TD
A[用户报告提取失败] --> B[定位 requestId]
B --> C[查看完整请求链路]
C --> D{错误类型?}
D -->|网络错误 | E[检查 ERP 连接]
D -->|数据库错误 | F[检查数据库连接]
D -->|文件错误 | G[检查文件权限]
E --> H[修复网络问题]
F --> H
G --> H
H --> I[重新执行提取]
```
**日志查询**
```powershell
# 1. 找到提取相关的错误日志
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\error-*.log" |
ConvertFrom-Json |
Where-Object { $_.operation -eq "extract" -and $_.message -like "*失败*" } |
Format-List timestamp, requestId, error, orderNumbers
```
**排查要点**
1. 查找 `operation: "extract"`的日志
2. 提取`requestId`用于全链路追踪
3. 检查`error`字段的具体错误信息
4. 查看`orderNumbers`确定哪些订单失败
---
### 场景 2物料清理执行缓慢
**症状**:用户报告 "清理任务太慢"
**排查步骤**
```mermaid
flowchart TD
A[清理缓慢报告] --> B[查找慢操作]
B --> C{哪个阶段慢?}
C -->|批量处理 | D[检查订单数量/物料数量]
C -->|重试操作 | E[检查 ERP 响应时间]
C -->|数据库操作 | F[检查数据库性能]
D --> G[优化批量大小]
E --> G
F --> G
```
**日志查询**
```powershell
# 1. 查找清理相关的慢操作
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\app-*.log" |
ConvertFrom-Json |
Where-Object { $_.operation -eq "cleaner" -and $_.duration -gt 5000 } |
Format-List timestamp, requestId, duration, slow, totalOrders, totalMaterials
```
**排查要点**
1. 查找 `duration > 5000ms` 的清理操作
2. 检查`totalOrders``totalMaterials` 确认数据量
3. 查看 `slow: true` 的批处理日志
---
### 场景 3登录失败
**症状**:用户无法登录
**排查步骤**
```mermaid
flowchart TD
A[登录失败] --> B[查找认证错误]
B --> C{错误类型?}
C -->|凭证错误 | D[检查用户名/密码]
C -->|ERP 连接错误 | E[检查 ERP 服务状态]
C -->|会话错误 | F[检查会话管理]
D --> G[修正登录信息]
E --> G
F --> G
```
**日志查询**
```powershell
# 1. 查找认证相关的错误
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\error-*.log" |
ConvertFrom-Json |
Where-Object { $_.userId -eq "admin" -and $_.message -like "*login*" } |
Format-List timestamp, requestId, error, userId, username
```
**排查要点**
1. 查找 `operation: "login"``message` 包含"login"的日志
2. 检查 `userId``username`
3. 查看`error`字段的具体错误信息
---
### 场景 4数据库插入失败
**症状**:数据无法保存到数据库
**排查步骤**
```mermaid
flowchart TD
A[数据库插入失败] --> B[查找数据库错误]
B --> C{错误类型?}
C -->|连接错误 | D[检查数据库服务]
C -->|SQL 语法错误 | E[检查 SQL 语句]
C -->|约束错误 | F[检查数据完整性]
D --> G[修复数据库问题]
E --> G
F --> G
```
**日志查询**
```powershell
# 1. 查找数据库相关的错误
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\error-*.log" |
ConvertFrom-Json |
Where-Object { $_.operationType -eq "INSERT" } |
Format-List timestamp, requestId, operationType, tableName, error
```
**排查要点**
1. 查找 `operationType: "INSERT"`的日志
2. 检查`tableName` 确定哪个表失败
3. 查看`error`字段的具体错误信息
---
### 场景 5配置文件读取失败
**症状**:应用启动失败,提示配置错误
**排查步骤**
```mermaid
flowchart TD
A[配置读取失败] --> B[查找配置相关错误]
B --> C{错误类型?}
C -->|文件不存在 | D[检查配置文件路径]
C -->|解析错误 | E[检查 YAML 格式]
C -->|验证错误 | F[检查配置字段]
D --> G[修复配置问题]
E --> G
F --> G
```
**日志查询**
```powershell
# 1. 查找配置相关的错误
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\error-*.log" |
ConvertFrom-Json |
Where-Object { $_.configPath } |
Format-List timestamp, requestId, configPath, isDev, error
```
**排查要点**
1. 查找 `configPath` 字段的日志
2. 检查 `isDev` 确定环境(开发/生产)
3. 查看`error`字段的具体错误信息
---
### 场景 6文件上传失败
**症状**:文件无法上传到 RustFS
**排查步骤**
**日志查询**
```powershell
# 1. 查找上传相关的错误
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\error-*.log" |
ConvertFrom-Json |
Where-Object { $_.fileSize -or $_.message -like "*upload*" } |
Format-List timestamp, requestId, fileSize, endpoint, bucket, error
```
**排查要点**
1. 查找 `fileSize` 字段的日志(表示文件操作)
2. 检查 `endpoint``bucket` 配置
3. 查看`error`字段的具体错误信息
---
### 场景 7验证任务无数据返回
**症状**:验证任务执行成功但无数据
**排查步骤**
**日志查询**
```powershell
# 1. 查找验证相关的日志
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\app-*.log" |
ConvertFrom-Json |
Where-Object { $_.operation -eq "validate" } |
Format-List timestamp, requestId, mode, useSharedProductionIds, recordCount
```
**排查要点**
1. 查找 `operation: "validate"`的日志
2. 检查 `mode`字段(数据来源)
3. 查看`useSharedProductionIds``recordCount`
---
## 日志最佳实践
### 1. 开发环境 vs 生产环境
```mermaid
flowchart LR
A[日志级别配置] --> B{环境?}
B -->|开发 | C[DEBUG 级别<br/>详细信息]
B -->|生产 | D[INFO 级别<br/>业务操作]
C --> E[调试问题]
D --> F[监控运行]
```
**配置示例**
```yaml
# config.yaml
logging:
level: debug # 开发环境
# level: info # 生产环境
```
---
### 2. 敏感信息保护
**永远不要记录**
- ❌ 密码
- ❌ Token/密钥
- ❌ 数据库连接字符串
- ❌ 用户个人信息
**正确做法**
```typescript
// ❌ 错误:记录敏感信息
log.error('Login failed', { password: userPassword })
// ✅ 正确:使用脱敏信息
log.error('Login failed', {
userId: 'admin',
reason: 'invalid_credentials' // 仅记录原因
})
```
---
### 3. 错误日志应该包含
**完整上下文**
```typescript
log.error('Database insert failed', {
requestId: getRequestId(), // 自动注入
operation: 'insert-materials',
userId: 'admin',
tableName: 'DiscreteMaterialPlan',
recordCount: 150,
error: error.message,
orderNumbers: ['SO001', 'SO002']
})
```
---
### 4. 性能监控
**关键指标**
- `duration > 1000ms`:一般警告
- `duration > 5000ms`:严重警告
- `duration > 10000ms`:需要立即调查
**监控脚本**
```powershell
# 每小时生成性能报告
Get-Content "C:\Users\pengq\AppData\Roaming\erpauto\logs\app-*.log" |
ConvertFrom-Json |
Where-Object { $_.duration -gt 1000 } |
Group-Object operation |
ForEach-Object {
[PSCustomObject]@{
Operation = $_.Name
SlowOperations = $_.Count
AvgDuration = [math]::Round(($_.Group | Measure-Object duration -Average).Average, 2)
MaxDuration = [math]::Round(($_.Group | Measure-Object duration -Maximum).Maximum, 2)
}
} | Format-Table -AutoSize
```
---
## 日志文件管理
### 文件位置
| 环境 | 路径 |
| -------- | ------------------------------------------------- |
| **开发** | `D:\FileLib\Projects\CodeMigration\ERPAuto\logs\` |
| **生产** | `C:\Users\<user>\AppData\Roaming\erpauto\logs\` |
### 文件命名
| 类型 | 命名格式 | 说明 |
| -------- | ------------------------ | ------------------ |
| 应用日志 | `app-YYYY-MM-DD.log` | 所有业务日志 |
| 错误日志 | `error-YYYY-MM-DD.log` | 仅错误级别日志 |
| 审计日志 | `audit-YYYY-MM-DD.jsonl` | 用户操作审计 |
| 压缩归档 | `*.log.gz` | 超过保留期限的日志 |
### 保留策略
```yaml
# config.yaml
logging:
appRetention: 14 # 应用日志保留 14 天
auditRetention: 30 # 审计日志保留 30 天
```
---
## 故障排查流程图
### 通用排查流程
```mermaid
flowchart TD
A[收到故障报告] --> B[确定故障类型]
B --> C{故障类型?}
C -->|功能错误 | D[查找相关 error 日志]
C -->|性能问题 | E[查找慢操作日志]
C -->|数据问题 | F[查找数据操作日志]
D --> G[定位 requestId]
E --> G
F --> G
G --> H[追踪完整请求链路]
H --> I[分析错误根因]
I --> J[制定修复方案]
J --> K[执行修复]
K --> L[验证修复效果]
```
---
## 总结
### 快速参考
| 需求 | 查询字段 |
| ---------- | ------------------------ |
| 完整追踪 | `requestId` |
| 性能排查 | `duration`, `slow` |
| 用户审计 | `userId` |
| 错误分析 | `error`, `operationType` |
| 数据库问题 | `tableName`, `records` |
| 文件问题 | `fileSize`, `filePath` |
### 联系支持
如遇日志相关问题,请联系技术支持团队并提供:
1. 故障时间段
2. 相关 `requestId`
3. 错误日志内容
---
_文档版本P0 Enhanced Logging_
_更新日期2026-04-04_

View File

@@ -0,0 +1,752 @@
# ERPAuto 日志系统实现文档
## 概述
ERPAuto 使用 **Winston** 作为核心日志库,实现了统一的主进程 - 渲染进程日志系统。系统支持日志级别管理、文件轮转、审计日志、错误全链路追踪等功能。
---
## 架构总览
```mermaid
graph TB
subgraph Renderer Process
RC[React Components]
UH[useLogger Hook]
LA[Logger API]
end
subgraph Preload Layer
PL[Preload Bridge]
LC[Level Cache]
end
subgraph Main Process
LH[Logger Handler]
IL[IPC Router]
WL[Winston Logger]
FT[File Transports]
CT[Console Transport]
AL[Audit Logger]
end
subgraph Storage
ALF[app-YYYY-MM-DD.log]
ELF[error-YYYY-MM-DD.log]
AUF[audit-YYYY-MM-DD.jsonl]
end
RC --> UH
UH --> LA
LA --> LC
LC -->|IPC Send| PL
PL -->|logger:forward| IL
IL --> LH
LH --> WL
WL --> CT
WL --> FT
FT --> ALF
FT --> ELF
AL --> AUF
style WL fill:#f9f,stroke:#333
style LH fill:#bbf,stroke:#333
style AL fill:#bfb,stroke:#333
```
---
## 核心组件
### 1. 主进程日志服务 (`src/main/services/logger/`)
#### 1.1 核心日志器 (`index.ts`)
```typescript
// 日志器创建与配置
import winston from 'winston'
import DailyRotateFile from 'winston-daily-rotate-file'
const logger = winston.createLogger({
level: 'info',
defaultMeta: { service: 'erpauto' },
transports: [new winston.transports.Console({ format: consoleFormat })]
})
```
**关键特性:**
- **双格式输出**:控制台(彩色文本)+ 文件JSON
- **每日轮转**:日志文件按日期拆分,自动压缩归档
- **错误序列化**:完整捕获 stack trace 和自定义属性
- **环境感知**:生产环境自动脱敏敏感信息
#### 1.2 日志级别与优先级
```typescript
export type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'verbose'
export const LOG_LEVEL_PRIORITY: Record<string, number> = {
verbose: 0,
debug: 1,
info: 2,
warn: 3,
error: 4
}
```
#### 1.3 错误工具类 (`error-utils.ts`)
```mermaid
flowchart LR
A[Error Occurs] --> B{Error Type?}
B -->|Error Instance| C[serializeError]
B -->|Error-like| C
B -->|Other| D[Wrap as UnknownError]
C --> E{Production?}
D --> E
E -->|Yes| F[sanitizeError]
E -->|No| G[Keep Full Details]
F --> H[Redact Sensitive Keys]
G --> I[Preserve Stack Trace]
H --> J[Log Output]
I --> J
```
**序列化流程:**
1. 捕获所有 enumerable 和 non-enumerable 属性
2. 递归处理 error cause 链
3. 生产环境脱敏 password/token/secret 等敏感字段
4. 提取堆栈中的文件/行号/列号信息
---
### 2. 审计日志服务 (`audit-logger.ts`)
**用途**:记录用户操作审计日志,满足合规要求
```typescript
interface AuditEntry {
timestamp: string // ISO 8601 时间戳
action: string // 操作类型LOGIN, EXTRACT, DELETE
userId: string // 用户 ID
username: string // 用户名
computerName: string // 计算机名
resource: string // 受影响的资源
status: 'success' | 'failure' | 'partial'
metadata: Record<string, unknown>
}
```
**格式特点:**
- **JSONL 格式**:每行一个 JSON 对象,便于流式解析
- **30 天轮转**:默认保留 30 天审计日志
- **独立文件**`audit-YYYY-MM-DD.jsonl`
---
### 3. IPC 日志处理器 (`src/main/ipc/logger-handler.ts`)
```mermaid
sequenceDiagram
participant R as Renderer
participant B as Buffer State
participant W as Winston
participant F as File
R->>B: Send Log Entry
Note over B: Circuit Breaker Check
alt Error Level
B->>B: Always Buffer
else Non-Error & Buffer < 500
B->>B: Buffer Entry
else Buffer >= 500
B->>B: Discard + Count
end
Note over B: Batch Processing
B->>B: 100ms Debounce OR 50 entries
B->>W: Flush Batch
W->>F: Write to File
```
**批处理策略:**
| 参数 | 值 | 说明 |
|------|-----|------|
| `DEBOUNCE_MS` | 100ms | 防抖等待时间 |
| `MAX_BATCH_SIZE` | 50 | 最大批次大小 |
| `CIRCUIT_BREAKER_THRESHOLD` | 500 | 熔断阈值 |
**熔断机制:**
- 当缓冲区 > 500 条时,丢弃非错误日志
- 错误日志始终绕过熔断器
- 每丢弃 100 条记录一次警告
---
### 4. 渲染进程日志 Hook (`src/renderer/src/hooks/useLogger.ts`)
```typescript
// 使用示例
function MyComponent() {
const logger = useLogger('MyComponent')
const handleClick = () => {
logger.info('User clicked button', { buttonId: 'submit' })
}
const handleError = (err: Error) => {
logger.error('Operation failed', { error: err.message })
}
}
```
**客户端级别过滤:**
```typescript
// 在发送 IPC 前检查日志级别,避免无效 IPC 调用
if (!shouldLog(level)) return
ipcRenderer.send(IPC_CHANNELS.LOGGER_FORWARD, { ... })
```
**FPS 监控:**
- 检测因过度日志导致的 UI 卡顿
- 当 FPS < 30 时发出警告
- 5 秒冷却期避免重复警告
---
### 5. 预加载层 API (`src/preload/api/logger.ts`)
```typescript
// 级别缓存机制
let cachedLevel: LogLevel = 'info'
// 监听主进程级别变更广播
ipcRenderer.on(IPC_CHANNELS.LOGGER_LEVEL_CHANGED, (level) => {
cachedLevel = level
})
// 客户端过滤
function shouldLog(level: LogLevel): boolean {
return priorities[level] >= priorities[cachedLevel]
}
```
---
### 6. 配置管理 (`src/main/services/config/config-manager.ts`)
```yaml
# config.yaml 配置示例
logging:
level: info # 日志级别
auditRetention: 30 # 审计日志保留天数
appRetention: 14 # 应用日志保留天数
```
**配置加载时机:**
1. 应用启动时加载 `config.yaml`
2. 调用 `applyLoggingConfig()` 配置 Winston
3. 调用 `applyAuditConfig()` 配置审计日志
---
## 日志数据流
```mermaid
flowchart TD
subgraph 渲染进程
A[Component] --> B[useLogger Hook]
B --> C{Level Check}
C -->|Pass| D[loggerApi.log]
C -->|Skip| E[Drop]
end
subgraph IPC 传输
D --> F[logger:forward]
F --> G[Context Bridge]
end
subgraph 主进程
G --> H[Logger Handler]
H --> I{Circuit Breaker}
I -->|Pass| J[Batch Buffer]
I -->|Block| K[Discard Counter]
J --> L{Debounce Timer}
L -->|100ms| M[Flush to Winston]
J -->|50 entries| M
end
subgraph Winston
M --> N[Console Transport]
M --> O[File Transport]
O --> P{Error Level?}
P -->|Yes| Q[error-DATE.log]
P -->|All| R[app-DATE.log]
end
subgraph 审计日志
S[logAudit] --> T[Audit Logger]
T --> U[audit-DATE.jsonl]
end
```
---
## 日志文件组织
### 目录结构
```
AppData/Roaming/erpauto/logs/
├── app-2024-04-01.log
├── app-2024-04-01.log.gz # 压缩归档
├── app-2024-04-02.log
├── error-2024-04-01.log # 仅错误级别
├── error-2024-04-01.log.gz
├── audit-2024-04-01.jsonl # 审计日志
└── audit-2024-04-01.jsonl.gz
```
### 文件格式
**应用日志 (JSON 格式):**
```json
{
"level": "info",
"message": "Extractor started",
"timestamp": "2024-04-01 10:30:00",
"service": "erpauto",
"context": "Extractor",
"orders": ["SO001", "SO002"]
}
```
**错误日志 (含堆栈):**
```json
{
"level": "error",
"message": "Database connection failed",
"timestamp": "2024-04-01 10:31:00",
"error": {
"name": "ConnectionError",
"message": "ECONNREFUSED",
"stack": "ConnectionError: ECONNREFUSED\n at TCP.connectWrap (...)",
"code": "ECONNREFUSED"
}
}
```
**审计日志 (JSONL 格式):**
```jsonl
{"timestamp":"2024-04-01T10:30:00Z","action":"LOGIN","userId":"1","username":"admin","computerName":"DESKTOP-001","resource":"/auth","status":"success","metadata":{}}
{"timestamp":"2024-04-01T10:35:00Z","action":"EXTRACT","userId":"1","username":"admin","computerName":"DESKTOP-001","resource":"orders","status":"success","metadata":{"orderCount":50}}
```
---
## IPC 通道定义
```typescript
// src/shared/ipc-channels.ts
export const IPC_CHANNELS = {
// 日志转发renderer → main
LOGGER_FORWARD: 'logger:forward',
// 获取当前日志级别
LOGGER_GET_LEVEL: 'logger:getLevel',
// 级别变更广播main → renderer
LOGGER_LEVEL_CHANGED: 'logger:levelChanged'
}
```
---
## 使用指南
### 在主进程中记录日志
```typescript
import { createLogger } from '@/main/services/logger'
const log = createLogger('MyService')
// 基础用法
log.info('Operation started')
log.warn('Disk space low')
log.error('Failed to connect', { error: err })
// 带上下文的日志
log.info('Processing batch', {
batchId: 'B001',
itemCount: 100,
estimatedTime: '5min'
})
// 错误日志(自动序列化堆栈)
try {
await riskyOperation()
} catch (error) {
log.error('Operation failed', { error })
}
```
### 在渲染进程中记录日志
```typescript
import { useLogger } from '@/renderer/src/hooks/useLogger'
function MyComponent() {
const logger = useLogger('MyComponent')
useEffect(() => {
logger.info('Component mounted')
return () => logger.debug('Component unmounted')
}, [])
const handleAction = async () => {
try {
await api.doSomething()
logger.info('Action succeeded')
} catch (err) {
logger.error('Action failed', { error: err.message })
}
}
}
```
### 记录审计日志
```typescript
import { logAudit } from '@/main/services/logger/audit-logger'
// 用户登录审计
logAudit('LOGIN', userId, {
username: 'admin',
computerName: 'DESKTOP-001',
resource: '/auth',
status: 'success',
metadata: { loginMethod: 'password' }
})
// 数据提取审计
logAudit('EXTRACT', userId, {
username: 'user1',
computerName: 'DESKTOP-002',
resource: 'materials',
status: 'success',
metadata: { orderCount: 50, materialCount: 1200 }
})
```
---
## 高级功能
### 1. 日志级别动态切换
```mermaid
sequenceDiagram
participant U as User (UI)
participant C as ConfigManager
participant M as Main Logger
participant R as Renderer
participant L as Level Cache
U->>C: Update logging.level
C->>M: applyLoggingConfig(newLevel)
M->>M: logger.level = newLevel
M->>R: Broadcast levelChanged
R->>L: cachedLevel = newLevel
Note over L: Future logs filtered at client
```
**代码示例:**
```typescript
// 主进程设置级别
import { setLogLevel } from '@/main/services/logger'
setLogLevel('debug')
// 渲染进程自动同步
// useLogger Hook 会自动接收级别变更广播
// 客户端过滤自动生效
```
### 2. 生产环境错误脱敏
```typescript
// 自动脱敏以下关键字段
const sensitiveKeys = [
'password', 'secret', 'token', 'apiKey',
'credentials', 'authorization', 'privateKey'
]
// 生产环境错误消息
{
"name": "AuthError",
"message": "An error occurred due to invalid credentials or configuration"
// 原始错误消息被脱敏
}
```
### 3. 错误上下文提取
```typescript
// 从堆栈跟踪提取位置信息
const errorContext = extractErrorContext(serializedError)
// 输出:
{
fileName: 'extractor.ts',
lineNumber: 142,
columnName: 15,
functionName: 'runExtraction'
}
```
---
## 最佳实践
### ✅ 推荐做法
```typescript
// 1. 使用 createLogger 创建带上下文的子日志器
const log = createLogger('DatabaseService')
// 2. 记录错误时传递完整 Error 对象
log.error('Query failed', { error })
// 3. 使用结构化元数据
log.info('Batch processed', {
batchId: 'B001',
duration: 1250,
itemCount: 100
})
// 4. 渲染进程使用 useLogger Hook
const logger = useLogger('LoginForm')
// 5. 敏感信息使用审计日志
logAudit('DELETE', userId, { ... })
```
### ❌ 避免的做法
```typescript
// 1. 避免直接 console.log
console.log('debug') // ❌ 不会被 Winston 捕获
// 2. 避免只记录错误消息
log.error(err.message) // ❌ 丢失堆栈和类型
// 3. 避免循环引用元数据
const obj: any = {}
obj.self = obj
log.info('test', { obj }) // ❌ 序列化失败
// 4. 避免过度日志
for (let i = 0; i < 1000; i++) {
logger.info(`Item ${i}`) // ❌ 触发熔断
}
```
---
## 故障排查
### 问题:日志文件不生成
**检查清单:**
1. 确认 `config.yaml` 中 logging 配置正确
2. 检查日志目录权限
3. 查看控制台输出是否有 Winston 错误
4. 验证 `applyLoggingConfig()` 是否被调用
### 问题:渲染进程日志未到达主进程
**调试步骤:**
```typescript
// 1. 检查 IPC 通道是否注册
// src/main/ipc/index.ts 应包含:
registerLoggerHandlers()
// 2. 检查 preload 暴露
// src/preload/index.ts 应暴露:
contextBridge.exposeInMainWorld('electron', api)
// 3. 检查级别过滤
console.log(window.electron.logger) // 应存在
```
### 问题:生产环境错误信息不完整
**原因**:生产环境自动脱敏
**解决方案**
- 查看 `error-DATE.log` 获取完整错误
- 开发环境禁用脱敏:设置开发模式构建
---
## 测试支持
### 单元测试示例
```typescript
import { createLogger } from '@/main/services/logger'
describe('Logger', () => {
it('should log with context', () => {
const log = createLogger('TestService')
// 测试逻辑...
expect(log).toBeDefined()
})
})
```
### 集成测试
```typescript
// tests/integration/ipc-logging.test.ts
import { loggerApi } from '@/preload/api/logger'
test('Renderer logs should reach Winston', async () => {
// Mock Winston transport
// Send log via IPC
// Assert log appears in main process
})
```
---
## 配置参考
### config.yaml 完整配置
```yaml
logging:
# 日志级别error | warn | info | debug | verbose
level: info
# 审计日志保留天数
auditRetention: 30
# 应用日志保留天数
appRetention: 14
```
### 日志级别说明
| 级别 | 使用场景 | 示例 |
| --------- | -------------- | ---------------------------- |
| `error` | 系统错误、异常 | 数据库连接失败、文件写入错误 |
| `warn` | 可恢复的警告 | 磁盘空间不足、重试操作 |
| `info` | 业务操作记录 | 用户登录、提取开始/结束 |
| `debug` | 技术调试信息 | API 请求参数、SQL 语句 |
| `verbose` | 详细跟踪 | 循环迭代、中间状态 |
---
## 相关文件索引
| 文件路径 | 职责 |
| -------------------------------------------- | ------------------ |
| `src/main/services/logger/index.ts` | Winston 日志器核心 |
| `src/main/services/logger/shared.ts` | 共享工具函数 |
| `src/main/services/logger/error-utils.ts` | 错误序列化/脱敏 |
| `src/main/services/logger/audit-logger.ts` | 审计日志服务 |
| `src/main/ipc/logger-handler.ts` | IPC 批处理与熔断 |
| `src/renderer/src/hooks/useLogger.ts` | React Hook |
| `src/preload/api/logger.ts` | Preload API |
| `src/shared/ipc-channels.ts` | IPC 通道定义 |
| `src/main/services/config/config-manager.ts` | 配置管理 |
---
## 架构图附录
### 完整日志系统架构
```mermaid
graph TB
subgraph 渲染进程 Renderer
UI[UI Components]
HL[useLogger Hook]
CF[Client Filter]
LC[Level Cache]
end
subgraph 预加载层 Preload
CB[Context Bridge]
IR[IPC Renderer]
LA[Logger API]
end
subgraph 主进程 Main
IH[IPC Handler]
BB[Batch Buffer]
CB2[Circuit Breaker]
WL[Winston Logger]
AC[Audit Logger]
CM[Config Manager]
end
subgraph 传输层 Transports
CT[Console]
AFT[App File]
EFT[Error File]
ATF[Audit File]
end
subgraph 文件系统 File System
ALF[app-DATE.log]
ELF[error-DATE.log]
AUF[audit-DATE.jsonl]
GZ[.gz Archive]
end
UI --> HL
HL --> CF
CF --> LC
LC --> LA
LA --> IR
IR --> CB
CB --> IH
IH --> CB2
CB2 --> BB
BB --> WL
WL --> CT
WL --> AFT
WL --> EFT
AC --> ATF
CM --> WL
AFT --> ALF
EFT --> ELF
ATF --> AUF
ALF --> GZ
ELF --> GZ
AUF --> GZ
style WL fill:#f9f,stroke:#333
style BB fill:#bbf,stroke:#333
style CB2 fill:#fbb,stroke:#333
style AC fill:#bfb,stroke:#333
```
---
_文档生成日期2026-04-04_
_项目版本ERPAuto v1.x_