java中logger默认不输出日志,因根handler的level被设为off;需手动添加consolehandler并设level,且logger与handler的level须同时满足才输出。

Java里Logger默认不输出日志?因为根处理器被禁用了
Java自带的java.util.logging(JUL)默认配置下,Logger对象看似“没反应”,不是代码写错了,而是LogManager初始化时把根Handler关了——它只留了个ConsoleHandler,但设了level = OFF。所以哪怕你调用logger.info("hello"),也啥都不打。
实操建议:
- 手动给
Logger加ConsoleHandler:Logger logger = Logger.getLogger("myapp"); logger.addHandler(new ConsoleHandler()); logger.setLevel(Level.INFO); - 或者改全局配置:在
logging.properties里设.handlers=java.util.logging.ConsoleHandler,并确保java.util.logging.ConsoleHandler.level=INFO - 别漏掉
logger.setUseParentHandlers(false),否则日志会重复输出(父logger再走一遍默认静默链)
怎么让Level真正生效?注意继承链和Handler独立级别
Level不是开关,是两级过滤:先过Logger自己的level,再过每个Handler自己的level。两者都得≥当前日志级别,才能输出。比如logger.setLevel(Level.WARNING),但ConsoleHandler设成INFO,那INFO日志仍不会出现——因为第一关就拦下了。
常见错误现象:
立即学习“Java免费学习笔记(深入)”;
- 调了
logger.warning("x")却没输出 → 检查logger.getLevel()是不是Level.OFF或低于WARNING - 日志出现在控制台又出现在文件 → 两个
Handler的level都放行了,且logger.setUseParentHandlers(true)(默认值) -
setLevel(Level.ALL)后还是看不到FINE→ConsoleHandler或FileHandler的level仍是INFO,必须单独设
FileHandler路径出错、日志写不进文件?相对路径和权限是关键
FileHandler构造时传的路径是相对于JVM启动目录的,不是类路径、也不是src目录。常见错误是写"logs/app.log",结果程序在/home/user/下运行,却试图往/home/user/logs/app.log写——而该目录可能不存在或无写权限。
实操建议:
- 用绝对路径测试是否能写:
new FileHandler("/tmp/test.log")(Linux/macOS)或new FileHandler("C:\temp\test.log")(Windows) - 创建父目录再初始化:
Files.createDirectories(Paths.get("logs")); new FileHandler("logs/app.log", true); - 第2个参数
true表示追加,不写默认覆盖;第3个参数false(默认)表示不格式化XML,保持纯文本 - 避免在IDE里双击运行——启动目录常是项目根目录;用终端cd进去再
java -jar更可控
为什么Formatter改了但日志还是老样子?Handler没绑定新Formatter
Formatter必须显式set到Handler上,Logger本身不持有Formatter。直接调logger.setFormatter(...)是无效的,编译都不过——Logger根本没有这个方法。
使用场景:
- 想让控制台日志带时间戳和类名 → 给
ConsoleHandler设SimpleFormatter或自定义子类 - 生产环境要结构化日志 → 用
FileHandler配XMLFormatter,但注意解析开销比SimpleFormatter高 - 中文乱码 →
ConsoleHandler默认用系统编码,可重写publish()或换StreamHandler指定Charset
容易被忽略的是:每次新建Handler都要重新setFormatter,复用已有Handler实例时,别以为上次设过就一直有效——除非你确认没被其他代码覆盖。










