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

范例:

<?xml version="1.0" encoding="utf-8"?><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处理


要产生日志的类操作:

@Controllerpublic class PrintTest { private static final Logger logger= LoggerFactory.getLogger(PrintTest.class); @RequestMapping(value = "/aa.html",method = RequestMethod.GET) public void prints(){ System.out.println("日志"); logger.warn("可能发生错误"); logger.info("这是关键信息"+this.toString()); logger.debug("debug?"); logger.error("error"); }}

上述代码实例化了一个静态常量logger进行日志输出

好了,以上就是笔者近来接触到的关于日志的了解,笔者精力有限,目前只了解了一下logback日志的操作,其他方法暂时没时间学习,等以后有机会了在进行深入学习,以上如有错误的请各位指正,像我一样的菜鸟请测试后使用,笔者也是每次使用前进行相关实验的。


天时人事日相催,冬至阳生春又来

以上是关于Java 日志输出(logback)的主要内容,如果未能解决你的问题,请参考以下文章

Java Logback配置文件这么写,还愁不会整理日志?

Java日志框架学习--LogBack和Log4j2--下

Spring Boot 集成 Logback 日志:控制台彩色日志输出 + 日志文件输出

Logback日志输出问号的问题解决方案

logback异步输出日志深入分析

Java可以如何实现文件的监听