2021-01-07

本文详细介绍了日志系统的重要性,包括日志级别概念,如SEVERE、WARNING到TRACE的区别。还探讨了不同日志框架的选择,如logback和log4j的比较,以及如何在SpringBoot中灵活配置日志,包括彩色输出和自定义过滤规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

日志的作用
在本地调试的时候,我们可以通过断点等方式进行调试、但是当系统在测试环境或者被部署到生产环境中,我们无法通过断点进行调试。而且很多时候我们都是等问题发生之后才能获知问题的出现。这个时候我们需要一个可靠的方式记录问题发生的情况。日志系统虽然不能实现什么业务、也无法提高系统的性能。但是日志是保证服务可靠的重要功能。

日志的基础知识
日志级别
假如根据java.util.logging.Level的描述,日志级别被分为 SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST
而我们去看org.slf4j.event.Level的描述,日志级别被分为 ERROR、WARN、INFO、DEBUG、TRACE。
两者对应的关系主要是

slf4j logging 描述
error SEVERE 程序运行遇见错误,并且此任务不能通过业务进行处理,需要关注并且及时处理 。
warn WARNING 返回预期之外的结果,虽然不影响业务执行但是需要被关注。
info INFO 记录程序运行时的请求内容、返回内容等一些调试时候需要的信息。
info CONFIG 记录系统配置等内容,方便调试使用。
debug FINE 调试过程中使用该级别的日志发现问题,排除故障。
debug FINER 调试过程中使用该级别的日志发现问题,排除故障。
trace FINEST 调试过程中使用该级别的日志发现问题,排除故障。
日志框架的选择
日志用来记录程序运行过程中的信息的功能。因为需要频繁的收集数据,日志系统难免会对我们系统生产影响,所以选择不同的日志框架会有不同的结果。

我们之前和现在接触的日志框架主要有。JUL、JCL、logback、log4j、log4j2、slf4j。

框架 简介
log4j Log4j是一个基于Java的日志记录工具,而在高并发情况下性能低下,现在一般使用log4j2或logback。隶属于Apache基金会
log4j2 一款Log4j的升级产品,然而Log4j 2并不兼容Log4j 1。隶属于Apache基金会
JCL (门面模式)一套Java日志接口,之前叫Jakarta Commons Logging,后更名为Commons Logging。隶属于Apache基金会
JUL 自Java1.4以来的官方日志实现,因为原生框架在写组件的时候可以避免过度依赖其他日志系统
slf4j (门面模式)类似于Commons Logging,本身并无日志的实现,需要其他日志框架的实现。
logback (Spring Boot默认)slf4j阵营的一套日志框架的实现,Logback必须配合Slf4j使用
日志的配置
日志的配置
SpringMVC
虽然现在JAVA项目多数都是使用Spring Boot了,但是一些老旧项目还是在使用着传统的MVC。而MVC配置日志参数的方式

log4jConfigLocation classpath:log4j.properties org.springframework.web.util.Log4jConfigListener 1 2 3 4 5 6 7 8 Spring Boot Spring Boot假如不需要自定义参数配置,可以直接在application.yml中进行参数配置

logging:

日志的等级,对不同包可以采用不同的等级

比如如下配置就是将root的等级设置为info,将com.learn设置为debug

level: {root: info,com.learn: debug}

file是设置日志的输出的路径file和path属性只能选一个,不能同时存在

file: log.log
1
2
3
4
5
6
Spring Boot 默认的配置名称
但是实际中我们开发可能会使用更加复杂的配置这个时候我们可以将日志配置写在一个单独的文件中。Spring Boot对于这些文件的名称有默认的规定

日志框架默认的文件名称

日志框架 默认文件名(只有一个文件起作用)
Logback logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
Log4j log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
Log4j2 log4j2-spring.xml, log4j2.xml
JDK (Java Util Logging) logging.properties
日志详细配置
我们下面主要介绍的基于logback使用时候的配置

标签解释
现在我们看一个简单的日志配置

<?xml version="1.0" encoding="UTF-8"?>
<!-- 定义一个日滚动(每天生成一份)的日志文件 -->
<appender name="file_out" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--日志文件输出的文件名-->
        <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
        <!--日志文件保留天数-->
        <MaxHistory>30</MaxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符,编码为UTF-8-->
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>

    <!--日志文件最大的大小-->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <MaxFileSize>10MB</MaxFileSize>
    </triggeringPolicy>
</appender>

<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx"
                converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
          value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
<!-- Console 输出设置 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        <charset>utf8</charset>
    </encoder>
</appender>


<!-- 定义日志全局最低输出级别,同时向控制台和日滚动文件输出 -->
<root level="INFO">
    <appender-ref ref="console" />
    <appender-ref ref="console_out" />
