java日志
2025年2月18日大约 4 分钟
JDK日志(java.util.logging=jul)
从jdk1.4起,JDK开始自带一套日志系统。JDK Logger最大的优点就是不需要任何类库的支持,只要有Java的运行环境就可以使用。
JDK默认的logging配置文件为:$JAVA_HOME/jre/lib/logging.properties,可以使用系统属性java.util.logging.config.file指定相应的配置文件对默认的配置文件进行覆盖,比如, java -Djava.util.logging.config.file=myfile
JDK Logging把日志分为如下七个级别,等级依次降低。
级别 | SEVERE | WARNING | INFO | CONFIG | FINE | FINER | FINEST |
---|---|---|---|---|---|---|---|
调用方法 | severe() | warning() | info() | config() | fine() | finer() | finest() |
含义 | 严重 | 警告 | 信息 | 配置 | 良好 | 较好 | 最好 |
如果将级别设置为INFO,则INFO后面的不会输出。info前面的全部输出。通过控制级别达到控制输出的目的。
import java.util.logging.Level;
import java.util.logging.Logger;
public class LogJDKTest {
private static Logger log = Logger.getLogger(LogJDKTest.class.toString());
public static void main(String[] args) {
// all→finest→finer→fine→config→info→warning→server→off
// 级别依次升高,后面的日志级别会屏蔽之前的级别
log.setLevel(Level.INFO);
log.finest("finest");
log.finer("finer");
log.fine("fine");
log.config("config");
log.info("info");
log.warning("warning");
log.severe("server");
}
}
控制台输出:
二月 18, 2025 2:12:12 下午 com.study.LogJDKTest main
信息: info
二月 18, 2025 2:12:12 下午 com.study.LogJDKTest main
警告: warning
二月 18, 2025 2:12:12 下午 com.study.LogJDKTest main
严重: server
1.JDK log默认会有一个控制台输出,它有两个参数,第一个参数设置输出级别,第二个参数设置输出的字符串。
2.同时也可以设置多个输出(Hander),每个输出设置不用的level,然后通过addHandler添加到了log中。
注意:为log设置级别与为每个handler设置级别的意义是不同的。
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class LogJDKTest {
public static Logger log = Logger.getLogger(LogJDKTest.class.toString());
static {
// Handler console = new ConsoleHandler();
// console.setLevel(Level.ALL);
// log.addHandler(console);
Handler console2 = new ConsoleHandler();
console2.setLevel(Level.OFF);
log.addHandler(console2);
}
public static void main(String[] args) {
// all→finest→finer→fine→config→info→warning→server→off
// 级别依次升高,后面的日志级别会屏蔽之前的级别
log.setLevel(Level.INFO);
log.finest("finest");
log.finer("finer");
log.fine("fine");
log.config("config");
log.info("info");
log.warning("warning");
log.severe("server");
}
}
控制台输出:
二月 18, 2025 2:16:41 下午 com.study.LogJDKTest main
信息: info
二月 18, 2025 2:16:41 下午 com.study.LogJDKTest main
警告: warning
二月 18, 2025 2:16:41 下午 com.study.LogJDKTest main
严重: server
Level.ALL,,则所有的信息都会被输出,如果设为 OFF,则所有的信息都不会输出。
logback
Logback 是 SLF4J 的官方实现,相比 Log4j 性能更高、配置更灵活,支持以下核心模块:
- logback-classic:核心模块,提供日志实现。
- logback-core:基础工具库。
- logback-access:与 Servlet 容器集成(Web 应用)。
Maven 依赖
<!-- pom.xml -->
<dependencies>
<!-- SLF4J API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.12</version>
</dependency>
<!-- Logback 实现 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.3</version>
</dependency>
</dependencies>
默认配置文件路径
- logback.xml 放置在
src/main/resources
目录下。
示例配置(logback.xml)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 日志格式:时间 | 线程 | 日志级别 | 类名 | 消息 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 文件滚动日志 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<!-- 按天分割日志,保留30天 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 根日志级别:INFO,输出到控制台和文件 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
<!-- 自定义包日志级别 -->
<logger name="com.example" level="DEBUG" />
</configuration>
获取 Logger 实例
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("Application started.");
try {
int result = 10 / 0;
} catch (Exception e) {
logger.error("Division by zero error", e);
}
logger.debug("Debug message (visible if level is DEBUG)");
}
}
输出示例
2024-06-15 14:30:45.123 [main] INFO com.example.Main - Application started.
2024-06-15 14:30:45.125 [main] ERROR com.example.Main - Division by zero error
java.lang.ArithmeticException: / by zero
at com.example.Main.main(Main.java:12)
按文件大小分割日志
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
</appender>
异步日志提升性能
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
<appender-ref ref="FILE" />
</appender>
环境变量动态配置
<property name="LOG_PATH" value="logs" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${LOG_PATH}/app.log</file>
</appender>
注意事项
- 依赖冲突:确保项目中无其他日志框架(如 Log4j)的依赖。
- 配置文件加载失败:检查
logback.xml
是否在resources
目录下。 - 日志文件权限:确保程序有权限写入日志目录(如
logs/
)。 - 日志级别优先级:
TRACE < DEBUG < INFO < WARN < ERROR
。