Solon 的日志设计哲学:不只是用 SLF4J 做统一门面

每个 Java 项目都需要日志。每个 Java 开发者都有一两个关于日志配置的"战争故事"——那个膨胀到 200 行的 XML、互相打架的桥接包、深夜因为日志级别没控制好打满磁盘的报警。

Solon 换了一种做法:保留行业标准(SLF4J),但用一段 YAML 替代了 XML 配置的混乱。日志配置不再是一个需要单独学习的"副项目",而是应用配置的自然延伸。

全栈:SLF4J 直通

Solon 原生使用 SLF4J 作为日志门面,没加任何私有包装层:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OrderService {
    static final Logger log = LoggerFactory.getLogger(OrderService.class);

    public void createOrder(Order order) {
        log.info("创建订单: {}", order.getId());
    }
}

没有桥接,没有适配器,没有额外依赖。如果你用过 SLF4J,你已经在用 Solon 的日志 API 了。

五个插件,一套配置

Solon 提供了五种日志实现,每种都对接同一套配置模型。切换实现只需换一个依赖:

插件 添加器支持 适用场景
solon-logging-simple console, cloud 测试/轻量,不产生本地日志文件
solon-logging-logback console, file, cloud 生产推荐(Logback 1.3.x, Java 8+)
solon-logging-logback-jakarta console, file, cloud Jakarta 命名空间(Logback 1.5.x, Java 11+)
solon-logging-log4j2 console, file, cloud 团队统一使用 Log4j2
water-solon-cloud-plugin console, cloud Water 服务治理平台对接

加入一个依赖就完成了配置:

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-logging-logback</artifactId>
</dependency>

就这样。不需要 logback.xml,不需要 log4j2.xml——除非你需要高级定制。

配置:一段 YAML 搞定

所有日志配置集中在 solon.logging.appendersolon.logging.logger 两个字段下:

solon:
  app:
    name: demoapp

solon.logging.appender:
  console:
    level: TRACE
    enable: true
    pattern: "%highlight{%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} #%5X{pid} [-%t][*%X{traceId}]%tags[%logger{20}]:} %n%msg%n"
  file:
    name: "logs/${solon.app.name}"
    level: INFO
    enable: true
    extension: ".log"
    maxFileSize: "10 MB"
    maxHistory: "7"
    pattern: "%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} #%5X{pid} [-%t][*%X{traceId}]%tags[%logger{20}]: %n%msg%n"
  cloud:
    level: INFO
    enable: true

框架内置三个添加器:

  • console — 标准输出,默认启用
  • file — 滚动日志文件,默认启用
  • cloud — 远程日志服务,默认关闭

按包控制日志级别

solon.logging.logger:
  "root":
    level: DEBUG
  "com.zaxxer.hikari":
    level: WARN
  "com.demo.order":
    level: INFO

优先级规则很简单:appender 级别 > logger 级别 > root 级别,更具体的配置优先。

五个级别,标准语义

TRACE < DEBUG < INFO < WARN < ERROR

和你一直在用的级别一样。

MDC:SLF4J 标准支持

Solon 直接继承 SLF4J 的 MDC 能力,没有封装私有 API。默认日志 pattern 中已经包含了 %X{pid}(进程 ID)和 %X{traceId}(分布式链路追踪 ID),这些由框架自动填充。

如果需要自定义上下文,用标准 SLF4J 方式:

import org.slf4j.MDC;

MDC.put("orderId", order.getId());
log.info("处理支付");
MDC.remove("orderId");

没有 Solon 专属的 MDC 包装类,就是原生 SLF4J。

自定义添加器

内置添加器不够用时,继承 AppenderBase

package demo.log;

import org.noear.solon.logging.event.AppenderBase;
import org.noear.solon.logging.event.LogEvent;

public class JsonAppender extends AppenderBase {
    @Override
    public void append(LogEvent logEvent) {
        String json = toJson(logEvent);
        send(json);
    }
}

app.yml 中注册:

solon.logging.appender:
  json:
    level: INFO
    class: demo.log.JsonAppender

异步批量日志:PersistentAppenderBase

对于高吞吐场景,Solon 提供了 PersistentAppenderBase——一个将日志事件缓冲后批量刷盘的基类:

package demo.log;

import org.noear.solon.logging.persistent.PersistentAppenderBase;
import org.noear.solon.logging.event.LogEvent;
import org.noear.solon.Solon;

public class DatabaseAppender extends PersistentAppenderBase {
    LogService logService;

    public DatabaseAppender() {
        Solon.context().getBeanAsync(LogService.class, bean -> {
            logService = bean;
        });
    }

    @Override
    public void onEvents(List<LogEvent> list) {
        if (logService != null) {
            logService.insertList(list);
        }
    }
}

适合将日志写入数据库、Elasticsearch 或其他远程存储,不阻塞请求线程。批量写入在高负载下能显著降低 I/O 开销。

高级定制:XML 逃生门

如果 YAML 不满足你的需求,在 classpath 根目录放一个 logback-solon.xmllog4j2-solon.xml 即可。框架会自动识别,且支持环境变体(logback-solon-dev.xmllogback-solon-prod.xml)。

也可以用标准的 logback.xmllog4j2.xml——但这样会失去按环境切换的能力。

云端日志:一个插件的事

分布式环境下,引入 water-solon-cloud-plugin 并启用 cloud 添加器:

solon.logging.appender:
  cloud:
    level: INFO
    enable: true

日志自动上报 Water 服务治理平台,无需额外部署日志采集 agent。

诚实地说

Solon 的日志模块不会替代完整的可观测性管道(Logstash + Elasticsearch、Loki + Grafana)。但对绝大多数项目来说,它覆盖了所有日常需求:

  • ✅ SLF4J 原生,告别桥接依赖
  • ✅ YAML 驱动,告别 XML 样板代码
  • ✅ 三个内置添加器(console / file / cloud)
  • ✅ 自定义添加器支持
  • ✅ 异步批量持久化
  • ✅ MDC 开箱即用
  • ✅ 按包控制日志级别
  • ✅ 环境感知配置切换
  • ✅ Logback/Log4j2 XML 逃生门

设计哲学和 Solon 的其他模块一样:用最少的配置解决最常见的问题,需要定制时绝不挡路。


如果你想了解完整的插件列表和配置参考,官方文档在 solon.noear.org

posted @ 2026-08-11 14:36  带刺的坐椅  阅读(40)  评论(0)    收藏  举报