天津手机版建站系统,网站建设主要做什么,徐州建设银行网站,wordpress焦点图插件前言#xff1a;目前市面上有挺多JAVA的日志框架#xff0c;比如JUL(JDK自带的日志框架),Log4j,Logback,Log4j2等#xff0c;有人可能有疑问说还有slf4j#xff0c;不过slf4j不是一种日志框架的具体实现#xff0c;而是一种日志门面#xff08;日志门面可以理解为是一种统…前言目前市面上有挺多JAVA的日志框架比如JUL(JDK自带的日志框架),Log4j,Logback,Log4j2等有人可能有疑问说还有slf4j不过slf4j不是一种日志框架的具体实现而是一种日志门面日志门面可以理解为是一种统一的接口只是为了规范日志没有具体的实现可以类比USB接口对于USB接口有好多个厂商这多个厂商生产出来的USB头都是一样的使得我们用起来就很方便slf4j其实也是一样。虽然市面上有很多日志框架但是笔者之前只是能够简单的使用日志框架而且使用时总感觉似懂非懂对目前市面上的日志框架并没有一个整体且系统的了解。因此笔者利用周末这两天系统的学习了一下目前市面上的框架也就有了这篇文章希望这篇文章能够帮助大家对JAVA日志框架有个清晰的认识。
笔者这篇文件是对该视频内容的提炼需要的可以自行观看。如果想快速了解日志的重点内容那么可以继续往下看。 视频链接
一、市面上主要日志简介
目前市面上主要的日志框架有JUL(JDK自带的日志框架),Log4j,Logback,Log4j2。 日志门面slf4jlog4j2也是一种日志门面不过因为其实现了丰富的日志功能所以不把其当做一种日志门面了 日志框架门面出现的先后顺序JUL,Log4j在slf4j门面技术出现之前logback,Log4j2在slf4j门面技术出现之后。因为JUL,Log4j在slf4j出现之前就有了所以这两个日志的实现并没有遵循slf4j的规范不过可以通过导入适配器的依赖来使用。因为Log4j2是对Log4j的升级JUL功能比较弱不过因为是JDK自带的日志实现不需要导入依赖使用起来比较方便所以本文只介绍Logback和Log4j2。 主流日志使用方式slf4jLogback、slf4jLog4j2
使用方式配置文件。
在使用各种库时第一步都是导入对应的依赖日志框架也是一样。此外对于记录的日志会有不同的日志级别日志显示或写入文件的条件就是当前日志级别大于所设置的日志级别时才会打印如果不设置日志级别系统会有默认的日志级别。
日志级别由高到低 error warninfodebugtrace(这个日志级别是针对slf4j门面的日志级别各种日志框架的日志级别都大同小异)
二、slf4jLogback使用
2.1 导入依赖
在导入依赖时我们需要导入slf4j的依赖(slf4j-api)和logback的依赖因为依赖的传递性logback-classic的依赖中包含了slf4j-api的依赖所以我们在实际的使用中只需要导入logback-classic的依赖即可 依赖情况 dependencygroupIdch.qos.logback/groupIdartifactIdlogback-classic/artifactIdversion1.2.3/version/dependency2.2 使用方式
对于日志我们分别测试下面这几种情况 2.2.1不使用配置文件 2.2.2使用配置文件 2.2.2.1输出到控制台 2.2.2.2输出到文件 2.2.2.3输出到文件对文件拆分 2.2.1 不使用配置文件
项目结构 执行右面的test01输出如下 如上图所示当不添加配置文件时默认的输出格式如上所示。只有trace日志级别的日志没有输出所以logback系统默认的日志级别是debug级别。
日志级别的值
/*** The codeOFF/code is used to turn off logging.*/
public static final Level OFF new Level(OFF_INT, OFF);/*** The codeERROR/code level designates error events which may or not* be fatal to the application.*/
public static final Level ERROR new Level(ERROR_INT, ERROR);/*** The codeWARN/code level designates potentially harmful situations.*/
public static final Level WARN new Level(WARN_INT, WARN);/*** The codeINFO/code level designates informational messages* highlighting overall progress of the application.*/
public static final Level INFO new Level(INFO_INT, INFO);/*** The codeDEBUG/code level designates informational events of lower* importance.*/
public static final Level DEBUG new Level(DEBUG_INT, DEBUG);/*** The codeTRACE/code level designates informational events of very low* importance.*/
public static final Level TRACE new Level(TRACE_INT, TRACE);/*** The codeALL/code is used to turn on all logging.*/
public static final Level ALL new Level(ALL_INT, ALL);//对应的具体值
public static final int OFF_INT Integer.MAX_VALUE;
public static final int ERROR_INT 40000;
public static final int WARN_INT 30000;
public static final int INFO_INT 20000;
public static final int DEBUG_INT 10000;
public static final int TRACE_INT 5000;
public static final int ALL_INT Integer.MIN_VALUE;2.2.2 使用配置文件
2.2.1 输出到控制台
配置文件名logback.xml 内容
?xml version1.0 encodingUTF-8 ?configuration!--%-10level 日志级别设置10个字符字符不够空格补齐左对齐%d{yyyy-MM-dd HH:mm:ss.SSS} 日期%c 当前类全限定名%M 当前执行日志的方法%L 行号%thread 线程名称%m或者%msg 信息%n 换行--property namepattern value[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/appender nameconsoleAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderroot levelALLappender-ref refconsoleAppender//root
/configuration看这个配置文件我们可以看到所有的内容都包含在configuration标签中configuration标签内部定义了property,appender,root标签其中property标签是定义配置文件内的变量方便我们使用即在后面直接引用该变量就行。其中appender标签和root标签是需要我们重点关注的内容。 我们知道日志一般可以输出到控制台或者文件中对于具体输出到控制台还是输出到文件中就是通过appender来控制的。因此我们可以通过appender标签来定义一个变量。其中appender标签的name属性就是变量名class属性就是变量的类型。appender标签内的target标签不太重要设置的具体值等同于Java中的System.out和System.err。appender标签内的encoder标签其实是定义日志的输出格式我们看到的日志一般都会包括日志级别线程名称时间文件全类名消息等信息就是通过该标签控制。所以这些是appender标签的核心内容。
虽然appender标签定义了具体的appender变量但决定是否使用该变量时通过下面的root标签来控制的我们可以看到root标签有个level属性我们将该属性值设置为ALL,则表示所有的日志级别都会显示。root标签下的appender-ref属性则是决定具体使用哪个appender变量。可以看到appender-ref标签的ref属性值为consoleAppender说明使用了变量名为consoleAppender的appender输出器。 执行效果如下 可以看到所有的日志信息全都输出了同样执行的test01()方法。此外日志显示为红色这其实就是System.err设置的效果。而且我们可以看到输出的日志具有特定的格式即[INFO ] 2023-12-18 08:26:32.869 com.xlb.LogBackDemo test01 main 14info 信息含义为日志级别 时间 当前类全限定名 当前执行日志的方法 线程名 行号消息体。这种输出格式即是我们通过encoder标签下的pattern标签定义的。格式化的含义具体如下
%-10level 日志级别设置10个字符字符不够空格补齐左对齐
%d{yyyy-MM-dd HH:mm:ss.SSS} 日期
%c 当前类全限定名
%M 当前执行日志的方法
%L 行号
%thread 线程名称
%m或者%msg 信息
%n 换行2.2.2.2 输出到文件
我们上面是将日志成功输出到了控制台下面我们将日志输出到文件大致过程和上面类似。 修改后的配置文件如下
?xml version1.0 encodingUTF-8 ?configuration!--%-10level 日志级别设置10个字符字符不够空格补齐左对齐%d{yyyy-MM-dd HH:mm:ss.SSS} 日期%c 当前类全限定名%M 当前执行日志的方法%L 行号%thread 线程名称%m或者%msg 信息%n 换行--property namepattern value[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property namelogDir valueF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOGBACK_StudyV2\\log/appender nameconsoleAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderappender namefileAppender classch.qos.logback.core.FileAppenderfile${logDir}\mylog.log/fileencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderroot levelALLappender-ref reffileAppender//root
/configuration实际上我们就只修改了这三个地方
最上面指定了日志文件的输出路径的变量指定位置为当前项目下的log文件夹中间添加了一个输出到文件的appender增加了file标签在其内部定义了日志文件的输出路径下面在root标签中指定了我们新添加的appender。 输出结果如下 可以看到控制台没有日志输出但是文件中有日志输出。
2.2.2.3 输出到控制台和文件
修改后的配置如下
?xml version1.0 encodingUTF-8 ?configuration!--%-10level 日志级别设置10个字符字符不够空格补齐左对齐%d{yyyy-MM-dd HH:mm:ss.SSS} 日期%c 当前类全限定名%M 当前执行日志的方法%L 行号%thread 线程名称%m或者%msg 信息%n 换行--property namepattern value[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property namelogDir valueF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOGBACK_StudyV2\\log/appender nameconsoleAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderappender namefileAppender classch.qos.logback.core.FileAppenderfile${logDir}\mylog.log/fileencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderroot levelALLappender-ref reffileAppender/appender-ref refconsoleAppender//root
/configuration可以看到对于新的配置文件我们只是增加了上面一行即在root标签中同时也使用了控制台的appender。 输出结果如下 可以看到日志记录输出到了控制台和文件中而且文件中的日志是追加的方式记录的可以查看日志的时间来看当前的日志记录。 从这个案例我们可以知道日志可以指定多个appender指定多个appender只需要增加对应的appender引用即可。
2.2.2.3 输出到文件对文件拆分
如果日志文件一直追加那么日志文件就可能变得非常大不方便日志管理或者有时候同类型的日志需要归档所以我们需要对日志文件进行拆分管理对文件拆分管理方式如下。 修改配置文件
?xml version1.0 encodingUTF-8 ?configuration!--%-10level 日志级别设置10个字符字符不够空格补齐左对齐%d{yyyy-MM-dd HH:mm:ss.SSS} 日期%c 当前类全限定名%M 当前执行日志的方法%L 行号%thread 线程名称%m或者%msg 信息%n 换行--property namepattern value[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property namelogDir valueF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOGBACK_StudyV2\\log/appender nameconsoleAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderappender namefileAppender classch.qos.logback.core.FileAppenderfile${logDir}\mylog.log/fileencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderappender namerollAppender classch.qos.logback.core.rolling.RollingFileAppenderencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoderfile${logDir}\roll_logback.log/file!-- 指定拆分规则--rollingPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicyfileNamePattern${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz/fileNamePatternmaxFileSize1KB/maxFileSize/rollingPolicy/appenderroot levelALLappender-ref refrollAppender//root
/configuration对于日志规则的拆分如上所示同样只需要修改这两处。
因为设置了日志文件的大小为1KB所以我们使用for循环来追加操作达到拆分文件的目的演示如下
代码
Testpublic void test02(){Logger logger LoggerFactory.getLogger(LogBackDemo.class);for (int i 0; i 200; i) {logger.trace(trace 信息);logger.debug(debug 信息);logger.info(info 信息);logger.warn(warn 信息);logger.error(error 信息);}}输出 可以看到日志文件按照我们设置的格式进行了拆分。
2.2.2.4 输出为html格式
除了上面几种格式还可以将logback输出为html的格式只需要下面这样设置即可
?xml version1.0 encodingUTF-8 ?configuration!--%-10level 日志级别设置10个字符字符不够空格补齐左对齐%d{yyyy-MM-dd HH:mm:ss.SSS} 日期%c 当前类全限定名%M 当前执行日志的方法%L 行号%thread 线程名称%m或者%msg 信息%n 换行--property namepattern value[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property namelogDir valueF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOGBACK_StudyV2\\log/appender nameconsoleAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderappender namefileAppender classch.qos.logback.core.FileAppenderfile${logDir}\mylog.log/fileencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderappender namerollAppender classch.qos.logback.core.rolling.RollingFileAppenderencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoderfile${logDir}\roll_logback.log/file!-- 指定拆分规则--rollingPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicyfileNamePattern${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz/fileNamePatternmaxFileSize1KB/maxFileSize/rollingPolicy/appender!-- html格式--appender namehtmlAppender classch.qos.logback.core.FileAppenderfile${logDir}\myHtmllog.html/fileencoder classch.qos.logback.core.encoder.LayoutWrappingEncoderlayout classch.qos.logback.classic.html.HTMLLayoutpattern${pattern}/pattern/layout/encoder/appenderroot levelALLappender-ref refhtmlAppender//root
/configuration同样改动很小输出如下使用test01 可以看到有个html文件。 浏览器打开该html日志文件展示如下 可以看到自动为我们添加了特定的样式使得日志以表格的形式展示。
2.2.2.5 过滤器
实际使用时可能每个appender我们想设置的日志级别都不同那么此时我们就需要一个过滤器该过滤器也是通过设置日志级别来控制是否输出当前appender的日志。
配置如下
?xml version1.0 encodingUTF-8 ?configuration!--%-10level 日志级别设置10个字符字符不够空格补齐左对齐%d{yyyy-MM-dd HH:mm:ss.SSS} 日期%c 当前类全限定名%M 当前执行日志的方法%L 行号%thread 线程名称%m或者%msg 信息%n 换行--property namepattern value[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property namelogDir valueF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOGBACK_StudyV2\\log/appender nameconsoleAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appender!-- 过滤器--appender nameconsoleFilterAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder!-- 配置过滤器(等于配置的级别才会输出)--filter classch.qos.logback.classic.filter.LevelFilter!-- 设置日志的输出级别--levelINFO/level!-- 高于level中设置的级别则打印日志--onMatchACCEPT/onMatch!-- 低于level中设置的级别则不打印--onMismatchDENY/onMismatch/filter!-- lt;!ndash; 配置临界值过滤器(输出大于等于level的日志)ndash;gt;--
!-- filter classch.qos.logback.classic.filter.ThresholdFilter--
!-- lt;!ndash; 设置日志的输出级别ndash;gt;--
!-- levelINFO/level--
!-- /filter--/appenderappender namefileAppender classch.qos.logback.core.FileAppenderfile${logDir}\mylog.log/fileencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderappender namerollAppender classch.qos.logback.core.rolling.RollingFileAppenderencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoderfile${logDir}\roll_logback.log/file!-- 指定拆分规则--rollingPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicyfileNamePattern${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz/fileNamePatternmaxFileSize1KB/maxFileSize/rollingPolicy/appender!-- html格式--appender namehtmlAppender classch.qos.logback.core.FileAppenderfile${logDir}\myHtmllog.html/fileencoder classch.qos.logback.core.encoder.LayoutWrappingEncoderlayout classch.qos.logback.classic.html.HTMLLayoutpattern${pattern}/pattern/layout/encoder/appenderroot levelALLappender-ref refconsoleFilterAppender//root/configuration在consoleAppender里设置了INFO级别的日志级别不过root标签下的日志级别是ALL我们看下输出 可以看到只输出了INFO级别的日志即我们在日志中配的INFO级别。下面我们看一下另一种过滤器
filter classch.qos.logback.classic.filter.ThresholdFilter!-- 设置日志的输出级别--levelINFO/level
/filter将上面的过滤器换成这个ThresholdFilter我们再看下输出 可以看到大于等于INFO级别的日志都进行了输出。从上面的输出可以看出这两种过滤器的差别。
2.2.2.6 异步日志
因为日志和业务逻辑无关日志只是便于我们处理问题。所以在项目中一般都会使用异步日志来提升业务逻辑的处理速度。异步日志的使用如下
?xml version1.0 encodingUTF-8 ?configuration!--%-10level 日志级别设置10个字符字符不够空格补齐左对齐%d{yyyy-MM-dd HH:mm:ss.SSS} 日期%c 当前类全限定名%M 当前执行日志的方法%L 行号%thread 线程名称%m或者%msg 信息%n 换行--property namepattern value[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property namelogDir valueF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOGBACK_StudyV2\\log/appender nameconsoleAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appender!-- 过滤器--appender nameconsoleFilterAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder!-- 配置过滤器(等于配置的级别才会输出)--
!-- filter classch.qos.logback.classic.filter.LevelFilter--
!-- lt;!ndash; 设置日志的输出级别ndash;gt;--
!-- levelINFO/level--
!-- lt;!ndash; 高于level中设置的级别则打印日志ndash;gt;--
!-- onMatchACCEPT/onMatch--
!-- lt;!ndash; 低于level中设置的级别则不打印ndash;gt;--
!-- onMismatchDENY/onMismatch--
!-- /filter--!-- lt;!ndash; 配置临界值过滤器(输出大于等于level的日志)ndash;gt;--filter classch.qos.logback.classic.filter.ThresholdFilter!-- 设置日志的输出级别--levelINFO/level/filter/appenderappender namefileAppender classch.qos.logback.core.FileAppenderfile${logDir}\mylog.log/fileencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderappender namerollAppender classch.qos.logback.core.rolling.RollingFileAppenderencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoderfile${logDir}\roll_logback.log/file!-- 指定拆分规则--rollingPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicyfileNamePattern${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz/fileNamePatternmaxFileSize1KB/maxFileSize/rollingPolicy/appender!-- html格式--appender namehtmlAppender classch.qos.logback.core.FileAppenderfile${logDir}\myHtmllog.html/fileencoder classch.qos.logback.core.encoder.LayoutWrappingEncoderlayout classch.qos.logback.classic.html.HTMLLayoutpattern${pattern}/pattern/layout/encoder/appender!-- 引入异步日志--appender nameasyncAppender classch.qos.logback.classic.AsyncAppenderappender-ref refconsoleAppender//appenderroot levelALLappender-ref refasyncAppender//root/configuration可以看到使用异步日志很简单我们只需要如上定义最终日志输出来的就是异步日志注意异步日志里面引用我们定义好的输出到控制台的consoleAppender。 下面我们看下输出
Testpublic void test03(){Logger logger LoggerFactory.getLogger(LogBackDemo.class);for (int i 0; i 200; i) {logger.trace(trace 信息);logger.debug(debug 信息);logger.info(info 信息);logger.warn(warn 信息);logger.error(error 信息);}for (int i 0; i 200; i) {System.out.println();}}我们可以看到输出的日志时穿插执行的即可以证明日志时异步输出的。
2.2.2.7 自定义日志
我们在上面使用的日志其实都是rootLogger我们应该记得在XML文件最后定义了root标签这个定义的其实就是rootLogger,rootLogger是日志框架自带的是所有日志的父级日志。什么是父级日志对于市面上的所有日志框架其实是有父子关系的不过这种父子关系不是通过继承实现而是通过包路径来体现的。如果包路径越具体说明其越是儿子。例如三个包com.aaa.bbb.ccc和com.aaa.bbb和com.aaa中com.aaa是com.aaa.bbb与com.aaa.bbb.ccc的父级日志com.aaa.bbb是com.aaa.bbb.ccc的父级日志。对于父级日志的设置可以对子级日志生效所以如果想一次生效多个日志那么可以对父级进行设置。而rootLogger就是所有包的父级日志。那这个日志包路径什么时候指定的呢我们可以看下面这一行代码
Logger logger LoggerFactory.getLogger(LogBackDemo.class);可以看到上面参数列表中我们传入了类java内部通过反射机制可以获得该类的全路径因为这个方法进行了重载所以也可以直接指定全路径名。 想要引入自定义日志需要下面这样配置 自定义日志引入
?xml version1.0 encodingUTF-8 ?configuration!--%-10level 日志级别设置10个字符字符不够空格补齐左对齐%d{yyyy-MM-dd HH:mm:ss.SSS} 日期%c 当前类全限定名%M 当前执行日志的方法%L 行号%thread 线程名称%m或者%msg 信息%n 换行--property namepattern value[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property namelogDir valueF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOGBACK_StudyV2\\log/appender nameconsoleAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appender!-- 过滤器--appender nameconsoleFilterAppender classch.qos.logback.core.ConsoleAppendertargetSystem.err/targetencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder!-- 配置过滤器(等于配置的级别才会输出)--
!-- filter classch.qos.logback.classic.filter.LevelFilter--
!-- lt;!ndash; 设置日志的输出级别ndash;gt;--
!-- levelINFO/level--
!-- lt;!ndash; 高于level中设置的级别则打印日志ndash;gt;--
!-- onMatchACCEPT/onMatch--
!-- lt;!ndash; 低于level中设置的级别则不打印ndash;gt;--
!-- onMismatchDENY/onMismatch--
!-- /filter--!-- lt;!ndash; 配置临界值过滤器(输出大于等于level的日志)ndash;gt;--filter classch.qos.logback.classic.filter.ThresholdFilter!-- 设置日志的输出级别--levelINFO/level/filter/appenderappender namefileAppender classch.qos.logback.core.FileAppenderfile${logDir}\mylog.log/fileencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoder/appenderappender namerollAppender classch.qos.logback.core.rolling.RollingFileAppenderencoder classch.qos.logback.classic.encoder.PatternLayoutEncoderpattern${pattern}/pattern/encoderfile${logDir}\roll_logback.log/file!-- 指定拆分规则--rollingPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicyfileNamePattern${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz/fileNamePatternmaxFileSize1KB/maxFileSize/rollingPolicy/appender!-- html格式--appender namehtmlAppender classch.qos.logback.core.FileAppenderfile${logDir}\myHtmllog.html/fileencoder classch.qos.logback.core.encoder.LayoutWrappingEncoderlayout classch.qos.logback.classic.html.HTMLLayoutpattern${pattern}/pattern/layout/encoder/appender!-- 引入异步日志--appender nameasyncAppender classch.qos.logback.classic.AsyncAppenderappender-ref refconsoleAppender//appenderroot levelALLappender-ref refconsoleAppender//root!-- 自定义日志--logger namecom.xlb levelinfo additivityfalseappender-ref refconsoleAppender//logger/configuration输出如下使用test01 可以看到输出了INFO,WARN,ERROR日志级别的日志。如果我们既有父级目录又有子级目录以子级日志目录设置的日志级别为准如下我将父级日志设置成INFO级别将子级日志设置成ALL级别并且去掉additivityfalse属性显示如下 可以看到同样的日志输出了两份下面加上additivityfalse再看下输出 可以看到日志输出只有一份并且是以子级日志级别为准的。
三、slf4jLog4j2使用
slf4jLog4j2日志的使用和slf4jlogback的使用大同小异
3.1 导入依赖
dependenciesdependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/version/dependencydependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-slf4j2-impl/artifactIdversion2.19.0/version/dependencydependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-core/artifactIdversion2.19.0/version/dependency
/dependencies测试类
package com.xlb;import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class LOG4J2Demo {Testpublic void test01(){Logger logger LoggerFactory.getLogger(LOG4J2Demo.class);logger.trace(trace 信息);logger.debug(debug 信息);logger.info(info 信息);logger.warn(warn 信息);logger.error(error 信息);}
}
3.2.1 不使用配置文件 可以看到只输出了ERROR级别的日志因此log4j2的日志的默认日志级别为error级别。
3.2.2 使用配置文件
3.2.2.1 输出到控制台
?xml version1.0 encodingUTF-8 ?Configurationpropertiesproperty namelogDirF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOG4J2_StudyV2\\log/propertyproperty namepattern[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property/propertiesAppenders
!-- 输出到控制台--Console nameconsoleAppender targetSYSTEM_ERR/Console/AppendersLoggersRoot leveltraceAppenderRef refconsoleAppender//Root/Loggers
/Configuration默认输出
?xml version1.0 encodingUTF-8 ?Configurationpropertiesproperty namelogDirF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOG4J2_StudyV2\\log/propertyproperty namepattern[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property/propertiesAppenders
!-- 输出到控制台--Console nameconsoleAppender targetSYSTEM_ERRpatternLayout pattern${pattern}//Console/AppendersLoggersRoot leveltraceAppenderRef refconsoleAppender//Root/Loggers
/Configuration格式化输出
3.2.2.2 输出到文件
我们上面是将日志成功输出到了控制台下面我们将日志输出到文件大致过程和上面类似。 修改配置文件如下
?xml version1.0 encodingUTF-8 ?Configurationpropertiesproperty namelogDirF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOG4J2_StudyV2\\log/propertyproperty namepattern[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property/propertiesAppenders
!-- 输出到控制台--Console nameconsoleAppender targetSYSTEM_ERRpatternLayout pattern${pattern}//Console!-- 输出到文件--File namefileAppender fileName${logDir}\\log4j2.log!-- 配置日志文件格式--patternLayout pattern${pattern}//File/AppendersLoggersRoot leveltraceAppenderRef reffileAppender//Root/Loggers
/Configuration3.2.2.3 输出到控制台和文件
?xml version1.0 encodingUTF-8 ?Configurationpropertiesproperty namelogDirF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOG4J2_StudyV2\\log/propertyproperty namepattern[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property/propertiesAppenders
!-- 输出到控制台--Console nameconsoleAppender targetSYSTEM_ERRpatternLayout pattern${pattern}//Console!-- 输出到文件--File namefileAppender fileName${logDir}\\log4j2.log!-- 配置日志文件格式--patternLayout pattern${pattern}//File/AppendersLoggersRoot leveltraceAppenderRef refconsoleAppender/AppenderRef reffileAppender//Root/Loggers
/Configuration3.2.2.4 输出到文件对文件拆分
?xml version1.0 encodingUTF-8 ?Configurationpropertiesproperty namelogDirF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOG4J2_StudyV2\\log/propertyproperty namepattern[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property/propertiesAppenders
!-- 输出到控制台--Console nameconsoleAppender targetSYSTEM_ERRpatternLayout pattern${pattern}//Console!-- 输出到文件--File namefileAppender fileName${logDir}\\log4j2.log!-- 配置日志文件格式--patternLayout pattern${pattern}//File!--fileName:日志文件名$${date:yyyy-MM-dd}:表示以日期为文件夹对日志文件进行归档
--RollingFile namerollingFile fileName${logDir}/rollog.logfilePattern${logDir}/$${date:yyyy-MM-dd}/rollog-%d{yyyy-MM-dd-HH-mm}-%i.logPolicies!-- 在系统启动时触发拆分规则产生一个日志文件--OnStartupTriggeringPolicy/!-- 按照文件的大小进行拆分--SizeBasedTriggeringPolicy size10KB/!-- 按照时间节点进行拆分拆分规则就是filePattern--TimeBasedTriggeringPolicy//PoliciesDefaultRolloverStrategy max30//RollingFile/AppendersLoggersRoot leveltraceAppenderRef refrollingFile//Root/Loggers
/Configuration3.2.2.5 自定义日志
?xml version1.0 encodingUTF-8 ?Configurationpropertiesproperty namelogDirF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOG4J2_StudyV2\\log/propertyproperty namepattern[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property/propertiesAppenders
!-- 输出到控制台--Console nameconsoleAppender targetSYSTEM_ERRpatternLayout pattern${pattern}//Console!-- 输出到文件--File namefileAppender fileName${logDir}\\log4j2.log!-- 配置日志文件格式--patternLayout pattern${pattern}//File!--fileName:日志文件名$${date:yyyy-MM-dd}:表示以日期为文件夹对日志文件进行归档
--RollingFile namerollingFile fileName${logDir}/rollog.logfilePattern${logDir}/$${date:yyyy-MM-dd}/rollog-%d{yyyy-MM-dd-HH-mm}-%i.logPolicies!-- 在系统启动时触发拆分规则产生一个日志文件--OnStartupTriggeringPolicy/!-- 按照文件的大小进行拆分--SizeBasedTriggeringPolicy size10KB/!-- 按照时间节点进行拆分拆分规则就是filePattern--TimeBasedTriggeringPolicy//PoliciesDefaultRolloverStrategy max30//RollingFile/AppendersLoggers!-- 自定义Logger--Logger namecom.xlb levelINFOincludeLocationfalse additivityfalse!-- 将控制台输出的consoleAppender设置为异步打印--AppenderRef refconsoleAppender//LoggerRoot leveltraceAppenderRef refconsoleAppender//Root/Loggers
/Configuration3.2.2.5 异步日志
3.2.2.6.1 xml中配置异步日志
?xml version1.0 encodingUTF-8 ?Configurationpropertiesproperty namelogDirF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOG4J2_StudyV2\\log/propertyproperty namepattern[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property/propertiesAppenders
!-- 输出到控制台--Console nameconsoleAppender targetSYSTEM_ERRpatternLayout pattern${pattern}//Console!-- 输出到文件--File namefileAppender fileName${logDir}\\log4j2.log!-- 配置日志文件格式--patternLayout pattern${pattern}//File!--fileName:日志文件名$${date:yyyy-MM-dd}:表示以日期为文件夹对日志文件进行归档
--RollingFile namerollingFile fileName${logDir}/rollog.logfilePattern${logDir}/$${date:yyyy-MM-dd}/rollog-%d{yyyy-MM-dd-HH-mm}-%i.logPolicies!-- 在系统启动时触发拆分规则产生一个日志文件--OnStartupTriggeringPolicy/!-- 按照文件的大小进行拆分--SizeBasedTriggeringPolicy size10KB/!-- 按照时间节点进行拆分拆分规则就是filePattern--TimeBasedTriggeringPolicy//PoliciesDefaultRolloverStrategy max30//RollingFile!-- 异步日志--Async namemyAsyncAppenderRef refconsoleAppender//Async/AppendersLoggersRoot leveltraceAppenderRef refrollingFile//Root/Loggers
/Configuration3.2.2.6.2 全局异步日志
全局日志需要在properties文件中指明xml文件中不需要特殊声明异步日志(文件名为log4j2.component.properties)
Log4jContextSelectororg.apache.logging.log4j.core.async.AsyncLoggerContextSelector?xml version1.0 encodingUTF-8 ?Configurationpropertiesproperty namelogDirF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOG4J2_StudyV2\\log/propertyproperty namepattern[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property/propertiesAppenders
!-- 输出到控制台--Console nameconsoleAppender targetSYSTEM_ERRpatternLayout pattern${pattern}//Console!-- 输出到文件--File namefileAppender fileName${logDir}\\log4j2.log!-- 配置日志文件格式--patternLayout pattern${pattern}//File!--fileName:日志文件名$${date:yyyy-MM-dd}:表示以日期为文件夹对日志文件进行归档
--RollingFile namerollingFile fileName${logDir}/rollog.logfilePattern${logDir}/$${date:yyyy-MM-dd}/rollog-%d{yyyy-MM-dd-HH-mm}-%i.logPolicies!-- 在系统启动时触发拆分规则产生一个日志文件--OnStartupTriggeringPolicy/!-- 按照文件的大小进行拆分--SizeBasedTriggeringPolicy size10KB/!-- 按照时间节点进行拆分拆分规则就是filePattern--TimeBasedTriggeringPolicy//PoliciesDefaultRolloverStrategy max30//RollingFile!-- 异步日志--
!-- Async namemyAsync--
!-- AppenderRef refconsoleAppender/--
!-- /Async--/AppendersLoggersRoot leveltraceAppenderRef refconsoleAppender//Root/Loggers
/Configuration按照上面这种方式声明的也是异步日志
3.2.2.6.3 混合异步日志
混合异步日志需要引入这个依赖否则会报错
!-- 混合异步日志用--dependencygroupIdcom.lmax/groupIdartifactIddisruptor/artifactIdversion3.4.3/version/dependency?xml version1.0 encodingUTF-8 ?Configurationpropertiesproperty namelogDirF:\\CODE\\JAVA\\LogStudyV2\\LogStudy\\LOG4J2_StudyV2\\log/propertyproperty namepattern[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n/property/propertiesAppenders
!-- 输出到控制台--Console nameconsoleAppender targetSYSTEM_ERRpatternLayout pattern${pattern}//Console!-- 输出到文件--File namefileAppender fileName${logDir}\\log4j2.log!-- 配置日志文件格式--patternLayout pattern${pattern}//File!--fileName:日志文件名$${date:yyyy-MM-dd}:表示以日期为文件夹对日志文件进行归档
--RollingFile namerollingFile fileName${logDir}/rollog.logfilePattern${logDir}/$${date:yyyy-MM-dd}/rollog-%d{yyyy-MM-dd-HH-mm}-%i.logPolicies!-- 在系统启动时触发拆分规则产生一个日志文件--OnStartupTriggeringPolicy/!-- 按照文件的大小进行拆分--SizeBasedTriggeringPolicy size10KB/!-- 按照时间节点进行拆分拆分规则就是filePattern--TimeBasedTriggeringPolicy//PoliciesDefaultRolloverStrategy max30//RollingFile!-- 异步日志--
!-- Async namemyAsync--
!-- AppenderRef refconsoleAppender/--
!-- /Async--/AppendersLoggersRoot leveltraceAppenderRef refconsoleAppender//Root!-- 自定义Logger让自定义的logger为异步loggerincludeLocationfalse表示取出日志中的行号信息记录日志的行号会使得日志记录的非常慢
--AsyncLogger namecom.xlb leveltraceincludeLocationfalse additivityfalse!-- 将控制台输出的consoleAppender设置为异步打印--AppenderRef refconsoleAppender//AsyncLogger/Loggers
/Configuration总结上面介绍大致介绍了市面上这两款日志的使用流程其实日志的使用基本上就是看如何对配置文件进行配置配置文件配置好后就可以很方便的使用日志进行记录。其实市面上虽然有好几种日志框架不过其实现的基本思想都差不多即有下面几点共性 1.都会分为不同的日志级别 1.1高于当前设置的日志级别就会打印 1.2低于当前设置的日志级别就不打印 2.都设置有输出处理器 2.1输出到控制台 2.2 输出到文件 2.3拆分文件 … 3格式化输出类似于[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %thread %L%m%n 4异步日志 5日志父子级关系 6自定义日志 希望这篇文章对日志的使用有所帮助希望能够一键三连呀~
如果想对日志有更深的理解可以看下这门b站上的课程这个可能前面20集左右是一个大佬现场直播手撸一个日志框架没有借助IDE在vim中一点点敲出来的很强不过课程是使用C讲解的有兴趣的可以听一下保证听完对日志会有一个更加深刻的认识 手撸日志框架