logback学习

Posted xanlv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了logback学习相关的知识,希望对你有一定的参考价值。

Logback是一个开源日志组件
一 导入相关jar包
logback-core:是其它两个模块的基础模块;
logback-classic:直接实现了slf4j API,可以直接与slf4j记录系统轻松切换,因此加上log4j-over-slf4j的jar包;
log4j-over-slf4j
logback-access:用于访问模块与Servlet容器集成提供通过Http来访问日志的功能。

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
    <scope>compile</scope>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-access</artifactId>
  <version>1.2.3</version>
</dependency>

Logback默认配置的步骤::
尝试在 classpath下查找文件logback-test.xml;
如果文件不存在,则查找文件logback.xml;
如果两个文件都不存在,logback用BasicConfigurator自动对自己进行配置,这会导致记录输出到控制台。
二 Logback体系结构
Logger、Appender、Layout
logback建立在三个主要的类之上:Logger、Appender和Layout。

这三个组件协调工作,使开发者可以按照消息的类型和级别记录消息,还可以控制消息的输出格式和输出目的地。

Logger上下文
loggerback比System.out.println最重要的一个优点就是禁用特定语句的同时却不会妨碍其它的语句。

在logback-classic里,这种分类是是logger固有的,每个logger被关联到一个loggerContext即上下文

二 logback.xml一个根节点和五个常用子节点
根节点
上下文名称
变量定义
日志打印
获取日志
logger的根节点
根节点
有三个属性,均可以不设置。

scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。

<configuration scan="true" scanPeriod="60 seconds" debug="false">
      <!--其他配置省略-->
</configuration>


节点来设置上下文名称,每个logger都关联到logger上下文,默认上下文名称为default。但可以使设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
例如:


<configuration scan="true" scanPeriod="60 seconds" debug="false">
  <contextName>myAppName</contextName>
  <!--其他配置省略-->
</configuration>

节点
有两个属性,为键值对:

name:键作为引用,引用方式为$;
value:值作为引用的内容;

<property name="normal-pattern" value="[%dyyyy-MM-dd HH:mm:ss.SSS %5p %c:%L] [%thread] %m%n"/>

使用键值对实现代码复用,修改起来也方便,主要用于日志的输出格式与输出路径。

节点
用于获取日志。有一个必须节点和两个可选节点:

name:受此logger约束的包或者类,也就是日志来源;
level:设置打印级别,约束的包中日志级别高于此级别的才能被收集;若未设置则向上级继承;
addtivity:是否向上级loger传递打印信息。默认是true。
logger是命了名的实体,大小写敏感且遵循层次化的命名规则。

如果logger的名称带上一个点号是另外一个logger的名称前缀,那么前者就被称为后者的祖先。

l日志级别:TRACE< DEBUG < INFO < WARN < ERROR 特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。

如果logger没有被分配级别,那么将从最近的祖先那里继承级别。

包含零个或多个元素,标识这个appender将会添加到这个loger。

节点
也是一个节点,为根logger节点,只有一个level属性。


<configuration>  
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
    <!-- encoder 默认配置为PatternLayoutEncoder -->  
    <encoder>  
      <pattern>%dHH:mm:ss.SSS [%thread] %-5level %logger36 - %msg%n</pattern>  
    </encoder>  
  </appender>  

  <!-- logback为java中的包 -->  
  <logger name="logback"/>  

<!--logback.LogbackDemo:类的全路径 -->  
  <logger name="logback.LogbackDemo" level="INFO" additivity="false"> 
    <appender-ref ref="STDOUT"/> 
  </logger>  

  <root level="ERROR">            
    <appender-ref ref="STDOUT" />  
  </root>
</configuration>

节点
输出日志。有两个必要的属性:

name:指定appender的名称;
class:指定appender的类别,例如输出到控制台
1.ConsoleAppender:

将日志输出到控制台,有2个节点:

:对日志进行格式化;
:字符串 System.out 或者 System.err ,默认 System.out ; //一般直接省略

