# 系统操作日志模块文档
## 概述
系统操作日志模块用于记录后台管理系统的所有操作请求,包括用户操作、API 调用、错误信息等,方便管理员进行系统监控、审计和问题排查。
## 技术特性
- **自动记录**: 通过中间件自动记录所有请求,无需手动调用
- **详细信息**: 记录用户信息、请求参数、响应结果、执行时间等
- **敏感信息保护**: 自动过滤密码等敏感信息
- **性能优化**: 不影响业务响应速度
- **多维度查询**: 支持按用户、模块、操作、状态、时间等多维度筛选
- **数据导出**: 支持导出日志数据为 Excel 文件
- **批量操作**: 支持批量删除和定期清理
## 数据库表结构
### system_logs 表
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | bigint | 主键 ID |
| user_id | bigint | 用户 ID |
| username | varchar(100) | 用户名 |
| module | varchar(50) | 模块名称 |
| action | varchar(100) | 操作名称 |
| method | varchar(10) | 请求方法 (GET/POST/PUT/DELETE) |
| url | text | 请求 URL |
| ip | varchar(45) | 客户端 IP 地址 |
| user_agent | text | 用户代理 |
| params | json | 请求参数 |
| result | text | 响应结果(仅错误时记录) |
| status_code | int | HTTP 状态码 |
| status | varchar(20) | 状态 (success/error) |
| error_message | text | 错误信息 |
| execution_time | int | 执行时间(毫秒) |
| created_at | timestamp | 创建时间 |
| updated_at | timestamp | 更新时间 |
## 核心组件
### 1. 中间件 (Middleware)
**LogRequestMiddleware**
位置: `app/Http/Middleware/LogRequestMiddleware.php`
功能:
- 自动拦截所有经过的请求
- 记录请求和响应信息
- 计算请求执行时间
- 提取用户信息和操作详情
- 过滤敏感参数
- 处理异常情况
使用方式:
```php
// 在路由中应用
Route::middleware(['log.request'])->group(function () {
// 需要记录日志的路由
});
```
### 2. 服务层 (Service)
**LogService**
位置: `app/Services/System/LogService.php`
主要方法:
- `create(array $data)`: 创建日志记录
- `getList(array $params)`: 获取日志列表(分页)
- `getListQuery(array $params)`: 获取日志查询构建器
- `getById(int $id)`: 根据 ID 获取日志详情
- `delete(int $id)`: 删除单条日志
- `batchDelete(array $ids)`: 批量删除日志
- `clearLogs(string $days)`: 清理指定天数前的日志
- `getStatistics(array $params)`: 获取日志统计信息
### 3. 控制器 (Controller)
**Log Controller**
位置: `app/Http/Controllers/System/Admin/Log.php`
接口列表:
- `GET /admin/logs`: 获取日志列表
- `GET /admin/logs/{id}`: 获取日志详情
- `GET /admin/logs/statistics`: 获取日志统计
- `POST /admin/logs/export`: 导出日志
- `DELETE /admin/logs/{id}`: 删除单条日志
- `POST /admin/logs/batch-delete`: 批量删除日志
- `POST /admin/logs/clear`: 清理历史日志
### 4. 请求验证 (Request Validation)
**LogRequest**
位置: `app/Http/Requests/LogRequest.php`
验证规则:
- `user_id`: 用户 ID(可选)
- `username`: 用户名(模糊查询,可选)
- `module`: 模块名称(可选)
- `action`: 操作名称(可选)
- `status`: 状态(success/error,可选)
- `start_date`: 开始日期(可选)
- `end_date`: 结束日期(可选)
- `ip`: IP 地址(可选)
- `page`: 页码(默认 1)
- `page_size`: 每页数量(默认 20,最大 100)
## API 接口文档
### 1. 获取日志列表
**接口**: `GET /admin/logs`
**请求参数**:
```json
{
"user_id": 1,
"username": "admin",
"module": "users",
"action": "创建 users",
"status": "success",
"start_date": "2024-01-01",
"end_date": "2024-12-31",
"ip": "192.168.1.1",
"page": 1,
"page_size": 20
}
```
**响应示例**:
```json
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"user_id": 1,
"username": "admin",
"module": "users",
"action": "创建 users",
"method": "POST",
"url": "http://example.com/admin/users",
"ip": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"params": {
"name": "test",
"email": "test@example.com"
},
"result": null,
"status_code": 200,
"status": "success",
"error_message": null,
"execution_time": 125,
"created_at": "2024-01-01 12:00:00",
"user": {
"id": 1,
"name": "管理员",
"username": "admin"
}
}
],
"total": 100,
"page": 1,
"page_size": 20
}
}
```
### 2. 获取日志详情
**接口**: `GET /admin/logs/{id}`
**响应示例**:
```json
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"user_id": 1,
"username": "admin",
"module": "users",
"action": "创建 users",
"method": "POST",
"url": "http://example.com/admin/users",
"ip": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"params": {
"name": "test",
"email": "test@example.com"
},
"result": null,
"status_code": 200,
"status": "success",
"error_message": null,
"execution_time": 125,
"created_at": "2024-01-01 12:00:00",
"user": {
"id": 1,
"name": "管理员",
"username": "admin",
"email": "admin@example.com",
"created_at": "2024-01-01 10:00:00"
}
}
}
```
### 3. 获取日志统计
**接口**: `GET /admin/logs/statistics`
**请求参数**:
```json
{
"start_date": "2024-01-01",
"end_date": "2024-12-31"
}
```
**响应示例**:
```json
{
"code": 200,
"message": "success",
"data": {
"total": 1000,
"success": 950,
"error": 50
}
}
```
### 4. 导出日志
**接口**: `POST /admin/logs/export`
**请求参数**: 与获取日志列表相同的查询参数
**响应**: Excel 文件下载
文件名格式: `系统操作日志_YYYYMMDDHHmmss.xlsx`
包含字段:
- ID
- 用户名
- 模块
- 操作
- 请求方法
- URL
- IP 地址
- 状态码
- 状态
- 错误信息
- 执行时间(ms)
- 创建时间
### 5. 删除单条日志
**接口**: `DELETE /admin/logs/{id}`
**响应示例**:
```json
{
"code": 200,
"message": "删除成功",
"data": null
}
```
### 6. 批量删除日志
**接口**: `POST /admin/logs/batch-delete`
**请求参数**:
```json
{
"ids": [1, 2, 3, 4, 5]
}
```
**响应示例**:
```json
{
"code": 200,
"message": "批量删除成功",
"data": null
}
```
### 7. 清理历史日志
**接口**: `POST /admin/logs/clear`
**请求参数**:
```json
{
"days": 30
}
```
**说明**: 清理指定天数前的所有日志记录,默认清理 30 天前的数据。
**响应示例**:
```json
{
"code": 200,
"message": "清理成功",
"data": null
}
```
## 日志记录规则
### 1. 自动记录的请求
所有经过 `log.request` 中间件的请求都会被自动记录,包括:
- 用户管理操作
- 角色管理操作
- 权限管理操作
- 部门管理操作
- 系统配置操作
- 其他所有后台管理操作
### 2. 不记录的请求
- 登录接口 (`POST /admin/auth/login`)
- 健康检查接口 (`GET /up`)
- 其他明确排除的路由
### 3. 敏感信息过滤
以下字段会被自动过滤,记录为 `******`:
- `password`
- `password_confirmation`
- `token`
- `secret`
- `key`
### 4. 错误日志处理
- 成功请求 (HTTP 状态码 < 400): `status` = `success`
- 失败请求 (HTTP 状态码 >= 400): `status` = `error`
- 错误时记录响应内容和错误消息
- 同时写入 Laravel 日志文件 (`storage/logs/laravel.log`)
## 模块和操作名称解析
### 模块名称
从 URL 路径中解析,例如:
- `/admin/users` → 模块: `users`
- `/admin/roles` → 模块: `roles`
- `/admin/configs` → 模块: `configs`
### 操作名称
根据 HTTP 方法和资源名称生成:
- `GET /admin/users` → 操作: `查询 users`
- `POST /admin/users` → 操作: `创建 users`
- `PUT /admin/users/1` → 操作: `更新 users`
- `DELETE /admin/users/1` → 操作: `删除 users`
## 性能优化建议
### 1. 定期清理日志
建议使用 Laravel 任务调度器定期清理历史日志:
```php
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
// 每天凌晨 2 点清理 90 天前的日志
$schedule->call(function () {
app(LogService::class)->clearLogs(90);
})->dailyAt('02:00');
}
```
### 2. 数据库索引
确保以下字段有索引:
- `user_id`
- `username`
- `module`
- `status`
- `created_at`
### 3. 分页查询
列表查询必须使用分页,避免一次加载过多数据。
### 4. 异步记录
日志记录操作应放在请求处理后,不影响响应速度。
## 前端集成示例
### Vue3 + Ant Design Vue
```vue
成功
失败
查询
重置
导出
{{ record.status === 'success' ? '成功' : '失败' }}
查看
删除
```
## 注意事项
1. **权限控制**: 日志管理接口需要相应的权限才能访问
2. **数据安全**: 敏感信息已自动过滤,但仍需注意日志数据的安全存储
3. **性能影响**: 虽然日志记录不影响响应速度,但大量日志会增加数据库负载
4. **定期备份**: 重要日志数据建议定期备份
5. **日志分析**: 可结合 BI 工具对日志数据进行深度分析
## 常见问题
### Q1: 为什么某些请求没有被记录?
A: 检查路由是否应用了 `log.request` 中间件,或者在中间件中是否被排除了。
### Q2: 日志数据过多怎么办?
A: 使用 `clearLogs` 方法定期清理历史日志,或设置任务调度器自动清理。
### Q3: 如何自定义日志记录规则?
A: 修改 `LogRequestMiddleware` 中的 `parseModule` 和 `parseAction` 方法。
### Q4: 日志记录会影响性能吗?
A: 日志记录在请求处理后执行,不影响响应速度。但大量日志会增加数据库写入压力。
### Q5: 如何查看完整的请求参数?
A: 在日志详情接口中,`params` 字段包含了完整的请求参数(敏感信息已过滤)。
## 更新日志
### v1.0.0 (2024-01-01)
- 初始版本
- 实现基础日志记录功能
- 支持多维度查询和筛选
- 支持数据导出
- 支持批量删除和清理