Logback学习笔记1 .
来源:互联网 发布:淘宝取件通知改回短信 编辑:程序博客网 时间:2024/09/21 06:34
引用:http://blog.csdn.net/milife2012/article/details/7277888
Logback介绍
Logback 分为三个模块:Core、Classic和 Access。Core模块是其他两个模块的基础。 Classic模块扩展了core模块。 Classic模块相当于log4j的显著改进版。Logback-classic直接实现了 SLF4J API。
要引入logback,由于Logback-classic依赖slf4j-api.jar和logback-core.jar,所以要把slf4j-api.jar、logback-core.jar、logback-classic.jar,添加到要引入Logbac日志管理的项目的class path中.
Logback的配置
Logger、Appender和 Layout
Logback建立于三个主要类之上:Logger、Appender和 Layout。Logger类是logback-classic模块的一部分,而Appender和Layout接口来自logback-core。作为一个多用途模块,logback-core不包含任何 logger。
Logger作为日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型、级别。Appender主要用于指定日志输出的目的地,目的地可以是控制台、文件、远程套接字服务器、 MySQL、 PostreSQL、 Oracle和其他数据库、 JMS和远程UNIX Syslog守护进程等。Layout负责把事件转换成字符串,格式化的日志信息的输出。
Logger context
各个logger都被关联到一个 LoggerContext,LoggerContext负责制造logger,也负责以树结构排列各 logger。
如果 logger的名称带上一个点号后是另外一个 logger的名称的前缀,那么,前者就被称为后者的祖先。如果 logger与其后代 logger之间没有其他祖先,那么,前者就被称为子logger之父。比如,名为 "com.foo""的 logger是名为"com.foo.Bar"之父。root logger位于 logger等级的最顶端,root logger可以通过其名称取得,如下所示:
Logger rootLogger=LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
其他所有logger也通过org.slf4j.LoggerFactory类的静态方法getLogger取得。 getLogger方法以 logger 名称为参数。用同一名字调用LoggerFactory.getLogger方法所得到的永远都是同一个logger对象的引用。
有效级别与级别继承
Logger 可以被分配级别。级别包括:TRACE、DEBUG、INFO、WARN和 ERROR,定义于 ch.qos.logback.classic.Level类。如果 logger没有被分配级别,那么它将从有被分配级别的最近的祖先那里继承级别。root logger默认级别是 DEBUG。
打印方法与基本选择规则
打印方法决定记录请求的级别。例如,如果 L是一个 logger实例,那么,语句 L.info("..")是一条级别为 INFO的记录语句。记录请求的级别在高于或等于其 logger的有效级别时被称为被启用,否则,称为被禁用。
记录请求级别为 p,其 logger的有效级别为 q,只有则当 p>=q时,该请求才会被执行。
该规则是 logback的核心。级别排序为: TRACE < DEBUG < INFO < WARN < ERROR。
Logger、Appenders及layouts的关系
一个 logger可以被关联多个 appender。方法 addAppender()为指定的 logger添加一个 appender。对于 logger的每个启用了的记录请求,都将被发送到 logger里的全部 appender及更高等级的 appender。换句话说,appender叠加性地继承了 logger 的层次等级。
Logger L的记录语句的输出会发送给 L及其祖先的全部 appender。如果 logger L的某个祖先 P设置叠加性标识为 false,那么,L的输出会发送给L与 P之间(含P)的所有 appender,但不会发送给P的任何祖先的appender。
Logger 的叠加性默认为 true。如果希望定制输出格式。这时为 appender 关联一个 layout即可。Layout负责根据用户意愿对记录请求进行格式化,appender负责将格式化化后的输出发送到目的地。
例如,转换模式"%-4relative [%thread] %-5level %logger{32} - %msg%n"在 PatternLayout里会输出形如:
176 [main] DEBUG manual.architecture.HelloWorld2 - Hello world.
第一个字段是自程序启动以来的逝去时间,单位是毫秒。
第二个地段发出记录请求的线程。
第三个字段是记录请求的级别。
第四个字段是与记录请求关联的 logger的名称。
"-"之后是请求的消息文字。
Logback的默认配置
如果配置文件 logback-test.xml和 logback.xml都不存在,那么 logback默认地会调用BasicConfigurator,创建一个最小化配置。最小化配置由一个关联到根 logger的ConsoleAppender组成。输出用模式为%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n的 PatternLayoutEncoder进行格式化。root logger默认级别是 DEBUG。
logback配置文件
Logback 配置文件的语法非常灵活。正因为灵活,所以无法用 DTD或 XML schema进行定义。尽管如此,可以这样描述配置文件的基本结构:以<configuration>开头,后面有零个或多个<appender>元素,有零个或多个<logger>元素,有最多一个<root>元素。
Logback默认配置的采用的步骤
1. 尝试在 classpath下查找文件 logback-test.xml;
2. 如果文件不存在,则查找文件 logback.xml;
3. 如果两个文件都不存在,logback用 Bas icConfigurator自动对自己进行配置,这会导致记录输出到控制台。
假设配置文件 logback-test.xml和 logback.xml都不存在,那么 logback默认地会调用BasicConfigurator,创建一个最小化配置。最小化配置由一个关联到根 logger的ConsoleAppender组成。输出用模式为%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n的 PatternLayoutEncoder进行格式化。还有,根 logger默认级别是 DEBUG。
最简单的配置方法就是使用默认配置。以下是logback用BasicConfigurator配置的简单例子:
package com.ttpod.chapters.configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
publicclass MyApp1 {
finalstatic Loggerlogger = LoggerFactory.getLogger(MyApp1.class);
publicstaticvoid main(String[] args) {
logger.info("Entering application."); //进行另一个application中
Foo foo =new Foo();
foo.doIt(); //执行其它中的日志输出方法
logger.info("Exiting application."); //退出另一个application
}
}
该类定义了一个静态变量 logger,然后实例化一个 Foo对象。Foo类如下
package com.ttpod.chapters.configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
publicclass Foo {
staticfinal Loggerlogger = LoggerFactory.getLogger(Foo.class);
publicvoid doIt() {
logger.debug("Did it again!"); //定义一个debug级别的日志输出
}
…………
}
自动打印警告和错误消息
当解析配置文件有警告或出错时,logback会在控制台上自动打印状态数据。如果没有警告或错误,还是想检查 logback的内部状态的话,可以调用 StatusPrinter的 print()方法。示例如下:
finalstatic Loggerlogger = LoggerFactory.getLogger(MyApp2.class);
publicstaticvoid main(String[] args) {
//在当前环境中假设 SLF4J已经被绑定到logback
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
//打印logback的内部状态
StatusPrinter.print(lc);
…………
}
}
对应的配置文件:
<?xmlversion="1.0"encoding="UTF-8"?>
<configuration>
<!--定义一个名为STDOUT的appender,并将其关联到ch.qos.logback.core.ConsoleAppender-->
<appendername="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders作用是将logger事件转换成字节数组,并将字节数组写入到输出流-->
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度
%msg:日志消息,%n是换行符-->
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<rootlevel="debug"> <!-- root logger,定义级别为debug-->
<appender-refref="STDOUT"/> <!--将名为STDOUT的appender添加到root logger下-->
</root>
</configuration>
控制台输出结果如下:
…………
20:12:33,359 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
20:12:33,359 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
20:12:33,359 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/D:/Workspaces/MyEclipse%208.5/logback_test/WebRoot/WEB-INF/classes/logback.xml]
20:12:33,484 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
20:12:33,484 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
20:12:33,500 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
20:12:33,593 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
20:12:33,593 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
20:12:33,593 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
20:12:33,593 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@cb6009 - Registering current configuration as safe fallback point
…………
Logback自定义配置
配置root logger
<root>元素配置根 logger。该元素有一个 level属性。没有 name 属性,因为已经被命名为"ROOT"。 Level属性的值大小写无关,其值为下面其中一个字符串:TRACE、DEBUG、INFO、WARN、ERROR、ALL和 OFF。注意不能设置为"INHERITED"或"NULL"。 <logger>元素可以包含零个或多个<appender-ref>元素。与<logger>元素类似,声明<root>元素后,会先关闭然后移除全部当前 appender,只引用声明了的 appender。如果 root 元素没有引用任何 appender,就会失去所有 appender。
假设我们不想看到"com.ttpod.file"包里的任何组件的任何 DEBUG信息,可以设置如下:
<?xmlversion="1.0"encoding="UTF-8"?>
<configuration>
<appendername="STDOUT"class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<!--设置configuration下的logger的级别为INFO,默认是继承root logger的debug级别 -->
<loggername="chapters.configuration"level="INFO"/>
<!--严格来说, root logger的level属性没有必要设置,因为 -->
<!-- root logger的级别被默认设置为DEBUG -->
<rootlevel="DEBUG">
<!--
在root标签内没有引入chapters.configuration,所有在此包下不会
显示任何组件的任何 DEBUG信息
-->
<appender-refref="STDOUT"/> <!--将appender引入到root logger -->
</root>
</configuration>
注意:由名为"chapters.configuration.Foo"的 logger生成的 DEBUG级别的信息都被屏蔽了.同样,也可以为任意数量的 logger设置级别。
配置 Appenders
Appender 用<appender>元素配置,该元素必要属性 name和 class。 name属性指定 appender的名称,class属性指定 appender类的全限定名。 <appender>元素可以包含零个或多个<layout>元素、零个或多个<encoder>元素和零个或多个<filter>元素。除了这三个常用元素之外,还可以包含 appender 类的任意数量的 javabean
属性。下图演示了常用结构,注意对 javabean属性的支持在图中不可见。
记录输出到多个 appender很简单,先定义各种 appender,然后在 logger里进行引用,就行了。如下面的配置文件所示:
<configuration>
<appendername="FILE"class="ch.qos.logback.core.FileAppender">
<file>myApp.log</file>
<!-- encoders are assigned by default the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</encoder>
</appender>
<appendername="STDOUT"class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<rootlevel="debug">
<appender-refref="FILE"/>
<appender-refref="STDOUT"/>
</root>
</configuration>
该配置文件定义了两个 appender,分别是"FILE"和"STDOUT"。"FILE"这个 appender 把记录输出到文件"myapp.log",它的 encoder是PatternLayoutEncoder,输出了日期、级别、线程名、logger名、文件名及记录请求的行号、消息和行分隔符。"STDOUT"这个 appender 把记录输出到控制台,它的 encoder只是输出消息和行分隔符。 myApp.log文件内容如下:
2011-12-25 16:56:48,593 INFO [main] c.t.c.c.MyApp3 [MyApp3.java:48] Entering application.
2011-12-25 16:56:48,593 DEBUG [main] c.t.c.c.Foo [Foo.java:24] Did it again!
2011-12-25 16:56:48,593 INFO [main] c.t.c.c.MyApp3 [MyApp3.java:52] Exiting application.
注意每个 appender都有自己的 encoder。Encoder通常不能被多个 appender共享,layout也是。所以,logback的配置文件里没有共享 encoder或 layout的语法。
Appender累积
默认情况下,appender是可累积的:logger会把记录输出到它自身的 appender和它所有祖先的 appender。因此,把同一 appender关联到多个 logger会导致重复输出,如下面的配置文件会导致重复的输出:
<configuration>
<appendername="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<loggername="chapters.configuration">
<appender-refref="STDOUT"/>
</logger>
<rootlevel="debug">
<appender-refref="STDOUT"/> <!—这会导致重复输出-->
</root>
</configuration>
输出结果如下:
20:53:29.328 [main] INFO c.t.chapters.configuration.MyApp2 - Entering application.
20:53:29.328 [main] INFO c.t.chapters.configuration.MyApp2 - Entering application.
20:53:29.328 [main] DEBUG com.ttpod.chapters.configuration.Foo - Did it again!
20:53:29.328 [main] DEBUG com.ttpod.chapters.configuration.Foo - Did it again!
20:53:29.328 [main] INFO c.t.chapters.configuration.MyApp2 - Exiting application.
20:53:29.328 [main] INFO c.t.chapters.configuration.MyApp2 - Exiting application.
覆盖默认的累积行为
如果你觉得默认的累积行为不合适,可以设置叠加性标识为 false以关闭它。这样的话,logger树里的某个分支可以输出到与其他 logger不同的 appender。
示例:叠加性标识
<configuration>
…………
<loggername="com.ttpod.chapters.configuration.Foo"additivity="false">
<appender-refref="FILE"/>
</logger>
<rootlevel="debug">
<appender-refref="STDOUT"/>
</root>
</configuration>
输出结果:
Entering application.
Exiting application.
此例中,logger"chapters.configuration.Foo"关联 appender"FILE",它的叠加性标记为false,这样它的记录输出仅会被发送到 appender"FILE",不会被发送到更高 logger等级关联的 appender。其他 logger不受此影响。用 additivityFlag.xml配置 MyApp3,运行后,控制台上由输出由"chapters.configuration.MyApp3"产生的记录。而 logger" chapters.configuration.Foo"将且仅仅将输出到文件 foo.log。
Layout格式化输出日志
配置自定义 layout
配置自定义layout与配置其他layout是一样的。 FileAppender和其子类需要一个encoder。如链接中的例子:http://logback.qos.ch/xref/chapters/layouts/MySampleLayout.html
此类中定义了一个处理格式的输出类,为了满足自定义的格式化的输出,把包裹了 MySampleLayout 的 LayoutWrappingEncoder实例传递给FileAppender。下面是配置文件:
<configurationdebug="true">
<appendername="STDOUT"class="ch.qos.logback.core.ConsoleAppender">
<encoderclass="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<!—自定义的格式化输出处理类-->
<layoutclass="com.ttpod.chapters.layouts.MySampleLayout"/>
</encoder>
</appender>
<rootlevel="DEBUG">
<appender-refref="STDOUT"/>
</root>
</configuration>
输出结果如下:
250 DEBUG [main] com.ttpod.chapters.introduction.HelloWorld1 - Hello world.
layout转换符
它和C语言的printf方法非常类似。格式转换由普通字符和转换字符组合而成。转换字符由%开始,紧跟着的是可选的格式修饰符和转换字符标示。使用%前缀的表示符号将被转换到实际的内容。如name, level, date, thread name.可用的转换符有:
转换符
描述
c
调用日志事件的所在记录器的名字,如一个logger的名字是my.test.bbb.ccc,调用的是WARN级别的日志输出,那么输出的是输出my.test.bbb.ccc,可以在其右边指定了精度,如%c{2}那么输出的是bbb.ccc
C
调用日志事件的所在的类名,和c转换符一样,可以在右边指定宽度,如%C{2}输出%C{2}
d
日志调用所发生的时间,日期格式在其后跟着的大括号内的格式指定如%d{yyyy-MM-dd HH:mm:ss},我现在输出的结果是2011-07-11 21:05:22,推荐使用的是log4j本身提供的日期格式,如%d{ISO8601},%d{ABSOLUTE},%d{DATE}
F
所处所在文件名,如上面说C转换符的例子,输出结果是LayoutTest.java
l
是的日志事件发生的位置信息,这个和虚拟机的实现有点关系,一般境况下能得到类,方法,行数源文件等信息,
L
只是输出触发日志事件代码所在的行号,性能损耗会小很多。
m
显示应用给日志提供的其他信息,如消息。logger.warn("Message 2");那么%m将得到的是Message 2
M
输出调用者所在的方法名
n
换行,和\r \r\n有相同功能,能识别系统的换行符,自动转换成\r或者\r\n,log4j推荐使用这个转换符,而不是\r或者\r\n
p
输出调用的日志的级别,如我是调用logger.debug方法,那么级别就是debug
r
输出自应用启动后第一次调用logger的日志输出方法,到输出该log信息耗费的毫秒数
t
输出所在线程的名字
x
输出产生的日志事件的线程的NDC(嵌套诊断上下文)
X
输出与生成的日志事件的线程关联的MDC(映射诊断上下文)。X转换符括号之间放置了一个key,就像在%X {clientNumber}中的clientNumberkey一样。在MDC correspondingvalue将被输出。
%
写上%%后将直接输出一个%符号
- Logback学习笔记1
- Logback学习笔记1 .
- Logback学习笔记1
- Logback学习笔记1
- logback 学习笔记
- Logback学习笔记
- Logback-学习笔记
- logback学习笔记
- logback学习笔记2
- logback学习笔记
- slf4j与LOGBack -- 学习笔记
- Logback学习笔记1——各节点的配置
- 日志系统-SLF4J+Logback --学习笔记
- 非常详细的logback学习笔记
- 【学习笔记】系列十七:Logback.properties
- logback(日志框架)私人学习笔记
- Logback笔记
- Logback学习
- 人脸识别的代码
- android dip dp px pt sp 的区别及联系
- frame buffer device驱动程序
- 递归问题与递归结构(三)
- 接口 Serializable
- Logback学习笔记1 .
- li前圆点换成图片
- SecureCRT下的串口不能输入
- Ruby on Rails 入门之:(10) Ruby中的对象
- QT、QTE、qtopia区别
- 单件模式和不能被继承的类
- 15个非常有用的 HTML5 开发教程和速查手册
- 两个队列实现一个栈&两个栈实现一个队列
- 在多个 PDF 中查找文本