集成日志功能
- 日志介绍
- 日志相关概念
- 选择Logback还是Log4j2?
- LogBack相关知识
- Logback
- Logback的基本概念
- Logback的日志级别
- Logback的配置文件
- Logback日志文件解析
- `logback-spring.xml`的配置项
- 标签说明
- 完整的logback-spring.xml配置示例
- 知识点补充
- 整合Spring Boot和Logback
日志介绍
1.什么是日志?
通过日志查看程序的运行过程,运行信息,异常信息等
2.日志的作用
- 快速的定位和排查问题;
- 记录用户信息;
- 记录操作信息,可以帮助恢复数据或者定位责任人;
- 记录程序的执行时间,方便获取优化和分析;
日志相关概念
1.slf4j
:
slf4j是一个日志接口(或称为门面/抽象层),它本身并不实现日志功能,而是为各种日志框架(如log4j、logback等)提供了一套统一的接口。
使用slf4j的好处是,开发者可以在代码中只使用slf4j的接口,然后在运行时或部署时根据实际需要选择具体的日志实现框架。这增加了代码的灵活性和可移植性。
slf4j与具体的日志实现框架(如log4j、logback)之间通过桥接器(binding)进行连接。
2.log4j
:
log4j是Apache的一个早期日志框架,它允许开发者通过配置文件灵活地控制日志的输出目标、记录级别、输出格式等。
随着时间的推移,log4j已经逐渐被其后续版本log4j2所取代。
3.logback
:
logback是log4j的创始人Ceki Gülcü开发的一个新的日志框架,它被视为log4j的继任者。
logback在性能、内存使用和灵活性方面都优于log4j,并且它直接实现了slf4j的接口,因此可以作为slf4j的一个具体实现。
logback本身包含了一套完整的日志解决方案,无需依赖其他库。
4.log4j2
:
log4j2是log4j的后续版本,它在性能、功能、灵活性和易用性方面都有了很大的提升。
log4j2支持异步日志记录,可以极大地提高多线程环境下的日志性能。
log4j2也支持通过配置文件进行灵活的配置,包括日志的输出目标、记录级别、输出格式等。
log4j2也提供了对slf4j的桥接支持,因此可以作为slf4j的一个具体实现。
总结:
①slf4j
是一个日志接口,它定义了日志记录的规范,但不具体实现日志功能。
②log4j
是一个早期的日志框架,但已经逐渐被其后续版本log4j2所取代。
③logback
是一个新的日志框架,它直接实现了slf4j的接口,并提供了高性能、灵活的日志记录功能。
④log4j2
是log4j的后续版本,它在性能、功能和易用性方面都有很大的提升,并支持作为slf4j的一个具体实现。
选择Logback还是Log4j2?
Log4j2
和Logback
都是Java中常用的日志框架,它们各有特点,适用于不同的使用场景。Log4j2的性能优于logback,主要得益于其采用的异步日志记录方式,这种机制能够在不阻塞主线程的情况下进行日志记录,从而提高效率。此外,Log4j2提供了更丰富的功能和配置选项,支持日志过滤器、多种插件等,这使得它在功能上更为强大。尽管Log4j2的配置文件相对复杂,需要更多的配置选项和语法知识,但它提供了XML、JSON、YAML等多种格式进行配置,增加了其灵活性。因此,如果对性能要求较高,或者需要更多的功能和配置选项,Log4j2是更好的选择。
相比之下,Logback虽然性能和功能上略逊于Log4j2,但它的稳定性更好,经过了更多的测试和优化。logback的配置相对简单,采用XML格式,配置文件结构清晰,更适合那些对配置要求不高,但希望日志框架稳定运行的场景。此外,logback由log4j的作者设计开发,拥有较大的社区支持,这意味着它在社区活跃度和用户反馈方面也有一定的优势。
综上所述,选择Log4j2还是logback取决于具体的需求。如果项目对性能和功能有较高要求,且团队有足够的资源配置能力,Log4j2是更优的选择。反之,如果项目更注重稳定性以及简单的配置需求,logback可能是更合适的选择。
LogBack相关知识
框架将提供一种使用Spring Boot和Logback的方法来实现日志文件本地保存,首先介绍一下Logback框架的基本知识和使用方法,然后再介绍如何将Logback和Spring Boot集成起来,最后演示如何使用Logback来记录日志并保存到本地文件中。
Logback
Logback是一个成熟和稳定的日志框架,是Log4j框架的继承者,具有更好的性能和更加丰富的配置选项。它可以与Spring Boot框架集成,实现日志输出到控制台或者文件。
Logback的基本概念
Logback由三个模块组成:
logback-core
:提供了更低级别的功能,最基本的日志系统。logback-classic
:提供了更高级别的功能,比如SLF4J API的实现,支持MDC(Mapped Diagnostic Contexts)。logback-access
:提供了用于HTTP访问日志的功能,包括访问日志和基于XML的HTTP访问日志。
Logback使用Logger来记录和输出日志,LoggerContext是Logger的容器,主要维护Logger和Appender的关系。
Appender用于将日志输出到不同的地方,比如控制台或者文件。
Logback的日志级别
Logback定义了五个日志级别,按照从低到高的顺序为TRACE、DEBUG、INFO、WARN、ERROR、FATAL。在实际应用中,应根据需要选择适当的日志级别。
TRACE:级别最低
DEBUG:调试级别的,常用于跟踪程序的进展
INFO:普通的打印信息(默认的日志级别)
WARN:警告级别,不影响使用,但应该注意
ERROR:错误级别,错误日志信息打印
FATAL:致命级别,因代码异常导致程序退出,级别最高
默认情况下,spring boot从控制台打印出来的日志级别只有INFO及以上级别,可以在application.yml
配置日志级别
# 设置日志级别
logging:
level:
root: ERROR
这种方式能将ERROR级别以及以上级别的日志输出到控制台上,其他级别将不会输出
Logback的配置文件
我们使用SLF4J框架记录日志时,会用到 logback.xml
和 logback-spring.xml
两个不同的配置文件
logback-spring.xml
只有在Spring应用程序运行的时候才生效,即带有@SpringBootApplication注解的类启动的时候才会生效。
如果不是Spring应用程序,而是一个main方法或者一个JUnit的测试方法,要用 logback.xml
来配置。如果没有logback.xml
这个文件,或者logback.xml
放的路径不对,则日志仍然是会打印出来的,而且会按照默认的DEBUG级别打印。这样一运行程序会有大量的DEBUG信息,把真正有用的信息都淹没了。
我们要想把这些烦人的DEBUG信息关掉,禁止它输出DEBUG信息,需要自己创建一个名为 logback.xml
的文件。一般Spring Boot项目里面已经带有一个 logback-spring.xml
文件了,最省事的方法是直接把 logback-spring.xml
复制一份,名字改成 logback.xml
就行,里面所有的配置语法都不用改。因为logback-spring和logback除了文件名不同,里面写法是完全一样的。
logback-spring.xml
存放的位置是在SpringApplication
主类所在的项目的resources
目录,也就是application.yml
或者application.properties
所在的目录。
logback.xml
存放的位置是在你启动的那个类所在的项目的resources
目录
SpringBoot 配置文件的加载顺序:
logback.xml—>application.properties—>logback-spring.xml
Logback日志文件解析
logback-spring.xml
的配置项
共有一个父标签、两种属性、三个节点:
一个父标签:
configuration
两种属性:contextName
和property
三个节点:appender
、root
、logger
标签说明
父标签(configuration
)
configuration
最外层标签,该标签有三个属性:
- scan
当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true - scanPeriod
设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 - debug
当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
<configuration scan="true" scanPeriod="10 seconds" debug="true">
</configuration>
两种属性标签(contextName
、property
)
contextName
标签用于指定日志上下文的名称。日志上下文是Logback框架中的一个重要概念,它表示一个独立的日志实例或日志环境。通过设置不同的上下文名称,您可以创建并配置多个独立的日志记录器,每个日志记录器可以有自己的日志级别、输出目标等配置。
<configuration scan="false" scanPeriod="60 seconds" debug="false">
<contextName>logback_demo</contextName>
</configuration>
property
用来定义变量值的标签, 有两个属性,name和value;其中name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。
<property name="APP_Name" value="myAppName" />
<contextName>${APP_Name}</contextName>
三个节点标签(appender
、logger
、root
)
appender
的意思是追加器,在这里可以理解为一个日志的渲染器(或者说格式化日志输出)。比如渲染console日志为某种格式,渲染文件日志为另一种格式。
标签属性:
-
name
:指定appender的名称,应该是唯一的。 -
class
:指定appender的实现类。例如,ch.qos.logback.core.ConsoleAppender表示控制台输出,ch.qos.logback.core.FileAppender表示文件输出。 -
其他属性
:具体取决于所选的appender类,例如文件路径、文件滚动策略等。
控制台输出时子标签: -
filter
:标签用于配置日志事件过滤器,可以根据特定的条件过滤和控制日志输出。 -
encoder
:ancoder的意思是追加器,在这里可以理解为渲染器,用来指定日志输出的格式。 -
rollingPolicy
:.日志记录器的滚动策略,按日期,按大小记录,只有在输出到文本中时才需要配置这个
控制台打印示例:
<!--0. 日志格式和颜色渲染 -->
<!-- 彩色日志依赖的渲染类 -->
<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="%green(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%thread] %highlight(%-5level) %red(%logger{50}) - %yellow(%msg) %n"/>
<!--1. 输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<!-- %d表示时间
%thread表示线程名
%-5level 表示日志级别,允许以五个字符长度输出
%logger{50}表示具体的日志输出者,比如类名,括号内表示长度
%msg表示具体的日志消息,就是logger.info("xxx")中的xxx
%n表示换行 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
输出到文本时示例:
<!--2. 输出到文档-->
<!-- 2.1 level为 DEBUG 日志,时间滚动输出 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${log.path}/web_debug.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档 -->
<!--如果第二天输出日志,会将当天的日志记录在<file>${log.path}/log_debug.log</file>,然后将昨天的日志归档到下面的文件中-->
<!--以天切分 %d{yyyy-MM-dd}-->
<fileNamePattern>${log.path}/web-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!--单个日志文件最大100M,到了这个值,就会再创建一个日志文件,日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
<!--所有的日志文件最大20G,超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!-- 此日志文档只记录debug级别的及以上 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 此日志文件只记录debug级别的
onMatch和onMismatch都有三个属性值,分别为Accept、DENY和NEUTRAL
onMatch="ACCEPT" 表示匹配该级别及以上
onMatch="DENY" 表示不匹配该级别及以上
onMatch="NEUTRAL" 表示该级别及以上的,由下一个filter处理,如果当前是最后一个,则表 示匹配该级别及以上
onMismatch="ACCEPT" 表示匹配该级别以下
onMismatch="NEUTRAL" 表示该级别及以下的,由下一个filter处理,如果当前是最后一个,则不匹配该级别以下的
onMismatch="DENY" 表示不匹配该级别以下的 -->
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
root
该标签的作用实际上是配置启用哪种appender,可以添加多个appender。
<!--root配置必须在appender下边-->
<!--root节点是对所有appender的管理,添加哪个appender就会打印哪个appender的日志-->
<!--root节点的level是总的日志级别控制,如果appender的日志级别设定比root的高,会按照appender的日志级别打印日志,-->
<!--如果appender的日志级别比root的低,会按照root设定的日志级别进行打印日志-->
<!--也就是说root设定的日志级别是最低限制,如果root设定级别为最高ERROR,那么所有appender只能打印最高级别的日志-->
<root level="DEBUG">
<!--<appender-ref ref="append中的名字" /> -->
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
logger
与root
是相对的,作用范围不同,root
相当于是对真个项目做配置,logger
就是对项目下某个包或者某个类单独做配置的。
该标签有两个属性
name
:用来指定受此loger约束的某一个包或者具体的某一个类。addtivity
:是否向上级loger传递打印信息。默认是true
<!-- logback为 com.pikaqiu.logbackdemo 中的包 -->
<logger name="com.pikaqiu.logbackdemo" level="debug" additivity="false">
<!-- 指定打印配置-->
<appender-ref ref="CONSOLE" />
</logger>
<!-- logback为 com.pikaqiu.logbackdemo.LogbackdemoApplicationTests 这个类 -->
<logger name="com.pikaiqu.logbackdemo.LogbackdemoApplicationTests" level="INFO" additivity="true">
<appender-ref ref="STDOUT"/>
</logger>
logger和root的关系
- root和logger是父子的关系。
logger的appender根据参数additivity决定是否要叠加root的appender,logger的级别是其自身定义的级别,和root的级别没什么关系。- logger对单个包或类添加配置,相当于局部配置,root相当于全局配置
如果logger里面配置了additivity=“false”,就会覆盖root的,只打印一遍;但是additivity=“true”,就会向上层再次传递,不会覆盖,而是打印两遍!
完整的logback-spring.xml配置示例
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds">
<contextName>logback</contextName>
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量-->
<property name="log.path" value="F:/logs" />
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg %n"/>
<!--输出到控制台-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<!--先将今天的日志保存在这个文件中-->
<file>${log.path}/log_debug.log</file>
<!--日志文件输出格式 %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
%d{HH: mm:ss.SSS}——日志输出时间
%thread——输出日志的进程名字,这在Web应用以及异步任务处理中很有用
%-5level——日志级别,并且使用5个字符靠左对齐
%logger{36}——日志输出者的名字
%msg——日志消息
%n——平台的换行符
-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<!--如果第二天输出日志,会将当天的日志记录在<file>${log.path}/log_debug.log</file>,然后将昨天的日志归档到下面的文件中-->
<!--以分钟切分 %d{yyyy-MM-dd_HH-mm}-->
<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd_HH-mm}.%i.log</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<!--单个日志文件最大100M,到了这个值,就会再创建一个日志文件,日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大20G,超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!--
此日志文件只记录debug级别的
onMatch和onMismatch都有三个属性值,分别为Accept、DENY和NEUTRAL
onMatch="ACCEPT" 表示匹配该级别及以上
onMatch="DENY" 表示不匹配该级别及以上
onMatch="NEUTRAL" 表示该级别及以上的,由下一个filter处理,如果当前是最后一个,则表示匹配该级别及以上
onMismatch="ACCEPT" 表示匹配该级别以下
onMismatch="NEUTRAL" 表示该级别及以下的,由下一个filter处理,如果当前是最后一个,则不匹配该级别以下的
onMismatch="DENY" 表示不匹配该级别以下的
-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<!--如果第二天输出日志,会将当天的日志记录在<file>${log.path}/log_debug.log</file>,然后将昨天的日志归档到下面的文件中-->
<!--以分钟切分 %d{yyyy-MM-dd_HH-mm}-->
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<!--单个日志文件最大100M,到了这个值,就会再创建一个日志文件,日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大20G,超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!--SizeAndTimeBasedRollingPolicy配置更灵活,所以改用SizeAndTimeBasedRollingPolicy-->
<!--<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!– 每天日志归档路径以及格式 –>
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!–日志文件保留天数–>
<maxHistory>15</maxHistory>
</rollingPolicy>-->
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<!--如果第二天输出日志,会将当天的日志记录在<file>${log.path}/log_debug.log</file>,然后将昨天的日志归档到下面的文件中-->
<!--以分钟切分 %d{yyyy-MM-dd_HH-mm}-->
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<!--单个日志文件最大100M,到了这个值,就会再创建一个日志文件,日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大20G,超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<!--如果第二天输出日志,会将当天的日志记录在<file>${log.path}/log_debug.log</file>,然后将昨天的日志归档到下面的文件中-->
<!--以分钟切分 %d{yyyy-MM-dd_HH-mm}-->
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<!--单个日志文件最大100M,到了这个值,就会再创建一个日志文件,日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大20G,超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--root配置必须在appender下边-->
<!--root节点是对所有appender的管理,添加哪个appender就会打印哪个appender的日志-->
<!--root节点的level是总的日志级别控制,如果appender的日志级别设定比root的高,会按照appender的日志级别打印日志,-->
<!--如果appender的日志级别比root的低,会按照root设定的日志级别进行打印日志-->
<!--也就是说root设定的日志级别是最低限制,如果root设定级别为最高ERROR,那么所有appender只能打印最高级别的日志-->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
<!--name:用来指定受此loger约束的某一个包或者具体的某一个类。-->
<!--addtivity:是否向上级loger传递打印信息。默认是true。-->
<logger name="com.pikaiqu.logbackdemo.LogbackdemoApplicationTests" level="debug" additivity="false">
<appender-ref ref="STDOUT" />
<appender-ref ref="INFO_FILE" />
</logger>
<!--配置多环境日志输出 可以在application.properties中配置选择哪个profiles : spring.profiles.active=dev-->
<!--生产环境:输出到文件-->
<springProfile name="pro">
<root level="info">
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="ERROR_FILE" />
<appender-ref ref="WARN_FILE" />
</root>
</springProfile>
<!--开发环境:打印控制台-->
<springProfile name="dev">
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</springProfile>
</configuration>
知识点补充
1.文件保存日志策略
日志轮转和归档是指将日志文件按一定规则进行分割和存档,以防止日志文件过大。Logback 提供了灵活的日志轮转和归档策略。
时间轮转策略
时间轮转策略可以按时间段(如每天、每小时)分割日志文件。在 logback-spring.xml 中配置 TimeBasedRollingPolicy
:
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/myapp.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/myapp.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
大小轮转策略
大小轮转策略可以按文件大小分割日志文件。在 logback-spring.xml 中配置 SizeBasedTriggeringPolicy
:
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/myapp.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${LOG_PATH}/myapp.%i.log</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>10</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>10MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
时间大小轮转策略
SizeAndTimeBasedRollingPolicy
:TimeBasedRollingPolicy的一个子类,实现了基于时间和日志文件大小的翻滚策略。按日期归档文件,但同时限制每个日志文件的大小。最常用的滚动策略。
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名:保存当天的日志记录 -->
<file>${log.path}/log_debug.log</file>
<!--日志文件输出格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--将当天的日志记录在<file>,然后将昨天的日志归档到下面的文件中-->
<!--按天切分 %d{yyyy-MM-dd} %i指定索引-->
<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--单个日志文件最大100M,超过后再创建一个日志文件,日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大20G,超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!--此日志文件只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
整合Spring Boot和Logback
实际使用springboot开发不需要直接添加该依赖,因为在spring-boot-starter
里面添加了spring-boot-starter-logging
,spring-boot-starter-logging
里引入了日志框架Logback和Slf4j的依赖。在进行web开发的时候引入的spring-boot-starter-web
又包含了spring-boot-starter
依赖。
① 按照上面的知识点配置项目需要的日志配置文件logback-spring.xml
② 在代码中使用,类中添加
private static final Logger LOGGER = LoggerFactory.getLogger(SystemUserController.class);
//方法中使用
LOGGER.info("----保存用户成功------");
LOGGER.error("----保存用户错误------");
LOGGER.debug("----跟踪保存用户------");
当然也可以使用lombok注解来使用
③ 设置日志打印mybatis 打印sql日志,首先确保日志里面有存入日志的appender和打印console的appender
<!-- sql文件,记录DEBUG级别日志 -->
<appender name="SQL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 实时输出的日志文件 -->
<file>${FILE_PATH}/sys-sql.log</file>
<append>true</append>
<!-- 历史日志分块,配置滚动的策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志名称的格式 -->
<fileNamePattern>${FILE_PATH}/sys-sql.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 保存的最长时间:天数 -->
<MaxHistory>${MAX_HISTORY}</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_PATTERN}</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>${FILE_SIZE}</MaxFileSize>
</triggeringPolicy>
<!-- 过滤掉非debug的日志,即此日志文件中只会输出debug日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>DEBUG</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>>
</filter>
</appender>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_PATTERN}</pattern>
</encoder>
</appender>
在logback-spring.xml
中配置以下
<!--mybatis日志 mapper包所在路径-->
<logger name="com.xxx.mapper" level="DEBUG" additivity="false">
<appender-ref ref="SQL_FILE" />
<appender-ref ref="STDOUT" />
</logger>
level需要是DEBUG等级; 因为sql日志是DEBUG等级的;name= 存放mapper文件的包路径,运行的时候可以看到console打印