本篇在jdk21下测试通过
1.日志接口
2.?志实现
在JDK 1.3及以前,Java打?志依赖System.out.println(), System.err.println()或者
e.printStackTrace(),Debug?志被写到STDOUT流,错误?志被写到STDERR流。这样打?志有?个?常?的缺陷,?常机械,?法定制,且?志粒度不够细分
System.out.println("123");
System.err.println("456");
注意了:这里案例采用的是log4j2的写法
2001年发布了Log4j,并将其捐献给了Apache软件基?会,成为Apache 基?会的顶级项?。Log4j 在设计上?常优秀,它定义的Logger、Appender、Level等概念对后续的 Java Log 框架有深远的影响,如今的很多?志框架基本沿?了这种思想
1.导入坐标
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.22.1</version>
</dependency>
2.编写配置文件 log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="MyFile" fileName="logs/app.log">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %c{1} - %msg%n</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
3.测试类
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MyLog4j {
private static final Logger logger = LogManager.getLogger(MyLog4j.class);
public static void main(String[] args) {
int i = 1;
String msg = "测试";
String s = null;
// 记录不同级别的日志
logger.debug("Debug message:{},{},{}", i, msg, s);
logger.info("Info message:{},{},{}", i, msg, s);
logger.warn("Warning message:{},{},{}", i, msg, s);
logger.error("Error message:{},{},{}", i, msg, s);
logger.fatal("Fatal error message:{},{},{}", i, msg, s);
}
}
sun公司对于log4j的出现内?隐隐表示嫉妒。于是在jdk1.4版本后,开始搞事情,增加了?个包为java.util.logging,简称为JUL,?以对抗log4j ,但是却给开发造成了麻烦。相互引?的项?之间可能使?了不同的?志框架,经常将代码搞得??混乱
import java.util.logging.Logger;
public class MyJul {
static Logger logger = Logger.getLogger(MyJul.class.getName());
public static void main(String[] args) {
int i = 1;
String msg = "测试";
String s = null;
logger.info( "Info message :" + i + " " + "s" + " " + msg);
}
}
从上?可以看出,JUL的api与log4j是完全不同的(参数只接受String)。由于?志系统互相没有关联,彼此没有约定,不同?的代码使?不同?志,替换和统?也就变成了?较棘?的?件事。假如你的应?使?log4j,然后项?引?了?个其他团队的库,他们使?了JUL,你的应?就得使?两个?志系统了,然后其他团队?使?了simplelog……这个时候如果要调整?志的输出级别,?于跟踪某个信息,简直就是?场灾难
那这个状况该如何解决呢?答案就是进?抽象,抽象出?个接?层,对每个?志实现都适配或者转接,这样这些提供给别?的库都直接使?抽象层即可 ,以后调?的时候,就调?这些接?。(?向接?思想)
于是,JCL(Jakarta Commons Logging)应运??,也就是commons-logging-xx.jar组件。JCL 只提供 log 接?,具体的实现则在运?时动态寻找。这样?来组件开发者只需要针对 JCL 接?开发,?调?组件的应?程序则可以在运?时搭配??喜好的?志实践?具
1.导入坐标
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.3.0</version>
</dependency>
2.测试代码
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyJul {
private static Log logger = LogFactory.getLog(MyJul.class);
public static void main(String[] args) {
int i = 1;
String msg = "测试";
String s = null;
logger.info( "Info message :" + i + " " + "s" + " " + msg);
logger.debug("Debug message :" + i + " " + "s" + " " + msg);
logger.fatal("Fatal message :" + i + " " + "s" + " " + msg);
logger.error("Error message :" + i + " " + "s" + " " + msg);
}
}
针对以上情况,log4j的作者再次出?,他觉得JCL不好?,???写了?个新的接?api,就是slf4j,并且为了追求更极致的性能,新增了?套?志的实现,就是logback,?时间烽烟?起……
1.导入坐标
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.10</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.14</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.14</version>
</dependency>
2.编写配置文件logback.xml
<configuration>
<!-- 定义日志输出格式 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{96} [%line] [%thread]- %msg%n</pattern>
</encoder>
</appender>
<!-- 定义日志文件输出 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天滚动,每天生成一个新的日志文件 -->
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 文件保留策略,只保留最近30天的日志文件 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 设置全局日志级别 -->
<root level="debug">
<!-- 将控制台和文件Appender关联到根Logger -->
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
<!-- 针对特定包或类设置不同的日志级别 -->
<!-- <logger name="com.andy.log.logback.*" level="debug" /> -->
</configuration>
3.测试代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyLogback {
static final Logger logger = LoggerFactory.getLogger(MyLogback.class);
public static void main(String[] args) {
int i = 1;
String msg = "测试";
String s = null;
// 记录不同级别的日志
logger.debug("Debug message:{}:{}:{}", i, msg, s);
logger.info("Info message:{}:{}:{}", i, msg, s);
logger.warn("Warning message:{},{},{}", i, msg, s);
logger.error("Error message:{}:{}:{}", i, msg, s);
}
}
请参考 “开创先驱的log4j” 的写法
log4j2以性能著称,它?其前身Log4j 1.x提供了重?改进,同时类?logback,它提供了Logback中可?的许多改进,同时修复了Logback架构中的?些固有问题。功能上,它有着和Logback相同的基本操作,同时?有??独特的部分,?如:插件式结构、配置?件优化、异步?志等
到log4j2,轰轰烈烈的java log战役基本就结束了