前言:
文末附一份个人总结的日常使用的配置文件
一、logback的介绍
Logback是由log4j创始人设计的另一个开源日志组件,官方网站: http://logback.qos.ch。
它当前分为下面下个模块:
logback-core:其它两个模块的基础模块
logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging。本文中,“logback”代表 logback-classic 模块
logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能(不做学习)
二、logback取代log4j的理由:
- 更快的实现:Logback的内核重写了,在一些关键执行路径上性能提升10倍以上。而且logback不仅性能提升了,初始化内存加载也更小了。
- Logback-classic非常自然实现了SLF4j:Logback-classic实现了SLF4j。在使用SLF4j中,你都感觉不到logback-classic。而且因为logback-classic非常自然地实现了slf4j , 所 以切换到log4j或者其他,非常容易,只需要提供成另一个jar包就OK,根本不需要去动那些通过SLF4JAPI实现的代码。
- 自动重新加载配置文件,当配置文件修改了,Logback-classic能自动重新加载配置文件。扫描过程快且安全,它并不需要另外创建一个扫描线程。这个技术充分保证了应用程序能跑得很欢在JEE环境里面。
- Lilith是log事件的观察者,和log4j的chainsaw类似。而lilith还能处理大数量的log数据 。
- Filters(过滤器)有些时候,需要诊断一个问题,需要打出日志。在log4j,只有降低日志级别,不过这样会打出大量的日志,会影响应用性能。在Logback,你可以继续 保持那个日志级别而除掉某种特殊情况,如alice这个用户登录,她的日志将打在DEBUG级别而其他用户可以继续打在WARN级别。要实现这个功能只需加4行XML配置。
- SiftingAppender(一个非常多功能的Appender):它可以用来分割日志文件根据任何一个给定的运行参数。如,SiftingAppender能够区别日志事件跟进用户的Session,然后每个用户会有一个日志文件。
- 自动压缩已经打出来的log:RollingFileAppender在产生新文件的时候,会自动压缩已经打出来的日志文件。压缩是个异步过程,所以甚至对于大的日志文件,在压缩过程中应用不会受任何影响。
堆栈树带有包版本:Logback在打出堆栈树日志时,会带上包的数据。 - 自动去除旧的日志文件:通过设置TimeBasedRollingPolicy或者SizeAndTimeBasedFNATP的maxHistory属性,你可以控制已经产生日志文件的最大数量。如果设置maxHistory 12,那那些log文件超过12个月的都会被自动移除。
三、logback的介绍
3.1、Logger、appender及layout
- Logger作为日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型、级别。
- Appender主要用于指定日志输出的目的地,目的地可以是控制台、文件、远程套接字服务器、 MySQL、PostreSQL、 Oracle和其他数据库、 JMS和远程UNIX Syslog守护进程等。
- Layout 负责把事件转换成字符串,格式化的日志信息的输出。
Logger 类是logback-classic 模块的一部分,而Appender 和Layout接口来自logback-core。
作为一个多用途模块,logback-core 不包含任何 logger。
3.2、logger context
各个logger 都被关联到一个 LoggerContext,LoggerContext负责制造logger,也负责以树结构排列各logger。其他所有logger也通过org.slf4j.LoggerFactory 类的静态方法getLogger取得。 getLogger方法以 logger名称为参数。用同一名字调用LoggerFactory.getLogger 方法所得到的永远都是同一个logger对象的引用。
3.3、命名层次
如果 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);
3.4、有效级别(Level)即级别继承
Logger 可以被分配级别。级别包括:TRACE、DEBUG、INFO、WARN 和 ERROR,定义于 ch.qos.logback.classic.Level 类。注意在 logback 里,Level 类是 final 的,不能被继承,Marker 对象提供了更灵活的方法。
如果 logger 没有被分配级别,那么它将从有被分配级别的最近的祖先那里继承级别。
更正式地说:
logger L 的有效级别等于其层次等级里的第一个非 null 级别,顺序是从 L 开始,向上,直至根 logger。
为确保所有 logger 都能够最终继承一个级别,根 logger 总是有级别,默认情况下,这个级别是 DEBUG。
3.5、打印方法和基本选择规则
根据定义,打印方法决定记录请求的级别。例如,如果 L 是一个 logger 实例,那么,语句 L.info("…")是一条级别为 INFO 的记录语句。
记录请求的级别在高于或等于其 logger 的有效级别时被称为被启用,否则,称为被禁用。如前所述,没有被分配级别的 logger 将从其最近的祖先继承级别。该规则总结如下:
基本选择规则
记录请求级别为 p,其 logger 的有效级别为 q,只有则当 p>=q时,该请求才会被执行。
该规则是 logback 的核心。级别排序为:TRACE < DEBUG < INFO < WARN < ERROR。
下表显示了选择规则是如何工作的。行头是记录请求的级别 p。列头是 logger 的有效级
别 q。行(请求级别)与列(有效级别)的交叉部分是按照基本选择规则得出的布尔值。
上个示例:
//Logger是ch.qos.logback.classic.Logger
Logger logger1 = (Logger) LoggerFactory.getLogger(AppTest.class.getName());
logger1.setLevel(Level.ERROR);
logger1.info("info message");
logger1.error("error message");
输出:
这里我将logger的级别设置为error,所以这个时候只有error、或者error级别信息才会打印。
3.6、获取 Logger
用同一名字调用 LoggerFactory.getLogger 方法所得到的永远都是同一个 logger 对象的引用。
@Test
public void testLog(){
Logger logger1 = LoggerFactory.getLogger(AppTest.class.getName());
Logger logger2 = LoggerFactory.getLogger(AppTest.class.getName());
logger1.info("hello world~~1");
System.out.println(logger1 == logger2);
}
logger命名
Logback 简化了 logger 命名,方法是在每个类里初始化 logger,以类的全限定名作为logger 名。这种定义 logger 的方法即有用又直观。由于记录输出里包含 logger 名,这种命名方法很容易确定记录消息来源。Logback 不限制 logger 名,你可以随意命名 logger。
然而,目前已知最好的策略是以 logger 所在类的名字作为 logger 名称
3.7、Appender
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 累积行为。
additivity的作用在于 children-logger是否使用 rootLogger配置的appender进行输出。
false:表示只用当前logger的appender-ref。
true:表示当前logger的appender-ref和rootLogger的appender-ref都有效。
3.8、layout
有些用户希望不仅可以定制输出目的地,还可以定制输出格式。这时为 appender 关联一个 layout 即可。Layout 负责根据用户意愿对记录请求进行格式化,appender 负责将格式化后的输出发送到目的地。PatternLayout 是标准 logback 发行包的一部分,允许用户按照类似于 C 语言的 printf 函数的转换模式设置输出格式。
例如,转换模式"%-4relative [%thread] %-5level %logger{32} - %msg%n"在 PatternLayout
里会输出形如:
176 [main] DEBUG manual.architecture.HelloWorld2 - Hello world.
第一个字段是自程序启动以来的逝去时间,单位是毫秒。
第二个地段发出记录请求的线程。
第三个字段是记录请求的级别。
第四个字段是与记录请求关联的 logger 的名称。
“-”之后是请求的消息文字。
3.9、参数化记录日志
Object entry = new SomeObject();
logger.debug("The entry is {}.", entry);
在评估是否作记录后,仅当需要作记录时,logger 才会格式化消息,用 entry 的字符串
值替换"{}"。换句话说,当记录语句被禁用时,这种方法不会产生参数构造所带来的性能消
耗。
四、logback的配置
Logback 可以通过编程式配置,或用 XML 格式的配置文件进行配置。
Logback 采取下面的步骤进行自我配置:
- 尝试在 classpath 下查找文件 logback-test.xml;
- 如果文件不存在,则查找文件 logback.xml;
- 如果两个文件都不存在,logback 用 BasicConfigurator 自动对自己进行配置,这会导致记录输出到控制台。
第三步也是最后一步是为了在缺少配置文件时提供默认(但基本的)记录功能。
4.1、默认配置—BasicConfigurator
假设配置文件 logback-test.xml 和 logback.xml 都不存在,那么 logback 默认地会调用BasicConfigurator , 创 建一 个 最小 化配 置 。最 小化 配置 由 一个 关联 到 根 logger 的ConsoleAppender 组成。输出用模式为%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}- %msg%n 的 PatternLayoutEncoder 进行格式化。还有,根 logger 默认级别是 DEBUG。
@Test
public void testLog() {
Logger logger = LoggerFactory.getLogger(AppTest.class);
logger.debug("debug:{}","debug level info ...");
logger.info("info:{}","info level info ...");
logger.error("error:{}","error level info ...");
}
输出:
4.1、用 logback-test.xml 或 logback.xml 自动配置
前面提到过,如果 classpath 里有 logback-test.xml 或 logback.xml,logback 会试图用它进行自我配置。下面的配置文件与刚才的 BasicConfigurator 等效。
(1) 根节点< configuration >
包含下面三个属性:
scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
例如:
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!--其他配置省略-->
</configuration>
(2) 子节点< contextName >
用来设置上下文名称,每个logger都关联到logger上下文,默认上下文名称为default。但可以使用< contextName >设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>myAppName</contextName>
<!--其他配置省略-->
</configuration>
(3) 子节点< property >
用来定义变量值,它有两个属性name和value,通过< property >定义的值会被插入到logger上下文中,可以使“${}”来使用变量。
name: 变量的名称
value: 的值时变量定义的值
例如:
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<property name="APP_Name" value="myAppName" />
<contextName>${APP_Name}</contextName>
<!--其他配置省略-->
</configuration>
(4) 子节点< appender >
负责写日志的组件,它有两个必要属性name和class。name指定appender名称,class指定appender的全限定名
Appender1:ConsoleAppender 把日志输出到控制台
有以下子节点:
< encoder >:对日志进行格式化。(具体参数稍后讲解 )
< target >:字符串System.out(默认)或者System.err(区别不多说了)
例如:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<property name="PATTERN" value="%-4relative [%thread] %-5level %logger{35} - %msg %n"/>
<!--appender begin-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
</appender>
<!--appender end-->
<!--logger begin-->
<!--logger end-->
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
上面的配置把级别在info及以上的日志通过控制台输出
Appender2:FileAppender
把日志添加到文件,有以下子节点:
< file >:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。
< append >:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。
< encoder >:对记录事件进行格式化。(具体参数稍后讲解 )
< prudent >:如果是 true,日志会被安全的写入文件,即使其他的FileAppender也在向此文件做写入操作,效率低,默认是 false。
例如:
<!--文件-->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
<append>true</append>
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
</appender>
Appender3:RollingFileAppender
RollingFileAppender继承自FileAppender,提供日志目标文件自动切换的功能。例如可以用日期作为日志分割的条件。
RollingFileAppender有两个重要属性,RollingPolicy负责怎么切换日志,TriggeringPolicy负责何时切换。为了使RollingFileAppender起作用,这两个属性必须设置,但是如果RollingPolicy的实现类同样实现了TriggeringPolicy接口,则也可以只设置RollingPolicy这个属性。
参数:
Property Name | Type | Description |
---|---|---|
file | String | 指定文件名。注意在windows当中,反斜杠 \ 需要转义,或直接使用 / 也可以。例如 c:/temp/test.logor 或 c:\\temp\\test.log 都可以。没有默认值,如果上层目录不存在,FileAppender会自动创建。 |
append | boolean | 是否以追加方式输出。默认为true。 |
encoder | Encoder | See OutputStreamAppender properties. |
rollingPolicy | RollingPolicy | 当发生日志切换时,RollingFileAppender的切换行为。例如日志文件名的修改 |
triggeringPolicy | TriggeringPolicy | 决定什么时候发生日志切换,例如日期,日志文件大小到达一定值 |
prudent | boolean |
FixedWindowRollingPolicy
不支持prudent模式。
TimeBasedRollingPolicy 支持prudent模式,但是需要满足一下两条约束:
|
RollingFileAppender之RollingPolicy
RollingPolicy实际上就是负责日志文件的切换以及重命名的。
RollingPolicy有几个常见的实现类:
- 1、TimeBasedRollingPolicy
它的滚动策略是基于时间的,例如根据天数,月份。
TimeBasedRollingPolicy继承了RollingPolicy和TriggeringPolicy接口。
它包含一个必需的属性:fileNamePattern 以及若干个可选属性。
Property Name | Type | Description |
---|---|---|
fileNamePattern | String | 这个必需的属性,决定了日志滚动时,归档日志的命名策略。它由文件名,以及一个%d转移符组成。%d{}花括号中需要包含符合SimpleDateFormat约定的时间格式,如果未指定,直接是%d,则默认相当于%d{yyyy-MM-dd}。 需要注意的是,在RollingPolicy节点的父节点appender节点中,节点的值可以显示声明,或忽略。如果声明file属性,你可以达到分离当前有效日志文件以及归档日志文件的目的。设置成之后,当前有效日志文件的名称永远都是file属性指定的值,当发生日志滚动时,再根据fileNamePattern的值更改存档日志的名称,然后创建一个新的有效日志文件,名为file属性指定的值。如果不指定,则当前有效日志文件名根据fileNamePattern变更。 同样需要注意的是,在%d{}中,不管是“/”还是“\”都被认为是文件分隔符。 多个%d转移符的情况: fileNamePaatern的值允许包含多个%d的情况,但是只有一个%d作为主要的日志滚动周期的参考值。其余非主要的%d需要包含一个"aux"的参数。 例如: < fileNamePattern >/var/log/%d{yyyy/MM, aux}/myapplication.%d{yyyy-MM-dd}.log</ fileNamePattern> 根据年月划分目录,再将相应月份按日期天数命名的归档日志存放在一起同一个月份文件夹当中。该属性值决定在每天0点的时候发生日志切换。 时区问题: 你可以将日期转换成相应时区的时间。 例如 aFolder/test.%d{yyyy-MM-dd-HH, UTC}.log //世界协调时间 aFolder/test.%d{yyyy-MM-dd-HH, GMT}.log //格林尼治时间 |
maxHistory | int | 可选参数,声明归档日志最大保留时间。如果你是基于月份的日志滚动,则当maxHisory为6时,说明会保留6个月的日志。大于6个月的就会被删除。日志所存在的目录也会被合适的删除掉 |
totalSizeCap | int | 可选参数,声明归档日志的最大存储量。当超过这个值,最老的归档日志文件也会被删除。 |
cleanHistoryOnStart | boolean | 可选参数,默认为false。如果设置为true,则当appender启动时,会删除所有归档日志文件。 |
TimeBaseRollingPolicy 支持自动压缩日志文件,这个功能通过设置fileNamePattern的值以 .gz 或者 .zip 结尾开启。
例如:
/logs/foo.%d.gz
例子:
<!--滚动FileAppender-->
<appender name="MINUTE-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">\
<file>info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--按照分钟来滚动-->
<fileNamePattern>
info_%d{yyyy-MM-dd=HH:mm}.log
</fileNamePattern>
<!--只保留近5min的日志-->
<maxHistory>5</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
</appender>
- 2、SizeAndTimeBasedRollingPolicy
有时候你不仅想通过时间来规定滚动策略,还希望同时限制每个日志文件的大小。在TimeBasedRoolingPolicy中已经提供限制总日志文件的大小的功能,而SizeAndTimeBasedRollingPolicy提供了更为强大的,针对单个日志文件的大小限制能力。
例子:
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 按天滚动 -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<!-- 每个日志文件最大为100M,保持60天,日志总大小最大为20 -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
需要注意的是:在该例子中,fileNamePattern中不仅包含了%d,还包含了%i,这两个都是必要的标识符。%i代表日志索引号。就是今天的日志已经拓展到第几份了,以0开始。
在1.1.7版本之前,使用的是SizeAndTimeBasedFNATP,之后就采用SizeAndTimeBasedRollingPolicy,SizeAndTimeBasedRollingPolicy继承了SizeAndTimeBasedFNATP。
- 3、FixedWindowRollingPolicy 固定窗口的日志滚动策略
每次触发器触发滚动事件时,则将log滚动一次
例子:
<appender name="WindowPolicy" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--file必填,不然不成功-->
<file>mlog.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<!--必须有%i-->
<fileNamePattern>mlog.%i.log</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>5</maxIndex>
</rollingPolicy>
<!--当文件达到3MB的时候引发滚动-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>3MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
</appender>
RollingFileAppender之RollingPolicy
TriggeringPolicy 负责RollingFileAppender何时发生日志滚动
TriggeringPolicy常见的实现类:
- SizeBasedTriggeringPolicy
SizeBasedTriggeringPolicy 检测当前活动日志文件的大小,当到达一定容量,就开启日志滚动。
SizeBasedTriggeringPolicy只接收一个参数,maxFileSize,默认值:10MB
可接受B,KB,MB,GB
一般配合FixedWindowRollingPolicy滚动策略进行使用
例子:
<appender name="WindowPolicy" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--file必填,不然不成功-->
<file>mlog.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<!--必须有%i-->
<fileNamePattern>mlog.%i.log</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>5</maxIndex>
</rollingPolicy>
<!--当文件达到3MB的时候引发滚动-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>3MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
</appender>
Appender的过滤器
过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一。返回DENY,日志将立即被抛弃不再经过其他过滤器;返回NEUTRAL,有序列表里的下个过滤器过接着处理日志;返回ACCEPT,日志会被立即处理,不再经过剩余过滤器。
过滤器被添加到< Appender > 中,为< Appender > 添加一个或多个过滤器后,可以用任意条件对日志进行过滤。< Appender > 有多个过滤器时,按照配置顺序执行。
下面是几个常用的过滤器:
- LevelFilter: 级别过滤器,根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。有以下子节点:
:设置过滤级别
:用于配置符合过滤条件的操作
:用于配置不符合过滤条件的操作
例子:
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>sys_info_%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
<!--只记录info级别的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>sys_error_%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
<!--只记录error级别的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
- ThresholdFilter: 临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。
例如:过滤掉所有低于INFO级别的日志。
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>sys_info_%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
<!--记录info级别及以上级别的日志-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
(5)logger
< loger >
用来设置某一个包或者具体的某一个类的日志打印级别、以及指定< appender >。< loger >仅有一个name属性,一个可选的level和一个可选的addtivity属性。
- name:
用来指定受此loger约束的某一个包或者具体的某一个类。 - level:
用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
如果未设置此属性,那么当前loger将会继承上级的级别。 - addtivity:
是否向上级loger传递打印信息。默认是true。
< loger >可以包含零个或多个< appender-ref >元素,标识这个appender将会添加到这个loger。
< root >也是< loger >元素,但是它是根loger。只有一个level属性,应为已经被命名为"root".
level:
用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。
默认是DEBUG。
< root >可以包含零个或多个元素,标识这个appender将会添加到这个loger。
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder 默认配置为PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- logback为java中的包 -->
<logger name="logback"/>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
附自己写的一份日常配置,可根据需要自行修改或者使用(基于logback 1.1.8,还请注意)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--日志目录-->
<property name="LOG_DIR" value="${catalina.base}/logs"/>
<!--项目名称-->
<property name="PROJECT_NAME" value="your_project"/>
<property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%C:%L] %-5level %msg%n"/>
<!--控制台Appender-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<encoder>
<pattern>${pattern}</pattern>
</encoder>
</appender>
<!--整个工程的日志-->
<appender name="ROOT-FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${PROJECT_NAME}-root.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_DIR}/${PROJECT_NAME}-root.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!-- 每个日志文件最大为20M,保持10天,日志总大小最大为20G-->
<maxFileSize>20MB</maxFileSize>
<maxHistory>10</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
<!--<totalSizeCap>100MB</totalSizeCap>-->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
</appender>
<!--某个模块的日志,需要单独定义-->
<!--<appender name="moduleA" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
<!--<file>${LOG_DIR}/moduleA.log</file>-->
<!--<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
<!--<FileNamePattern>${LOG_DIR}/moduleA.%d{yyyy-MM-dd}.log</FileNamePattern>-->
<!--<maxHistory>10</maxHistory>-->
<!--</rollingPolicy>-->
<!--<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">-->
<!--<pattern>${pattern}</pattern>-->
<!--</encoder>-->
<!--</appender>-->
<!--某个模块的日志-->
<!--<logger name="com.souche.test" level="info">-->
<!--<appender-ref ref="moduleA"/>-->
<!--</logger>-->
<!--过滤,只输出error级别日志-->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${PROJECT_NAME}-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_DIR}/${PROJECT_NAME}-error.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!-- 每个日志文件最大为20M,保持10天,日志总大小最大为10G-->
<maxFileSize>20MB</maxFileSize>
<maxHistory>14</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
<!--<totalSizeCap>50MB</totalSizeCap>-->
</rollingPolicy>
<!--只记录error级别的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
</appender>
<root level="info">
<!--控制台输出-->
<appender-ref ref="STDOUT"/>
<!--日志全量,文件输出-->
<appender-ref ref="ROOT-FILE"/>
<!--error日志,文件输出-->
<appender-ref ref="error"/>
</root>
</configuration>