Keel Logger API

官方文档:概述与设计、使用指南、扩展与集成及 AI 集成。

View on GitHub

Keel Logger API — AI 集成指南

读者:自动编程助手、代码代理、RAG 检索到的上下文。
目标:在最少试错的前提下,正确调用本库 API、正确扩展适配器与日志类型,并避开已知语义陷阱。

人类可读的设计说明见同目录 概述与设计使用者指南扩展与集成


1. 执行任务前的固定事实(勿臆造)


2. 类型与包 — 速查(生成 import 时用)

用途 类型
通用 Logger Logger, BaseLogger io.github.sinri.keel.logger.api.logger
泛型记录器 SpecificLogger<T>, BaseSpecificLogger<T> 同上
通用一条日志 Log io.github.sinri.keel.logger.api.log
可扩展日志基类 SpecificLog<T> 同上
键值上下文 LogContext 同上
级别 LogLevel io.github.sinri.keel.logger.api
输出契约 LogWriterAdapter, BaseLogWriter, SilentLogWriter io.github.sinri.keel.logger.api.adapter
文本渲染(可继承) LogTextRenderBaseLogWriter 已实现) 同上
工厂 LoggerFactory, BaseLoggerFactory, SilentLoggerFactory io.github.sinri.keel.logger.api.factory
指标 MetricRecord, MetricRecorder io.github.sinri.keel.logger.api.metric
堆栈折叠前缀集合 LoggingStackSpecification.IgnorableCallStackPackageSet io.github.sinri.keel.logger.api

不要引用未导出实现类:ThrowableRenderMetricRecordImplSharedLoggerFactoryHolder(JPMS 下不可访问;语义上也不应依赖)。


3. 选择 API 的决策规则

  1. 只需要字符串日志、类型为 Logger
    new BaseLogger("topic")LoggerFactory / LoggerFactory.getShared().createLogger(Class)

  2. 需要结构化构建(异常、多字段 context)
    → 使用 logger.info(log -> …) / error(log -> …) 等同级别 Consumer 重载,不要在 Consumer 内手动改级别(方法会覆盖为对应级别)。

  3. 需要业务子类字段(审计等)
    → 定义 class X extends SpecificLog<X>,用 protected extra(k,v) 或自有字段;用 factory.createLogger(topic, X::new) 得到 SpecificLogger<X>

  4. 需要统一输出到文件/Vert.x/远端
    → 实现 LogWriterAdapter,注入 BaseLogger 或自定义 BaseLoggerFactory 子类 + LoggerFactory.replaceShared(...)

  5. 需要完全不打日志且尽量少分配
    visibleLevel(LogLevel.SILENT) 或使用 SilentLogger(注意:SilentLogger.visibleLevel(LogLevel) 会抛异常)。

  6. 需要调用路径存在但写入为空(测试/占位)
    SilentLogWriterSilentLoggerFactory;知悉:**默认 BaseLogger 仍可能在高级别下构造 SpecificLog 再交给空适配器 **(与 SILENT 级别短路不同)。

  7. 指标
    MetricRecord.create(...) + 自行持有的 MetricRecorder 实现;不要试图通过 LogWriterAdapter 发送 MetricRecord(无此 API)。


4. 推荐最小正确片段(可复制模板)

4.1 工厂 + 类名作 topic

Logger logger = LoggerFactory.getShared().createLogger(MyClass.class);
logger.

visibleLevel(LogLevel.DEBUG);
logger.

info("started");

4.2 带上下文

logger.warning("slow query",ctx ->ctx.

put("ms",elapsed).

put("sql",sqlHash));

4.3 异常 + context

logger.error(log ->log
        .

message("handler failed")
    .

exception(e)
    .

context("requestId",requestId));

4.4 自定义适配器(骨架)

public final class MyAdapter implements LogWriterAdapter {
    @Override
    public void accept(String topic, SpecificLog<?> log) {
        // 读取 log.timestamp(), log.level(), log.message(), log.context().toMap(), log.exception(), log.extra()
    }
}

4.5 自定义 SpecificLog(骨架)

public final class AuditLog extends SpecificLog<AuditLog> {
    public AuditLog actor(String id) {
        return extra("actor", id);
    }
}
// SpecificLogger<AuditLog> log = factory.createLogger("audit", AuditLog::new);

5. 必须避免的常见错误

错误做法 原因 正确做法
调用 message(LogLevel level, String msg, Object... args) 并假设 log.level() == level 该方法只做可见性判断,SpecificLog 调用 level(level),记录内默认级别仍为构造时的 INFO debug/info/...Consumer 重载
SilentLoggerFactory 等同于「零分配」 工厂创建的是普通 BaseLogger,仅适配器为空 需要短路时用 SILENTSilentLogger
在子类中公开调用父类 extra 以外的随意 Map extra() 返回内部 map;若需稳定序列化契约应明确字段 优先 extra(k,v) 或明确字段 + getter
假设 MetricRecord.labels() 不可变 返回内部可变 map 集成实现若需快照则拷贝
多线程共享 LateObject 且无外部同步 set/get 非并发语义;ensure 的 supplier 可能多次调用 按文档仅在单线程或外部同步下使用

6. 级别语义(生成条件日志时核对)


7. 修改本仓库时的自检清单(AI 改 keel-logger-api 源码用)


8. 检索关键词(供嵌入向量库 / 标题)

Keel Logger API, LogWriterAdapter, SpecificLog, SpecificLogger, BaseLogger, LoggerFactory.getShared, replaceShared, LogLevel SILENT, MetricRecorder, BaseLogWriter, LogTextRender, LoggingStackSpecification, JPMS io.github.sinri.keel.logger.api.