日志的作用
在本地调试的时候,我们可以通过断点等方式进行调试、但是当系统在测试环境或者被部署到生产环境中,我们无法通过断点进行调试。而且很多时候我们都是等问题发生之后才能获知问题的出现。这个时候我们需要一个可靠的方式记录问题发生的情况。日志系统虽然不能实现什么业务、也无法提高系统的性能。但是日志是保证服务可靠的重要功能。
日志的基础知识
日志级别
- 假如根据
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配置日志参数的方式
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
Spring Boot
Spring Boot假如不需要自定义参数配置,可以直接在application.yml中进行参数配置
logging:
# 日志的等级,对不同包可以采用不同的等级
# 比如如下配置就是将root的等级设置为info,将com.learn设置为debug
level: {root: info,com.learn: debug}
# file是设置日志的输出的路径file和path属性只能选一个,不能同时存在
file: log.log
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"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="/log" />
<!-- 定义一个日滚动(每天生成一份)的日志文件 -->
<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>
</configuration>
我们来解释下里面标签的作用
标签 | 属性 | 描述 |
---|---|---|
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>
配置说明
就这就是一个简单的控制台输入的配置
文件输出配置
下面一个简单的日志文件输出配置
<!--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>
控制台彩色输出配置
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<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>
带过滤器的配置
有的时候我们想根据不同的包或者不同的错误内容、不同的错误级别实现不同的日志输出方式,我们可以使用日志系统中的过滤器。
之前文件日志配置中一段内容
在上面的例子上,我们其实已经使用了系统自带的过滤器配置。下面的内容就将Error级别从日志系统剔除出去了。这样我们就实现了虽然基础级别设置的为INFO,但是还是可以不输出Error
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--过滤 Error-->
<level>ERROR</level>
<!--匹配到就禁止-->
<onMatch>DENY</onMatch>
<!--没有匹配到就允许-->
<onMismatch>ACCEPT</onMismatch>
</filter>
点开ch.qos.logback.classic.filter.LevelFilter
我们可以看到这个类的内部逻辑
可以看到日志中配置的过滤器器
public class LevelFilter extends AbstractMatcherFilter<ILoggingEvent> {
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();
}
}
}
我们追踪父类,会发现其实它实现了接口ch.qos.logback.core.filter.Filter
,那么我们知道filter标签中,我们可以通过配置实现Filter的类来实现自己的逻辑
public abstract class Filter<E> 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;
}
}
所以这样我们可以尝试使用自己的过滤器,实现自己的日志逻辑。在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>
我们使用ch.qos.logback.core.filter.EvaluatorFilter
过滤器,其使用的匹配规则是我们自定义的dai.samples.log.config.MyEventEvaluator
,其内部逻辑为
public class MyEventEvaluator extends EventEvaluatorBase<ILoggingEvent> {
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;
}
}
一个配置demo
现在我们将上面内容汇总汇总到一起写一个配置。
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<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}}" />
<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>
</configuration>
配置效果
控制台输出
控制台输出使用了彩色输出
<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}}" />
<appender name="all" class="ch.qos.logback.core.ConsoleAppender">
<!--展示格式 layout-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</layout>
</appender>
我们请求一个接口会输出下面内容
自定义的输出
我们可以看到有两个不是彩色的输出[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>
文件输出
<!--定义日志文件的存储地址 勿在 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>
配置中根据不同的日志级别输出到不同的文件中,文件地址为/log/info,/log/error,/log/warn
实际中日志也才对应的文件中生成了
文件中日志输出的格式,并不和控制台一样。因为我们为文件输出设置了自己的格式
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
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
本篇文章涉及的源码下载地址:https://gitee.com/daifyutils/springboot-samples