logback优点

比较吸引的几个优点如下:

  • 内核重写,初始化内存加载更小
  • 文档比较齐全
  • 支持自动重新加载配置文件,扫描过程快且安全,它并不需要另外创建一个扫描线程
  • 支持自动去除旧的日志文件,可以控制已经产生日志文件的最大数量

logback加载

在项目中引入logback依赖:

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>

启动项目时,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>

<!-- 输出logback内部日志信息,每隔30s判断一下配置文件有没有更新,若更新,则重新加载 -->
<configuration scan="true" scanPeriod="30 seconds" debug="true"> <!--
scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
  • 设置变量<property>

<configuration>
<!-- 定义日志文件的存储地址 -->
<property name="LOG_HOME" value="log"/>
<!-- 格式化输出 -->
<property name="LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5level][%t][%file:%line][%X{traceId}] -| %m%n"/>
</configuration>
  • <logger>与<root>

<logger>用来设置某一个包或者具体某一个类的日志打印级别、以及指定appender。<logger>可以包含零个或者多个<appender-ref>元素,标识这个appender将会添加到这个logger。

<root>也是<logger>元素,但它是根logger,只有一个level属性,因为它的name就是ROOT

<!-- name:必填,指定受此logger约束的某一个包或者具体的某一个类。这个name表示的是LoggerFactory.getLogger(XXX.class),XXX的包路径,包路径越少越是父级
level:用来设置打印级别,五个常用打印级别从低至高依次为TRACE、DEBUG、INFO、WARN、ERROR,如果未设置此级别,那么当前logger会继承上级的级别
additivity:是否向上级logger传递打印信息,默认为true -->
<logger name="com.example.iot" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="INFO-APPENDER"/>
<appender-ref ref="ERROR-APPENDER"/>
</logger> <!-- 没有配置<appender-ref>,表示此<logger>不会打印出任何信息 -->
<logger name="com.example.iot.demo1" level="DEBUG" additivity="true" /> <!-- 没有配置level,即继承父级的level,<logger>的父级为<root>,那么level=info -->
<logger name="com.example.iot.demo2" additivity="false" /> <!-- 控制台输出日志级别 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
  • <appender>

负责写日志的组件,有两个必要属性name和class

  1. 常用的控制台输出:ConsoleAppender
<!-- name指定<appender>的名称
class指定<appender>的全限定名 -->
<!-- 控制台输出 appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- <encoder>表示输出格式 -->
<pattern>${LOG_PATTERN}</pattern>
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
<charset>utf8</charset>
</encoder>
</appender>
  1. 常用的滚动记录文件:RollingFileAppender
<!-- INFO日志 appender: 按照每天生成日志文件 -->
<appender name="INFO-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
<file>${LOG_HOME}/iot-sdk-info.log</file>
<!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名:
%d:可以包含一个Java.text.SimpleDateFormat指定的时间格式
%i:自增数字
-->
<fileNamePattern>${LOG_HOME}/iot-sdk-info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件保存历史数量:控制保留的归档文件的最大数量,如果超出数量就删除旧文件 -->
<maxHistory>30</maxHistory>
<!-- 文件大小超过100MB归档 -->
<maxFileSize>100MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
  • <encoder>

encoder节点负责两件事情:

  1. 把日志信息转换为字节数组
  2. 把字节数组写到输出流

以下是一个常用配置:

<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 用来设置日志的输入格式,使用“%+转换符”的方式,如果要输出”%”则必须使用”\”进行转义。-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式化输出:https://logback.qos.ch/manual/layouts.html
%d 表示日期,
%thread 表示线程名,
%level 日志级别从左显示5个字符宽度,
%t 线程名
%file:%line 文件名+行号,
%m 日志消息,%n是换行符
%X{traceId}:自定义设置的参数,后面会说。
-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %t %file:%line %X{traceId} -| %m%n</pattern>
<charset>utf8</charset>
</encoder>
</appender>
  • <filter>