<configuration>
  <appender name="Console" class="ch.qos.logback.core.ConsoleAppender"> 
    <encoder> 
      <pattern>%-4relative [%thread] %-5level %logger35 - %msg %n</pattern> 
    </encoder> 
  </appender> 

  <root level="DEBUG"> 
    <appender-ref ref="STDOUT" /> 
  </root> 
</configuration>

2.RollingFileAppender:

滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。有7个节点:

:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。

:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。 // 一般使用默认值

:对记录事件进行格式化。 // 重要,指出了输出格式

:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 // 重要,指出了输出的文件夹

: 告知 RollingFileAppender 何时激活滚动。

:当为true时,日志会被安全的写入文件,即使其他的FileAppender也在向此文件做写入操作,效率低,默认是 false。 // 一般使用默认值

:过滤器,过滤不需要的日志。


滚动策略,常用有按时间滚动和按窗体大小滚动。

按时间滚动:每天生成一个日志文件,保存30天的日志文件

<configuration>  
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">  

    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
      <fileNamePattern>logFile.%dyyyy-MM-dd.log</fileNamePattern>  
      <maxHistory>30</maxHistory>   
    </rollingPolicy>  

    <encoder>  
      <pattern>%-4relative [%thread] %-5level %logger35 - %msg%n</pattern>  
    </encoder>  
  </appender>

  <root level="DEBUG">  
    <appender-ref ref="FILE" />
  </root>  
</configuration>

使用SizeAndTimeBasedFNATP 组件还可以按时间滚动的同时按大小滚动

<appender name="qmqConsumerAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <FileNamePattern>logFile.%dyyyy-MM-dd.log</FileNamePattern>
        <maxHistory>30</maxHistory>
        <!-- 按时间回滚的同时,按文件大小来回滚 -->
        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>100MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <--省略代码-->
</appender>

按文件大小滚动:当文件大于20MB时,生成新的日志文件。窗口大小是1到3,当保存了3个归档文件后,将覆盖最早的日志。

<configuration>  
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
    <file>test.log</file>  

    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">  
      <fileNamePattern>tests.%i.log.zip</fileNamePattern>  
      <minIndex>1</minIndex>  
      <maxIndex>3</maxIndex>  
    </rollingPolicy>  

    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">  
      <maxFileSize>5MB</maxFileSize>  
    </triggeringPolicy>  
    <encoder>  
      <pattern>%-4relative [%thread] %-5level %logger35 - %msg%n</pattern>  
    </encoder>  
  </appender>  

  <root level="DEBUG">  
    <appender-ref ref="FILE" />  
  </root>  
</configuration>

负责两件事,一是把日志信息转换成字节数组,二是把字节数组写入到输出流。

<encoder>  
   <pattern>[%dyyyy-MM-dd HH:mm:ss.SSS %5p %c:%L] [%thread] [taskNo=%XtaskNo] QTraceId[%Xqtraceid] %m%n"</pattern>  
</encoder>
//  %dyyyy-MM-dd HH:mm:ss.SSS     日志输出时当前时间
//  %5p         记录事件的级别,最多5个字符
//  %c          日志名称(通常是构造函数的参数)
//  %L          输出执行记录请求的行号
//  %thread     输出产生记录事件的线程名
//  %Xqtraceid        输出mdc.put();中键为qtraceid的值。

//[2018-04-25 16:41:50.459 ERROR com.qunar.flight.shylock.service.impl.LogService:158] [main] [taskNo=] QTraceId[] 画图成功了

转换符与修饰符

