You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么StreamHandler未捕获日志消息,对应代码运行断言失败?

问题根因

这段代码的核心问题是 java.util.logging.StreamHandler 默认采用带缓冲的输出逻辑,日志内容不会实时写入到传入的 ByteArrayOutputStream 中。
调用 log.info("test") 之后,日志内容仅被写入了 StreamHandler 的内部缓冲区,还没有被刷入到 baos 里,所以此时调用 baos.toByteArray() 拿到的是空数组,触发断言失败。
默认情况下 StreamHandler 只会在三种场景下把缓冲区内容刷入底层输出流:

  • 内部缓冲区被写满
  • StreamHandler 的 close() 方法被调用
  • 写入的日志等级高于等于 Handler 配置的 flushLevel(默认是 Level.SEVERE,info 等级远低于这个阈值,不会触发自动 flush)
修复方案

可以选择以下任意一种方式解决:

  • 手动调用 StreamHandler 的 flush() 方法:
import java.io.ByteArrayOutputStream;
import java.util.logging.SimpleFormatter;
import java.util.logging.Logger;
import java.util.logging.StreamHandler;

Logger log = Logger.getLogger("foo");
log.setUseParentHandlers(false);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 先持有Handler实例,不要直接匿名添加
StreamHandler handler = new StreamHandler(baos, new SimpleFormatter());
log.addHandler(handler);
log.info("test");
handler.flush(); // 手动将缓冲区内容刷入baos
assert baos.toByteArray().length > 0;
  • 打印完日志后关闭 StreamHandler,close 操作会自动触发 flush:
log.info("test");
handler.close();
assert baos.toByteArray().length > 0;
  • 自定义 StreamHandler 的 flushLevel 为 Level.INFO,这样 info 及以上等级的日志写入后会自动触发 flush。

内容的提问来源于stack exchange,提问作者yegor256

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:24:03