logback优点
比较吸引的几个优点如下:
- 内核重写,初始化内存加载更小
- 文档比较齐全
- 支持自动重新加载配置文件,扫描过程快且安全,它并不需要另外创建一个扫描线程
- 支持自动去除旧的日志文件,可以控制已经产生日志文件的最大数量
logback加载
在项目中引入logback依赖:
复制代码 ch.qos.logback logback-classic ${logback.version}
启动项目时,logback会按照如下顺序扫描配置文件:
- 在系统配置文件System Properties中寻找是否有logback.configurationFile对应的value
- 在classpath下寻找是否有logback.groovy(即logback支持groovy与xml两种配置方式)
- 在classpath下寻找是否有logback-test.xml
- 在classpath下寻找是否有logback.xml
以上任何一项找到了,就不进行后续扫描,按照对应的配置进行logback的初始化,可从控制台输出信息中查看加载的配置文件。
当所有以上四项都找不到的情况下,logback会调用ch.qos.logback.classic.BasicConfigurator
的configure方法,构造一个ConsoleAppender用于向控制台输出日志,默认日志输出格式为%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
。
ContextInitializer类中相关方法摘录如下:
final public static String GROOVY_AUTOCONFIG_FILE = "logback.groovy";final public static String AUTOCONFIG_FILE = "logback.xml";final public static String TEST_AUTOCONFIG_FILE = "logback-test.xml";final public static String CONFIG_FILE_PROPERTY = "logback.configurationFile";... public URL findURLOfDefaultConfigurationFile(boolean updateStatus) { ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this); URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus); if (url != null) { return url; } url = getResource(TEST_AUTOCONFIG_FILE, myClassLoader, updateStatus); if (url != null) { return url; } url = getResource(GROOVY_AUTOCONFIG_FILE, myClassLoader, updateStatus); if (url != null) { return url; } return getResource(AUTOCONFIG_FILE, myClassLoader, updateStatus);}public void autoConfig() throws JoranException { StatusListenerConfigHelper.installIfAsked(loggerContext); URL url = findURLOfDefaultConfigurationFile(true); if (url != null) { configureByResource(url); } else { Configurator c = EnvUtil.loadFromServiceLoader(Configurator.class); if (c != null) { try { c.setContext(loggerContext); c.configure(loggerContext); } catch (Exception e) { throw new LogbackException(String.format("Failed to initialize Configurator: %s using ServiceLoader", c != null ? c.getClass().getCanonicalName() : "null"), e); } } else { BasicConfigurator basicConfigurator = new BasicConfigurator(); basicConfigurator.setContext(loggerContext); basicConfigurator.configure(loggerContext); } }}复制代码
logback配置文件解析
-
根节点<configuration>
复制代码
-
设置变量<property>
复制代码
-
<logger>与<root>
<logger>用来设置某一个包或者具体某一个类的日志打印级别、以及指定appender。<logger>可以包含零个或者多个<appender-ref>元素,标识这个appender将会添加到这个logger。
<root>也是<logger>元素,但它是根logger,只有一个level属性,因为它的name就是ROOT
复制代码
-
<appender>
负责写日志的组件,有两个必要属性name和class
- 常用的控制台输出:ConsoleAppender
复制代码 ${LOG_PATTERN} utf8
- 常用的滚动记录文件:RollingFileAppender
复制代码 INFO ${LOG_HOME}/iot-sdk-info.log true ${LOG_HOME}/iot-sdk-info.%d{yyyy-MM-dd}.%i.log 30 100MB ${LOG_PATTERN} utf8
-
<encoder>
encoder节点负责两件事情:
- 把日志信息转换为字节数组
- 把字节数组写到输出流
以下是一个常用配置:
复制代码 %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %t %file:%line %X{traceId} -| %m%n utf8
-
<filter>
配合appender使用,<filter>是<appender>的一个子节点,表示在当前给到的日志级别下再进行一次过滤
- Level 级别过滤器
根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据onMath和onMismatch接收(ACCEPT)或拒绝(DENY)日志。
复制代码 ERROR ACCEPT DENY ${LOG_PATTERN} utf8
- ThresholdFilter: 临界值过滤器
将日志级别低于<level>的全部进行过滤。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。
复制代码 INFO ${LOG_PATTERN} utf8
自定义appender
logback提供的appender基本够用,有时候也免不了有自定义的需求。以下是一个简单的自定义appender:
package com.example.iot.demo;import ch.qos.logback.classic.spi.ILoggingEvent;import ch.qos.logback.core.AppenderBase;public class DemoAppender extends AppenderBase{ @Override protected void append(ILoggingEvent eventObject) { // 打印格式化后的日志信息 System.out.println(eventObject.getFormattedMessage()); }}复制代码
在配置文件中引入DemoAppender
${LOG_PATTERN} utf8 复制代码
常用配置
复制代码 ${LOG_PATTERN} utf8 INFO ${LOG_HOME}/iot-sdk-info.log true ${LOG_HOME}/iot-sdk-info.%d{yyyy-MM-dd}.%i.log 30 100MB ${LOG_PATTERN} utf8 ERROR ACCEPT DENY ${LOG_HOME}/iot-sdk-error.log true ${LOG_HOME}/iot-sdk-error.%d{yyyy-MM-dd}.%i.log 30 100MB ${LOG_PATTERN} utf8
参考: