`
baobeituping
  • 浏览: 1045875 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

在新的项目中使用logback来作为日志记录系统

阅读更多

Logback手册
中文版
文档版本:0.1
发布日期:2010年4月23日
原作者:Ceki Gülcü、Sébastien Pennec
中文版译者:陈华
联系方式:clinker@163.com
禁止用于商业用途 Logback 手册中文版
I
目录
目录 ..........................................................................................................................I
译者声明.......................................................................................................................... 1
发布记录.......................................................................................................................... 1
1. 介绍.......................................................................................................................... 2
1.1. 什么是logback ............................................................................................ 2
1.2. 第一步 ........................................................................................................ 2
1.2.1. 必要条件.............................................................................................. 2
1.3. 构建logback................................................................................................ 5
2. 体系结构................................................................................................................... 6
2.1. logback的体系结构 ..................................................................................... 6
2.2. Logger、Appender和Layout ........................................................................ 6
2.2.1. Logger上下文 ...................................................................................... 6
2.2.2. 有效级别(Level)即级别继承 ............................................................. 7
2.2.3. 打印方法和基本选择规则 ..................................................................... 9
2.2.4. 获取Logger........................................................................................ 10
2.2.5. Appender和Layout..............................................................................11
2.2.6. 参数化记录 ........................................................................................ 13
2.2.7. 更好的替代方法 ................................................................................. 13
2.2.8. 工作原理............................................................................................ 14
2.2.9. 性能................................................................................................... 15
3. 配置........................................................................................................................ 17
3.1. Logback里的配置 ..................................................................................... 17
3.2. 自动配置................................................................................................... 17
3.3. 用logback-test.xml或logback.xml自动配置 ............................................... 19
3.4. 自动打印警告和错误消息 .......................................................................... 19
3.5. 把默认配置文件的位置作为系统属性进行指定........................................... 21
3.6. 配置文件修改后自动重新加载 ................................................................... 22
3.7. 直接调用JoranConfigurator ........................................................................ 22
禁止用于商业用途 Logback 手册中文版
II
3.8. 查看状态消息............................................................................................ 24
3.9. 监听状态消息............................................................................................ 25
3.10. 配置文件语法............................................................................................ 26
3.10.1. 标记名大小写敏感性 .......................................................................... 26
3.10.2. 配置logger,或<logger>元素 .............................................................. 26
3.10.3. 配置根logger,或<root>元素.............................................................. 27
3.10.4. 示例................................................................................................... 27
3.10.5. 配置Appender .................................................................................... 30
3.10.6. Appender累积 .................................................................................... 32
3.10.7. 覆盖默认的累积行为 .......................................................................... 34
3.10.8. 设置上下文名称 ................................................................................. 35
3.10.9. 变量替换............................................................................................ 36
4. Appender ................................................................................................................. 44
4.1. 什么是Appender ....................................................................................... 44
4.2. AppenderBase ............................................................................................ 45
4.3. Logback-core ............................................................................................. 46
4.3.1. OutputStreamAppender ........................................................................ 46
4.3.2. ConsoleAppender ................................................................................ 47
4.3.3. FileAppender ...................................................................................... 48
4.3.4. RollingFileAppender ............................................................................ 51
4.3.5. TimeBasedRollingPolicy ...................................................................... 54
4.3.6. 触发策略概述..................................................................................... 60
4.4. Logback Classic ......................................................................................... 61
4.4.1. SocketAppender .................................................................................. 61
4.4.2. JMSAppenderBase............................................................................... 64
4.4.3. SMTPAppender ................................................................................... 70
4.4.4. DBAppender ....................................................................................... 78
4.4.5. SyslogAppender .................................................................................. 84
4.4.6. SiftingAppender .................................................................................. 85
4.4.7. 自定义Appender ................................................................................ 87
禁止用于商业用途 Logback 手册中文版
III
4.5. Logback Access .......................................................................................... 89
4.5.1. SocketAppender .................................................................................. 89
4.5.2. SMTPAppender ................................................................................... 89
4.5.3. DBAppender ....................................................................................... 90
4.5.4. SiftingAppender .................................................................................. 92
5. Encoder ................................................................................................................... 94
5.1. 什么是encoder .......................................................................................... 94
5.2. Encoder接口 ............................................................................................. 94
5.3. LayoutWrappingEncoder ............................................................................. 95
5.4. PatternLayoutEncoder ................................................................................. 96
6. 排版(Layout)....................................................................................................... 97
6.1. 什么是layout ............................................................................................ 97
6.2. Logback-classic .......................................................................................... 97
6.2.1. 自定义layout ..................................................................................... 97
6.2.2. PatternLayout .....................................................................................101
6.2.3. 转换符说明 .......................................................................................103
6.2.4. 格式修饰符 .......................................................................................107
6.2.5. 圆括号的特殊含义.............................................................................108
6.2.6. 求值式(Evaluator).......................................................................... 110
6.2.7. 创建自定义格式转换符...................................................................... 115
6.2.8. HTMLLayout ..................................................................................... 117
6.3. Logback access.......................................................................................... 119
6.3.1. 自定义layout .................................................................................... 119
6.3.2. PatternLayout ..................................................................................... 119
6.3.3. HTMLLayout .....................................................................................122
7. 过滤器(Filter).....................................................................................................123
7.1. 在logback-classic里 .................................................................................123
7.1.1. 常规过滤器 .......................................................................................123
7.1.2. TurboFilters .......................................................................................132
7.1.3. 重复消息过滤器(DuplicateMessageFilter)........................................135
禁止用于商业用途 Logback 手册中文版
IV
7.2. 在logback-access里..................................................................................137
7.2.1. 过滤器 ..............................................................................................137
8. 映射诊断环境(Mapped Diagnostic Context) ..........................................................139
8.1. 高级用法..................................................................................................141
8.2. 自动访问MDC .........................................................................................148
8.3. MDC和受管线程 .....................................................................................150
8.3.1. MDCInsertingServletFilter...................................................................150
9. 记录隔离................................................................................................................152
9.1. 最简易的方法...........................................................................................152
9.2. 上下文选择器(Context Selector) ............................................................152
9.2.1. ContextJNDISelector ..........................................................................153
9.2.2. 在应用程序里设置JNDI变量 ............................................................153
9.2.3. 为Tomcat配置ContextJNDISelector ...................................................154
9.3. 在共享类库里使用静态引用......................................................................155
10. JMX配置器 ....................................................................................................159
10.1. 使用JMX配置器 .....................................................................................159
10.2. 避免内存泄露...........................................................................................161
10.3. 多个应用程序里的JMXConfigurator..........................................................161
10.4. 支持JMX.................................................................................................162
10.4.1. Jetty启用JMX(在JDK 1.5和JDK1.6上通过测试) .........................163
10.4.2. Jetty启用MX4J(在JDK 1.5和JDK1.6上通过测试) .......................164
10.4.3. Tomcat启用JMX(在JDK 1.5和JDK1.6上通过测试) .....................166
10.4.4. Tomcat启用MX4J(在JDK 1.5和JDK1.6上通过测试) ...................166
11. Joran ...............................................................................................................168
11.1. 历史回顾..................................................................................................168
11.2. SAX还是DOM? ....................................................................................169
11.3. 模式(Pattern)........................................................................................169
11.4. 动作(Action) ........................................................................................169
11.5. RuleStore..................................................................................................170
11.6. 解释上下文(Interpretation context) .........................................................171
禁止用于商业用途 Logback 手册中文版
V
11.7. Hello world ...............................................................................................171
11.8. 合作动作..................................................................................................172
11.9. 隐式动作(Implicit actions).....................................................................173
11.10. 实践中的隐式动作....................................................................................175
11.10.1. 默认类映射 ................................................................................176
11.10.2. 属性集合....................................................................................176
11.10.3. 动态新规则 ................................................................................176
12. 从log4j迁移 ...................................................................................................178
12.1. 迁移log4j的layout...................................................................................178
12.2. 迁移log4j的appender ..............................................................................179
禁止用于商业用途 Logback 手册中文版
1 / 180
译者声明
原文档版权说明:http://creativecommons.org/licenses/by-nc-sa/2.5/
原文档地址:http://logback.qos.ch/manual/index.html
本人遵守原文档之版权规定。
翻译此文档的目的是仅为方便本人学习和阅读。
在引用、转载本文档的部分全部内容时,请标注译者信息,包括姓名和电子邮件地址。
如果您阅读本文档,即表示已经完全接受并遵守上述声明。由于您违反上述声明而造成的一切后果,由您承担,本人不承担任何责任。
译文处理了原手册的部分文字错误。
译文根据logback发行包的实际代码和文档对原手册进行了部分修正。
翻译本文时,logback版本是0.9.20,slf4j版本是1.5.11。
发布记录 版本 日期 作者 说明
0.1
2010-04-23
陈华
禁止用于商业用途 Logback 手册中文版
2 / 180
1. 介绍
1.1. 什么是logback
Logback为取代log4j而生。
Logback由log4j的创立者Ceki Gülcü设计。以十多年设计工业级记录系统的经验为基础,所创建的logback比现有任何记录系统更快、占用资源更少,有时差距非常大。
Logback提供独特而实用的特性,比如Marker、参数化记录语句、条件化堆栈跟踪和强大的事件过滤功能。以上列出的仅仅是logbook实用特性的一小部分。
对于自身的错误报告,logback依赖状态(Status)对象,状态对象极大地简化了故障查找。你也许想在上下文中使用状态对象而不是记录。
Logback-core附带了Joran,Joran是个强大的、通用的配置系统,你可以在自己的项目里使用Joran以获得巨大的作用。
1.2. 第一步
1.2.1. 必要条件
Logback-classic依赖slf4j-api.jar和 logback-core.jar。
现在让我们开始体验logback。
示例 1.1:记录基本模版
(logback-examples/src/main/java/chapters/introduction/HelloWorld1.java) package chapters.introduction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HelloWorld1 { public static void main(String[] args) { Logger logger = LoggerFactory .getLogger("chapters.introduction.HelloWorld1");
禁止用于商业用途 Logback 手册中文版
3 / 180
logger.debug("Hello world."); } }
HelloWorld1类导入了SLF4J API定义的Logger类和LoggerFactory类,更明确地说是定义在org.slf4j包里的两个类。
main()方法的第一行里,调用LoggerFactory类的静态方法getLogger取得一个Logger实例,将该实例赋值给变量logger。这个logger被命名为“chapters.introduction.HelloWorld1”。main方法继续调用这个logger的debug方法并传递参数“Hello world”。我们称之为main方法包含了一条消息是“Hello world”、级别是DEBUG的记录语句。
注意上面的例子并没有引用任何logback的类。多数情况下,只要涉及到记录,你只需要引用SLF4J的类。因此在绝大多数情况下,你的类只导入SLF4J的API,基本可以忽略logback的存在。
运行示例程序: java chapters.introduction.HelloWorld1
运行后会在控制台输出下面的一行文字。得益于logback提供了默认配置策略,当没有发现默认配置文件时,logback会为根(root) logger添加一个ConsoleAppender。 20:49:07.962 [main] DEBUG chapters.introduction.HelloWorld1 - Hello world.
Logback可以通过内置的状态系统来报告其内部状态。通过StatusManager组件可以访问logback生命期内发生的重要事件。目前,我们调用StatusPrinter类的print()方法来打印logback的内部状态。
示例1.2:打印Logger状态
(logback-examples/src/main/java/chapters/introduction/HelloWorld2.java) package chapters.introduction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.core.util.StatusPrinter; public class HelloWorld2 { public static void main(String[] args) { Logger logger = LoggerFactory .getLogger("chapters.introduction.HelloWorld2");
禁止用于商业用途 Logback 手册中文版
4 / 180
logger.debug("Hello world."); // print internal state LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); StatusPrinter.print(lc); } }
运行后输出如下: 12:49:22.203 [main] DEBUG chapters.introduction.HelloWorld2 - Hello world. 12:49:22,078 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml] 12:49:22,093 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml] 12:49:22,093 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Setting up default configuration.
Logback说它没有找到配置文件logback-test.xml和logback.xml(稍后解释),于是用默认策略进行配置,即用一个基本的ConsoleAppender。Appender类可被视为输出目的地的。Appender包含许多不同类型的目的地,包括控制台、文件、Syslog、TCP套接字、JMS和其他。用户可以很容易地自定义Appender。
当发生错误时,logback将自动在控制台上打印其内部状态。
之前的两个示例相当简单,大型程序里真实记录志情况也不会有太大区别。记录系统的基本模式不会改变,可能改变的是配置过程。也许你想按照自己的需要来定制或配置logback,之后的章节会讨论配置logback。
在上面的例子里,我们调用StatusPrinter.pring()方法来打印logback的内部状态。在诊断与logback相关的问题时,logback的内部状态信息会非常有用。
在应程序里启用记录的三个必需步骤如下:
1. 配置logback环境。方法有繁有简,稍后讨论。
2. 在每个需要执行记录的类里,调用org.slf4j.LoggerFactory类的getLogger()方法获取一个Logger实例,以当前类名或类本身作为参数。
禁止用于商业用途 Logback 手册中文版
5 / 180
3. 调用取得的logger实例的打印方法,即debug()、info()、warn()和error(),把记录输出到配置里的各appender。
1.3. 构建logback
Logback使用Maven2进行构建。
安装Maven2后,解压logback发行包,在解压后的目录下执行mvn package命令,就可以构建整个logback项目,包括各个模块。Maven会自动下载所需外部类库。
Logback发行包包含完整的源代码,你可以修改源代码,创建自己的版本。你还可以发布修改过的版本,前提是遵守LGPL或EPL。
Logback在以下JDK进行过构建和测试。 JDK Operating System
Sun JDK 1.5.0.06
Windows XP Sun JDK 1.5.0.08 Linux 64bit AMD
WebLogic JRockit 1.5.0.14
Linux 64bit AMD IBM JDK 1.6.0.1 Linux 64bit AMD
Sun JDK 1.6.0.16 (64 bit)
Windows 7 (64 bit)
禁止用于商业用途 Logback 手册中文版
6 / 180
2. 体系结构
2.1. logback的体系结构
Logback的基本结构充分通用,可应用于各种不同环境。目前,logback分为三个模块:Core、Classic和Access。
Core模块是其他两个模块的基础。Classic模块扩展了core模块。Classic模块相当于log4j的显著改进版。Logback-classic直接实现了SLF4J API,因此你可以在logback与其他记录系统如log4j和java.util.logging (JUL)之间轻松互相切换。Access模块与Servlet容器集成,提供HTTP访问记录功能。本文不讲述access模块。
本文中,“logback”代表logback-classic模块。
2.2. Logger、Appender和Layout
Logback建立于三个主要类之上:Logger、Appender和Layout。这三种组件协同工作,使开发者可以按照消息类型和级别来记录消息,还可以在程序运行期内控制消息的输出格式和输出目的地。
Logger类是logback-classic模块的一部分,而Appender和Layout接口来自logback-core。作为一个多用途模块,logback-core不包含任何logger。
2.2.1. Logger上下文
任何比System.out.println高级的记录API的第一个也是最重要的优点便是能够在禁用特定记录语句的同时却不妨碍输出其他语句。这种能力源自记录隔离(space)——即所有各种记录语句的隔离——是根据开发者选择的条件而进行分类的。在logback-classic里,这种分类是logger固有的。各个logger都被关联到一个LoggerContext,LoggerContext负责制造logger,也负责以树结构排列各logger。
Logger是命名了的实体。它们的名字大小写敏感且遵从下面的层次化的命名规则:
命名层次:
禁止用于商业用途 Logback 手册中文版
7 / 180
如果logger的名称带上一个点号后是另外一个logger的名称的前缀,那么,前者就被称为后者的祖先。如果logger与其后代logger之间没有其他祖先,那么,前者就被称为子logger之父。
比如,名为“com.foo"”的logger是名为“com.foo.Bar”之父。同理,“java”是“java.util"”之父,也是“java.util.Vector”的祖先。
根logger位于logger等级的最顶端,它的特别之处是它是每个层次等级的共同始祖。如同其他各logger,根logger可以通过其名称取得,如下所示: Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
其他所有logger也通过org.slf4j.LoggerFactory 类的静态方法getLogger取得。getLogger方法以logger名称为参数。Logger接口的部分基本方法列举如下: package org.slf4j; public interface Logger { // Printing methods: public void trace(String message); public void debug(String message); public void info(String message); public void warn(String message); public void error(String message); }
2.2.2. 有效级别(Level)即级别继承
Logger可以被分配级别。级别包括:TRACE、DEBUG、INFO、WARN和ERROR,定义于ch.qos.logback.classic.Level类。注意在logback里,Level类是final的,不能被继承,Marker对象提供了更灵活的方法。
如果logger没有被分配级别,那么它将从有被分配级别的最近的祖先那里继承级别。更正式地说:
logger L的有效级别等于其层次等级里的第一个非null级别,顺序是从L开始,向上直至根logger。
禁止用于商业用途 Logback 手册中文版
8 / 180
为确保所有logger都能够最终继承一个级别,根logger总是有级别,默认情况下,这个级别是DEBUG。
下面的四个例子包含各种分配级别值和根据级别继承规则得出的最终有效(继承)级别。
 例1 Logger名 分配级别 有效级别 root DEBUG DEBUG
X
none
DEBUG X.Y none DEBUG
X.Y.Z
none
DEBUG
例1里,仅根logger被分配了级别。级别值DEBUG被其他logger X、X.Y和X.Y.Z继承。
 例2 Logger名 分配级别 有效级别 root ERROR ERROR
X
INFO
INFO X.Y DEBUG DEBUG
X.Y.Z
WARN
WARN
例2里,所有logger都被分配了级别。级别继承不发挥作用。
 例3 Logger名 分配级别 有效级别 root DEBUG DEBUG
X
INFO
INFO X.Y none INFO
X.Y.Z
ERROR
ERROR
例3里,根logger、X和X.Y.Z分别被分配了DEBUG、INFO和ERROR级别。X.Y从其父X继承级别。
 例4 Logger名 分配级别 有效级别
禁止用于商业用途 Logback 手册中文版
9 / 180
root DEBUG DEBUG
X
INFO
INFO X.Y none INFO
X.Y.Z
none
none
例4里,根logger和X分别被分配了DEBUG和INFO级别。X.Y和X.Y.Z从其最近的父X继承级别,因为X被分配了级别。
2.2.3. 打印方法和基本选择规则
根据定义,打印方法决定记录请求的级别。例如,如果L是一个logger实例,那么,语句L.info("..")是一条级别为INFO的记录语句。
记录请求的级别在高于或等于其logger的有效级别时被称为被启用,否则,称为被禁用。如前所述,没有被分配级别的logger将从其最近的祖先继承级别。该规则总结如下:
基本选择规则
记录请求级别为p,其logger的有效级别为q,只有则当p>=q时,该请求才会被执行。
该规则是logback的核心。级别排序为:TRACE < DEBUG < INFO < WARN < ERROR。
下表显示了选择规则是如何工作的。行头是记录请求的级别p。列头是logger的有效级别q。行(请求级别)与列(有效级别)的交叉部分是按照基本选择规则得出的布尔值。 请求级别p 有效级别q
TRACE
DEBUG
INFO
WARN
ERROR
OFF
TRACE
YES
NO
NO
NO
NO
NO
DEBUG
YES
YES
NO
NO
NO
NO
INFO
YES
YES
YES
NO
NO
NO
WARN
YES
YES
YES
YES
NO
NO
ERROR
YES
YES
YES
YES
YES
NO
OFF
YES
NO
NO
NO
NO
NO
禁止用于商业用途 Logback 手册中文版
10 / 180
下面是基本选择规则的例子。 // 取得名为"com.foo"的logger实例 Logger logger = LoggerFactory.getLogger("com.foo"); // 设其级别为INFO logger.setLevel(Level.INFO); Logger barlogger = LoggerFactory.getLogger("com.foo.Bar"); // 该请求有效,因为WARN >= INFO logger.warn("Low fuel level."); // 该请求无效,因为DEBUG < INFO. logger.debug("Starting search for nearest gas station."); // 名为"com.foo.Bar"的logger实例barlogger, 从"com.foo"继承级别 // 因此下面的请求有效,因为INFO >= INFO. barlogger.info("Located nearest gas station."); // 该请求无效,因为DEBUG < INFO. barlogger.debug("Exiting gas station search");
译者注:上例的logger.setLevel(Level.INFO)无效。org.slf4j.Logger没有setLevel()方法,ch.qos.logback.classic.Logger有此方法。
2.2.4. 获取Logger
用同一名字调用LoggerFactory.getLogger方法所得到的永远都是同一个logger对象的引用。
例如, Logger x = LoggerFactory.getLogger("wombat"); Logger y = LoggerFactory.getLogger("wombat");
x和y指向同一个logger对象。
因此,可以配置一个logger,然后从其他地方取得同一个实例,不需要到处传递引用。生物学里的父母总是先于其孩子,而logback不同,它可以以任何顺序创建和配置logger。特别的是,即使“父”logger是在其后代初始化之后才初始化的,它仍将查找并链接到其后
禁止用于商业用途 Logback 手册中文版
11 / 180
代们。
通常是在程序初始化时对logback环境进行配置。推荐用读配置文件类进行配置。稍后会讲这种方法。
Logback简化了logger命名,方法是在每个类里初始化logger,以类的全限定名作为logger名。这种定义logger的方法即有用又直观。由于记录输出里包含logger名,这种命名方法很容易确定记录消息来源。Logback不限制logger名,你可以随意命名logger。
然而,目前已知最好的策略是以logger所在类的名字作为logger名称。
2.2.5. Appender和Layout
有选择性地启用或禁用记录请求仅仅是logback功能的冰山一角。Logback允许打印记录请求到多个目的地。在logback里,一个输出目的地称为一个appender。目前有控制台、文件、远程套接字服务器、MySQL、PostreSQL、Oracle和其他数据库、JMS和远程UNIX Syslog守护进程等多种appender。
一个logger可以被关联多个appender。
方法addAppender为指定的logger添加一个appender。对于logger的每个启用了的记录请求,都将被发送到logger里的全部appender及更高等级的appender。换句话说,appender叠加性地继承了logger的层次等级。例如,如果根logger有一个控制台appender,那么所有启用了的请求都至少会被打印到控制台。如果logger L有额外的文件appender,那么,L和L后代的所有启用了的请求都将同时打印到控制台和文件。设置logger的additivity为false,则可以取消这种默认的appender累积行为。
控制appender叠加性的规则总结如下。
Appender叠加性
Logger L的记录语句的输出会发送给L及其祖先的全部appender。这就是“appender叠加性”的含义。
然而,如果logger L的某个祖先P设置叠加性标识为false,那么,L的输出会发送给
禁止用于商业用途 Logback 手册中文版
12 / 180
L与P之间(含P)的所有appender,但不会发送给P的任何祖先的appender。
Logger的叠加性默认为true。
示例: Logger名 关联的Appender 叠加性标识 输出目标 说明 root A1 不可用 A1 叠加性标识不适用于根logger
x
A-x1,A-x2
true
A1,A-x1,A-x2
根和x x.y none true A1, A-x1, A-x2 根和x
x.y.z
A-xyz1
true
A1, A-x1, A-x2, A-xyz1
根、x.y.z和x security A-sec false A-sec 因为叠加性标识为false,所以appender不累积。只有A-sec
security.access
none
true
A-sec
只有security,因为security的叠加性标识为false。
有些用户希望不仅可以定制输出目的地,还可以定制输出格式。这时为appender关联一个layout即可。Layout负责根据用户意愿对记录请求进行格式化,appender负责将格式化化后的输出发送到目的地。PatternLayout是标准logback发行包的一部分,允许用户按照类似于C语言的printf函数的转换模式设置输出格式。
例如,转换模式"%-4relative [%thread] %-5level %logger{32} - %msg%n"在PatternLayout里会输出形如: 176 [main] DEBUG manual.architecture.HelloWorld2 - Hello world.
第一个字段是自程序启动以来的逝去时间,单位是毫秒。
第二个地段发出记录请求的线程。
第三个字段是记录请求的级别。
禁止用于商业用途 Logback 手册中文版
13 / 180
第四个字段是与记录请求关联的logger的名称。
“-”之后是请求的消息文字。
2.2.6. 参数化记录
因为logback-classic里的logger实现了SLF4J的Logger接口,某些打印方法可接受多个参数。这些不同的打印方法主要是为了在提高性能的同时尽量不影响代码可读性。
对于某个Logger,下面的代码 logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
在构造消息参数时有性能消耗,即把整数i和entry[i]都转换为字符串时,还有连接多个字符串时。不管消息会不会被记录,都会造成上述消耗。
一个可行的办法是用测试语句包围记录语句以避免上述消耗,比如, if(logger.isDebugEnabled()) { logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); }
当logger的debug级别被禁用时,这个方法可以避免参数构造带来的性能消耗。另一方面,如果logger的DEBUG级别被启用,那么会导致两次评估logger是否被启用:一次是isDebugEnabled方法,一次是debug方法。在实践中,这种额外开销无关紧要,因为评估logger所消耗的时间不足实际记录请求所用时间的1%。
2.2.7. 更好的替代方法
还有一种基于消息格式的方便的替代方法。假设entry是一个object,你可以编写: Object entry = new SomeObject(); logger.debug("The entry is {}.", entry);
在评估是否作记录后,仅当需要作记录时,logger才会格式化消息,用entry的字符串值替换"{}"。换句话说,当记录语句被禁用时,这种方法不会产生参数构造所带来的性能消耗。
禁止用于商业用途 Logback 手册中文版
14 / 180
2.2.8. 工作原理
介绍过logback的核心组件后,下面描述logback框架在用户调用logger的打印方法时所做的事情。在本例中,用户调用名为com.wombat的logger的info()方法。
1. 取得过滤链(filter chain)的判定结果
如果TurboFilter链存在,它将被调用。Turbo filters能够设置一个上下文范围内的临界值,这个临界值或者表示过滤某些与信息有关(比如Marker、级别、Logger、消息)的特定事件,或者表示与每个记录请求相关联的Throwable。如果过滤链的结果是FilterReply.DENY,则记录请求被抛弃。如果结果是FilterReply.NEUTRAL,则继续下一步,也就是第二步。如果结果是FilterReply.ACCEPT,则忽略过第二步,进入第三步。
2. 应用基本选择规则
Logback对logger的有效级别与请求的级别进行比较。如果比较的结果是记录请求被禁用,logback会直接抛弃请求,不做任何进一步处理。否则,继续下一步。
3. 创建LoggingEvent对象
记录请求到了这一步后,logback会创建一个ch.qos.logback.classic.LoggingEvent对象,该对象包含所有与请求相关的参数,比如请求用的logger、请求级别、消息、请求携带的异常、当前时间、当前线程、执行记录请求的类的各种数据,还有MDC。注意有些成员是延迟初始化的,只有当它们真正被使用时才会被初始化。MDC用来为记录请求添加额外的上下文信息。之后的章节会讨论MDC。
4. 调用appender
创建了LoggingEvent对象后,logback将调用所有可用appender的doAppend()方法,这就是说,appender继承logger的上下文。
所有appender都继承AppenderBase抽象类,AppenderBase在一个同步块里实现了doAppend方以确保线程安全。AppenderBase的doAppender()方法也调用appender关联的自定义过滤器,如果它们存在的话。自定义过滤器能被动态地关联到任何appender,另有章节专门讲述它。
5. 格式化输出
那些被调用了的appender负责对记录事件(LoggingEvent)进行格式化。然而,有些但不是全部appender把格式化记录事件的工作委托给layout。Layout对LoggingEvent实例进行格式化,然后把结果以字符串的形式返回。注意有些appender,比如SocketAppender,把记录事件进行序列化而不是转换成字符串,所以它们不需要也没有layout。
6. 发送记录事件(LoggingEvent)
禁止用于商业用途 Logback 手册中文版
15 / 180
记录事件被格式化后,被各个appender发送到各自的目的地。
下图是整个流程的UML图。
2.2.9. 性能
一个关于记录的常见争论是它的计算代价。这种关心很合理,因为即使是中等大小的应用程序也会生成数以千计的记录请求。人们花了很多精力来测算和调整记录性能。尽管如此,用户还是需要注意下面的性能问题。
1. 记录被彻底关闭时的记录性能
你可以将根logger的级别设为最高级的Level.OFF,就可以彻底关闭记录。当记录被彻底关闭时,记录请求的消耗包括一次方法调用和一次整数比较。在CPU为3.2Ghz的Pentium D电脑上,一般需要20纳秒。
但是,任何方法调用都会涉及“隐藏的” 参数构造消耗,例如,对于logger x, x.debug("Entry number: " + i + "is " + entry[i]);
把整数i和entry[i]都转换为字符串和连接各字符串会造成消息参数构造消耗,不管消息是否被记录。
参数构造消耗可以变得非常高,同时也跟参数大小有关。利用SLF4J的参数化记录可以避免这种消耗。 x.debug("Entry number: {} is {}", i, entry[i]);
这种方式不会造成参数构造消耗。与前面的debug()方法相比,这种方法快得多。只有当请求在被发送给appender时,消息才会被格式化。在格式化的时候,负责格式化消息的组件性能很高,不会对整个过程造成负面影响。格式化1个和3个参数分别需要2和4微妙。
请注意,无论如何,应当避免在紧密循环里或者非常频繁地调用记录语句,因为很
禁止用于商业用途 Logback 手册中文版
16 / 180
可能降低性能。即使记录被禁用,在紧密循环里作记录仍然会拖慢应用程序,如果记录被启用,就会产生大量(也是无用的)输出。
2. 当记录启用时,判断是否进行记录的性能
在logback中,logger在被创建时就明确地知道其有效级别(已经考虑了级别继承)。当父logger的级别改变时,所有子logger都会得知这个改变。因此,在根据有效级别去接受或拒绝请求之前,logger能够作出准即时判断,不需要咨询其祖先。
3. 实际记录(格式化和写入输出设备)
性能消耗包括格式化肌瘤输出和发送到目的地。我们努力使layout(formatter)和appender都尽可能地快。记录到本地机器的文件里的耗时一般大约在9至12微秒。如果目的地是远程服务器上的数据库时,会增加早几个毫秒。
尽管功能丰富,logback最首要的一项设计目标就是执行速度,重要程度仅排在可靠性之后。为提高性能,logback的一些组件已经被多次重写。
禁止用于商业用途 Logback 手册中文版
17 / 180
3. 配置
在第一部分,我们将介绍配置logback的各种方法,给出了很多配置脚本例子。在第二部分,我们将介绍Joran,它是一个通用配置框架,你可以在自己的项目里使用Joran。
3.1. Logback里的配置
把记录请求插入程序代码需要相当多的计划和努力。有观察显示大约4%的代码是记录。所以即使是一个中等规模的应用程序也会包含数以千计的记录语句。考虑到数量庞大,我们需要使用工具来管理记录语句。
Logback可以通过编程式配置,或用XML格式的配置文件进行配置。
Logback采取下面的步骤进行自我配置:
1. 尝试在classpath下查找文件logback-test.xml;
2. 如果文件不存在,则查找文件logback.xml;
3. 如果两个文件都不存在,logback用BasicConfigurator自动对自己进行配置,这会导致记录输出到控制台。
第三步也是最后一步是为了在缺少配置文件时提供默认(但基本的)记录功能。
3.2. 自动配置
最简单的配置方法就是使用默认配置。
BasicConfigurator用法的简单例子:
((logback-examples/src/main/java/chapters/configuration/MyApp1.java)) package manual.configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyApp1 { final static Logger logger = LoggerFactory.getLogger(MyApp1.class); public static void main(String[] args) { logger.info("Entering application.");
禁止用于商业用途 Logback 手册中文版
18 / 180
Foo foo = new Foo(); foo.doIt(); logger.info("Exiting application."); } }
该类定义了一个静态变量logger,然后实例化一个Foo对象。Foo类如下((logback-examples/src/main/java/chapters/configuration/Foo.java)): package manual.configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Foo { static final Logger logger = LoggerFactory.getLogger(Foo.class); public void doIt() { logger.debug("Did it again!"); } }
假设配置文件logback-test.xml和logback.xml都不存在,那么logback默认地会调用BasicConfigurator,创建一个最小化配置。最小化配置由一个关联到根logger的ConsoleAppender组成。输出用模式为%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n的PatternLayoutEncoder进行格式化。还有,根logger默认级别是DEBUG。
因此,chapters.configuration.MyApp1运行后的输出应当类似于: 16:06:09.031 [main] INFO chapters.configuration.MyApp1 - Entering application. 16:06:09.046 [main] DEBUG chapters.configuration.Foo - Did it again! 16:06:09.046 [main] INFO chapters.configuration.MyApp1 - Exiting application.
MyApp1程序通过调用org.slf4j.LoggerFactory类和org.slf4j.Logger类连接到logback,取得想要的logger,然后继续。注意Foo类对logback唯一的依赖是通过引入org.slf4j.LoggerFactory和org.slf4j.Logger。
禁止用于商业用途 Logback 手册中文版
19 / 180
3.3. 用logback-test.xml或logback.xml自动配置
前面提到过,如果classpath里有logback-test.xml或logback.xml,logback会试图用它进行自我配置。下面的配置文件与刚才的BasicConfigurator等效。
示例:基本配置文件(logback-examples/src/main/java/chapters/configuration/sample0.xml) <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT" /> </root> </configuration>
把sample0.xml重命名为logback.xml或logback-test.xml,放到classpath里,运行后会和上例的输出几乎一样。
3.4. 自动打印警告和错误消息
当解析配置文件有警告或出错时,logback会在控制台上自动打印状态数据。如果没有警告或错误,你还是想检查logback的内部状态的话,可以调用StatusPrinter的print()方法。MyApp2程序等价于MyApp1,只是多了两行打印内部状态数据的代码。
示例:打印logback的内部状态信息
(logback-examples/src/main/java/chapters/configuration/MyApp2.java) public static void main(String[] args) { // assume SLF4J is bound to logback in the current environment LoggerContext lc = (LoggerContext)
禁止用于商业用途 Logback 手册中文版
20 / 180
LoggerFactory.getILoggerFactory(); // print logback's internal status StatusPrinter.print(lc); logger.info("Entering application."); Foo foo = new Foo(); foo.doIt(); logger.info("Exiting application."); }
如果一切顺利,控制台上会输出如下: 17:44:58,578 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] 17:44:58,671 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set 17:44:58,671 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender] 17:44:58,687 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT] 17:44:58,812 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Popping appender named [STDOUT] from the object stack 17:44:58,812 |-INFO in ch.qos.logback.classic.joran.action.LevelAction - root level set to DEBUG 17:44:58,812 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[root] 17:44:58.828 [main] INFO chapters.configuration.MyApp2 - Entering application. 17:44:58.828 [main] DEBUG chapters.configuration.Foo - Did it again! 17:44:58.828 [main] INFO chapters.configuration.MyApp2 - Exiting application.
在输出的最后面,你可以看到上例输出的内容。你也应当注意到logback的内部消息,也就是Status对象,它可以方便地访问logback的内部状态。
可以不用从代码里调用StatusPrinter,而是在配置文件里进行相关配置,即使没有出现错误。方法是,设置configuration元素的debug属性为true。请注意debug属性只与状态数据有关,它不影响logback的配置,更不会影响记录级别。
示例:debug模式的基本配置
禁止用于商业用途 Logback 手册中文版
21 / 180
(logback-examples/src/main/java/chapters/configuration/sample1.xml) <configuration debug="true"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned by default the type ch.qos.logback.classic.encoder.PatternLayoutEncoder --> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT" /> </root> </configuration>
把configuration元素的debug属性设为true后,会输出状态信息,但是前提是:
1. 找到了配置文件;
2. 配置文件是格式化良好的XML。
如果其中任一条件未满足,Joran就会因为配置文件不可读而无法读取debug属性。如果找到了配置文件,但却不是格式化良好的,那么logback会检测出错误并把内部状态打印到控制台。然而,如果找不到配置文件,由于这不是个严重的错误,logback不会自动打印状态数据。使用编程式的主动调用StatusPrinter.print()可以确保始终打印状态信息,如MyApp2。
3.5. 把默认配置文件的位置作为系统属性进行指定
设置名为logback.configurationFile的系统属性,把默认配置文件的位置作为属性值,这种方法也可以。属性值即配置文件位置可以是个URL、classpath里的一个资源,或者是程序外部的文件路径。 java -Dlogback.configurationFile=/path/to/config.xml chapters.configuration.MyApp1
禁止用于商业用途 Logback 手册中文版
22 / 180
3.6. 配置文件修改后自动重新加载
如果设置成自动重新加载,logback-classic会扫描配置文件里的变化,并且当发生变化后进行重新配置。设置访方法是设configuration元素的scan属性为true。
示例:扫描配置文件的变化并自动重新配置
(logback-examples/src/main/java/chapters/configuration/scan1.xml) <configuration scan="true"> ... </configuration>
默认情况下,每隔一分钟扫描一次。configuration元素的scanPeriod属性控制扫描周期,其值可以带时间单位,包括:milliseconds、seconds、minutes和hours。
示例:指定不同的扫描周期
(logback-examples/src/main/java/chapters/configuration/scan2.xml) <configuration scan="true" scanPeriod="30 seconds"> ... </configuration>
如果没写明时间单位,则默认为毫秒。
内部实现是这样的,当设置扫描属性为true时,会安装一个叫ReconfigureOnChangeFilter的TurboFilter。每次调用logger的打印方法时,都会进行扫描。比如,当名为myLogger的logger执行“myLogger.debug("hello");”时,如果scan属性为true,则ReconfigureOnChangeFilter会被调用。而且,即使myLogger的debug级别被禁用了,仍然会调用上述过滤器。
考虑到在任何logger在每次被调用时都要调用ReconfigureOnChangeFilter,这个过滤器的性能就变得十分关键了。为提高性能,不会在每个logger被调用时去检查是否需要扫描,而是每隔16次记录操作进行一次检查。简言之,当配置文件改变后,它会被延时重新加载,延时时间由扫描间隔时间和一些logger调用所决定。
3.7. 直接调用JoranConfigurator
Logback依赖Joran,Joran是logback-core的一部分,是个配置类库。Logback的默认配
禁止用于商业用途 Logback 手册中文版
23 / 180
置机制是调用JoranConfigurator对classpath上的默认配置文件进行处理。不管出于什么理由,如果你想重新实现logback的默认配置机制的话,你可以直接调用JoranConfigurator。下面没的程序MyApp3就调用了JoranConfigurator对作为参数传入的配置文件进行处理。
示例:直接调用JoranConfigurator
(logback-examples/src/main/java/chapters/configuration/MyApp3.java) package chapters.configuration; /** * Demonstrates programmatic invocation of Joran. * */ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.joran.JoranConfigurator; import ch.qos.logback.core.joran.spi.JoranException; import ch.qos.logback.core.util.StatusPrinter; public class MyApp3 { final static Logger logger = LoggerFactory.getLogger(MyApp3.class); public static void main(String[] args) { // assume SLF4J is bound to logback in the current environment LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); try { JoranConfigurator configurator = new JoranConfigurator(); configurator.setContext(lc); // the context was probably already configured by default // configuration rules lc.reset(); configurator.doConfigure(args[0]); } catch (JoranException je) { // StatusPrinter will handle this } StatusPrinter.printInCaseOfErrorsOrWarnings(lc); logger.info("Entering application."); Foo foo = new Foo();
禁止用于商业用途 Logback 手册中文版
24 / 180
foo.doIt(); logger.info("Exiting application."); } }
本程序直接取得LoggerContext,创建新JoranConfigurator并设置它要操作的上下文,重置logger上下文,最后要求配置器用参数中的配置文件对上下文进行配置。同时打印了内部状态数据。
3.8. 查看状态消息
Logback把内部数据放在一个StatusManager对象里,并通过LoggerContext访问。
StatusManager通过logback上下文来访问所有数据对象。为把内存占用保持在合理的范围内,默认的StatusManager实现将状态消息按头和尾两部分存储。头部存储开始的H条状态消息,尾部存储后面的T条消息。现在的H=T=150,将来或许会改变。
Logback-classic带了一个叫ViewStatusMessagesServlet的Servlet,它以HTML表格的格式打印与当前LoggerContext关联的StatusManager的内容。示例如下。
要加到自己的web应用程序里,可以在WEB-INF/web.xml里添加如下内容: <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>
禁止用于商业用途 Logback 手册中文版
25 / 180
</servlet-mapping>
访问地址是http://host/yourWebapp/lbClassicStatus
3.9. 监听状态消息
你也可以为StatusManager附加一个StatusListener,这样就能立即对状态消息作出响应,尤其对那些logback配置完成之后的消息。注册一个状态监听器可以方便地实现对logback内部状态的无人监管。
Logback带了一个叫OnConsoleStatusListener的StatusListener实现,可以把状态消息打印到控制台。
下例演示了如何为StautsManager注册一个OnConsoleStatusListener实例。 LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); StatusManager statusManager = lc.getStatusManager(); OnConsoleStatusListener onConsoleListener = new OnConsoleStatusListener(); statusManager.add(onConsoleListener);
注意注册了的状态监听器只会接收被注册之后的状态消息,不会注册之前的消息。
也可以在配置文件里注册一个或多个状态监听器。如下面的例子。
示例:注册状态监听器
(logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml) <configuration> <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> ... the rest of the configuration file </configuration>
还可以通过设置Java系统属性“logback.statusListenerClass”注册状态监听器,例如, java -Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener ...
禁止用于商业用途 Logback 手册中文版
26 / 180
3.10. 配置文件语法
到目前为止,正如你已经在这份手册里看到的不少例子,logback允许你重新定义记录行为而不必重新编译你的代码。实际上,你可以轻易地配置logback,比如禁用程序里某些地方的记录功能,或者直接输出到一个UNIX系统守护进程、数据库、日志查看器,或把记录事件发送到远程logback服务器,远程logback服务器按照其本地策略进行记录,比如把记录时间发送到第二个logback服务器。
本节剩余部分介绍配置文件的语法。
Logback配置文件的语法非常灵活。正因为灵活,所以无法用DTD或XML schema进行定义。尽管如此,可以这样描述配置文件的基本结构:以<configuration>开头,后面有零个或多个<appender>元素,有零个或多个<logger>元素,有最多一个<root>元素。如下图所示:
3.10.1. 标记名大小写敏感性
从logback 0.9.17版起,标记名不区分大小些。比如,<logger>、<Logger>和<LOGGER>都是合法元素且表示同一个意思。按照隐式规则,标记名除了首字母外要区分大小写。因此,<xyz>与<Xyz>等价,但不等价于<xYz>。隐式规则一般遵循Java世界里常用的驼峰命名规则。因为很难确定一个标记什么时候与显式动作相关,什么时候又与隐式动作相关,所以很难说XML标记是否是大小写敏感。如果你不确定标记名的大小写,就用驼峰命名法,基本不会错。
3.10.2. 配置logger,或<logger>元素
Logger是用<logger>元素配置的。<logger>元素有且仅有一个name属性、一个可选的level属性和一个可选的additivity属性。
Level属性的值大小写无关,其值为下面其中一个字符串:TRACE、DEBUG、INFO、WARN、ERROR、ALL和OFF。还可以是一个特殊的字符串“INHERITED”或其同义词
禁止用于商业用途 Logback 手册中文版
27 / 180
“NULL”,表示强制继承上级的级别。
<logger>元素可以包含零个或多个<appender-ref>元素,表示这个appender会被添加到该logger。强调一下,每个用<logger>元素声明的logger,首先会移除所有appender,然后才添加引用了的appender,所以如果logger没有引用任何appender,就会失去所有appender。
3.10.3. 配置根logger,或<root>元素
<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。
3.10.4. 示例
假设我们不想看到“chapters.configuration”包里的任何组件的任何DEBUG信息,可以设置如下:
示例:设置logger级别
(logback-examples/src/main/java/chapters/configuration/sample2.xml) <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned by default the type ch.qos.logback.classic.encoder.PatternLayoutEncoder --> <encoder> <pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <logger name="chapters.configuration" level="INFO" />
禁止用于商业用途 Logback 手册中文版
28 / 180
<!-- Strictly speaking, the level attribute is not necessary since --> <!-- the level of the root level is set to DEBUG by default. --> <root level="DEBUG"> <appender-ref ref="STDOUT" /> </root> </configuration>
对于MyApp3应用上述配置文件后,输出如下: 17:34:07.578 [main] INFO chapters.configuration.MyApp3 - Entering application. 17:34:07.578 [main] INFO chapters.configuration.MyApp3 - Exiting application.
注意由名为“chapters.configuration.Foo”的logger生成的DEBUG级别的信息都被屏蔽了。
你可以为任意数量的logger设置级别。下面的配置文件里,我们为logger“chapters.configuration”设置级别为INFO,同时设置logger“chapters.configuration.Foo”级别为DEBUG。
示例:设置多个logger的级别 <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned by default the type ch.qos.logback.classic.encoder.PatternLayoutEncoder --> <encoder> <pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <logger name="chapters.configuration" level="INFO" /> <logger name="chapters.configuration.Foo" level="DEBUG" /> <root level="DEBUG"> <appender-ref ref="STDOUT" />
禁止用于商业用途 Logback 手册中文版
29 / 180
</root> </configuration>
对于MyApp3应用上述配置文件后,输出如下: 17:39:27.593 [main] INFO chapters.configuration.MyApp3 - Entering application. 17:39:27.593 [main] DEBUG chapters.configuration.Foo - Did it again! 17:39:27.593 [main] INFO chapters.configuration.MyApp3 - Exiting application.
经JoranConfigurator用sample3.xml对logback进行配置后,各logger和各自级别如下表所示: Logger 名 分配级别 有效级别 root DEBUG DEBUG
chapters.configuration
INFO
INFO chapters.configuration.MyApp3 null INFO
chapters.configuration.Foo
DEBUG
DEBUG
MyApp3类的INFO级别的记录语句和Foo.doIt()的DEBUG消息都被启用。注意根logger总是设为非null值,默认为DEBUG。
注意,基本选择规则依赖于被调用的logger的有效级别,而不是appender所关联的logger的级别。Logback首先判断记录语句是否被启用,如果启用,则调用logger等级里的appender,无视logger的级别。配置文件sample4.xml演示了这一点。
示例:logger级别(logback-examples/src/main/java/chapters/configuration/sample4.xml) <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned by default the type ch.qos.logback.classic.encoder.PatternLayoutEncoder --> <encoder> <pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n </pattern>
禁止用于商业用途 Logback 手册中文版
30 / 180
</encoder> </appender> <logger name="chapters.configuration" level="INFO" /> <root level="OFF"> <appender-ref ref="STDOUT" /> </root> </configuration>
用sample4.xml对logback进行配置后,各logger和各自级别如下表所示: Logger 名 分配级别 有效级别 root OFF OFF
chapters.configuration
INFO
INFO chapters.configuration.MyApp3 null INFO
chapters.configuration.Foo
null
INFO
配置里唯一的appender“STDOUT”,被关联到级别为OFF的根logger,但是运行MyApp3后会输出: 17:52:23.609 [main] INFO chapters.configuration.MyApp3 - Entering application. 17:52:23.609 [main] INFO chapters.configuration.MyApp3 - Exiting application.
根logger的级别不起任何作用,是因为chapters.configuration.MyApp3里的logger和chapters.configuration.Foo类的INFO级别都是启用的。附注:logger“chapters.configuration” 即使没有任何Java代码直接引用它也会存在,全因为在配置文件里声明了它。
3.10.5. 配置Appender
Appender用<appender>元素配置,该元素必要属性name和class。
name属性指定appender的名称,class属性指定appender类的全限定名。
<appender>元素可以包含零个或多个<layout>元素、零个或多个<encoder>元素和零个或多个<filter>元素。除了这三个常用元素之外,还可以包含appender类的任意数量的javabean属性。下图演示了常用结构,注意对javabean属性的支持在图中不可见。
禁止用于商业用途 Logback 手册中文版
31 / 180
<layout>元素的class属性是必要的,表示将被实例化的layout类的全限定名。和<appender>元素一样, <layout>元素可以包含layout的的javabean属性。因为太常用了,所以当当layout是PatternLayout时,可以省略class属性。
<encoder>元素class属性是必要的,表示将被实例化的encoder类的全限定名。因为太常用了,所以当当encoder是PatternLayoutEncoder时,可以省略class属性。
记录输出到多个appender很简单,先定义各种appender,然后在logger里进行引用,就行了。如下面的配置文件所示:
示例:多个logger (logback-examples/src/main/java/chapters/configuration/multiple.xml) <configuration> <appender name="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> <appender name="STDOUT"
禁止用于商业用途 Logback 手册中文版
32 / 180
class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> </configuration>
该配置文件定义了两个appender,分别是“FILE”和“STDOUT”。
“FILE”这个appender把记录输出到文件“myapp.log”,它的encoder是PatternLayoutEncoder,输出了日期、级别、线程名、logger名、文件名及记录请求的行号、消息和行分隔符。
“STDOUT”这个appender把记录输出到控制台,它的encoder只是输出消息和行分隔符。
注意每个appender都有自己的encoder。Encoder通常不能被多个appender共享,layout也是。所以,logback的配置文件里没有共享enco

分享到:
评论

相关推荐

    logback+self4j 进行日志记录

    关于logback-test.xml配置详解,包括简单项目demo解压运行

    logback-spring.xml

    放在项目的resources下即可,用于配置日志打印在控制台的格式等信息,并且也可以调日志信息打印出来的颜色,还能够使日志信息记录在日志文件上并保存在项目根路径下,springboot则用此logback-spring.xml命名,若是maven...

    SpringBoot Logback日志记录到数据库的实现方法

    主要介绍了SpringBoot Logback日志记录到数据库的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    logback-test:一个入门项目,可使用LogBack日志记录框架快速入门

    logback中有5个日志级别:TRACE,DEBUG,INFO,WARN和ERROR 记录器级别的继承-如果为记录器分配了级别,它将覆盖其祖先的级别。 如果未为记录器分配级别,则它将继承其层次结构中的第一个非空级别。 记录器附加...

    Logback用户手册中文版

    Logback用户手册中文版,非常详细的介绍了logback的使用,我最初学习的时候看的这个,很有条理性。...Logback-core附带了Joran,Joran是个强大的、通用的配置系统,你可以在自己的项目里使用Joran以获得巨大的作用。

    terse-logback:使用Logback进行结构化的日志记录,跟踪和可观察性

    对于一直在询问(年份)的所有人来说,是否有其他可替代性的蜂窝可观察性:是的,最后是肯定的! 仅使用日志和功能标志破解了最巧妙的小解决方案: : —慈善专业(@mipsytipsy) 文献资料 可从获得文档。 展示柜 在...

    springboot 日志配置文件(完整的中文注释)

    spring boot项目记录日志、每日日志归档、彩色日志都会在logback-spring.xml文件中进行配置。给大家分享完整的日志配置信息,以及各种配置的各种含义,有着完整的中文注释。 此logback.xml文件既有成彩色输出也有...

    logback.xml

    记录日志文件的logback.xml文件,将这个放在项目的resources就可以了,每天会将日志自动打包

    logback-servlet:Servlet for Logback在运行时配置日志级别

    Servlet for Logback在运行时配置日志级别。 特征 在运行时更改每个记录器的Logback级别 从初始logback.xml将级别重置为其默认值 按名称或级别对记录器进行排序 按名称过滤记录器 用法 将文件放入您的项目中,并将...

    【SpringBoot探索二】SpringBoot项目集成日志记录功能

    该资源为博客文章"【SpringBoot探索二】SpringBoot项目集成日志记录功能"中的示例

    json-log-domain:使用Logback和Stackdriver支持JSON日志记录的库

    使用特定于域的子树进行JSON日志记录 基于YAML的简单定义格式 通过或插件生成的用户友好型帮助程序类 Markdown文档生成器 Elasticsearch配置生成器 JAX-RS日志注释 多个域可以合并在同一个log语句中。 错误,功能...

    hipchat-log-appender:直接从代码到您最喜欢的聊天程序进行 DevOps 日志记录

    特征标准(logback)日志记录Hipchat 配置(针对自己的环境) 可配置的日志记录安装要使用 hipchat 日志附加程序,应将依赖项添加为项目中的运行时依赖项。 在 Maven 中心可用:'...

    logstash-logback-encoder:Logback JSON编码器和附加器

    !! 本文档适用于正在开发的下一版本。 有关请参见。 Logstash Logback编码器 提供编码器,布局和附加程序,以JSON和登录。...将其包含在您的项目中 Maven风格: &lt; groupId&gt;net.logstash.logback&lt;/ groupId

    SpringBoot日记——日志框架篇.docx

    在项目的开发中,日志是必不可少的一个记录事件的组件,所以也会相应的在项目中实现和构建我们所需要的日志框架。 而市面上常见的日志框架有很多,比如:JCL、SLF4J、Jboss-logging、jUL、log4j、log4j2、logback...

    Struts2 + Spring 2.5 + Hibernate 3.3 整合(实际使用项目,version1)

    用sf4j及logback(log4j的升级版)记录日志;proxool(据说是dbcp和c3p0三者中最优秀的)做连接池;使用jquery的ajax实现仿google人名自动补全;头像上传剪切压缩处理。 包含有完整的jar包和源代码,这是专门为我们...

    一个可靠、通用、快速且灵活的 Java 日志记录框架

    鉴于下游用户可能在其项目中依赖 Java EE(在 javax 命名空间中)或 Jakarta EE(在 jakarta 命名空间中),因此 logback 支持这两种 EE 替代方案被认为很重要。 版本 1.3.x 支持 Java EE,而版本 1.4.x 支持 ...

    java版ss源码-logback-json-logger:logback-json-logger

    然后,您可以在记录器配置中使用编码器。 &lt;? xml version = " 1.0 " encoding = " UTF-8 " ?&gt; &lt; configuration &gt; &lt; appender name = " STDOUT " class = " ch.qos.logback.core.ConsoleAppender " &gt; &lt...

    JavaEE WEB小项目

    用sf4j及logback(log4j的升级版)记录日志; proxool(据说是dbcp和c3p0三者中最优秀的)做连接池; 使用jquery的ajax实现仿google人名自动补全;头像上传剪切压缩处理。 3、包含有完整的jar包和源代码,可以直接...

    logstash-gelf:适用于所有主要日志记录框架的Java Graylog扩展日志格式(GELF)实现

    使用Graylog扩展日志记录格式( 1.0和1.1)提供对logstash的日志记录,以用于: logstash-gelf从1.14.0版本开始需要Java 7或更高版本。 1.13.x和更早的版本需要Java6。有关更多文档,另请参见或 。 将其包含在您的...

    Struts2 + Spring3 + Hibernate3.5 整合(实际使用项目,version2)

    用sf4j及logback(log4j的升级版)记录日志;proxool(据说是dbcp和c3p0三者中最优秀的)做连接池;使用jquery的ajax实现仿google人名自动补全;头像上传剪切压缩处理。 包含有完整的jar包和源代码,可以直接下载...

Global site tag (gtag.js) - Google Analytics