主要参考资料:
(推荐)java日志框架知识:https://www.cnblogs.com/gavanwanggw/p/7305218.html
log4j配置详解:https://blog.youkuaiyun.com/sinat_30185177/article/details/73550377
包或类的日志配置:https://www.cnblogs.com/yidaxia/p/5820036.html
Log4j迁移到Logback:https://blog.youkuaiyun.com/abc86319253/article/details/48731297
这里,以log4j为例,主要探究以下几个问题:
1、更改配置文件名字(log4j.properties),是否可以正常读取配置文件?
2、如何为单独一个类或者一个包配置日志?
3、additivity属性有什么作用?
4、appender的"Threshold = ERROR "和rootLogger的level有什么区别,同时配置会有什么效果?
5、如何实现不同日志系统的桥接?
一、环境配置:
引入jar包(log4j-1.2.17.jar)后,创建配置文件(log4j.properties)如下:
### \u8BBE\u7F6E###
log4j.rootLogger = info,stdout,D,E
### \u8F93\u51FA\u4FE1\u606F\u5230\u63A7\u5236\u62AC ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### \u8F93\u51FADEBUG \u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\u5230=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### \u8F93\u51FAERROR \u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\u5230=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E\://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern =%-d{yyyy-MM-dd HH\:mm\:ss} [ %t\:%r ] - [ %p ] %m%n
创建测试类进行测试:
二、探究结果:
-
问题一
测试结果:文件名修改后,日志打印无法正常进行,文件名必须为log4j.properties。
-
问题二
要给某一个包或者类配置日志,只需加上类似如下配置即可:(配置logger,指定包名或者类名,additivity属性等)
#com.thunisoft.crj.test.ClassLog\u5305\u4E0B\u914D\u7F6E\u7684\u65E5\u5FD7
log4j.logger.com.thunisoft.crj.test.ClassLog=DEBUG, message
log4j.additivity.com.thunisoft.crj.test.ClassLog=false
log4j.appender.message=org.apache.log4j.RollingFileAppender
log4j.appender.message.File=E\://logs/message.log
log4j.appender.message.Append=true
log4j.appender.message.MaxFileSize=1GB
log4j.appender.message.MaxBackupIndex=5
log4j.appender.message.layout=org.apache.log4j.PatternLayout
log4j.appender.message.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.message.encoding=UTF-8
-
问题三:
关于additivity:
additivity是 子Logger 是否继承 父Logger 的 输出源(appender) 的标志位。详细说,默认情况下 子Logger 会继承 父Logger 的appender(additivity=true),也就是说 子Logger 会在 父Logger 的appender里输出。若是additivity设为false,则 子Logger 仅仅会在自己的appender里输出。而不会在 父Logger 的appender里输出。
换句话说,在子logger(这里指是message)中配置additivity=false,不会在父logger(这里指是rootLogger,包括stdout,D,E)中的appender输出,只会在自己的appender中输出。
-
问题四:
关于Threshold:(使用场景:比如把一些报错ERROR日志单独存到指定文件)
Threshold属性可以指定日志level
Log4j根据日志信息的重要程度从大到小,分OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL
比如我们指定某个appender的Threshold为WARN,那这个appender输出的日志信息就是WARN级别以及WARN以上的级别;
假如我们指定的是ERROR,那这个就输出ERROR或者FATAL日志信息;
当然这里有个提前 rootLogger里配置的level比如小于Threshold层级 否则无效 还是按照总的rootLogger里的level来输出,一般我们实际实用的话 rootLogger里配置DEBUG,然后某个文件专门存储ERRO日志,就配置下Threshold为ERROR,这个就是我们的最佳实践,不要乱七八糟瞎配置;
关于这一点,在上面的配置试验中就可以看出:由于D这个appender配置的“Threshold=DEBUG”级别小于rootLogger中配置的INFO,因此,按照info的级别输出。而E这个appender配置的“Threshold=ERROR”级别大于rootLogger中配置的INFO,则输出对应的日志级别以error为准。
-
问题五:
由于logback日志组件性能比log4j好,项目中我们更多的是使用logback。为此,如果之前使用log4j,则需要将log4j迁移到logback(只要三步):
1,引入需要的jar包(是maven则加入对应的依赖)
或者
<!-- logback日志配置开始 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.7</version>
</dependency>
<!-- logback日志配置结束 -->
2,在src目录下创建logback.xml文件
项目之前的使用log4j.properties可以用http://logback.qos.ch/translator/转换到等价的logback配置文件。PS:转换后的配置文件,pattern参数需要修改。
如log4j的pattern配置 %-d{yyyy-MM-dd HH:mm:ss,SSS} [%c:%L]-[%p] %m%n 在logback里面不在起效。
我把它调整为 %date [%level] [%thread] %logger{80} [%file : %line] %msg%n
另外按日期产生日志文件策略的pattern也需要修改(具体查看下文的logback.xml配置文件)。参考:https://blog.youkuaiyun.com/chenminghe271/article/details/38682493
转化后:
<?xml version="1.0" encoding="UTF-8"?>
<!-- For assistance related to logback-translator or configuration -->
<!-- files in general, please contact the logback user mailing list -->
<!-- at http://www.qos.ch/mailman/listinfo/logback-user -->
<!-- -->
<!-- For professional support please see -->
<!-- http://www.qos.ch/shop/products/professionalSupport -->
<!-- -->
<configuration>
<appender name="message" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
<encoding>UTF-8</encoding>
<Append>true</Append>
<File>E://logs/message.log</File>
<encoder>
<pattern>%date [%level] [%thread] %logger{80} [%file : %line] %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<maxIndex>5</maxIndex>
<FileNamePattern>E://logs/message.log .%i</FileNamePattern>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>1GB</MaxFileSize>
</triggeringPolicy>
</appender>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target>
<encoder>
<pattern>%date [%level] [%thread] %logger{80} [%file : %line] %msg%n</pattern>
</encoder>
</appender>
<appender name="D" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--See http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
<!--and http://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy-->
<!--for further documentation-->
<Append>true</Append>
<File>E://logs/log.log</File>
<encoder>
<pattern>%date [%level] [%thread] %logger{80} [%file : %line] %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
<appender name="E" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--See http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
<!--and http://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy-->
<!--for further documentation-->
<Append>true</Append>
<File>E://logs/error.log</File>
<encoder>
<pattern>%date [%level] [%thread] %logger{80} [%file : %line] %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<logger name="com.thunisoft.crj.test.ClassLog" additivity="false" level="DEBUG">
<appender-ref ref="message"/>
</logger>
<root level="INFO">
<appender-ref ref="stdout"/>
<appender-ref ref="D"/>
<appender-ref ref="E"/>
</root>
</configuration>
3,把打印日志类使用的logger类替换为SLF4J的logger类(注意是LoggerFactory)
桥接完成!
结束和声明
以上纯属个人观点和体会,相关的资料和观点来自网络的朋友们!
希望这篇文章能对你有所帮助!
欢迎大家来一起讨论分享干货,或者批评指正!
更加热切盼望各路大神前辈给些指导和建议!
转载请注明出处!或者联系我!(chenruijia_java@163.com)