maven 官网仓库地址:maven repo
历史背景
1、日志是什么?
日志是每天记录我们程序情况的。日志管理的目的是为了记录日志。
2、为什么会有日志?
1、问题追溯,通过日志文件的记录可以使我们运维或者程序员快速查找问题根源。
2、状态检测,检测我们系统状况,为项目出现的问题做好预警。
3、安全审计
3、日志级别划分
日志级别一共分为五层:1、ERROR(错误) 2、WARNING(警告)3、INFO(常规状态)4、Debug(调试信息)5、Trace(调试,信息更详细)
private static Logger logger=Logger.getLogger(String.valueOf(类名.class));//对哪里做检测
public static void main(String[] args) {
logger.info("这是一个inf");//各种行为产生的日志级别以及相应的反馈。
logger.warning("警告!警告!");
}
4、日志对性能的影响
1、static对Logger实例化的影响。
2、合理判定日志等级。
3、优先使用参数,减少字符串的拼接。
Java自带的日志类库有很多,如jdk自带的Logger、log4j、Logback,他们之间互不兼容,slf4j是解决他们之间不兼容的适配器接口。
log4j、Logback非常相似,都是java日志的框架实现,但是为什么要在log4j之后又做一个Logback呢?
是因为:
1、Logback实现了对内核的重写使得性能提高,初始化内存加载小。
2、测试充分,经过数年间Logback经受了大大小小不同级别的测试。
3、 Logback-classic非常自然地实现了slf4j,所以切换到其他的日志狂阶非常容易只需要提供几个jar包就可以了。
4、自动从新加载配置文件。当我们对配置文件做了更改之后Logback-classic自动对我们的配置文件做加载。
5、Lilith不仅仅是能够对log事件观测,还能处理大量log文件。
异常处理最佳实践
在Java中,异常处理是一项非常重要的技能,良好的异常处理能够使程序更加健壮和可靠。以下是一些异常处理的最佳实践:
1.不要捕获所有异常。应该尽可能地具体地捕获异常,并处理它们。
2.不要在catch语句块中使用System.out.println()等输出语句。应该使用日志记录工具,例如Log4j、Slf4j等等。
3.不要在finally语句块中使用return语句。如果在finally语句块中使用return语句,那么可能会覆盖try语句块中的return语句,导致程序出现意外行为。
4.不要忽略异常。即使是无法处理的异常,也应该在日志中记录下来,以便于后续的调试和分析。
5.不要在循环中捕获异常。应该尽可能地将try-catch语句块放在循环外面。
slf4j和log4j
slf4j是通用的接口规范,log4j是具体实现的日志插件,slf4j也可以搭配其他实现的jar包一起使用。
一、What
1、slf4j和log4j的区别是什么?
log4j:log for java,Apache的一个开源项目,可以通过一个配置文件灵活配置日志的输送目的地、记录级别、输出格式。
slf4j:simple log facade for java,译为简单日志门面。官方介绍为,SLF4J作为各种日志系统的简单Facade或抽象,允许最终用户在部署时插入所需的日志框架。
总结:slf4j是通用的接口规范,log4j是具体实现的日志插件。
二、Why
1、log4j为什么搭配slf4j一起使用?
在知晓了slf4j是一套接口、log4j是一套具体实现后,就需要理解编程中“接口”的意义(统一规范、解耦、提高编程灵活性和可维护性)。
同理,在实现不同项目开发中“日志记录”的过程中,引入一套通用的日志接口规范后,既能兼容不同项目中使用的不同日志实现插件,又能在后期维护中随时更换其他的日志实现插件。
2、为什么推荐使用slf4j作为日志接口规范?
日志实现插件可以根据需要更换Logback或其他。日志接口规范还有Commons Logging,而slf4j的出现主要因为对前者的不满意,所以slf4j是对Commons Logging的改进。这里改进主要看一点:支持带占位符的字符串。
例如
String me = "jettech";
String you = "zhangsan";
// Commons Logging 打印日志
log.info("Hello, " + you + ". I'm " + me + ".");
// slf4j 打印日志
log.info("Hello, {}. I'm {}.", you, me);
————————————————
三、How
1、log4j怎样搭配slf4j使用?
1.1 引入依赖
maven坐标为
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.13</version>
</dependency>
报错:
SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.
检查自己的maven依赖,发现已经引入了slf4j-api-xx.jar了,这是为什么呢?其原因是,SLF4J本身不是一个日志实现库,而是一个日志库的抽象层,它必须依赖底层的日志库,SLF4J必须和其他日志库配合才能正常运行。一般来说,需要将抽象层(例如slf4j-api-xx.jar)+中间层(例如slf4j-log4j12)+实现层(例如log4j)这三层都配置好才能保证SLF4J正常运行。有的日志库也可以去掉中间层,例如slf4j-api和slf4j-simple就可以直接配合。
slf4j+log4j组合
1)抽象层+中间层+实现层的方式解决
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>2.0.7</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.slf4j</groupId>-->
<!-- <artifactId>slf4j-simple</artifactId>-->
<!-- <version>2.0.7</version>-->
<!-- </dependency>-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
还要加个log4j配置文件:log4j.properties 在resources资源下面创建
# Set root logger level to DEBUG and its only appender to console.
log4j.rootLogger=DEBUG, console
# console is set to be a ConsoleAppender.
log4j.appender.console=org.apache.log4j.ConsoleAppender
# console uses PatternLayout.
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold = DEBUG
log4j.appender.console.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
或者用slf4j+logback组合
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.3.0</version>
</dependency>
2).抽象层+实现层的方式解决
引入下面的依赖,重新编译后就正常了,注意假如你从maven库里复制来的有 test,需要改成 compile或者就不加这个scope,不加的时候默认是compile,才能正常使用,test表示只有在测试环境下,才可以使用,而springboot是运行在main方法中,不属于测试环境,所以这个包就相当于没有加入依赖,也就没有被加载到。改成compile则表示编译的时候就会加载此jar包.
可以看到,无论是第一个错误还是第二个错误,都是依赖版本的问题,官方在Jdk1.9开始对于slf4j-api以及其他如slf4j-log4j12等依赖的绑定机制不同了,Jdk1.9对应slf4j-api以及slf4j-log4j12的版本从1.8.0开始。所以,为了解决以上两个问题,(如果我们使用的是Jdk1.8及以下)我们可以直接降低这两个依赖的版本到1.8.0以下,或者升级为Jdk1.9再使用这两个依赖的版本为1.8.0以上。
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
<!-- <scope>test</scope>-->
</dependency>
!!!特别注意:以上slf4j-log4j12的scope要么直接去掉,要么改为compile,因为test代表只有在测试(@Test)的时候该依赖才起作用。
1.2 创建一个静态常量的日志对象
在需要打印日志的Java Bean 中,定义属性成员:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
...
private static final Logger logger = LoggerFactory.getLogger(getClass());
...
...
logger.info("Hello, world.")
PS: 日志对象在类的实例中一般不需要修改和多份对象,所以常用static和final修饰。文章来源:https://www.toymoban.com/news/detail-603847.html
2、常用的日志框架该如何组合选择?
常用组合方式为:
1. Slf4j + Logback
2. Slf4j + Log4j
3. Commons Logging + Log4j
PS: Logback更适合搭配Slf4j,不建议搭配Commons Logging, 因为Logback与Slf4j为同一作者,兼容性更好文章来源地址https://www.toymoban.com/news/detail-603847.html
到了这里,关于java slf4j,Commons Logging与log4j,Logback,tinylog和异常配合使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!