欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

logback记日志真的很好使 博客分类: logback 日志log4jlogbacklog 

程序员文章站 2024-03-18 08:02:33
...

前言:    

   使用logback 来记录日志真是一个不错的选择,正像logback官网上介绍的那样:

写道
Logback is intended as a successor to the popular log4j project, picking up where log4j leaves off.

     logback扩展了log4j很多功能,以前一直不明白logback好在哪儿,因为log4j完全够用了,为啥还要用logback来写日志呢? 直到有一天用log4j来记录日志被一个问题所难住了。

 

问题1:

     

       需要以天为单位记录日志,每天生成一个日志文件,比如xxx.log.yyyy-mm-dd,很自然就想到log4j的appender类 DailyRollingFileAppender,但是发现一个问题,使用这个appender没有办法设置MaxFileSize 这个值,不能控制最大文件数,时间一长服务端的磁盘就被历史日志给撑爆了,所以只能在服务端启动一个定时脚本定时去清理历史文件,或者,要自己写代码去扩展DailyRollingFileAppender的行为,加入自动清理历史日志的功能。但是经过实践都不是最佳解决方案,不是说不能实现,只是实现过程有很多细节需要处理。

 

问题2:

        因为系统是一个SAAS系统,所以系统记录日志希望按照有系统用户来区分,即一个用户一个日志文件,行为日志都记录在各自的日志文件中。如果第一个问题还能通过某种方式是适配实现的话,那这个需求用log4j基本没有可能实现了,或者实现起来要很费周折了。

 

新的发现:

       偶然间在百度上发现,使用logback的siftingappender 可以轻松解决以上第二个问题。http://bbs.csdn.net/topics/390401271?page=1  。

  

在执行的上下文开始地方设置线程绑定参数,例如:MDC.put("app", onsListener.getCollectionName());

 

配置logback.xml 放置在classpath的根目录上,配置文件内容如下:

 

<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="false">
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<target>System.out</target>
		<encoding>${loggingCharset}</encoding>
		<!-- <filter class="com.alibaba.citrus.logconfig.logback.LevelRangeFilter"> 
			<levelMax>INFO</levelMax> </filter> -->
		<layout class="ch.qos.logback.classic.PatternLayout">
			<pattern><![CDATA[%d{yyyy-MM-dd HH:mm:ss} %level %X{app} %logger{35}- %msg%n]]></pattern>
		</layout>
	</appender>


	<appender name="statis" class="ch.qos.logback.classic.sift.SiftingAppender">
		<discriminator>
			<Key>app</Key>
			<DefaultValue>unknown</DefaultValue>
		</discriminator>
		<sift>
			<appender name="FILE-${app}"
				class="ch.qos.logback.core.rolling.RollingFileAppender">
				<File>${log.dir}/incr/incr-${app}.log</File>
				<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
					<fileNamePattern>${log.dir}/incr/%d{yyyy-MM-dd}-incr-${app}.log
					</fileNamePattern>
					<maxHistory>8</maxHistory>
				</rollingPolicy>
				<encoder>
					<pattern><![CDATA[%d{yyyy-MM-dd HH:mm:ss} %level %logger{35}- %msg%n]]></pattern>
				</encoder>
			</appender>

		</sift>
	</appender>
	<logger name="com.dfire.tis.realtime.transfer">
		<level value="INFO" />
		<appender-ref ref="statis" />
	</logger>

	<root>
		<level value="ERROR" />
		<appender-ref ref="STDOUT" />
	</root>

</configuration>
 

 

  • 通过SiftingAppender来实现不同用户的日志通过线程绑定变量$app来实现文件隔离,并且可通过系统环境变量的方式灵活设置日志文件的名称。
  • 通过设置TimeBasedRollingPolicy来实现按天来滚动添加日志文件,设置maxHistory属性来设置最大保留日志文件个数,看系统磁盘,和每天打印日志大小来判断保留的日志文件个数。

maven依赖:

 

<dependency>
	<groupId>ch.qos.logback</groupId>
	<artifactId>logback-classic</artifactId>
	<version>1.1.3</version>
</dependency>
    
     该依赖中,slf4j-api logger门面一起传递依赖进来了,理论上在项目不就不需要依赖其他和log相关的第三方包了,除非项目中是用 apache commons-logging 来记录日志的,那还要在依赖一个jcl-over-slf4j的桥接依赖包。

 

另外需要将classpath中的log4j.xml 或者log4j.properties配置文件删除。

 

 总结: 

     接触logback之后有一种得来全部费工夫的感觉,之前一直试图通过log4j来实现实现而没有实现的需求,在logback中已经完美支持了,都怪我之前只顾低头走老路,没有抬头环顾一下周围是否还有什么其他的方式来实现,或者也没有和其他同事讨论一下是否有更好的解决方案,只顾一个人埋头搞自己的一亩三分田,这个对一个程序员来说是很要命的。现在的社会是讲究合作和效率的,发现和理解一个新事物的本质和特性对一个程序员也是一下必备的技能。

  从此,我们可以快乐地向世界大声喊出“hello logback”,log4j的时代过去了,bye bye log4j