本文目录
Log在Spring的前世今生
Log对于任一系统的重要性不言而喻。
跟JPA类似,Spring中的Log也只是提供了接口定义,然后在项目中,需要项目自行选用Log的具体实现。
值得一提的是,Spring跟Spring Boot使用的Log接口与默认实现不同:
- Spring的Log接口是JCL (Jakarta Commons Logging)。Spring框架采用了JUL(属于java.util.logging)来作为默认的Log实现。
- Spring Boot的Log接口是SLF4J,Simple Logging Facade for Java。且使用Logback来作为标准实现。
另外一个有名的Log的实现是Log4j和Log4j2。当然最近的Log4j2的漏洞问题,导致Log4j2颇有些谈虎色变的味道。
log4j, logback和log4j2
log4j
是Apache的一个开源项目,已经结束了生命周期;
logback
官网上介绍说Logback is intended as a successor to the popular log4j project
,也就是log4j 1.x的一个后续,基于SLF4J API的原生实现。
log4j2
,官网Log4j2是log4j 1.x和logback的改进版。其采用了一些新技术(无锁异步等),使得日志的吞吐量、性能比log4j 1.x提高了10倍,并解决了一些死锁的bug,而且配置更加简单灵活。
SLF4J API
不管是Logback还是log4j2,应用程序实际上通过SLF4J API再进行编程。
SLF4J Manual上有个非常基础的例子:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
另外一个典型案例(同样来自SLF4J Manual):
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Wombat {
final Logger logger = LoggerFactory.getLogger(Wombat.class);
Integer t;
Integer oldT;
public void setTemperature(Integer temperature) {
oldT = t;
t = temperature;
logger.debug("Temperature set to {}. Old value was {}.", t, oldT);
if(temperature.intValue() > 50) {
logger.info("Temperature has risen above 50 degrees.");
}
}
}
还可以使用Fluent Logging API
:
int newT = 15;
int oldT = 16;
// using traditional API
logger.debug("Temperature set to {}. Old value was {}.", newT, oldT);
// using fluent API, log message with arguments
logger.atDebug().log("Temperature set to {}. Old value was {}.", newT, oldT);
// using fluent API, add arguments one by one and then log message
logger.atDebug().setMessage("Temperature set to {}. Old value was {}.").addArgument(newT).addArgument(oldT).