logback

来源:互联网 发布:腾讯数据存储架构 编辑:程序博客网 时间:2024/05/03 21:00

为啥有logback?
Logback为取代log4j而生。
Logback由log4j的创立者Ceki Gülcü设计。以十多年设计工业级记录系统的经验为基础,所创建的logback比现有任何记录系统更快、占用资源更少,有时差距非常大

0. 需要添加的 JAR 包
logback-core.jar – logback 核心包,必备
slf4j-api.jar – 通用日志接口包,可以在logback与其他记录系统如log4j和java.util.logging (JUL)之间轻松互相切换
Logback-classic – 实现了 SLF4J API,扩展了core模块

1. 系统启动,默认家在classpath下的logback.xml 或者 logback-test.xml。 这里可以把默认配置文件的位置作为系统属性进行指定
java -Dlogback.configurationFile=/path/to/config.xml chapters.configuration.MyApp1

2. 在根元素configuration中配置属性scan=”true”后,当配置文件修改后自动重新加载,默认每分钟扫描一次。
configuration元素的 scanPeriod 属性控制扫描周期,其值可以带时间单位,包括:milliseconds、seconds、minutes和hours。
如果没写明时间单位,则默认为毫秒。示例:

<configuration debug="true" scan="true" scanPeriod="30 minutes"></configuration>

为提高性能,不会在每个logger被调用时去检查是否需要扫描,而是每隔16次记录操作进行一次检查。
简言之,当配置文件改变后,它会被延时重新加载,延时时间由扫描间隔时间和一些logger调用所决定
debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。

3. Logback-classic带了一个叫ViewStatusMessagesServlet的Servlet,它以HTML表格的格式打印与当前LoggerContext关联的StatusManager的内容

<servlet>     <servlet-name>ViewStatusMessages</servlet-name>  <servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class></servlet><servlet-mapping>     <servlet-name>ViewStatusMessages</servlet-name>  <url-pattern>/lbClassicStatus</url-pattern></servlet-mapping>

访问地址是http://host/yourWebapp/lbClassicStatus。

4. 可以这样描述配置文件的基本结构:
以<configuration>开头,后面有零个或多个<appender>元素,有零个或多个<logger>元素,有最多一个<root>元素

a. Logger是用<logger>元素配置的。<logger>元素有且仅有一个name属性、一个可选的level属性和一个可选的additivity属性。
Logger: Level属性的值大小写无关,其值为下面其中一个字符串:TRACE、DEBUG、INFO、WARN、ERROR、ALL和OFF。
还可以是一个特殊的字符串“INHERITED”或其同义词“NULL”,表示强制继承上级的级别
<logger>元素可以包含零个或多个<appender-ref ref=”logger的name” >元素,表示这个appender会被添加到该logger。强调一下,每个用<logger>元素声明的logger,首先会移除所有appender,然后才添加引用了的appender,所以如果logger没有引用任何appender,就会失去所有appender。

b. <root>元素配置根logger。该元素有一个level属性。没有name属性,因为已经被命名为“ROOT”。
ROOT: Level属性的值大小写无关,其值为下面其中一个字符串:TRACE、DEBUG、INFO、WARN、ERROR、ALL和OFF。注意不能设置为“INHERITED” 或“NULL”。

c. 配置Appender:
Appender用 <appender>元素配置,该元素必要属性name和class。name属性指定appender的名称,class属性指定appender类的全限定名。
<appender>元素可以包含零个或多个<layout>元素、零个或多个<encoder>元素和零个或多个<filter>元素。
<layout>元素的class属性是必要的,表示将被实例化的layout类的全限定名。因为太常用了,所以当当layout是PatternLayout时,可以省略class属性。
<encoder>元素class属性是必要的,表示将被实例化的encoder类的全限定名。因为太常用了,所以当当encoder是PatternLayoutEncoder时,可以省略class属性。

注意每个appender都有自己的encoder。Encoder通常不能被多个appender共享,layout也是。所以,logback的配置文件里没有共享encoder或layout的语法。

5.常用Appender(负责写记录事件的组件):
a. ConsoleAppender, FileAppender, RollingFileAppender, FixedWindowRollingPolicy
ConsoleAppender把事件添加到控制台,更准确地说是System.out或System.err,默认为前者。ConsoleAppender按照用户指定的encoder对事件进行格式化。System.out和System.err都是java.io.PrintStream类型,因此,它们被包裹在有缓冲I/O操作的OutputStreamWriter里

b. 通过时间戳保证唯一文件名(比如对于不断启动的短生命周期的程序):

<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" /><appender name="logfile" class="ch.qos.logback.core.FileAppender">    <file>logfile-${bySecond}.log</file>    <append>false</append>    <encoder>      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>    </encoder></appender>

timestamp元素有两个属性:key和datePattern。属性key是变量名,对余下的配置元素可用。属性datePattern表示把当前时间(解析配置文件的时间)转换成字符串时使用的日期模式,遵从java.text.SimpleDateFormat里的约定。

c. RollingFileAppender继承FileAppender,能够滚动记录文件。例如,RollingFileAppender能先记录到文件“log.txt”,然后当符合某个条件时,变成记录到其他文件。
RollingFileAppender有两个与之互动的重要子组件。第一个是RollingPolicy,负责滚动。第二个是TriggeringPolicy,决定是否以及何时进行滚动。所以,RollingPolicy负责“什么”, TriggeringPolicy负责“何时”。要想RollingFileAppender起作用,必须同时设置RollingPolicy和TriggeringPolicy。不过,如果RollingPolicy也实现了TriggeringPolicy接口,那么只需要设置RollingPolicy

