Java 日志输出(logback)
Posted Sharing Tec
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 日志输出(logback)相关的知识,希望对你有一定的参考价值。
笔者最近看到有的项目会输出系统日志,保存了很多系统运行的关键信息,感觉很有用,于是想了解一些这方面的知识,并尝试是否能加载到自己的下一个项目中去
小知识:
properties加载配置
<!-- 加载根目录下(可修改)所有properties配置文件-->
<context:property-placeholder location="classpath:*.properties" ignore-unresolvable="true"/>
<!-- 分别加载这两个配置文件-->
<context:property-placeholder location="classpath*:log.properties,classpath*:quartz.properties" ignore-unresolvable="true"/>
<!-- 加载单一配置文件-->
<context:property-placeholder location="classpath:log.properties" ignore-unresolvable="true"/>
<!-- ignore-unresolvable="true" 字段非必须的-->
<context:property-placeholder location="classpath:*.properties"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<!-- 这种可以加载多个配置文件-->
<list>
<value>classpath:log.properties</value>
<value>classpath:quartz.properties</value>
</list>
</property>
<property name="location">
<!-- 这种只能加载一个配置文件-->
<value>classpath:quartz.properties</value>
</property>
</bean>
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
只能存在一个实例对象,如果有相同属性名的,多个文件只会读取最后一个
classpath:只会到指定路径查找读取配置文件
classpath*:不仅去class路径还包括了jar文件中class路径进行查找,要遍历所有的classpath,
所以加载速度较慢
日志实现方式之logback
优点:自动加载配置文件,代码不会有具体实现类,减少侵入
该日志系统的配置文件名称只能是logback.xml或logback-text.xml
范例:
<configuration scan="true" scanPeriod="1" debug="false">
<!--scan:配置文件发生那个变化是否重新加载;scanPeriod:检测配置文件间隔,默认单位毫秒;debug:是否打印logback内部日志-->
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</layout>
</appender>
<appender name="FILE-LOG" class="ch.qos.logback.core.FileAppender">
<file>i:\\TEST.TXT</file>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</layout>
<append>true</append>
<prudent>false</prudent>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
</appender>
<appender name="FILE-LOG2" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>i:\\aa-%d{yyyy-MM-dd}.TXT</fileNamePattern>
<!-- 生成:aa-2019-12-22.log 文件-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</layout>
<append>true</append>
<prudent>false</prudent>
</appender>
<logger name="com.doself.out.PrintTestOUT" level="debug" additivity="false">
<appendr-ref ref="FILE-LOG2"/>
</logger>
<!--使用了logger的不需要在root里面添加-->
<root level="info">
<appender-ref ref="CONSOLE-LOG"/>
<appender-ref ref="FILE-LOG"/>
</root>
</configuration>
在上述文件中,创建了日志系统,<logger>标签的内容需注释掉,这里笔者暂时还没试验成功
文件结构:
根标签:configuration:
子标签:
appender:设置日志
logger:设置独立日志(包,类等)
root:加载日志块
执顺序为:logger-root-appender
日志输出格式(使用%转义):
c/lo/logger{length}:length,不输入标识完全输出logger名称,0标识最后边点号后字符,其他数字表示最后边点号前的字符数量
C/class{length}:输出指定记录的请求的调用者的全限定名,length同上
d/date{pattern}:输出时间格式,格式同simpleDateFormat
caller{depth}:输出调用者的位置信息,depth深度
L:执行日志的请求行号
m/msg/message:输出应用程序提供的信息
m:输入执行日志请求的方法名(这个咱不理解,慎用)
n:换行
p/le/level:输出日志级别
r/relative:输出程序启动到创建的时间(毫秒)
t/thread:输出产生日志的线程名
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
上述意思为:
日志格式为:时间按照格式yyyy-MM-dd' 'HH:mm:ss.sss进行输出,调用者名称,线程名,行号,日志级别,程序信息,换行
Filter:日志过滤
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
上述代码表示:当匹配(onmatch)到level等级为INFO的信息是拒绝,不匹配(onmismatch)的接受
Logger
当我们需要特定位置的日志按照一定要求输出时,会用到logger标签,表示某个位置的日志按照特定日志输出appender进行执行输出
<logger name="com.doself.out" level="debug" additivity="false">
<appendr-ref ref="FILE-LOG2"/>
</logger>
上述代码表示:com.doself.out包内的日志,不在向上(root)传递,直接通过FILE-LOG2执行,日志级别包括debug及其往上日志
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</layout>
</appender>
上述代码表示日志会在控制台按照给定格式输出
<appender name="FILE-LOG" class="ch.qos.logback.core.FileAppender">
<file>i:\\TEST.TXT</file>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</layout>
<append>true</append>
<prudent>false</prudent>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
</appender>
上述代码表示,会将日志输出到i:\TEST.TXT文件内,且通过过滤器,不匹配info级别日志
<appender name="FILE-LOG2" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>i:\\aa-%d{yyyy-MM-dd}.TXT</fileNamePattern>
<!-- 生成:aa-2019-12-22.log 文件-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</layout>
<append>true</append>
<prudent>false</prudent>
</appender>
上述代码与上一个类似,这里对文件名进行了调整,结果就是每天会生成一个日志文件
<root level="info">
<appender-ref ref="CONSOLE-LOG"/>
<appender-ref ref="FILE-LOG"/>
</root>
上述代码表示会加载这两个日志处理器,等级为info及以上
在上述各个功能中,日志每次发生都会进行一次IO,这样会对性能产生一定的影响,因此有一个异步写日志的功能
<appender name="async" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>256</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref ="FILE-LOG2"/>
</appender>
<discardingThreshold>:表示丢弃tract,debug,info级别日志的门限。如设置40,表示容量还剩40%时,丢弃上述级别日志
<queueSize>:最大容量
<appender-ref:表示那个appender进行异步输出
上述过程通过新建一条线程,并将日志缓存到队列,将队列内容交由指定appender处理
要产生日志的类操作:
public class PrintTest {
private static final Logger logger= LoggerFactory.getLogger(PrintTest.class);
public void prints(){
System.out.println("日志");
logger.warn("可能发生错误");
logger.info("这是关键信息"+this.toString());
logger.debug("debug?");
logger.error("error");
}
}
上述代码实例化了一个静态常量logger进行日志输出
好了,以上就是笔者近来接触到的关于日志的了解,笔者精力有限,目前只了解了一下logback日志的操作,其他方法暂时没时间学习,等以后有机会了在进行深入学习,以上如有错误的请各位指正,像我一样的菜鸟请测试后使用,笔者也是每次使用前进行相关实验的。
天时人事日相催,冬至阳生春又来
以上是关于Java 日志输出(logback)的主要内容,如果未能解决你的问题,请参考以下文章