跳转到正文

日志业务重点文件与方法

Java 包名及文件开关的升级映射见接入调整

重点覆盖跨后端查询门面、MQ 协议与投递、JSON Lines 保存以及迁移编排。采集上下文和记录器见 Component 日志方法,具体后端选择见日志存储

本页按重点文件查阅方法;表内方法名可打开源码。重载共享的约束写在表前,差异在各行说明。源码链接固定到核对版本,接入前提见快速开始

SystemLogQueryService

源码:SystemLogQueryService

查询门面。每次调用从 ObjectProvider 按 own.system-log.query.backend 选择唯一候选;未设置 backend 时也必须恰好只有一个 Provider,否则抛业务异常。构造器由 Lombok 生成,参数是 ObjectProvider<SystemLogQueryProvider> 和 SystemLogQueryProperty。

方法 / 重载用途、参数与返回值注意事项
page(SystemLogQuery query)委托选定后端分页,返回 PageModel<SystemLogVo>。query 非 null,不自动限定当前用户。
pageForUser(SystemLogQuery query, Long userId)覆盖 query.userId 后分页。userId 非 null;会修改 Query,不可在多个用户请求间共享。
getById(String id)按字符串 ID 查询,向 Provider 传 userId=null。不限制用户;是否缺失返回 null 由 Provider 处理。
getByIdForUser(String id, Long userId)将 ID 与非 null 用户 ID 一同交给 Provider。id 是后端统一 String,不要求都可转 Long。
getByTraceId(String traceId)按 TraceId 返回单条 VO。不是整个链路列表,TraceId 不一定唯一。
getByTraceIdForUser(String traceId, Long userId)按 TraceId 与非 null 用户 ID 查询。必须让后端在选择记录时限定用户,不能先随意取一条再当完整结果。
statsForTimeRange(SystemLogStatsTimeRangeQuery query)返回时间统计分组 List<ChildrenItemModel<ItemCountModel,ItemCountModel>>。仅支持统计的 Provider 可用,不自动当前用户过滤。
statsForUserTimeRange(SystemLogStatsTimeRangeQuery query)返回用户与时间分组统计 List<ChildrenItemModel<ItemCountModel,ItemLongCountModel>>。字段和时间口径以统计后端为准。
statsForUserCountTimeRange(SystemLogStatsTimeRangeQuery query)返回用户数量统计 List<ItemCountModel>。不等于日志条数;onlyApp 等条件看实现。
statsForDeviceCountTimeRange(SystemLogStatsTimeRangeQuery query)返回设备统计分组 List<ChildrenItemModel<ItemCountModel,ItemCountModel>>。无统计能力的 Provider 抛“不支持统计查询”,不是空列表。

SystemLogQueryProvider

源码:SystemLogQueryProvider

后端实现的公共契约。RDBMS、MongoDB、ClickHouse、Elasticsearch 的 Query→原生条件映射并不完全相同。新增 Provider 要明确空结果、时间时区、ID 和用户隔离语义。

方法 / 重载用途、参数与返回值注意事项
backend()返回 SystemLogQueryBackendEnum,用于门面选取。相同 backend 多 Bean 会导致候选不唯一。
page(SystemLogQuery query)实现分页并转成公共 PageModel<SystemLogVo>。仅映射实际支持条件,不能忽略 userId 隔离。
getById(String id, Long userId)按 ID 查单条;userId=null 表示管理范围,否则限定归属。不要把无法转换的 ID 无条件当成数据库异常。
getByTraceId(String traceId, Long userId)按链路和可选用户取一条。TraceId 不是权限凭证;多条时选择策略需明确。
statsForTimeRange(SystemLogStatsTimeRangeQuery query)扩展时间分组统计;默认抛 BusinessSimpleException。当前只有 Elasticsearch Provider 覆盖统计,不能据接口存在推断所有后端支持。
statsForUserTimeRange(SystemLogStatsTimeRangeQuery query)扩展用户时间分组统计;默认抛 BusinessSimpleException。当前只有 Elasticsearch Provider 覆盖统计,不能据接口存在推断所有后端支持。
statsForUserCountTimeRange(SystemLogStatsTimeRangeQuery query)扩展用户数量统计;默认抛 BusinessSimpleException。当前只有 Elasticsearch Provider 覆盖统计,不能据接口存在推断所有后端支持。
statsForDeviceCountTimeRange(SystemLogStatsTimeRangeQuery query)扩展设备分组统计;默认抛 BusinessSimpleException。当前只有 Elasticsearch Provider 覆盖统计,不能据接口存在推断所有后端支持。

在已注入 SystemLogQueryService logs 的可信后台方法中,按当前用户查询应传独立 Query。import 为 com.own.business.system.log.entity.query.SystemLogQuery