#模式符号               - 用途(附加说明);可选附加选项(附加选项说明)
#  %c                   - 日志名称(通常是构造函数的参数);数字("ab.cd.e" 的名称使用 %c3 会输出 "a.c.e")
#  %C                   - 调用者的类名(速度慢,不推荐使用);数字(同上)
#  %d                   - 日志时间;SimpleDateFormat所能使用的格式
#  %F                   - 调用者的文件名(速度极慢,不推荐使用)
#  %l                   - 调用者的函数名、文件名、行号(速度极其极其慢,不推荐使用)
#  %L                   - 调用者的行号(速度极慢,不推荐使用)
#  %m %msg %message     - 日志内容
#  %M                   - 调用者的函数名(速度极慢,不推荐使用)
#  %n                   - 换行符号
#  %p %le %level        - 日志优先级别(DEBUG, INFO, WARN, ERROR)
#  %r %relative         - 输出日志所用毫秒数
#  %t %thread           - 调用者的进程名          
#  %Xkey              - 输出mdc.put()中键值对的值。

#模式修饰符      - 对齐        - 最小长度      - 最大长度     
# %20c              右           20              ~
# %-20c             左           20              ~
# %.30c             ~           ~               30
# %20.30c           右           20              30
# %-20.30c          左           20              30

MDC
mdc是Mapped Diagnostic Context的缩写,翻译为映射诊断环境。给客户端的每一个记录添加一个唯一戳(uniquely stamp)。用户把环境信息放入MDC。
MDC类只有静态方法,是基于每个线程进行管理的,开发者会向MDC插入恰当的环境信息,比如客户端的id、ip地址、请求参数等。

看成是一个与当前线程绑定的哈希表,可以往其中添加键值对。

// 基本用法
MDC.put("userId",1000);

// 高级用法 服务器的每个线程都有自己独立的MDC戳
MDC.put("qtraceid", QTraceClientGetter.getClient().getCurrentTraceId());

常规过滤器:自定义过滤器、级别过滤器、临界值过滤器、求职过滤器;

TurboFilters:重复消息过滤器;

过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一。返回DENY,日志将立即被抛弃不再经过其他过滤器;返回NEUTRAL,有序列表里的下个过滤器过接着处理日志;返回ACCEPT,日志会被立即处理,不再经过剩余过滤器。多个过滤器时,按照配置顺序执行。

自定义过滤器

创建:需要继承Fliter抽象类并重写decide()方法。

使用:

package com.qunar.flight.shylock.utils;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
/**
 * @Author: fanghao
 * @Description:
 * @Date: Create in 16:14 2018/4/26
 * @Modified By:
 */
public class SampleFilter extends Filter<ILoggingEvent> 
    @Override
    public FilterReply decide(ILoggingEvent event) 
        if (event.getMessage().contains("aaaa")) 
            return FilterReply.ACCEPT;
         else 
            return FilterReply.DENY;
        
    


// 使用自定义过滤器
<configuration>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="com.qunar.flight.shylock.utils.SampleFilter"/>
        <--省略代码-->
    </appender>
</configuration>

LeverFilter

级别过滤器,根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。有以下子节点:

:设置过滤级别

:用于配置符合过滤条件的操作

:用于配置不符合过滤条件的操作

例如:将过滤器的日志级别配置为INFO,所有INFO级别的日志交给appender处理,非INFO级别的日志,被过滤掉。

<configuration>  
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">  
    <filter class="ch.qos.logback.classic.filter.LevelFilter">  
      <level>INFO</level>  
      <onMatch>ACCEPT</onMatch>  
      <onMismatch>DENY</onMismatch>  
    </filter>  
    <--省略代码-->
</configuration>

ThresholdFilter

临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。

例如:过滤掉所有低于INFO级别的日志。

<configuration>  
  <appender name="CONSOLE"   class="ch.qos.logback.core.ConsoleAppender">  
    <!-- 过滤掉 TRACE 和 DEBUG 级别的日志-->  
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">  
      <level>INFO</level>  
    </filter>  
    <--省略代码-->
</configuration>

EvaluatorFilter

需要添加一个jar包 janino

<dependency>
  <groupId>org.codehaus.janino</groupId>
  <artifactId>janino</artifactId>
  <version>3.0.8</version>
</dependency>

求值过滤器,含有一个节点:

鉴别器,常用的鉴别器是JaninoEventEvaluato,也是默认的鉴别器,它以任意的java布尔值表达式作为求值条件,求值条件在配置文件解释过成功被动态编译,布尔值表达式返回true就表示符合过滤条件。evaluator有个子标签,用于配置求值条件。

