简介
本文件为 DouPHP 的审计日志系统提供完整说明,覆盖用户行为审计(登录/登出、操作日志、访问日志)、安全事件日志(登录失败、权限拒绝、异常操作)、日志存储策略(本地文件、数据库、集中式日志管理)、日志查询与分析(时间范围筛选、用户行为追踪、操作溯源)、清理策略与存储空间管理,以及日志安全与隐私保护。
项目结构
DouPHP 的审计能力由“业务侧埋点 + 审计服务 + 通用日志基础设施”三部分构成:
- 业务侧埋点:在登录成功/失败、后台操作等关键路径调用审计接口记录审计日志。
- 审计服务:统一写入 user_log、admin_log、book_log 等表,并负责 IP、模块、XSS 过滤等横切逻辑。
- 通用日志基础设施:按日落盘的系统运行日志,支持级别控制、采样、限流、敏感信息脱敏和自动上下文补全。
graph TB
A["业务代码<br/>登录/操作/访问"] --> B["审计服务 AuditService"]
B --> C["数据库表<br/>user_log / admin_log / book_log"]
A --> D["通用日志 Log"]
D --> E["存储目录 storage/log/<br/>log_YYYY-MM-DD.log"]
核心组件
- 审计服务(AuditService)
- 提供 writeUserLog、writeBookLog、writeAdminLog 三个入口,统一处理 IP、模块、结果码、详情字段与 XSS 过滤。
- 管理员日志写库时自动从 Request 推导路由模块,未传 IP 时回退到构造注入的来源 IP。
- 通用日志(Log)
- 分级日志(emergency/alert/critical/error/warning/notice/info/debug)。
- 自动上下文补全(request_id、scene、ip、route、module、action、user/admin/work 身份)。
- 生产安全:敏感键名掩码、URL 查询串参数掩码、trace 长度收敛。
- 性能:采样率、每分钟同 key 限流、白名单级别/场景。
- 存储:按日文件 log_YYYY-MM-DD.log,默认路径 storage/log/。
- 清理:提供 clean() 方法,保留最近 N 天日志。
架构总览
审计日志在请求生命周期中的位置如下:
- 前端/API/后台控制器或服务在关键动作处调用 audit() 或 Log::xxx()。
- AuditService 将结构化数据写入数据库;Log 将运行期日志写入文件。
- 管理端通过 ManagerService 提供的列表构建器对 admin_log 进行筛选与分页展示。
sequenceDiagram
participant U as "用户/客户端"
participant C as "控制器/服务"
participant AS as "审计服务"
participant DB as "数据库"
participant LG as "通用日志"
participant FS as "文件系统"
U->>C : 发起登录/操作请求
C->>AS : 写入审计日志(user_log/admin_log)
AS->>DB : INSERT 审计记录
C->>LG : 记录运行日志(可选)
LG->>FS : 写入 log_YYYY-MM-DD.log
DB-->>U : 返回响应
详细组件分析
用户行为审计(登录/登出、操作日志、访问日志)
- 登录成功/失败
- 前台登录流程在失败分支记录 LOGIN_FAIL,成功分支记录 LOGIN_SUCCESS,并附带失败原因标签(如账户锁定)。
- 微信登录在成功与异常分支分别记录登录成功与异常失败。
- 后台登录
- 后台登录成功后记录 ADMIN_LOGIN_SUCCESS;失败分支记录 ADMIN_LOGIN_FAIL,并附带输入错误等细节标签。
- 访问日志
- 通用日志 Log 自动捕获 request_id、scene、ip、route、module、action、user/admin/work 身份,便于后续按访问维度检索。
flowchart TD
Start(["登录入口"]) --> Check["校验账号/密码/状态"]
Check --> |失败| FailLog["记录 LOGIN_FAIL<br/>含失败原因标签"]
Check --> |成功| SuccessLog["记录 LOGIN_SUCCESS"]
FailLog --> End(["结束"])
SuccessLog --> End
安全事件日志(登录失败、权限拒绝、异常操作)
- 登录失败
- 前台/微信/后台登录失败均记录失败审计日志,包含失败原因标签(如输入错误、账户锁定)。
- 权限拒绝
- 后台操作日志通过 action/module/details 描述具体操作与模块,结合 result=0 可识别失败/拒绝事件。
- 异常操作
- 通用日志使用 warning/error 等级记录异常上下文,配合自动上下文(route、module、action、user/admin/work)便于定位。
日志存储策略
- 数据库存储(审计日志)
- user_log:会员行为审计(登录成功/失败、业务操作等)。
- admin_log:后台管理员操作审计(模块、动作、结果、详情、IP)。
- book_log:预约相关审计(状态变更、操作者类型与 ID、备注)。
- 本地文件存储(运行日志)
- 路径:storage/log/log_YYYY-MM-DD.log。
- 特性:按日滚动、级别过滤、采样与限流、敏感信息脱敏。
- 集中式日志管理(建议)
- 可将 storage/log 下的日志通过采集器(如 Filebeat/Fluent Bit)转发至 ELK/Loki/Splunk 等平台,实现集中检索与告警。
日志查询与分析
- 时间范围筛选
- 后台管理端支持按日期起止(含当日 0 点与 23:59:59)过滤 admin_log。
- 用户行为追踪
- 通过 user_log 的 user_id/action/details/created_at 追踪会员行为轨迹。
- 操作溯源
- admin_log 的 module/action/details/ip/created_at 可还原管理员操作链路与来源 IP。
- 通用日志的 request_id 可在一次请求内串联多条运行日志。
flowchart TD
Q["查询条件<br/>时间/用户/IP/模块/动作"] --> F["构建过滤条件"]
F --> P["分页查询"]
P --> R["渲染行数据<br/>翻译动作/模块/结果"]
R --> O["输出列表"]
日志清理策略与存储空间管理
- 文件日志清理
- 使用 Log::clean(keepDays) 清理 storage/log 下超过保留期的日志文件。
- 可通过定时任务定期执行,避免磁盘占满。
- 数据库日志归档
- 建议对 user_log/admin_log/book_log 建立按月/季度的归档策略,历史数据迁移至冷存储或只读实例。
- 采样与限流
- 通过设置采样率与每分钟同 key 最大条数,降低高频日志对 I/O 的影响。
日志安全保护与隐私保护
- 敏感信息脱敏
- 通用日志对敏感键名(password/token/secret/api_key/authorization/cookie 等)进行掩码替换。
- URL 查询串中命中敏感参数名的值会被替换为占位符,保留路径与其他参数便于排障。
- XSS 防护
- 审计日志写入前对 action/details 进行文本过滤,防止恶意内容入库。
- 最小化上下文
- 非调试模式会截断 trace 长度,减少堆栈信息泄露风险。
依赖关系分析
- 业务层依赖
- 登录流程依赖审计服务记录登录成功/失败。
- 后台各模块在服务层调用审计服务记录操作日志。
- 审计服务依赖
- 依赖数据库门面进行插入。
- 依赖 Session 获取当前管理员 ID(当未显式传入)。
- 依赖 Request 获取路由模块(仅 admin_log)。
- 通用日志依赖
- 依赖配置开关、级别权重、采样与限流策略。
- 依赖文件系统写入日志。
classDiagram
class AuditService {
+writeUserLog(userId, action, result, details, ip)
+writeBookLog(bookId, action, beforeStatus, afterStatus, remark, operatorType, operatorId, ip)
+writeAdminLog(adminId, action, result, details, module, ip)
}
class Log {
+info(message, context)
+warning(message, context)
+error(message, context)
+setMinLevel(level)
+setSampleRate(rate)
+setMaxPerMinutePerKey(max)
+clean(keepDays)
}
AuditService --> "写入" DB : "user_log/admin_log/book_log"
Log --> "写入" FS : "storage/log/*.log"
性能与容量规划
- 写入性能
- 审计日志为单条插入,建议在数据库层面为 created_at、user_id、admin_id、module、action 建立合适索引以提升查询效率。
- 通用日志采用按日文件追加写入,注意磁盘 I/O 与锁竞争;在高并发场景可考虑异步落盘或外部日志收集。
- 容量规划
- 文件日志:根据站点访问量与日志级别估算每日大小,设定保留天数与轮转策略。
- 数据库日志:按业务增长预估表体积,制定归档与清理周期。
- 采样与限流
- 合理设置采样率与每分钟同 key 上限,避免热点日志打满磁盘或数据库。
故障排查指南
- 无法写入审计日志
- 检查数据库连接与表权限;确认 AuditService 是否被正确注入 Request 与 IP。
- 核对 action 是否为有效常量,非法值会抛出异常。
- 无法查看后台操作日志
- 确认 ManagerService 的过滤条件是否正确(用户名/管理员ID/模块/IP/日期范围)。
- 检查权限边界:非 ALL 权限管理员只能看到自身日志。
- 文件日志过大或丢失
- 检查 Log::clean 是否按计划执行;调整 keepDays。
- 检查采样率与限流配置是否过严导致日志缺失。
- 敏感信息泄露
- 确认敏感键名清单已覆盖新增字段;检查 URL 查询串是否包含敏感参数。
结论
DouPHP 的审计日志体系以“业务埋点 + 审计服务 + 通用日志”为核心,既满足合规与可追溯性要求,又兼顾性能与安全。通过统一的审计写入接口、完善的运行日志能力与管理端查询界面,可实现对用户行为、管理员操作与系统运行的全面监控。建议在生产环境结合集中式日志平台与定期清理策略,确保系统稳定与数据安全。
附录:存储、查询与安全策略
- 存储策略
- 数据库:user_log/admin_log/book_log,建议按业务维度建索引。
- 文件:storage/log/log_YYYY-MM-DD.log,按日滚动,支持清理。
- 集中式:通过采集器将文件日志转发至 ELK/Loki 等平台。
- 查询与分析
- 时间范围:YYYY-MM-DD 起止(含当日边界)。
- 用户追踪:基于 user_id 与 created_at 回溯行为序列。
- 操作溯源:基于 admin_id/module/action/details/ip 还原操作链。
- 安全与隐私
- 敏感键名掩码、URL 查询串参数掩码、trace 长度收敛。
- 审计写入前对关键字段进行 XSS 过滤。
- 配置参考
- 应用密钥与调试开关位于配置文件,可根据环境调整。