Java.util.logging (JUL) 终极指南:从基础配置到高级玩法

一、快速入门:JUL基础用法

1. 基础日志输出

java 复制代码
import java.util.logging.Logger;
import java.util.logging.Level;

public class BasicJUL {
    // 获取Logger实例(推荐使用类全限定名)
    private static final Logger LOG = Logger.getLogger(BasicJUL.class.getName());

    public static void main(String[] args) {
        // 输出不同级别日志
        LOG.info("程序启动");     // 信息级别
        LOG.warning("内存不足");  // 警告级别
        LOG.severe("致命错误");   // 严重错误
        
        // 带参数的日志
        String userName = "张三";
        LOG.log(Level.INFO, "用户登录: {0}", userName);
        
        // 记录异常
        try {
            throw new IOException("文件未找到");
        } catch (IOException e) {
            LOG.log(Level.SEVERE, "发生IO异常", e);
        }
    }
}

二、核心配置:logging.properties详解

1. 默认配置问题

  • 默认级别:INFO(只输出INFO及以上级别)

  • 默认输出:控制台(ConsoleHandler)

  • 默认格式:简单文本(无时间戳)

2. 自定义配置文件

ini 复制代码
# logging.properties
# 全局日志级别
.level= INFO

# 控制台处理器配置
handlers= java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=[%1$tF %1$tT] [%4$-7s] %5$s %n

# 文件处理器配置
handlers= java.util.logging.FileHandler
java.util.logging.FileHandler.pattern = ./logs/app_%u.log
java.util.logging.FileHandler.limit = 10485760  # 10MB
java.util.logging.FileHandler.count = 5
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

3. 加载配置文件

csharp 复制代码
// 启动时指定配置文件
public static void main(String[] args) throws IOException {
    InputStream is = BasicJUL.class.getResourceAsStream("/logging.properties");
    LogManager.getLogManager().readConfiguration(is);
    // ...其他代码...
}

三、高级玩法:自定义Handler与Filter

1. 自定义邮件报警Handler

less 复制代码
public class EmailHandler extends Handler {
    @Override
    public void publish(LogRecord record) {
        if (record.getLevel().intValue() >= Level.SEVERE.intValue()) {
            // 调用邮件发送API
            sendAlertEmail(record.getMessage());
        }
    }

    @Override public void flush() {}
    @Override public void close() {}
    
    private void sendAlertEmail(String msg) {
        // 实现邮件发送逻辑
    }
}

// 注册自定义Handler
LOG.addHandler(new EmailHandler());

2. 日志 过滤器

less 复制代码
// 只记录包含特定关键字的日志
LOG.setFilter(record -> record.getMessage().contains("支付"));

// 组合过滤条件
LOG.setFilter(record -> 
    record.getLevel() == Level.SEVERE || 
    record.getMessage().startsWith("用户")
);

四、性能优化:避免常见陷阱

1. 参数化日志(避免无效字符串拼接)

less 复制代码
// 错误写法(即使日志级别关闭也会执行字符串拼接)
LOG.fine("用户信息:" + user.toString());

// 正确写法(使用lambda延迟计算)
LOG.fine(() -> "用户信息:" + user.toString());

2. 异步日志处理

scala 复制代码
// 自定义异步Handler
public class AsyncHandler extends Handler {
    private final Executor executor = Executors.newSingleThreadExecutor();

    @Override
    public void publish(LogRecord record) {
        executor.execute(() -> {
            // 转发给其他Handler处理
            getHandlers().forEach(h -> h.publish(record));
        });
    }
    // ...其他方法...
}

// 使用方式
Handler asyncHandler = new AsyncHandler();
asyncHandler.addHandler(new ConsoleHandler());
LOG.addHandler(asyncHandler);

五、与其他框架整合

1. 在Spring Boot中使用JUL

ini 复制代码
# application.properties
# 禁用Spring Boot默认的Logback
logging.config=classpath:logging.properties
logging.level.org.springframework=WARN
logging.level.com.yourpackage=DEBUG

2. 与SLF4J 桥接

xml 复制代码
<!-- pom.xml -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jul-to-slf4j</artifactId>
    <version>2.0.7</version>
</dependency>
arduino 复制代码
// 启动类配置
public class Main {
    static {
        SLF4JBridgeHandler.removeHandlersForRootLogger();
        SLF4JBridgeHandler.install();
    }
}

六、常见问题排雷指南

问题现象 解决方案
日志文件不生成 检查文件路径权限,确认FileHandler配置正确
日志级别设置不生效 确保没有代码动态修改Logger级别
日志格式混乱 检查SimpleFormatter.format的转义字符
性能低下 使用异步Handler,避免同步阻塞
第三方库日志过多 单独设置包级别:com.third.package.level = WARNING

JUL哲学

虽然功能不如 Log4j / Logback 强大,但JUL作为Java 标准库

  • 无需额外依赖,适合简单应用

  • 可通过配置满足基本需求

  • 与其他日志框架桥接方便

适合场景

  • 小型工具/脚本
  • 对日志要求不高的场景
  • 需要避免第三方依赖的项目
相关推荐
不务专业的程序员--阿飞11 分钟前
JVM无法分配内存
java·jvm·spring boot
你的人类朋友12 分钟前
JWT的组成
后端
李昊哲小课15 分钟前
Maven 完整教程
java·maven
Lin_Aries_042124 分钟前
容器化简单的 Java 应用程序
java·linux·运维·开发语言·docker·容器·rpc
脑花儿31 分钟前
ABAP SMW0下载Excel模板并填充&&剪切板方式粘贴
java·前端·数据库
北风朝向1 小时前
Spring Boot参数校验8大坑与生产级避坑指南
java·spring boot·后端·spring
闭着眼睛学算法1 小时前
【华为OD机考正在更新】2025年双机位A卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
java·c语言·javascript·c++·python·算法·华为od
山海不说话1 小时前
Java后端面经(八股——Redis)
java·开发语言·redis
哈哈很哈哈1 小时前
Flink SlotSharingGroup 机制详解
java·大数据·flink
canonical_entropy1 小时前
一份关于“可逆计算”的认知解码:从技术细节到哲学思辨的完整指南
后端·低代码·deepseek