</root>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 我们来解释下里面标签的作用

标签 属性 描述
configuration 日志配置的根标签
scan 设置配置重载,当为true的时候,配置的变化会被日志框架重载
scanPeriod 设置监测配置变更的时间
debug debug模式,为true的时候还会打印logback 内部日志
conversionRule 彩色日志依赖的渲染类
conversionWord 渲染类的名称
converterClass 此配置对应的类地址
property 自定义的变量,此参数可以在下面的配置中使用,注意数据加载是有顺序的,参数配置需要在使用它的地方之前完成
name 参数名称
value 参数值
appender 设置日志输出的子节点
name 子节点名称
class 对应的类,比如ch.qos.logback.core.rolling.RollingFileAppender为文件输出,ch.qos.logback.core.ConsoleAppender为控制台输出
layout 配置控制台显示格式
class 格式配置的处理类
filter 过滤方法的配置
class 使用的过滤器
evaluator 过滤器使用ch.qos.logback.core.boolex.EventEvaluator 完成不同逻辑的拦截处理,而evaluator就是EventEvaluator
class 对应的EventEvaluator类
onMatch 当过滤器匹配的时候需要进行的操作 DENY:拒绝操作, NEUTRAL:此过滤器不处理交由下一个过滤器处理, ACCEPT:同意操作
onMismatch 当过滤器不匹配的时候需要进行的操作 DENY:拒绝操作, NEUTRAL:此过滤器不处理交由下一个过滤器处理, ACCEPT:同意操作
rollingPolicy 循环策略
class 循环策略对应的处理类
FileNamePattern 设置日志文件输出的文件名
MaxHistory 设置日志文件保留天数
encoder 用来设置日志的输出格式
pattern 设置输出格式的字符串
charset 设置字符集
triggeringPolicy 循环策略的触发器
class 触发器对应的处理类
MaxFileSize 文件大小的设置
root 根节点,可以通过appender-ref将子节点配置合并进来
level 日志级别基础级别的设置,可选参数TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
appender-ref 引入子节点的操作
ref 子节点的地址(子节点名称)
日志输入格式

格式 说明
%d{HH:mm:ss.SSS} 日志输出时间
%thread 输出日志的进程名字,这在Web应用以及异步任务处理中很有用
%-5level 日志级别,并且使用5个字符靠左对齐
%logger 日志输出者的名字
%msg 日志消息
%n 平台的换行符
配置控制台输出
下面一个简单的控制台输出配置

<!--demo:输出到控制台 ConsoleAppender-->
<appender name="consoleLog1" class="ch.qos.logback.core.ConsoleAppender">
    <!--展示格式 layout-->
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>%d -1 %msg%n</pattern>
    </layout>
</appender>

1
2
3
4
5
6
7
配置说明
就这就是一个简单的控制台输入的配置

文件输出配置
下面一个简单的日志文件输出配置

<!--demo:输出到文件 ConsoleAppender-->
<appender name="consoleLog2" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高,
        所以我们使用下面的策略,可以避免输出 Error 的日志-->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <!--过滤 Error-->
        <level>ERROR</level>
        <!--匹配到就禁止-->
        <onMatch>DENY</onMatch>
        <!--没有匹配到就允许-->
        <onMismatch>ACCEPT</onMismatch>
    </filter>
    <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
        如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
        的日志改名为今天的日期。即,<File> 的日志都是当天的。
    -->
    <File>${logback.dir}/info.${logback.name}.log</File>
    <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
        <FileNamePattern>${logback.dir}/info.${logback.name}.%d{yyyy-MM-dd}.log</FileNamePattern>
        <!--只保留最近90天的日志-->
        <maxHistory>90</maxHistory>
        <!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
        <totalSizeCap>1GB</totalSizeCap>
    </rollingPolicy>
    <!--日志输出编码格式化-->
    <encoder>
        <charset>UTF-8</charset>
        <pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
    </encoder>
</appender>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
控制台彩色输出配置










${CONSOLE_LOG_PATTERN}
utf8


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
带过滤器的配置
有的时候我们想根据不同的包或者不同的错误内容、不同的错误级别实现不同的日志输出方式,我们可以使用日志系统中的过滤器。

之前文件日志配置中一段内容
在上面的例子上,我们其实已经使用了系统自带的过滤器配置。下面的内容就将Error级别从日志系统剔除出去了。这样我们就实现了虽然基础级别设置的为INFO,但是还是可以不输出Error

    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <!--过滤 Error-->
        <level>ERROR</level>
        <!--匹配到就禁止-->
        <onMatch>DENY</onMatch>
        <!--没有匹配到就允许-->
        <onMismatch>ACCEPT</onMismatch>
    </filter>

