Logback学习笔记1 .

本文详细介绍了Logback日志框架的组成部分、配置方法、关键概念和自定义配置技巧,帮助开发者掌握如何高效地管理和输出日志信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引用:http://blog.youkuaiyun.com/milife2012/article/details/7277888

 

Logback介绍

Logback 分为三个模块:CoreClassic AccessCore模块是其他两个模块的基础。 Classic模块扩展了core模块。 Classic模块相当于log4j的显著改进版。Logback-classic 直接实现了 SLF4J API

要引入logback,由于Logback-classic依赖slf4j-api.jarlogback-core.jar,所以要把slf4j-api.jarlogback-core.jarlogback-classic.jar添加到要引入Logbac日志管理的项目的class path.

 

Logback的配置

LoggerAppender Layout

Logback建立于三个主要类之上:LoggerAppender LayoutLogger类是logback-classic模块的一部分,而AppenderLayout接口来自logback-core。作为一个多用途模块,logback-core 不包含任何 logger

Logger作为日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型、级别。Appender主要用于指定日志输出的目的地,目的地可以是控制台、文件、远程套接字服务器、 MySQL PostreSQL Oracle和其他数据库、 JMS和远程UNIX Syslog守护进程等。Layout 负责把事件转换成字符串,格式化的日志信息的输出。

 

Logger context

各个logger 都被关联到一个 LoggerContextLoggerContext负责制造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 可以被分配级别。级别包括:TRACEDEBUGINFOWARN 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

 

LoggerAppenderslayouts的关系

一个 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

最简单的配置方法就是使用默认配置。以下是logbackBasicConfigurator 配置的简单例子:

package com.ttpod.chapters.configuration;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

publicclass MyApp1 {

finalstatic Logger logger = 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 Logger logger = LoggerFactory.getLogger(Foo.class);

publicvoid doIt() {

logger.debug("Did it again!");    //定义一个debug级别的日志输出

}

    …………

}

 

自动打印警告和错误消息

当解析配置文件有警告或出错时,logback 会在控制台上自动打印状态数据。如果没有警告或错误,还是想检查 logback 的内部状态的话,可以调用 StatusPrinter print()方法。示例如下:

finalstatic Logger logger = 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>

<!--定义一个名为STDOUTappender,并将其关联到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"/>    <!--将名为STDOUTappender添加到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 属性的值大小写无关,其值为下面其中一个字符串:TRACEDEBUGINFOWARNERRORALL 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 loggerdebug级别 -->

    <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 都有自己的 encoderEncoder 通常不能被多个 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\nlog4j推荐使用这个转换符,而不是\r或者\r\n

p 

输出调用的日志的级别,如我是调用logger.debug方法,那么级别就是debug

r 

输出自应用启动后第一次调用logger的日志输出方法,到输出该log信息耗费的毫秒数

t 

输出所在线程的名字

x 

输出产生的日志事件的线程的NDC(嵌套诊断上下文)

X 

输出与生成的日志事件的线程关联的MDC(映射诊断上下文)。X转换符括号之间放置了一个key,就像在%X {clientNumber}中的clientNumberkey 一样。在MDC correspondingvalue将被输出。

% 

写上%%后将直接输出一个%符号

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值