转载自 : https://www.jianshu.com/p/1ded57f6c4e3
作者:beanlam
获取LogFactory的基本信息
public static void main( String[] args )
{
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
ProjectInfo projectInfo = (ProjectInfo)context.getBean("projectInfo");
log.debug(projectInfo.getName());
LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
StatusPrinter.print(lc);
}
日志级别:
TRACE < DEBUG < INFO < WARN < ERROR
在 logback 中,每个 logger 都是一个单例,调用 LoggerFactory.getLogger
方法时,如果传入的 logger name 相同,获取到的 logger 都是同一个实例。
在为 logger 命名时,用类的全限定类名作为 logger name 是最好的策略,这样能够追踪到每一条日志消息的来源。
参数化打印日志
经常能看到打印日志的时候,使用以下这种方式打印日志:
logger.debug("the message is " + msg + " from " + somebody);
这种打印日志的方式有个缺点,就是无论日志级别是什么,程序总要先执行 "the message is " + msg + " from " + somebody
这段字符串的拼接操作。当 logger 设置的日志级别为比 DEBUG 级别更高级别时,DEBUG 级别的信息不回被打印出来的,显然,字符串拼接的操作是不必要的,当要拼接的字符串很大时,这无疑会带来很大的性能白白损耗。
应该采用占位符的方式
logger.debug("the message {} is from {}", msg, somebody);
性能经验
在 logback 中,将日志信息格式化,以及输出到目的地,是最损耗性能的操作
建议使用占位符的方式参数化记录日志
配置方式
logback 提供的配置方式有以下几种:
-
编程式配置
- xml 格式
- groovy 格式
logback 在启动时,根据以下步骤寻找配置文件:
- 在 classpath 中寻找 logback-test.xml文件
- 如果找不到 logback-test.xml,则在 classpath 中寻找 logback.groovy 文件
- 如果找不到 logback.groovy,则在 classpath 中寻找 logback.xml文件
- 如果上述的文件都找不到,则 logback 会使用 JDK 的 SPI 机制查找 META-INF/services/ch.qos.logback.classic.spi.Configurator 中的 logback 配置实现类,这个实现类必须实现
Configuration
接口,使用它的实现来进行配置 - 如果上述操作都不成功,logback 就会使用它自带的
BasicConfigurator
来配置,并将日志输出到 console
test.xml 放在 src/test/resources 目录下。maven 打包的时候也不会把这个文件打进 jar 包里。
logback 启动的时候解析配置文件大概需要 100 毫秒的时间,如果希望更快启动,可以采用 SPI 的方式。
默认配置:
<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>
配置logger
在配置文件中,logger 的配置在
<logger> 标签中配置,<logger> 标签只有一个属性是一定要的,那就是 name,除了 name 属性,还有 level 属性,additivity 属性可以配置,不过它们是可选的。
level 的取值可以是 TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF, INHERITED, NULL
, 其中 INHERITED
和 NULL
的作用是一样的,并不是不打印任何日志,而是强制这个 logger 必须从其父辈继承一个日志级别。
additivity 的取值是一个布尔值,true 或者 false。
<logger> 标签下只有一种元素,那就是 <appender-ref>,可以有0个或多个,意味着绑定到这个 logger 上的 Appender。
配置root
<root> 标签和 <logger> 标签的配置类似,只不过 <root> 标签只允许一个属性,那就是 level 属性,并且它的取值范围只能取 TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF
。
<root> 标签下允许有0个或者多个 <appender-ref>。
配置 appender 节点
<appender> 标签有两个必须填的属性,分别是 name 和 class,class 用来指定具体的实现类。<appender> 标签下可以包含至多一个 <layout>,0个或多个 <encoder>,0个或多个 <filter>,除了这些标签外,<appender> 下可以包含一些类似于 JavaBean 的配置标签。
<layout> 包含了一个必须填写的属性 class,用来指定具体的实现类,不过,如果该实现类的类型是 PatternLayout
时,那么可以不用填写。<layout> 也和 <appender> 一样,可以包含类似于 JavaBean 的配置标签。
<encoder> 标签包含一个必须填写的属性 class,用来指定具体的实现类,如果该类的类型是 PatternLayoutEncoder
,那么 class 属性可以不填。
如果想要往一个 logger 上绑定 appender,则使用以下方式:
<configuration>
<contextName>myAppName</contextName>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %contextName [%t] %level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
定义变量
<configuration>
<property name="USER_HOME" value="/home/sebastien" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
...
</appender>
<root level="debug">
...
</root>
</configuration>
可以通过外部变量定义
<property file="src/main/java/chapters/configuration/variables1.properties" />
<property resource="resource1.properties" />
示例
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<property name="component" value="weeklyr"/>
<property name="logPath" value="C:/weeklyr/logs"/>
<!-- 控制台输出日志 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %highlight(%-5level) %cyan([%thread] [%logger{50}%replace(.%X{method}:%X{line}){'\.:',''}]) %msg%n</pattern>
</layout>
</appender>
<!-- 文件输出日志 (文件大小策略进行文件输出,超过指定大小对文件备份)-->
<appender name="FILE-debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<File>${logPath}/${component}-debug.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${logPath}/${component}-debug.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>5</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>1MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %-5level [%thread] [%logger{50}%replace(.%X{method}:%X{line}){'\.:',''}] %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="FILE-error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<File>${logPath}/${component}-error.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${logPath}/${component}-error.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>5</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>1MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %-5level [%thread] [%logger{50}%replace(.%X{method}:%X{line}){'\.:',''}] %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 设置第三方包 -->
<logger name="org.springframework" level="ERROR"/>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE-debug" />
<appender-ref ref="FILE-error" />
</root>
</configuration>