JavaSE6️⃣调试:断言&日志

1、断言

断言 Assertion(Java 1.4+)

在代码中的预置检查条件,用于确保代码在运行时满足特定条件。

1.1、语法

使用 assert 关键字,

可指定断言失败后的异常信息,便于调试。

  • 断言成功:表达式为 true,程序正常运行。

  • 断言失败:表达式为 false,抛出 AssertionError 异常。

    assert 表达式;
    assert 表达式 : "异常信息";	// 指定断言失败后的异常信息
    

示例(假设断言已启用)

public static void main(String[] args) {
    int x = 10;
    assert x >= 0;	// ok
    
    x = -10;
    assert x >= 0;	// 抛出 AssertionError 错误
}

1.2、启用断言

启用断言:Java 断言默认关闭,需要向 JVM 传递参数显式启用。

-enableassertions(可简写 -ea

  1. 指定类启用:向 JVM 传递参数 。

    java -ea 类名.java
    # 示例:java -ea Main.java
    
  2. 指定包启用:指定包名,以三个 . 结尾。

    java -ea 包名...
    # 示例:java -ea indi.jaywee.user...
    

1.3、使用时机

Hint:启用断言会影响性能,且断言失败会导致程序异常结束。

  1. 开发/测试环境:可启用断言,方便程序调试。
  2. 生产环境禁用断言以提高性能,使用以下机制。
    1. 异常处理机制:处理代码中的异常。
    2. 日志框架:将程序运行过程中的信息输出到日志中,便于排查和调试。

2、日志

日志(Logging

用于在应用程序中输出信息,方便调试、运维、监控等工作。

2.1、功能

日志框架通常提供以下功能。

作用
记录 输出日志信息
目标处理 将日志输出到不同位置,如控制台、文件、数据库等
格式化 自定义日志输出格式
级别 指定日志级别,如 SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST 等
过滤 按位置、级别等过滤日志

2.2、标准库

java.util.logging.Logger

Java SE 内置日志库。

  1. 日志级别:高于指定级别的日志才会输出
    1. 类型SEVEREWARNINGINFOCONFIGFINEFINERFINEST
    2. 设置:使用 Logger.setLever() 设置日志级别(默认 INFO)。
  2. 支持添加处理器、过滤器、父类日志等功能。

示例

public class MyDemo { 
    public static void main(String[] args) {
        Logger logger = Logger.getGlobal();

        logger.warning("I'm warning!");
        logger.info("I'm info!");
        logger.fine("I'm fine!");
    }
}

输出结果

三月 07, 2023 3:47:50 下午 indi.jaywee.java.MyDemo main
警告: I'm warning!
三月 07, 2023 3:47:50 下午 indi.jaywee.java.MyDemo main
信息: I'm info!

2.3、第三方库(❗)

Java 标准库使用较麻烦,第三方日志库提供更强大的功能。

通常是采用日志门面 + 日志实现的方式。

日志门面:面向接口编程。支持接入多种日志框架,减少应用和具体日志框架的耦合性。

Commons Logging SLF4J(👍)
含义 简单的日志接口 简单日志门面(Simple Logging Facade for Java)
提供者 Apache QOS.ch
日志绑定方式 (静态绑定)编译时 (动态绑定)运行时,可在运行期间替换底层日志框架
性能 - 性能更好,兼容性更佳

日志实现:均由 Apache 提供,根据需要选择。

Log4j Logback(👍)
说明 功能强大,使用方便 Log4j 改进版
线程安全 支持,但可能引起死锁 更稳定的多线程支持,允许在不同程序之间共享日志配置
异步日志 2.x 开始支持 支持
配置方式 文件(propertiesxml 文件(xmlgroovy)、编程(Java、Spring Boot
插件 - 更加丰富
生态圈 拥有更多用户、集成应用支持 更活跃的社区支持
说明 1.x 已淘汰,2.x 之后较少更新维护 持续更新发展中

过去主流是 Commons Logging + Log4j

目前趋势是 SLF4J + Logback

2.3.1、日志门面

Commons Logging

特点

  1. 日志实现支持:自动发现类路径下可用的日志系统,按以下优先级。
    1. Log4j
    2. JDK Logging
    3. LogKit
  2. 日志级别
    1. FATAL:致命错误
    2. ERROR:一般错误
    3. WARN:警告信息
    4. INFO:一般信息(默认)
    5. DEBUG:调试信息
    6. TRACE:详细跟踪信息
  3. 日志绑定类装载时动态绑定

org.apache.commons.logging

  1. Log 接口:定义日志记录的方法。

  2. LogFactory 类:用于获取 Log 实例

    public class Main {
        // 获取实例
        private static final Log LOG = LogFactory.getLog(Main.class);
    
        public static void foo() {
            // 输出日志
            LOG.info("foo");
        }
    }
    

SLF4J

特点:更加灵活,性能更好。

  1. 日志实现支持:自动发现类路径下可用的日志系统,按以下优先级。
    1. Log4j
    2. Logback(通常)
    3. JDK Logging
    4. SimpleLogger
  2. 日志级别:支持 6 种日志级别,与 Commons Logging 相同。
  3. 日志绑定编译时静态绑定,性能更好。

org.slf4j

  1. Logger接口:定义日志记录的方法。

  2. LoggerFactory 类:用于获取 Logger 实例

    public class Main {
        // 获取实例
        private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
    
        public static void foo() {
            // 输出日志
            LOGGER.info("foo");
        }
    }
    

2.3.2、日志实现

Log4j:组件化设计的日志系统

主要组件:

  1. Logger:记录日志信息。

  2. Filter:过滤日志信息。

  3. Layout:将日志信息转换为指定格式的字符串。

  4. Appender:指定输出目的地。

    ┌────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌─────────┐
    │ Logger │───>│  Filter  │───>│  Layout  │───>│ Appender │───>│  目的地  │
    └────────┘    └──────────┘    └──────────┘    └──────────┘    └─────────┘
    

Logback:Log4j 的继承者

在 Log4j 功能的基础上,具有更高性能和更丰富的特性。

posted @ 2023-03-07 23:05  Jaywee  阅读(32)  评论(0编辑  收藏  举报

👇