<appender name="logfile" class="ch.qos.logback.core.rolling.RollingFileAppender">  <File>${log.base}.log</File>  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">      <FileNamePattern>${log.base}.%d{yyyy-MM-dd}.log.zip</FileNamePattern>  </rollingPolicy>  <layout class="ch.qos.logback.classic.PatternLayout">      <pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>  </layout></appender>

同样也可以指定 maxHistory 属性,控制被保留的归档文件的最大数量,超出数量就删除旧文件

6. Encoder负责两件事,一是把事件转换为字节数组,二是把字节数组写入输出流。encoder不但可以完全控制待写出的字节的格式,而且可以控制字节何时及是否被写出。 在logback 0.9.19版之前没有encoder。
Layout,只负责把事件转换为字符串。此外,因为layout不能控制事件何时被写出,所以不能成批地聚集事件。相比之下,encoder不但可以完全控制待写出的字节的格式,而且可以控制字节何时及是否被写出。目前,PatternLayoutEncoder是唯一有用的encoder,它基本上是封装了PatternLayout,让PatternLayout负责大多数工作

注意:在之前的版本里,多数appender依靠layout来把事件转换成字符串并用java.io.Writer把字符串输出。在之前的版本里,用户需要在FileAppender里嵌入一个PatternLayout。

<appender name="logfile" class="ch.qos.logback.core.FileAppender">    <File>logfile.log</File>    <layout class="ch.qos.logback.classic.PatternLayout">        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>    </layout></appender>

而从0.9.19版开始,FileAppender和其子类使用encoder,不接受layout。 如

<appender name="logfile" class="ch.qos.logback.core.FileAppender">    <file>logfile.log</file>    <encoder>        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>    </encoder></appender>

对于console 同样no longer admits a layout as a sub-component, set an encoder instead.

对于这个变化总的来说:既然PatternLayout是最常用的layout,logback便提供了PatternLayoutEncoder,它扩展了LayoutWrappingEncoder,且仅使用PatternLayout。从logback 0.9.19版起,FileAppender或其子类在只要用到PattternLayout时,都必须换成PatternLayoutEncoder。

7. Layout负责把事件转换成字符串。Layout接口的format()方法的参数是代表任何类型的事件,返回字符串

8. 附上两段appender的配置

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">    <encoder>        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>    </encoder></appender>
<appender name="logfile2" class="ch.qos.logback.core.rolling.RollingFileAppender">    <File>${bySecond}.log</File>    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">        <FileNamePattern>%d{yyyy-MM-dd-HH-mm-ss}.log</FileNamePattern>    </rollingPolicy>    <encoder>        <pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>    </encoder></appender>

上文转自:logback学习记录

9.下面附上一段我在实际项目中使用logback的配置

<configuration>     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">            <evaluator>                 <expression>logger.contains("springframework")</expression>            </evaluator>            <OnMismatch>NEUTRAL</OnMismatch>            <OnMatch>DENY</OnMatch>        </filter>        <encoder charset="UTF-8">            <pattern>%-4r - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n </pattern>        </encoder>    </appender>        <appender name="Logs-all" class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>F:/temp/logs/Logs-all.log</file>        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">            <fileNamePattern>Logs-all.%d{yyyy-MM-dd}.log.zip</fileNamePattern>        </rollingPolicy>        <encoder>            <pattern>%-1relative - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} -- %msg%n</pattern>        </encoder>    </appender>        <appender name="TIMEOUT-SQL" class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>F:/temp/logs/timeout-sql.log</file>        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">            <fileNamePattern>timeout-sql.%d{yyyy-MM-dd}.log.zip</fileNamePattern>        </rollingPolicy>        <encoder>            <pattern>%-1relative - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} -- %msg%n</pattern>        </encoder>    </appender>        <appender name="TIMEOUT-REQUEST" class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>F:/temp/logs/timeout-request.log</file>        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">            <fileNamePattern>timeout-request.%d{yyyy-MM-dd}.log.zip</fileNamePattern>        </rollingPolicy>        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">            <maxFileSize>6MB</maxFileSize>        </triggeringPolicy>        <encoder>            <pattern>%-1relative - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} -- %msg%n</pattern>        </encoder>    </appender>    <!-- ===================================================================== -->    <!--  以下是logger的定义                                                   -->    <!-- ===================================================================== -->    <logger name="com.dengsilinming.dao.ibatis.IbatisGenericDaoImpl" additivity="true">        <level value="DEBUG"/>        <appender-ref ref="TIMEOUT-SQL"/>    </logger>    <logger name="com.dengsilinming.web.filter.timer.TimerFilter" additivity="true">        <level value="WARN"/>        <appender-ref ref="TIMEOUT-REQUEST"/>    </logger>        <logger name="java.sql.Connection">          <level value="debug" />      </logger>     <logger name="java.sql.PreparedStatement">          <level value="debug" />      </logger>     <logger name="java.sql.ResultSet">          <level value="debug" />      </logger>    <!-- ===================================================================== -->    <!--  Root logger的定义                                                    -->    <!-- ===================================================================== -->     <root level="INFO">    <appender-ref ref="STDOUT" />    </root>  </configuration>
原创粉丝点击