OK,现在我们整理Logback的配置。关于Logback的使用比较简单,和使用log4j也没什么太大区别,这里就不做赘述了。
这里先来贴出一份完整的logback.xml的配置文件,以后如果用到相关配置直接这里复制就好了。
<?xml version="1.0" encoding="UTF-8"?> <!-- debug:打印logback内部日志信息,实时查看logback的运行状态,默认为false --> <!-- scan:配置文件如果发生改变,是否被重新加载,默认为true。 --> <!-- scanPeriod:设置检测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒,默认的时间间隔为1分钟,默认为true。 --> <configuration debug="true" scan="true" scanPeriod="30 seconds"> <contextName>Application</contextName> <!-- 时间戳定义,timeReference:使用日志产生日期为时间基准 --> <timestamp key="byDay" datePattern="yyyy-MM-dd" timeReference="contextBirth" /> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径,可以使用系统变量 --> <!-- <property name="LOG_HOME" value="${app.home}/log" /> --> <property name="LOG_HOME" value="log" /> <!-- 控制台输出,生产环境将请stdout去掉 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符 --> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <!-- 按照每天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 日志输出文件 --> <file>${LOG_HOME}/LoggingBack-${byDay}.log</file> <!-- 追加日志到原文件结尾 --> <append>false</append> <!-- timebasedrollingpolicy:演示时间和大小为基础的日志文件归档 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定。 --> <!--可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。 --> <!--而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <!-- 文件滚动日期格式:每天:.YYYY-MM-dd(默认);每星期:.YYYY-ww;每月:.YYYY-MM --> <!-- 每隔半天:.YYYY-MM-dd-a;每小时:.YYYY-MM-dd-HH;每分钟:.YYYY-MM-dd-HH-mm --> <fileNamePattern>${LOG_HOME}/log-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 控制归档文件的最大数量的保存,删除旧的文件,默认单位天数 --> <maxHistory>7</maxHistory> <!-- 设置当前日志的文件的大小,决定日志翻滚 --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, --> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n </pattern> </encoder> </appender> <!-- 可以写多个日志文件appender,然后区分多个模块的日志 --> <appender name="LOGGINGBACK2" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/LoggingBack2.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/LOG-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxHistory>7</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n </pattern> </encoder> </appender> <!-- 指定一个包,name必填,additivity选填:控制是否继承父类appender,默认true --> <!-- level选填,如果木有指定从最近的父类继承,顶级为root的级别 --> <logger name="org.linkinpark.commons.logbackLogging" level="INFO" additivity="true"> <appender-ref ref="FILE" /> </logger> <!-- 指定一个具体的文件 --> <logger name="org.linkinpark.commons.logbackLogging.LoggingBack2" level="ERROR" additivity="false"> <appender-ref ref="LOGGINGBACK2" /> </logger> <root level="DEBUG"> <appender-ref ref="STDOUT" /> </root> </configuration>
上面的配置文件说明:
1,日志级别的继承。我们可以配置多个日志,顶级是root日志。然后每个日志都可以从距离自己最近的父类来继承父类的日志级别,当然自己也可以重写。关于继承看下面这个例子:
值得注意的是:我们在定义包或者文件类的日志级别的时候,写包名必须从头到尾写,不能从中间写。比如x.y.z,我们写的要x.y或者x这样子写,不能y.z这样。自己不小心掉坑半天,我晕。
Logger name | Assigned level | Effective level |
---|---|---|
root | DEBUG | DEBUG |
X | INFO | INFO |
X.Y | none | INFO |
X.Y.Z | ERROR | ERROR |
2,默认情况下子类会从距离自己最近的父类继承父类的appender,即使自己重新定义了<appender-ref>,所以如果我们不想继承的时候,设置additivity属性为false就好了。
3,实际的项目中,一般情况下项目发布到Linux服务器上,所以这个时候没有必要设置控制台的输出,为了不影响性能,所以我们一般都直接定义root,然后也只定义root的日志级别就够了。
上面的配置文件中,我只是为了在平时编码过程中来控制台看日志输出而已。
4,上面的appender属性我配置了不管是true,还是false,每次还是总是给我添加到日志结尾了,郁闷,这个属性实际编码中可以忽略了。
5,日志的滚动一般都是有了最新的文件,然后将原来旧的文件重新命名,然后新的日志输出到最新的日志文件里面的,也就是说file属性指定文件每次都是最新的日志输出文件呢,别搞混了。
6,实际编码中,如果需要为不同的模块,或者某一个模块中要配置不同的日志文件,这个时候就可以定义多个appender,然后定义多个logger,然后设置additivity属性为false,appender-ref指向不同的日志append,OK,这样子就实现了不同文件的不同日志备份。
最后,我们就写一个具体的例子,来看下为不同的日志文件生成不同的项目日志,配置文件还是用上面的OK了,2个测试代码如下:
package org.linkinpark.commons.logbackLogging; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LoggingBack { private static Logger logger = LoggerFactory.getLogger(LoggingBack.class); @Test public void test() { logger.debug("LoggingBack.debug()。。。"); logger.info("LoggingBack.info()。。。"); logger.error("LoggingBack.error()。。。"); } }
package org.linkinpark.commons.logbackLogging; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LoggingBack2 { private static Logger logger = LoggerFactory.getLogger(LoggingBack2.class); @Test public void test() { LoggingBack huhu = new LoggingBack(); huhu.test(); logger.debug("LoggingBack2.debug()。。。"); logger.info("LoggingBack2.info()。。。"); logger.error("LoggingBack2.error()。。。"); } }
运行上面的测试,log文件夹下生成2个不同的日志。
LoggingBack-2016-03-01.log和LoggingBack2.log2个文件。
先打开LoggingBack-2016-03-01.log看下,该文件是默认的包下面的日志文件,设置的级别为info级别:
01:10:17.485 [main] INFO org.linkinpark.commons.logbackLogging.LoggingBack - LoggingBack.info()。。。 01:10:17.487 [main] ERROR org.linkinpark.commons.logbackLogging.LoggingBack - LoggingBack.error()。。。
然后再打开
LoggingBack2.log看下,该文件是我指定的一个特殊的类,设置的级别是error级别:
01:10:17.487 [main] ERROR org.linkinpark.commons.logbackLogging.LoggingBack2 - LoggingBack2.error()。。。
OK,没有问题,成功的区分了2种不同的文件,我们在实际编码中,如果多个模块中需要输出到不同的日志文件的话就可以使用这种方式。
总结:
Logback的核心对象:Logger、Appender、Layout。Logback主要建立于Logger、Appender 和 Layout 这三个类之上。
1,Logger:日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型、级别。Logger对象一般多定义为静态常量,如:
2,Appender:用于指定日志输出的目的地,目的地可以是控制台、文件、远程套接字服务器、 MySQL、 PostreSQL、Oracle和其他数据库、 JMS和远程UNIX Syslog守护进程等。
3,Layout:负责把事件转换成字符串,格式化的日志信息的输出。具体的Layout通配符,可以直接查看帮助文档。
上面的3个核心对象和log4j一样的,所以我这里就不做赘述了。