java
var query = new SystemLogQuery();
var page = logs.pageForUser(query, authenticatedUserId);
// authenticatedUserId 取自已认证身份,不能直接采用请求中任意 userId。

SystemLogMqMessageCodec

源码:SystemLogMqMessageCodec

MQ 使用 UTF-8 JSON,type=own.system-log.v1。只校验协议所需结构和大小,不自动执行采集快照的脱敏/限深规则。

方法 / 重载用途、参数与返回值注意事项
encode(SystemLog log)验证 ID、operator、operation/startedAt、response/completedAt,序列化为 byte[],再检查最大 65536 字节。缺结构抛 IllegalArgumentException;序列化可抛 IOException;没有创建 Exchange 或发送消息。
decode(byte[] bytes)先检查非空及 <=65536 字节,再解析 SystemLog 并验证完整性。禁止尾随 JSON token;结构/大小异常与 JSON 解析异常分别传播。

RabbitProducerSystemLogPersistence

源码:RabbitProducerSystemLogPersistence

作为转发保存器实现 SystemLogForwardingPersistence。Lombok 构造器接收专用 RabbitTemplate 与 producer 配置;声明 AutoCloseable 管理该模板资源。

方法 / 重载用途、参数与返回值注意事项
save(SystemLog log)编码后发送持久化消息,设置 type/contentType/messageId/TraceId,等待 correlated confirm。nack、returned、超时均失败;确认成功只表示 Broker 接收,不等于消费者已保存。中断恢复标记。
close()调用 template.destroy 释放专用模板。生命周期结束使用,不在每条消息后调用;不要传共享模板再随意销毁。

SystemLogRabbitConsumerListener

源码:SystemLogRabbitConsumerListener

同步消费后分发实际保存器。构造时排除 SystemLogForwardingPersistence,防止再投递回 MQ;必须至少一个实际保存器。

方法 / 重载用途、参数与返回值注意事项
SystemLogRabbitConsumerListener(List<SystemLogPersistence> persistences)过滤转发器并固定实际保存器列表。空列表/仅转发器会构造失败,不能只装 consumer 没有存储实现。
receive(Message message)验证 type/contentType 与 JSON;暂设日志 TraceId,逐个同步保存,最后恢复原 MDC。任一后端失败仍继续其他后端,最终拒绝且不重新入队;之前成功的后端不回滚,重放可能重复。

失败消息是否进入死信队列取决于实际 RabbitMQ 配置,拒绝不等于模块自动配置了重试。采集 enabled=false 不会替代 consumer 自身的启停配置。

SystemLogFileJsonService

源码:SystemLogFileJsonService;实现:SystemLogFileJsonServiceImpl

按原始 SystemLog 写 JSON Lines,不转换为数据库查询 VO。一次写一行完整 JSON,以请求开始日期归档;不提供查询 Provider。

方法 / 重载用途、参数与返回值注意事项
save(SystemLog log)包装成单元素列表,再执行批量路径。log=null 立即抛异常。
save(Collection<SystemLog> logs)转为 Iterable 路径。实现对整个 null 集合无操作,但 null 元素会失败。
save(Iterable<SystemLog> logs)小批迭代、按日期分文件追加。后续批次失败不回滚前面的文件写入。

SystemLogFileJsonServiceImpl

源码:SystemLogFileJsonServiceImpl

正式写入实现;Lombok 构造接收 SystemLogFileJsonProperty。空 Iterable 不创建文件,非空时要求有效 writeBatchSize、savePath 和 filePrefix。

方法 / 重载用途、参数与返回值注意事项
save(Iterable<SystemLog> logs)每批按 TimeUtil.DEFAULT_ZONE_ID 的请求日期分组,写 prefix_日期.jsonl,使用进程锁、文件锁并 force(false)。旧文件末尾不是换行则拒绝追加;不会去重或自动修复残缺尾行。文件锁不能替代跨后端事务。

私有 directory 校验目录与前缀;validateLog 要求原始 ID/身份/起止时间;append 检查尾部并逐行写;writeFully 循环处理部分写入。实现不做迁移调度,重复 save 会重复追加。完整配置与文件样例见日志存储

SystemLogBackupHook

源码:SystemLogBackupHook

迁移适配器契约。输入输出是 SystemLogStandardEntity,源读取和目标保存与实时 SystemLogPersistence 是不同入口。