1
2
3
4
5
6
7
8
点开ch.qos.logback.classic.filter.LevelFilter我们可以看到这个类的内部逻辑

可以看到日志中配置的过滤器器

public class LevelFilter extends AbstractMatcherFilter {
Level level;

public LevelFilter() {
}

public FilterReply decide(ILoggingEvent event) {
    if (!this.isStarted()) {
        return FilterReply.NEUTRAL;
    } else {
        return event.getLevel().equals(this.level) ? this.onMatch : this.onMismatch;
    }
}

public void setLevel(Level level) {
    this.level = level;
}

public void start() {
    if (this.level != null) {
        super.start();
    }

}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
我们追踪父类,会发现其实它实现了接口ch.qos.logback.core.filter.Filter,那么我们知道filter标签中,我们可以通过配置实现Filter的类来实现自己的逻辑

public abstract class Filter extends ContextAwareBase implements LifeCycle {
private String name;
boolean start = false;

public Filter() {
}

public void start() {
    this.start = true;
}

public boolean isStarted() {
    return this.start;
}

public void stop() {
    this.start = false;
}

public abstract FilterReply decide(E var1);

public String getName() {
    return this.name;
}

public void setName(String name) {
    this.name = name;
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
所以这样我们可以尝试使用自己的过滤器,实现自己的日志逻辑。在filter配置ch.qos.logback.core.filter.Filter的实现类,比如ch.qos.logback.core.filter.EvaluatorFilter

现在我们有了这样一个需求,所有controller包的异常使用controller的配置,我们就可以使用下面的配置

<!--controller的特殊打印-->
<appender name="controller" class="ch.qos.logback.core.ConsoleAppender">
    <!-- 在日滚动文件中,强制只保存错误INFO级别以上的信息 -->
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator class="dai.samples.log.config.MyEventEvaluator">
            <page>dai.samples.log.controller.*</page>
        </evaluator>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
    <!--展示格式 layout-->
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>[controller] - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
    </layout>
</appender>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
我们使用ch.qos.logback.core.filter.EvaluatorFilter过滤器,其使用的匹配规则是我们自定义的dai.samples.log.config.MyEventEvaluator,其内部逻辑为

public class MyEventEvaluator extends EventEvaluatorBase {

private String page;

/**
 * 进行参数匹配
 */
@Override 
public boolean evaluate(ILoggingEvent event)
        throws NullPointerException, EvaluationException {
    String loggerName = event.getLoggerName();
    String substring = page.substring(0, page.indexOf(".*"));
    return loggerName.startsWith(substring);
}

public String getPage() {
    return page;
}

public void setPage(String page) {
    this.page = page;
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
一个配置demo
现在我们将上面内容汇总汇总到一起写一个配置。

<?xml version="1.0" encoding="UTF-8"?>
<appender name="all" class="ch.qos.logback.core.ConsoleAppender">
    <!--展示格式 layout-->
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
    </layout>
</appender>

<!--controller的特殊打印-->
<appender name="controller" class="ch.qos.logback.core.ConsoleAppender">
    <!-- 在日滚动文件中,强制只保存错误INFO级别以上的信息 -->
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator class="dai.samples.log.config.MyEventEvaluator">
            <page>dai.samples.log.controller.*</page>
        </evaluator>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
    <!--展示格式 layout-->
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>[controller] - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
    </layout>
</appender>

<!--service的特殊打印-->
<appender name="service" class="ch.qos.logback.core.ConsoleAppender">
    <!-- 在日滚动文件中,强制只保存错误INFO级别以上的信息 -->
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator class="dai.samples.log.config.MyEventEvaluator">
            <page>dai.samples.log.service.*</page>
        </evaluator>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
    <!--展示格式 layout-->
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>[service] - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
    </layout>
</appender>


<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="INFO_HOME" value="/log/info" />
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="ERROR_HOME" value="/log/error" />
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="WARN_HOME" value="/log/warn" />

<!-- 定义一个日滚动(每天生成一份)的日志文件 -->
<appender name="error_out" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--日志文件输出的文件名-->
        <FileNamePattern>${ERROR_HOME}/learn.log.%d{yyyy-MM-dd}.log</FileNamePattern>
        <!--日志文件保留天数-->
        <MaxHistory>30</MaxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符,编码为UTF-8-->
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <!--过滤 Error-->
        <level>ERROR</level>
    </filter>
    <!--日志文件最大的大小-->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <MaxFileSize>10MB</MaxFileSize>
    </triggeringPolicy>
</appender>

<!-- 定义一个日滚动(每天生成一份)的日志文件 -->
<appender name="info_out" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--日志文件输出的文件名-->
        <FileNamePattern>${INFO_HOME}/learn.log.%d{yyyy-MM-dd}.log</FileNamePattern>
        <!--日志文件保留天数-->
        <MaxHistory>30</MaxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符,编码为UTF-8-->
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <!--过滤 Error-->
        <level>INFO</level>
    </filter>
    <!--日志文件最大的大小-->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <MaxFileSize>10MB</MaxFileSize>
    </triggeringPolicy>
</appender>

<!-- 定义一个日滚动(每天生成一份)的日志文件 -->
<appender name="warn_out" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--日志文件输出的文件名-->
        <FileNamePattern>${WARN_HOME}/learn.log.%d{yyyy-MM-dd}.log</FileNamePattern>
        <!--日志文件保留天数-->
        <MaxHistory>30</MaxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符,编码为UTF-8-->
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <!--过滤 Error-->
        <level>WARN</level>
    </filter>
    <!--日志文件最大的大小-->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <MaxFileSize>10MB</MaxFileSize>
    </triggeringPolicy>
</appender>

<root level="INFO">
    <!--添加到这个log的appender-->
    <appender-ref ref="all"/>
    <!--添加到这个log的appender-->
    <appender-ref ref="controller"/>
    <!--添加到这个log的appender-->
    <appender-ref ref="service"/>
    <!--添加到这个log的appender-->
    <appender-ref ref="error_out"/>
    <!--添加到这个log的appender-->
    <appender-ref ref="info_out"/>
    <!--添加到这个log的appender-->
    <appender-ref ref="warn_out"/>
</root>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 配置效果 控制台输出 控制台输出使用了彩色输出

<appender name="all" class="ch.qos.logback.core.ConsoleAppender">
    <!--展示格式 layout-->
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
    </layout>
</appender>

1
2
3
4
5
6
7
8
9
10
我们请求一个接口会输出下面内容

在这里插入图片描述

自定义的输出
我们可以看到有两个不是彩色的输出[service]、[controller]
这是因为我们配置中针对controller和service进行了特殊的输出配置

<!--controller的特殊打印-->
<appender name="controller" class="ch.qos.logback.core.ConsoleAppender">
    <!-- 在日滚动文件中,强制只保存错误INFO级别以上的信息 -->
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator class="dai.samples.log.config.MyEventEvaluator">
            <page>dai.samples.log.controller.*</page>
        </evaluator>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
    <!--展示格式 layout-->
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>[controller] - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
    </layout>
</appender>

<!--service的特殊打印-->
<appender name="service" class="ch.qos.logback.core.ConsoleAppender">
    <!-- 在日滚动文件中,强制只保存错误INFO级别以上的信息 -->
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator class="dai.samples.log.config.MyEventEvaluator">
            <page>dai.samples.log.service.*</page>
        </evaluator>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
    <!--展示格式 layout-->
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>[service] - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
    </layout>
</appender>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
文件输出

<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="INFO_HOME" value="/log/info" />

<!-- 定义一个日滚动(每天生成一份)的日志文件 -->
<appender name="info_out" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--日志文件输出的文件名-->
        <FileNamePattern>${INFO_HOME}/learn.log.%d{yyyy-MM-dd}.log</FileNamePattern>
        <!--日志文件保留天数-->
        <MaxHistory>30</MaxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符,编码为UTF-8-->
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <!--过滤 Error-->
        <level>INFO</level>
    </filter>
    <!--日志文件最大的大小-->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <MaxFileSize>10MB</MaxFileSize>
    </triggeringPolicy>
</appender>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
配置中根据不同的日志级别输出到不同的文件中,文件地址为/log/info,/log/error,/log/warn

实际中日志也才对应的文件中生成了

在这里插入图片描述

文件中日志输出的格式,并不和控制台一样。因为我们为文件输出设置了自己的格式

%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 1 2 3 2019-08-05 21:18:39.689 [http-nio-8000-exec-1] INFO o.a.c.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet' 2019-08-05 21:18:39.690 [http-nio-8000-exec-1] INFO org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started 2019-08-05 21:18:39.706 [http-nio-8000-exec-1] INFO org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 16 ms 2019-08-05 21:18:39.733 [http-nio-8000-exec-1] INFO dai.samples.log.service.LogService - INFO的日志输出:info 2019-08-05 21:18:39.733 [http-nio-8000-exec-1] INFO dai.samples.log.controller.LogController - INFO的日志输出:info

1
2
3
4
5
6
本篇文章涉及的源码下载地址:https://gitee.com/daifyutils/springboot-samples

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值