配合appender使用,<filter>是<appender>的一个子节点,表示在当前给到的日志级别下再进行一次过滤

  1. Level 级别过滤器

根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据onMath和onMismatch接收(ACCEPT)或拒绝(DENY)日志。

<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 只记录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>${LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
  1. ThresholdFilter: 临界值过滤器

将日志级别低于<level>的全部进行过滤。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。

<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 记录info级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>

自定义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<ILoggingEvent> {
@Override
protected void append(ILoggingEvent eventObject) {
// 打印格式化后的日志信息
System.out.println(eventObject.getFormattedMessage());
}
}

在配置文件中引入DemoAppender

<appender name="DEMO-APPENDER" class="com.example.iot.demo.DemoAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender> <logger name="com.example.iot.demo" level="DEBUG" additivity="true">
<appender-ref ref="DEMO-APPENDER"/>
</logger>

常用配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" debug="true">
<!-- logback的根节点 <configuration>的属性scan、scanPeriod、debug
scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
--> <!-- 定义日志文件的存储地址 -->
<property name="LOG_HOME" value="log"/>
<!-- 格式化输出:
%d 表示日期,
%thread 表示线程名,
%level 日志级别从左显示5个字符宽度,
%thread 线程名
%file:%line 文件名:行号,
%m 日志消息,
%n 换行符,
%X{traceId} 自定义设置的参数
%mdc 自定义参数
-->
<property name="LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%5level) -- [%15.15t] %cyan(%-23.23logger{23}) : %m%n"/> <!-- appender是configuration的子节点,是负责写日志的组件 -->
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
<charset>utf8</charset>
</encoder>
</appender> <!-- INFO日志 appender: 按照每天生成日志文件 -->
<appender name="INFO-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,记录info级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
<file>${LOG_HOME}/iot-sdk-info.log</file>
<!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名: %d可以包含一个Java.text.SimpleDateFormat指定的时间格式 -->
<fileNamePattern>${LOG_HOME}/iot-sdk-info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件保存历史数量:控制保留的归档文件的最大数量,如果超出数量就删除旧文件 -->
<maxHistory>30</maxHistory>
<!-- 文件大小超过100MB归档 -->
<maxFileSize>100MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender> <!-- 错误日志 appender: 按照每天生成日志文件 -->
<appender name="ERROR-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录error级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志名称 -->
<file>${LOG_HOME}/iot-sdk-error.log</file>
<append>true</append>
<!-- 每天生成一个日志文件,保存30天的日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名:按天回滚 daily -->
<fileNamePattern>${LOG_HOME}/iot-sdk-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件保留天数 -->
<maxHistory>30</maxHistory>
<!-- 文件大小超过100MB归档 -->
<maxFileSize>100MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender> <!-- 指定项目中某个包,当有日志操作行为时的日志记录级别
级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE
additivity=false 表示匹配之后,不再继续传递给其他的logger
-->
<logger name="com.example.iot" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="INFO-APPENDER"/>
<appender-ref ref="ERROR-APPENDER"/>
</logger> <!-- 控制台输出日志级别 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

参考:

  1. Logback documentation
  2. Java日志框架:logback详解

Logback配置解析的更多相关文章

  1. Spring Boot系列一:默认日志logback配置解析

    前言 今天来介绍下Spring Boot如何配置日志logback,我刚学习的时候,是带着下面几个问题来查资料的,你呢 如何引入日志? 日志输出格式以及输出方式如何配置? 代码中如何使用? 正文 Sp ...

  2. Spring Boot默认日志logback配置解析

    前言 今天来介绍下Spring Boot如何配置日志logback,我刚学习的时候,是带着下面几个问题来查资料的,你呢 如何引入日志? 日志输出格式以及输出方式如何配置? 代码中如何使用? 正文 Sp ...

  3. (转)Spring Boot干货系列:(七)默认日志logback配置解析

    转:http://tengj.top/2017/04/05/springboot7/ 前言 今天来介绍下Spring Boot如何配置日志logback,我刚学习的时候,是带着下面几个问题来查资料的, ...

  4. logback 配置解析

    http://www.cnblogs.com/cb0327/p/5759441.html 正文 回到顶部 1.根节点<configuration>包含的属性 scan: 当此属性设置为tr ...

  5. 一秒完成springboot与logback配置

    1. 一秒配置与效果 1.1 一秒配置 ​ spring boot中无须添加任何依赖,直接在resources文件夹下面新建logback.xml文件,将以下代码复制过去,配置完成,可以使用了. &l ...

  6. logback 配置

    logback 配置 logback的配置方式包括:编程配置.XML文件配置.Groovy文件配置.对于使用log4j的用户,还可以通过logback提供的工具( http://logback.qos ...

  7. logback配置详解

    本文转自:https://segmentfault.com/a/1190000008315137 概览 简单地说,Logback 是一个 Java 领域的日志框架.它被认为是 Log4J 的继承人.L ...

  8. logback -- 配置详解 -- 一 -- <configuration>及子节点

    附: logback.xml实例 logback -- 配置详解 -- 一 -- <configuration>及子节点 logback -- 配置详解 -- 二 -- <appen ...

  9. logback 配置详解(上)

    logback 配置详解(一)<configuration> and <logger> 一:根节点<configuration>包含的属性: scan: 当此属性设 ...

随机推荐

  1. 工具推荐:Backdoor-apk,安卓APK文件后门测试工具

    工具推荐:Backdoor-apk,安卓APK文件后门测试工具 Backdoor-apk可以看成是一个shell脚本程序,它简化了在Android APK文件中添加后门的过程.安全研究人员在使用该工具 ...

  2. XSS报警机制(前端防火墙:第二篇)

    XSS报警机制(前端防火墙:第二篇) 在第一章结尾的时候我就已经说了,这一章将会更详细的介绍前端防火墙的报警机制及代码.在一章出来后,有人会问为什么不直接防御,而是不防御报警呢.很简单,因为防御的话, ...

  3. centos 安装memcache服务后memcahce本机连接Permission

    自己手动在虚拟机下装了下memcache,整个过程真是充满波折,本身用php5.3安装memcache扩展就麻烦很多,无法通过yum直接安装,安装方法详见http://chenwei.me/blog/ ...

  4. XSS注入常用语句

    <script>alert('hello,gaga!');</script> //经典语句,哈哈! >"'><img src="javas ...

  5. python时序数据分析--以示例说明

    Python时间序列数据分析--以示例说明 标签(空格分隔): 时间序列数据分析 本文的内容主要来源于博客:本人做了适当的注释和补充. https://www.analyticsvidhya.com/ ...

  6. Python 使用 Redis 操作

    1.redis简介 redis是一款开源免费的高性能key-value数据库,redis特点: 支持更多的数据类型:字符串(String).列表(List).哈希(Map).数字(Int).集合(Se ...

  7. 编译器是如何实现32位整型的常量整数除法优化的?[C/C++]

    引子 在我之前的一篇文章[ ThoughtWorks代码挑战——FizzBuzzWhizz游戏 通用高速版(C/C++ & C#) ]里曾经提到过编译器在处理除数为常数的除法时,是有优化的,今 ...

  8. 【Android开发日记】之入门篇(九)——Android四大组件之ContentProvider

    数据源组件ContentProvider与其他组件不同,数据源组件并不包括特定的功能逻辑.它只是负责为应用提供数据访问的接口.Android内置的许多数据都是使用ContentProvider形式,供 ...

  9. 监听 手机back键和顶部的回退

    // 回退事件,监听 手机back键和顶部的回退 pushHistory(); window.addEventListener("popstate", function(e) { ...

  10. hash算法原理详解

    转载出处http://blog.csdn.net/tanggao1314/article/details/51457585 一.概念 哈希表就是一种以 键-值(key-indexed) 存储数据的结构 ...