滤去消息中不含”billing”字符串的日志


<configuration>  

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">        
      <evaluator> <!-- 默认为 ch.qos.logback.classic.boolex.JaninoEventEvaluator -->  
        <expression>return message.contains("billing");</expression>   // message 是日志的原始消息,为java代码其它使用可见中文手册
      </evaluator>  
      <OnMatch>ACCEPT </OnMatch> 
      <OnMismatch>DENY</OnMismatch> 
    </filter>  
    <encoder>  
      <pattern>  
        %-4relative [%thread] %-5level %logger - %msg%n  
      </pattern>  
    </encoder>  
  </appender>  

  <root level="INFO">  
    <appender-ref ref="STDOUT" />  
  </root>  
</configuration>

Logback-classic会自动帮我们导出logging event的属性到evaluation 表达式中,所以我们可以直接使用以下属性判断:

三 其它的Appender
FileAppender:把日志添加到文件,非滚动。功能少,使用少;
DBAppender:把日志事件写入数据库;
SiftingAppender:它可以用来分割日志文件根据任何一个给定的运行参数。如,SiftingAppender能够区别日志事件跟进用户的Session,然后每个用户会有一个日志文件;
SMTPAppender:当输出的日志满足条件时,就像某邮箱发送日志通知;

<?xml version="1.0" encoding="UTF-8"?>
<!--
    off->trace->debug->info->warn->error
    scan:
        当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
    scanPeriod:
        设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
    debug:
        当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<configuration scan="true" scanPeriod="60 seconds" debug="true">
    <!--
        这里是属性,我们可以定义很多的属性,然后用这些健值对来代替直接的pattern string
        使用这种方式能够更好的统一管理不同的APPENDER
    -->
    <property name="log-name" value="homework-log"/>

    <!--该段表示从mail.properties文件读取配置文件,该文件路径跟SRC目录齐平-->
<!--
    <property file="logbackconf/mail/mail.properties" />
