目录
spring-boot日志相关梳理(-)里提到slf4j系列,因为后续的很多日志框架都依赖于它,重点看看slf4j.
slf4j官方文档:http://www.slf4j.org/docs.html
用户手册:http://www.slf4j.org/manual.html
HelloWorld
1.建议maven项目 slf4j,pom中添加依赖
<properties>
<slf4j.version>1.7.28</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
2.创建如下类
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");
}
}
a> 没有引入任何实现依赖-->丢弃日志
直接运行HelloWorld,输出如下:
原因:LoggerFactory.bind()
b> slf4j-simple 依赖
修改pom文件
<properties>
<slf4j.version>1.7.28</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
运行HelloWorld
自定义配置:
配置文件位置:src/main/resources/simplelogger.properties
文件内容
org.slf4j.simpleLogger.logFile=simple.log
org.slf4j.simpleLogger.defaultLogLevel=info
重新运行HelloWorld, 发现输出到根目录下simple.log文件中
配置解析可以参考:SimpleLoggerConfiguration; 优先参考SystemProperties, 其次simplelogger.properties
经典语法
使用占位符方式传递参数, 详细细节:http://www.slf4j.org/faq.html#logging_performance
logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
流式使用api(Fluent Logging API)
ps:SLF4J API version 2.0.0 以后才可以:https://repo1.maven.org/maven2/org/slf4j/
修改pom文件
<properties>
<slf4j.version>2.0.0-alpha1</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
修改Java代码:
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.atInfo().log("Hello World,{}", print("fluent info"));
logger.atDebug().log("Hello World,{}", print("fluent debug "));
logger.atDebug().addArgument(() -> print("fluent debug argument")).log("Hello World,{}");
logger.info("Hello World,{}", print("info"));
logger.debug("Hello World,{}", print("debug"));
}
private static String print(String message) {
System.out.println(message);
return message;
}
}
运行HelloWorld,输出:
随着参数的增多,fluent 的优越性就体现出来了
和其他的日志框架绑定
1. log4j version 1.2
pom文件
<properties>
<slf4j.version>1.7.28</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!--绑定log4j version1.2-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
2.java.util.logging,也叫jdk1.4logging
修改pom文件
<properties>
<slf4j.version>1.7.28</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
3.绑定 NOP, 默认丢弃所有日志
<properties>
<slf4j.version>1.7.28</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
4.Binding for Jakarta Commons Logging,把所有slf4j日志代理给JCL
<properties>
<slf4j.version>1.7.28</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jcl</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
5.绑定logback : 因为slf4j和logback的作者属于同一人,原生两者就是相互支持的,不用再做转换
<properties>
<slf4j.version>1.7.28</slf4j.version>
<logback.version>1.7.28</logback.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
常见的FAQ:
1. slf4j和common log :http://www.slf4j.org/faq.html#yet_another_facade
common-log 和slf4j的定位都是日志相关接口,但是两者实现理念不同
slf4j存在的原因:(1) slf4j设计理念简单; (2) 引入两个新特性:日志参数化(有助于改善日志的性能);Marker Objects [算是对象的插拔渲染吧,个人理解]
2. 如何获取slf4j和对应日志的绑定关系
3.如何高效的打印日志:http://www.slf4j.org/faq.html#logging_performance
a> 直接拼接字符串
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
b> 先判断日志级别:
if(logger.isDebugEnabled()) { logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); }
c> 参数化 (性能至少比a好30倍)
Object entry = new SomeObject(); logger.debug("The entry is {}.", entry);