方法 / 重载用途、参数与返回值注意事项
list(LocalDateTime startTime, LocalDateTime endTime, String sort, int limit)读取下一批标准记录;sort 为源实现的游标,首批空串。游标与时间过滤需要稳定推进;不是普通分页页码。各后端时间边界见迁移页。
save(Collection<SystemLogStandardEntity> list)保存一批标准记录到目标。是否去重/覆盖由目标决定,没有所有目标的原子性。
name()返回迁移后端枚举,用于 origin/target 选择。同名多实现被配置 Map 覆盖,不是全部执行。
before()目标迁移前准备,默认无操作。核心在进入循环前对目标调用,不自动调用源的 before。
after()目标迁移完成后收尾,默认无操作。核心未放 finally;中途异常不保证执行。
ignoreTime()默认 false;false 时下一批 begin 更新为末条请求时间。true 时只推进 searchAfter,不更新时间。
getIdFromStandardEntity(SystemLogStandardEntity source)36 字符 ID 按 UUID 转 Long;其他尝试 parseLong,失败返回 null。36 字符但不是合法 UUID 会抛异常;不是无损可逆的跨后端 ID 协议。

SystemLogBackupHookConfig

源码:SystemLogBackupHookConfig

根据开关、源、目标注册迁移 Hook。构造器接收配置与全部 Hook 列表,检查源与目标不能相同;未启用或配置不足时可只记录日志而不建立选择结果。

方法 / 重载用途、参数与返回值注意事项
SystemLogBackupHookConfig(SystemLogBackupProperty systemLogBackupProperty, List<SystemLogBackupHook> systemLogBackupHookList)按 name() 构建静态映射,再选择 origin 和 targets。重复 name 覆盖;部分目标找不到时列表可能含 null,不能只看列表非空。
getGainBackupHook()返回所选源 Hook。未选中抛“没有指定备份的数据源”。
getSaveBackupHookList()返回目标 Hook 列表。列表未建立抛业务异常;调用前确保每个目标实际有实现。

SystemLogBackupHookCore

源码:SystemLogBackupHookCore

显式、同步执行迁移,不是定时器。应用通过受控后台调用,需先配置源和所有目标并验证目标写入能力。

方法 / 重载用途、参数与返回值注意事项
run(LocalDateTime startTime, LocalDateTime endTime)使用配置 pageSize 委托三参数运行。时间不可 null;不会因方法被注册成 Bean 就自动启动。
run(LocalDateTime startTime, LocalDateTime endTime, int pageSize)目标 before→循环源 list→各目标 save→推进末条时间/游标→可选间隔→目标 after。pageSize 要自行保证正数;任一目标失败中止,已成功写入不回滚,after 不保证执行;不持久化断点。

AdminSystemLogController

源码:AdminSystemLogController

HTTP 前缀 /api/admin/system/log,ResultModel 包装。构造器接收 SystemLogQueryService。

方法 / 重载用途、参数与返回值注意事项
page(SystemLogQuery query)POST /page,返回公共分页 VO。不强制用户范围。
getById(String id)GET /{id},返回单条 VO。String ID;空结果按 Provider 返回,可能 data=null。
getByTraceId(String traceId)GET /trace/{traceId},返回单条 VO。管理端此方法标 @LoginIgnore 且不限定用户,应用需控制公开范围。

AppSystemLogController

源码:AppSystemLogController

HTTP 前缀 /api/app/system/log,ResultModel 包装。构造器接收 SystemLogQueryService。

方法 / 重载用途、参数与返回值注意事项
page(SystemLogQuery query)POST /page,返回公共分页 VO。覆盖当前用户 ID,不采用客户端指定的归属。
getById(String id)GET /{id},返回单条 VO。String ID;空结果按 Provider 返回,可能 data=null。
getByTraceId(String traceId)GET /trace/{traceId},返回单条 VO。使用当前非 null 用户 ID 限定,TraceId 不能绕过归属。

AdminSystemLogStatsController

源码:AdminSystemLogStatsController

HTTP 前缀 /api/admin/system/log/stats。构造器接收查询服务,当前统计依赖 Elasticsearch Provider;方法无独立 PermissionOperation 注解,需核实应用管理端访问策略。

方法 / 重载用途、参数与返回值注意事项
statsForTimeRange(SystemLogStatsTimeRangeQuery query)POST /time/range;返回时间分组统计。不同层级 Item 的含义见日志查询页。
statsForUserTimeRange(SystemLogStatsTimeRangeQuery query)POST /user/time/range;返回用户时间分组。管理范围,不自动当前用户。
statsForUserCountTimeRange(SystemLogStatsTimeRangeQuery query)POST /user/count/time/range;返回用户数量统计。不是下载分页。
statsForUserCountTimeRangeOnlyApp(SystemLogStatsTimeRangeQuery query)POST /only/app/user/count/time/range;强制 query.onlyApp=1 后统计。会修改 Query,其他过滤规则仍由后端决定。
statsForDeviceCountTimeRange(SystemLogStatsTimeRangeQuery query)POST /device/count/time/range;返回设备统计分组。记录未采集到所需字段时不能凭空补全统计。

验证与使用场景

查询请求和模型见日志查询,生产/消费配置与消息确认见RabbitMQ 集中保存,有副作用的历史迁移流程见历史迁移。真实投递、写库与迁移需在已准备的应用环境中按对应场景验证。