-->

    <contextName>$log-name</contextName>
    <!-- 要注意与property的区别 -->
    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>

    <!--
        每个logger都关联到logger上下文,默认上下文名称为“default”。
        但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
    -->
    <!--
        <contextName>homework-log</contextName>
    -->
    <!--appender包含如下的子标签:
        <encoder>
        <file>
        <rollingPolicy>
        <filter>
        <triggeringPolicy>
        等
    -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 这个appender是最基础,也是最重要的了,主要我们用来在控制台打印信息  -->
        <encoder>
            <pattern>%-4relative [%t] %-5level %logger35 - %file %class %m%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--
        TimeBasedRollingPolicy
        FixedWindowRollingPolicy
            根据固定窗口算法重命名文件的滚动策略。有以下子节点:
            <minIndex>:窗口索引最小值
            <maxIndex>:窗口索引最大值,当用户指定的窗口过大时,会自动将窗口设置为12。
            <fileNamePattern >:必须包含“%i”例如,假设最小值和最大值分别为1和2,
            命名模式为 mylog%i.log,会产生归档文件mylog1.log和mylog2.log。
            还可以指定文件压缩选项,例如,mylog%i.log.gz 或者 没有log%i.log.zip
        <triggeringPolicy> 告诉RollingFileAppender什么时候激活滚动
            SizeBasedTriggeringPolicy: 查看当前活动文件的大小,如果超过指定大小会告知
            RollingFileAppender :触发当前活动文件滚动。只有一个节点:
            <maxFileSize>:这是活动文件的大小,默认值是10MB。
    -->
    <appender name="preAuthorization.warning" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>$catalina.home/logs/b2c.preAuthorization.warning.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>$catalina.home/logs/b2c.preAuthorization.warning.log.%dyyyy-MM-dd</fileNamePattern>
            <append>true</append>
            <maxHistory>30</maxHistory>
            <!--月?日?要看你的fileNamePattern-->
        </rollingPolicy>


        <!-- 关于filter -->
        <!--
            过滤内容
            过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一。
            返回DENY,日志将立即被抛弃不再经过其他过滤器;
            返回NEUTRAL,有序列表里的下个过滤器过接着处理日志;
            返回ACCEPT,日志会被立即处理,不再经过剩余过滤器
        LevelFilter
            <level>:设置过滤级别
            <onMatch>:用于配置符合过滤条件的操作
            <onMismatch>:用于配置不符合过滤条件的操作
        ThresholdFilter:
            临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;
            当日志级别低于临界值时,日志会被拒绝。
        EvaluatorFilter:
            求值过滤器,评估、鉴别日志是否符合指定条件。需要额外的两个JAR包,
            commons-compiler.jar和janino.jar有以下子节点:
            <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
                <evaluator>  默认为 ch.qos.logback.classic.boolex.JaninoEventEvaluator
                    <expression>return message.contains("billing");</expression>
                </evaluator>
                <OnMatch>ACCEPT </OnMatch>
                <OnMismatch>DENY</OnMismatch>
            </filter>
        -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>WARN</level>
        </filter>
        <!--必须匹配到INFO才可以-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>%-4relative [%t] %-5level %logger35 - %file %class %m%n</pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>test.log</file>

        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>tests.%i.log.zip</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>300000</maxIndex>
        </rollingPolicy>

        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>5MB</maxFileSize>
        </triggeringPolicy>
        <encoder>
            <pattern>%-4relative [%t] %-5level %logger35 - %file %class %m%n</pattern>
        </encoder>
    </appender>
    <!--
        另外还有SocketAppender、SMTPAppender、DBAppender、SyslogAppender、SiftingAppender,
        并不常用,这些就不在这里讲解了,大家可以参考官方文档。当然大家可以编写自己的Appender。
    -->

    <!--
        encoder
        负责两件事,一是把日志信息转换成字节数组,二是把字节数组写入到输出流。
        重要的如下:
            (1)%c   输出日志的logger名,可有一个整形参数,功能是缩短logger名,设置为0表示只输入logger最右边点符号之后的字符串。
                    Conversion specifier Logger name Result
            (2)%class  输出执行记录请求的调用者的全限定名。参数与上面的一样。尽量避免使用,除非执行速度不造成任何问题。
            (3)%contextName 输出上下文名称。
            (4)%date %ddd MMM yyyy ;HH:mm:ss.SSS
            (5)%file    输出执行记录请求的java源文件名。尽量避免使用,除非执行速度不造成任何问题。
            (6)m / msg / message 输出应用程序提供的信息。logger.info(xxx);xxx信息
            (7)M / method   输出执行日志请求的方法名。尽量避免使用,除非执行速度不造成任何问题。
            (8)n    输出平台先关的分行符“\\n”或者“\\r\\n”。
            (9)p / le / level   输出日志级别。
            (10)r / relative    输出从程序启动到创建日志记录的时间,单位是毫秒
            (11)t / thread  输出产生日志的线程名。
            (12)replace(p )r, t   p 为日志内容,r 是正则表达式,将p 中符合r 的内容替换为t 。例如, "%replace(%msg)'\\s', ''"
            off trace debug info warn error
    -->
    <!--
        additivity:        是否向上级loger传递打印信息。默认是true。
        name: 限定类名字
        level
    -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoder 默认配置为PatternLayoutEncoder -->
        <encoder>
            <pattern>%-4relative [%t] %-5level %logger35 - %file %class %m%n %M $bySecond</pattern>
        </encoder>
    </appender>
    <!-- smtp -->
    <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
        <smtpHost>mail.corp.qunar.com</smtpHost>
        <to>kris.zhang@qunar.com</to>
        <!-- 可以定义更多的发送目标 -->
        <!--
            <to>cody.zhang@qunar.com</to>
            <to>bort.zhang@qunar.com</to>
            <to>weiqiang.yuan@qunar.com</to>
            <to>junhua.lu@qunar.com</to>-->
        <!--
