在 Java 里,日志是开发与调试过程中的关键工具。下面将从基础到高阶,详细讲解 Java 日志的使用方法。
1. System.out.println(初级)
这是最简单的输出日志方式,不过仅适用于临时调试。
public class Main {
public static void main(String[] args) {
System.out.println("程序启动");
int result = add(3, 5);
System.out.println("计算结果: " + result);
}
public static int add(int a, int b) {
return a + b;
}
}
缺点:
- 日志级别无法控制。
- 输出格式不能自定义。
- 无法将日志定向到文件。
2. JUL(Java Util Logging,中级)
JUL 是 Java 内置的日志框架,无需额外添加依赖。
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
private static final Logger logger = Logger.getLogger(Main.class.getName());
public static void main(String[] args) {
logger.info("程序启动");
try {
int result = divide(10, 0);
logger.info("计算结果: " + result);
} catch (Exception e) {
logger.log(Level.SEVERE, "除法运算出错", e);
}
}
public static int divide(int a, int b) {
if (b == 0) {
logger.warning("除数不能为零");
}
return a / b;
}
}
配置文件(logging.properties):
handlers=java.util.logging.ConsoleHandler
.level=INFO
java.util.logging.ConsoleHandler.level=FINE
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
优点:
- 无需额外引入依赖。
- 支持基本的日志级别控制。
缺点:
- 配置不够灵活。
- 社区活跃度较低。
3. Log4j(中级到高级)
Log4j 是一款功能强大的日志框架,需要添加依赖。
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.2</version>
</dependency>
使用示例:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Main {
private static final Logger logger = LogManager.getLogger(Main.class);
public static void main(String[] args) {
logger.info("程序启动");
try {
int result = divide(10, 0);
logger.info("计算结果: {}", result);
} catch (Exception e) {
logger.error("除法运算出错", e);
}
}
public static int divide(int a, int b) {
if (b == 0) {
logger.warn("除数不能为零");
}
return a / b;
}
}
配置文件(log4j2.xml):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="File" fileName="app.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
优点:
- 支持多种输出目标(控制台、文件、数据库等)。
- 灵活的配置方式。
- 高性能。
4. SLF4J + Logback(高级)
这是 Java 日志的标准组合,SLF4J 作为门面,Logback 作为实现。
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
使用示例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
logger.info("程序启动");
try {
int result = divide(10, 0);
logger.info("计算结果: {}", result);
} catch (Exception e) {
logger.error("除法运算出错", e);
}
}
public static int divide(int a, int b) {
if (b == 0) {
logger.warn("除数不能为零");
}
return a / b;
}
}
配置文件(logback.xml):
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
优点:
- 支持参数化日志。
- 自动扫描配置文件变更。
- 高性能异步日志。
5. 最佳实践
-
日志级别使用:
ERROR:系统发生错误时使用。WARN:出现潜在问题时使用。INFO:记录系统运行的关键信息。DEBUG:开发调试阶段使用。TRACE:记录详细的执行流程。
-
参数化日志:
// 推荐写法 logger.info("用户 {} 登录成功", username); // 不推荐写法 logger.info("用户 " + username + " 登录成功"); -
异常处理:
try { // 业务逻辑 } catch (Exception e) { logger.error("操作失败", e); } -
日志隔离:
- 不同模块使用不同的 Logger。
- 使用 MDC(Mapped Diagnostic Context)添加上下文信息。
-
性能优化:
- 避免在循环中打日志。
- 使用异步日志处理大量日志。
总结
- 新手:可先使用 JUL。
- 项目:建议采用 SLF4J + Logback 的组合。
- 大型系统:可考虑引入 ELK Stack 进行日志聚合与分析。
通过合理运用日志,能极大提升系统的可维护性和问题排查效率。
1356

被折叠的 条评论
为什么被折叠?



