当前位置:网站首页>【日志框架】
【日志框架】
2022-08-04 00:51:00 【昱浑】
日志打印
- 建议用{}占位而不是字符串拼接
- 打日志前先判断日志级别是否可用:
- 先根据等级过滤规则再决定写不写;
- 先往一个管道写了内容,但再经等级过滤丢弃,徒增开销。
日志框架
Slf4J
Slf4J 不是底层日志框架,只是门面框架(抽象),需要配合jul、log4j、logback、log4j2等底层框架(真正干活的)使用。
- 避免日志对代码的耦合,更换日志框架时也不需改动任何代码。不论使用哪种底层框架时,在代码层面都一样。
- 避免引入第三方jar而其中日志框架不一致时需要同时维护不同的日志框架对应的配置文件。

补充:更老的门面框架还有jcl, 所以会看到有程序应用 jcl + log4j 这种搭配。Slf4J 后采用 Slf4J + log4j,但一些 jcl + log4j 项目也想用Slf4J 时,可以通过引入 jcl-over-slf4j log桥接工具的依赖,将原本输出到jcl的日志输出重定向到 SLF4J。
如果只用了slf4j,而没有使用任何底层框架,就会出现以下错误:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
log4j
- 依赖
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> - 配置文件 log4j.properties
log4j.rootLogger=info, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=target/spring.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n - 代码
输出import org.apache.log4j.Logger; //更多请阅读:https://www.yiibai.com/log4j/log4j_sample_program.html public class log4jExample{ static Logger log = Logger.getLogger(log4jExample.class.getName()); public static void main(String[] args) { if (log.isDebugEnabled()) { log.debug("### Hello this is an debug message"); } log.info("### Hello this is an info message"); // 不支持占位符 } }2022-07-27 21:10:03,358 INFO [org.example.log4jExample] - ### Hello this is an info message
logback (原生实现 SLF4J)
Logback 旨在作为流行的 log4j 项目的继承者,在 log4j 1.x 停止的地方接手。
Logback 的架构非常通用,可以在不同的情况下应用。 目前,logback 分为三个模块,logback-core、logback-classic 和 logback-access。
logback-core 模块为其他两个模块奠定了基础。
logback-classic 模块可以同化为 log4j 1.x 的显着改进版本。 此外,logback-classic 原生实现了 SLF4J API。
logback-access 模块与 Tomcat 和 Jetty 等 Servlet 容器集成,以提供 HTTP 访问日志功能。 请注意,您可以轻松地在 logback-core 之上构建自己的模块。
依赖
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>默认配置
Logback 默认配置的步骤 参考:https://www.cnblogs.com/warking/p/5710303.html
- 尝试在 classpath下查找文件logback-test.xml;
- 如果文件不存在,则查找文件logback.xml;
- 如果两个文件都不存在,logback用BasicConfigurator自动对自己进行配置,这会导致记录输出到控制台。
logback.xml
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
<logger name="com.apache.ibatis" level="DEBUG"/>
</configuration>
代码
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogbackExample { static Logger log = LoggerFactory.getLogger(LogbackExample.class); public static void main(String[] args) { if (log.isDebugEnabled()) { log.debug("### Hello this is an debug message"); } log.info("### Hello this is an info message"); // 不支持占位符 } }输出
129 [main] INFO org.example.LogbackExample - ### Hello this is an info message如果需要将日志按规则生成到文件,也可以在logback.xml中配置;logback.xml中各标签的含义,查阅上文。
如图可以配置将日志信息同时实时输出到终端和离线输出到日志文件。
@Slf4j 注解
能够少写两行代码,不用每次都在类的最前边写上:
private static final Logger logger = LoggerFactory.getLogger(this.XXX.class);
需要 lombok依赖。如果是基于SpringBoot,因为默认加入了Slf4j-api和logback的依赖,所以只需要添加lombok的依赖即可。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
- 代码
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SLF4JExample {
public static void main(String[] args) {
if (log.isDebugEnabled()) {
log.debug("### Hello this is an debug message");
}
log.info("### Hello this is an info message"); // log 由lombok提供,如报错是idea的问题
}
}
log4j 适配 Slf4j
- 依赖
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.28</version>
</dependency>
只需要依赖 slf4j-log4j12,它自身依赖log4j 和 slf4j-api 两个包。
配置
由于底层框架仍然使用的是log4j,仍然需要 配置文件: log4j.propertieslog4j.rootLogger=info, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=target/spring.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n代码
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogSlf4jExample { static Logger log = LoggerFactory.getLogger(LogSlf4jExample.class); public static void main(String[] args) { if (log.isDebugEnabled()) { log.debug("### Hello this is an debug message"); } log.info("### Hello this is an info message"); // 不支持占位符 } }
在代码层面已经实现和使用logback时一样了,都是从 org.slf4j.LoggerFactory 这个包下 getLogger来获取 Logger 对象。
当然也可以使用 @Slf4j 注解的方法。代码是一样的,无法看出底层框架是log4j还是logback。
边栏推荐
猜你喜欢

Jmeter cross-platform operation CSV files

Web3 安全风险令人生畏?应该如何应对?

因为一次bug的教训,我决定手撕Nacos源码(先撕客户端源码)

typescript51 - basic use of generics

ping数据包中的进程号

typescript53 - generic constraints

LeetCode third topic (the Longest Substring Without Repeating Characters) trilogy # 3: two optimization

数据库扩容也可以如此丝滑,MySQL千亿级数据生产环境扩容实战

电子组装行业对MES管理系统的需求分析

The problem of disorganized data output by mnn model
随机推荐
第1章:初识数据库与MySQL----MySQL安装
114. 如何通过单步调试的方式找到引起 Fiori Launchpad 路由错误的原因
电子制造企业部署WMS仓储管理系统的好处是什么
【面经】被虐了之后,我翻烂了equals源码,总结如下
2022-08-03: What does the following go code output?A: 2; B: 3; C: 1; D: 0.package main import "fmt" func main() { slice := []i
typescript55-泛型约束
研究生新生培训第四周:MobileNetV1, V2, V3
jmeter distributed stress test
身为程序员的我们如何卷死别人?破局重生。
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之三:两次优化
vxe-table 从页面批量删除数据 (不动数据库里的数据)
中原银行实时风控体系建设实践
dynamic memory two
2023年航空航天、机械与机电工程国际会议(CAMME 2023)
教你如何定位不合理的SQL?并优化之
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之三:两次优化
Tanabata festival coming, VR panoramic look god assists for you
boot issue
分布式事务框架 seata
Vant3—— 点击对应的name名称跳转到下一页对应的tab栏的name的位置