-->
        <from>kris.zhang@qunar.com</from>
        <subject>报警邮件</subject>
        <!-- 采用html渲染方式,可以自定义CSS -->
        <layout class="ch.qos.logback.classic.html.HTMLLayout">
            <!--不写,采用默认格式 -->
            <pattern>%date%level%thread%message</pattern>
        </layout>
        <!--
                可以使用自定义格式
            <layout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%date %-5level %logger35 - %message%n</pattern>
            </layout>
        -->
        <!-- 这里可以用来设定缓冲区 -->
        <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
            <!-- send just one log entry per email -->
            <bufferSize>64</bufferSize>
        </cyclicBufferTracker>
<!--
        可以自定义出触发方式,默认的是遇到error警报就进行触发
        <evaluator class="chapters.appenders.mail.CounterBasedEvaluator" />
        public class CounterBasedEvaluator extends ContextAwareBase implements EventEvaluator 

              static int LIMIT = 1024;
              int counter = 0;
              String name;

              public boolean evaluate(Object event) throws NullPointerException,
                  EvaluationException 
                counter++;

                if (counter == LIMIT) 
                  counter = 0;

                  return true;
                 else 
                  return false;
                
              
        
-->
    </appender>

    <!-- 程序中使用logger有两种方式:
    (1)直接使用logger的名字来进行引用如下:
    private final static Logger logger = LoggerFactory.getLogger("loggerName");
    比如此时有一个logger:
    <logger name="loggerName" level="INFO" additivity="trues">
        <appender-ref ref="STDOUT"/>
    </logger>
    那么就会使用该logger
    (2)使用class.getName(),他会根据类的全限定名!注意是全限定名。比如此时有一个logger
        private final static Logger logger = LoggerFactory.getLogger(MyClass.class);
        比如MyClass是:com.qunar.fresh.MyClass
        那么
        com
        com.qunar
        com.qunar.fresh
        都是他的父亲logger,都可以进行匹配。
        com.qunar.fresh.MyClass则是对应的logger。
        因此有如下:
        果additivity==true,那么会打印多次(logger会传递给父亲。
        最后的祖宗,就是root。如果什么都找不到,则会匹配root
    -->
    <logger name="com" level="WARN" additivity="false">
        <!-- 可以添加多个appender-ref,他找到对应的appender-->
        <appender-ref ref="EMAIL"/>
        <appender-ref ref="console"/>
    </logger>

    <!--
        项目中如果调式数据库,则可以打开这个注释,不过要注意
        对应的日志太多了!!!
    -->
    <!--
    <logger name="java.sql.Connection" level="DEBUG" />
    <logger name="java.sql.Statement" level="DEBUG" />
    <logger name="java.sql.PreparedStatement" level="DEBUG" />
    <logger name="java.sql.ResultSet" level="DEBUG" />
    -->
    <!--
        root中的level非常重要,他具有总控的功,如他设定为error那么无论子logger设定什么,只有level为error的
        才可以打印出来,默认为debug,有时候你打不出日志,检查root设定的对不对。
    -->
    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="EMAIL"/>
    </root>
</configuration>

<!--
    更详细的清参考源代码和官方文档:
    http://logback.qos.ch/documentation.html
-->
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>
    <SMTP name="Mail" subject="Error Log" to="XXXXX@qq.com" from="XXXXX@163.com" replyTo="XXXXX@163.com"
          smtpProtocol="smtp" smtpHost="smtp.163.com" smtpPort="25" bufferSize="50" smtpDebug="false"
          smtpPassword="password" smtpUsername="XXXXX@163.com">
    </SMTP>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Mail"/>
    </Root>
  </Loggers>
</Configuration>

https://wenku.baidu.com/view/71a056eb0975f46527d3e138.html?pn=50

以上是关于logback学习的主要内容,如果未能解决你的问题,请参考以下文章

logback学习

学习logback配置的验证学到了哪些东西?

logback学习

logback学习

logback logback.xml 常用配置详解

logback 配置详解