一次接入,统一应用日志、访问日志与审计日志。
官方网站 · 在线文档 · Java API · Maven Central
UniLog 是面向企业级 Spring Boot 应用的统一日志框架。它通过一个 Starter
收敛日志后端、结构化字段、请求关联、安全脱敏、文件滚动和采集规范,让业务团队
不再为每个项目重复维护 logback.xml、log4j2.xml 与日志平台适配代码。
项目覆盖两条兼容线:
| 兼容线 | Java | Spring Boot 基线 | Logback | Log4j2 | 推荐用途 |
|---|---|---|---|---|---|
| Legacy | 8 | 2.7.18 | 支持 | 支持 | 仅用于存量系统治理与迁移过渡 |
| Modern | 17+ | 3.5.16、4.1.0 | 支持 | 支持 | 新系统默认选择 |
两条线共享 unilog-core:业务代码只依赖 SLF4J 和统一 API,不直接依赖 Logback、Log4j2,也不需要因升级 Java 改写日志调用。
- 生产格式:单行 UTF-8 ECS JSON(NDJSON),本地开发使用可读文本。
- 三类物理通道:
application、access、audit,分别检索、滚动、限额和授权。 - 关联字段:
trace.id、span.id、request.id;自动桥接 Spring/Micrometer 常见的traceId、spanId。 - 文件滚动:UTC 按天 + 按大小双触发,GZIP 压缩,186 天时间窗,另设总容量上限。
- 容器:只写 stdout,由 Filebeat/Fluent Bit 采集,集中平台执行 186 天生命周期。
- 虚机/物理机:应用内滚动,禁止再用 logrotate 重命名同一活动文件。
- 普通日志与访问日志:有界异步、队列满时阻塞,不静默丢弃。
- 审计日志:强制 actor/结果/描述,自动事件 ID 与发生时间,同步本地证据并可双写不可变存储。
- 安全请求上下文:关联 request/trace、稳定用户 ID、可信来源 IP 和单向 session 引用。
- 安全:控制字符中和、敏感键自动掩码、字段和值长度上限、禁止默认调用任意对象
toString()。 - 治理:字段保留区、稳定事件名、错误码命名空间、Semgrep 规则、验收脚本、容量计算器。
flowchart LR
A["Spring Boot 业务应用"] --> B["UniLog Starter"]
B --> C["application<br/>业务事件"]
B --> D["access<br/>HTTP 访问"]
B --> E["audit<br/>审计事件"]
C --> F{"输出模式"}
D --> F
E --> F
F -->|console| G["容器 stdout"]
F -->|file| H["滚动 JSON 文件"]
G --> I["Filebeat / Fluent Bit"]
H --> I
I --> J["Elasticsearch / OpenSearch"]
UniLog 负责应用侧“生成一致、可关联、可治理的日志”;采集、索引生命周期、访问控制 和不可变归档由平台侧负责。两者共同构成完整的生产日志链路。
先选择与你的项目完全一致的独立指南:
| 运行基线 | Logback | Log4j2 |
|---|---|---|
| Java 8 + Spring Boot 2.7 | 接入步骤 | 接入步骤 |
| Java 17+ + Spring Boot 3.5 | 接入步骤 | 接入步骤 |
| Java 17+ + Spring Boot 4.1 | 接入步骤 | 接入步骤 |
每条路线都包含 Maven、Gradle、application.yml、Lombok 根目录文件位置、依赖树检查
和完整示例。公共第一步是从 Maven Central 导入 BOM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>dev.flyfish</groupId>
<artifactId>unilog-bom</artifactId>
<version>2.2.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>然后只增加所选路线对应的一个 Starter。以 Spring Boot 3 + Logback 为例:
<dependency>
<groupId>dev.flyfish</groupId>
<artifactId>unilog-spring-boot3-starter-logback</artifactId>
</dependency>在 src/main/resources/application.yml 写入:
spring:
application:
name: order-service
flyfish:
unilog:
mode: console # local | console | file | both | auto
environment: prod
retention-days: 186本地开发将 mode 设为 local,控制台会按 APP / HTTP / AUDIT 输出紧凑文本;
生产的 console、file 和 both 仍输出完整 ECS JSON。
在业务源码包建立自己的日志目录,事件、字段和错误码只定义一次:
public final class OrderLogCatalog {
public enum Event implements LogEventName {
ORDER_CREATED("order.created"),
ORDER_CREATION_FAILED("order.creation.failed");
private final String value;
Event(String value) { this.value = value; }
public String value() { return value; }
}
public enum Field implements LogFieldName {
ORDER_ID("business.order.id");
private final String value;
Field(String value) { this.value = value; }
public String value() { return value; }
}
public enum Error implements LogErrorCode {
ORDER_CREATION_FAILED("ORDER-1007");
private final String value;
Error(String value) { this.value = value; }
public String value() { return value; }
}
}使用类型安全目录记录业务日志:
log.info(
OrderLogCatalog.Event.ORDER_CREATED,
LogOutcome.SUCCESS,
LogFields.of(
OrderLogCatalog.Field.ORDER_ID, orderId,
CommonLogField.LABELS_CHANNEL, "web"
)
);框架内置通用审计动作和分类,标准权限动作无需再写字符串:
auditLogger.log(AuditEvent.builder(StandardAuditAction.PERMISSION_GRANTED)
.outcome(LogOutcome.SUCCESS)
.actor(AuditActorType.ADMIN, operatorId)
.target("role", "finance-admin")
.description("Grant finance-admin role")
.reason(ticketNo)
.build());使用 Lombok 时,lombok.config 必须与 pom.xml 或 build.gradle 同级,不能放进
src/main/resources。完整文件树、依赖与 @CustomLog 示例见
业务日志目录、Lombok 与审计接入。
| 模式 | 输出 | 使用场景 |
|---|---|---|
local |
可读文本 stdout | 本地开发;不得用于生产采集 |
console |
ECS JSON stdout | Kubernetes、Docker、云原生,生产默认 |
file |
ECS JSON 文件 | 虚机、物理机、纯内网部署 |
both |
stdout + 文件 | 迁移期;长期使用会导致双份成本 |
auto |
dev/local/test→local,其余→console | 默认行为 |
unilog-core/ Java 8 字节码;统一 API、上下文、安全与领域策略
unilog-logback-support/ Java 8 字节码;受控 MDC 的 ECS Logback 编码器
unilog-log4j2-support/ Java 8 字节码;受控 MDC 的 ECS Log4j2 序列化器
unilog-spring-boot2-autoconfigure/ javax.servlet;Spring Boot 2.7
unilog-spring-boot3-autoconfigure/ jakarta.servlet;Spring Boot 3/4
unilog-*-starter-logback/ Logback 一键依赖
unilog-*-starter-log4j2/ Log4j2 一键依赖
examples/ 六套完整示例
ops/ Filebeat、Fluent Bit、ILM/ISM、K8s、systemd
policies/ Semgrep、Maven Enforcer 治理模板
tools/ 架构、文档、Schema、安全与兼容性检查
scripts/ 全量构建与示例启动脚本
docs/ 架构、规范、迁移、运维与推广手册
业务服务应优先只导入 dev.flyfish.unilog.api。bootstrap、context、http、security、spring.*、logback 与 log4j2 包属于框架扩展或适配层;除明确扩展点外,不建议在业务代码中直接依赖。Java 源码禁止内联完全限定类名,统一使用显式 import;日志 XML 中的实现类名是框架插件实例化语法,不适用 Java 导入规则。
bash scripts/verify-distribution.sh
./mvnw -B -ntp clean verify
bash scripts/check-dependency-tree.sh
bash scripts/smoke-examples.shJava 8 运行时单独验证:
./mvnw -B -ntp \
-pl examples/java8-logback-demo,examples/java8-log4j2-demo \
-am verify- 从 Maven Central 导入并锁定
dev.flyfish:unilog-bom:2.2.1,禁止业务项目直接漂移子模块版本。 - 根据真实峰值计算总容量上限;容量上限小于 186 天日志量时,会提前删除旧文件。
- 容器生产必须配置集中日志平台的 186 天生命周期,不把容器节点磁盘当长期留存介质。
- 审计日志必须进入独立索引、独立权限和不可变归档;同步本地文件不等于不可抵赖。
- Log4j2 项目必须彻底排除默认 Logback,启动时检测到双后端会直接失败。
- 生产禁止记录原始请求/响应正文、Cookie、Authorization、令牌、密码、身份证、银行卡等敏感值;具体业务审计事件只能显式选择经过审批的标量快照字段。
- 自动 HTTP access 日志适配 Spring MVC Servlet 栈:Boot 2 使用
javax.servlet,Boot 3/4 使用jakarta.servlet。 - 应用提供一个
UniLogIdentityProviderBean 后,认证用户的稳定 ID 会自动进入作用域内的 application、最终 access 和使用同一上下文的 audit 事件;租户等强业务身份字段使用受控命名空间。 - WebFlux、网关自定义 Netty 管线、消息消费、批处理和定时任务仍可直接使用
unilog-core,但不会自动生成 Servlet access 事件;应在各自处理边界显式记录完成事件。 - access 永远只记录访问元数据,不记录请求体或响应体。只有具体
AuditEvent显式调用requestFields/responseFields时才会保留经过字段级数据分级、脱敏和审批的业务快照;框架没有全局 Body 抓取器。 - 本地文件的
totalSizeCap优先保护磁盘。当容量不足以容纳 186 天数据时,旧文件会早于 186 天删除;严格留存必须由 Elasticsearch/OpenSearch 生命周期和归档存储共同保证。 mvnw/mvnw.cmd是安全启动器,调用已安装且受信任的 Maven,不会自动下载 Maven Wrapper 二进制。CI 或开发机需预装 Maven 3.8.6+。
| 文档 | 内容 |
|---|---|
| 执行摘要 | 管理层决策、双版本基线与推广目标 |
| 架构与兼容矩阵 | 模块边界、Java/Spring Boot/Servlet 兼容关系 |
| 日志输出规范 | JSON 格式、事件名、字段与示例 |
| 级别与粒度 | TRACE/DEBUG/INFO/WARN/ERROR 使用边界 |
| 接入路线选择 | 按 Boot 版本和日志后端选择独立指南 |
| 业务目录与 Lombok | 类型安全常量、根目录配置、身份与审计 |
| 完整配置参考 | 全量配置项、优先级、环境模板和文件布局 |
| 运维与留存 | 186 天、容量、滚动、采集与故障处理 |
| 安全与审计 | 敏感数据、日志注入、审计事件与权限 |
| 可观测性集成 | Trace、Metric、Elastic/OpenSearch 对接 |
| 迁移指南 | 存量 Logback/Log4j2 项目迁移步骤 |
| 故障排查 | 双绑定、配置未生效、磁盘与异步问题 |
| 字段字典 | 公司字段注册和 ECS 映射 |
| 推广治理 | 试点、版本治理、门禁与责任分工 |
| 验收清单 | 发布前技术、运行与合规验收 |
| 代码架构与约定 | 包边界、设计模式、API 与代码门禁 |
| 1.x → 2.x 迁移 | 坐标、包名、配置前缀和运维模板迁移 |
| 文件文档策略 | 各类文件注释与机器可读格式例外 |
| 运行时安全边界 | 可信代理、MDC、审计、失败策略与非目标 |
| 审计追溯接入 | 强制字段、安全上下文、不可变存储与失败策略 |
| Maven Central 发布 | 发布模块、签名、验证、工作流与不可变版本门禁 |
UniLog 采用 Apache License 2.0 开源。欢迎通过 Issue 反馈问题、通过 Pull Request 提交改进;提交前请阅读 CONTRIBUTING.md。安全漏洞不要公开披露,请按照 SECURITY.md 使用 GitHub 私密漏洞报告。
当前源码已完成 80 项离线结构与策略检查、包含 18 个模块和 54 项测试的 Maven 全量 构建、真实 JDK 8 Legacy 构建,以及六套示例的 JDK 8/21 端到端 NDJSON 冒烟测试。 CI/发布门禁可复现这些检查:
bash scripts/verify-distribution.sh
bash scripts/build-legacy-java8.sh
bash scripts/build-modern-java17.sh
JAVA8_HOME=/path/to/jdk8 JAVA17_HOME=/path/to/jdk17 bash scripts/smoke-examples.sh详细结果见 交付验证报告。