为啥有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>
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>