很多项目在生产上严禁使用System.out输出,性能太低,原因是System.out输出会导致线程等待(同步),而使用Logger输出线程不等待日志的输出(异步),而继续执行。
接下来看一看springboot的日志配置,说一下把日志记录到文件中的配置方式。
默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台。在实际使用中,大家应该看到很多这种日志了,例如:
2021-04-20 13:51:32.777 INFO 5540 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9090 (http) with context path ''
2021-04-20 13:51:32.783 INFO 5540 --- [ main] com.demo.DemoRunApplication : Started DemoRunApplication in 6.496 seconds (JVM running for 7.757)
2021-04-20 13:51:39.218 INFO 5540 --- [nio-9090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2021-04-20 13:51:39.218 INFO 5540 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2021-04-20 13:51:39.256 INFO 5540 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms
2021-04-20 13:51:39.290 INFO 5540 --- [nio-9090-exec-1] com.demo.controller.StudentController : 查询所有学生
2021-04-20 13:51:39.435 INFO 5540 --- [nio-9090-exec-1] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
什么是Logback?
Logback是由log4j创始人设计的又一个开源日志组件。与log4j类似,但是比log4j更强大,是log4j的改良版本。
slf4j log4j logback的关系
slf4j是一系列的日志接口,而log4j和logback是具体实现了的日志框架。在官方文档中描述了三者的关系:slf4j译为简单日志门面,是日志框架的抽象,而log4j和logback是众多日志框架中的几种。
a) log4j是apache实现的一个开源日志组件
b) logback同样是由log4j的作者实现的,拥有更好的特性,是slf4j的原生实现
c) log4j2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活
上面已经讲解了lomback在idea或eclipse中打印日志的信息,下面会介绍将日志打印保存到日志文件中的方式。
使用logback添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
web依赖包或spring-boot-starter依赖包中自带了spring-boot-starter-logging依赖,所以若导入了web包,可以不用单独添加logging依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
logging:
level:
root: info
com.demo: debug
file: log/app-log.log
1.1:属性讲解
(1)file: 日志输出到根目录下log文件夹,app-log.log文件中
(2)root: 定义了root的级别是info
(3) com.demo: 打印com.demo包下面的所有日志,级别为debug级别
1.2日志输出:
2021-04-19 17:03:49.455 INFO 10864 --- [http-nio-9090-exec-1] com.demo.controller.StudentController : 查询所有学生
2021-04-19 17:03:49.541 INFO 10864 --- [http-nio-9090-exec-1] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
2021-04-19 17:03:49.675 DEBUG 10864 --- [http-nio-9090-exec-1] com.demo.dao.StudentDao.findAll : ==> Preparing: select * from student;
2021-04-19 17:03:49.717 DEBUG 10864 --- [http-nio-9090-exec-1] com.demo.dao.StudentDao.findAll : ==> Parameters:
2021-04-19 17:03:49.752 DEBUG 10864 --- [http-nio-9090-exec-1] com.demo.dao.StudentDao.findAll : <== Total: 5
定制日志的格式
在yml文件中添加如下配置:
logging.pattern.console=%d{yyyy-MM-dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n
logging.pattern.file=%d{yyyy-MM-dd-HH:mm} [%thread] %-5level %logger- %msg%n
上面配置的含义如下:
%d{HH:mm:ss.SSS}——日志输出时间
%thread——输出日志的进程名字,这在Web应用以及异步任务处理中很有用
%-5level——日志级别,并且使用5个字符靠左对齐
%logger- ——日志输出者的名字
%msg——日志消息
%n——平台的换行符
1.3 spring-boot日志配置 logging.path logging.file 注意事项
logging.path 和 logging.file只能配置一个
注:二者不能同时使用,如若同时使用,则只有logging.file生效
默认情况下,日志文件的大小达到10MB时会切分一次,产生新的日志文件,默认级别为:ERROR、WARN、INFO
官方文档中有这么一句:
If you want to write log files in addition to the console output you
need to set a logging.file or logging.path property
也就是说,它们不会同时生效,只配置其中一个就好了。
例:logging.path = ./logs/demo.log 想指定文件名为demo.log,但只会生成demo.log的目录,然后生成spring.log的文件
例:logging.file= ./log/demo.log 会在项目根目录下生成log文件夹及demo.log文件
方式二:自定义配置文件
在实际开发中,可以看到很多项目中会有logback-spring.xml。或者自定义命名为其他的文件名。
根据不同的日志系统,你可以按如下规则组织配置文件名,就能被正确加载:
logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
log4j2-spring.xml, log4j2.xml
logging.properties
Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置(如使用logback-spring.xml,而不是logback.xml)。springboot启动时会先加载logback.xml文件,然后再加载配置文件yml及properties,所以如果有参数定义在yml中,在logback.xml文件中是读取不到的,建议使用logback-spring.xml文件名,会在yml加载之后加载。
默认的命名规则,并且放在 src/main/resources 下面即可
如果想修改配置文件的名字,application.yml可以通过logging.config属性指定自定义的名字:
logging.config=classpath:logging-con.xml
如果日志配置文件的名字是默认规则的名字,则无需配置loggin.config属性了
logback-spring.xml的配置如下
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径
<property name="LOG_HOME" value="/app/user/runtime/log/" />
-->
<property name="LOG_HOME" value="/app/user/runtime/log/" />
<property name="PATTERN"
value="%-12(%d{yyyy-MM-dd HH:mm:ss.SSS}) %-5level [%thread] [%c] %msg%n " />
<!-- 控制台输出 -->
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="LOG"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/logback.%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<!-- 单个日志文件最大值,达到之后就进行切割。 -->
<MaxFileSize>300MB</MaxFileSize>
<!-- 日志文件总体的最大值,达到之后就不再产生日志。 -->
<totalSizeCap>10GB</totalSizeCap>
<!-- 日志文件最多保留的天数,也就是过期时间。 -->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 日志输出级别 -->
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
<!-- additivity:是否向上级logger传递打印信息。默认是true。 -->
<logger name="com.demo" level="debug" additivity="false">
<appender-ref ref="LOG"/>
</logger>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
关于配置文件中的属性,标签可参考《https://blog.csdn.net/Inke88/article/details/75007649》
%-12(%d{yyyy-MM-dd HH:mm:ss.SSS}) %-5level [%thread] [%c] %msg%n 格式详解
说明:此处讲解的是将application.yml中的logging.path配置与logback-spring.xml文件配合使用,在yml中修改目录后,动态修改日志存储目录;并且logging.path属性只能配置目录,默认打印日志文件名为spring.log,配合logback-spring.xml一起使用可以修改日志文件名。ps:不算是一种独立的日志打印方式。
application.yml中的配置
logging:
path: E:/log
logback-spring.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径
<property name="LOG_HOME" value="/app/user/runtime/log/" />
-->
<property name="LOG_HOME" value="${LOG_PATH}" />
<property name="PATTERN"
value="%-12(%d{yyyy-MM-dd HH:mm:ss.SSS}) %-5level [%thread] [%c] %msg%n " />
<!-- 控制台输出 -->
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="LOG"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/logback.%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<!-- 单个日志文件最大值,达到之后就进行切割。 -->
<MaxFileSize>300MB</MaxFileSize>
<!-- 日志文件总体的最大值,达到之后就不再产生日志。 -->
<totalSizeCap>10GB</totalSizeCap>
<!-- 日志文件最多保留的天数,也就是过期时间。 -->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 日志输出级别 -->
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
<!-- additivity:是否向上级logger传递打印信息。默认是true。 -->
<logger name="com.demo" level="debug" additivity="true"/>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="LOG"/>
</root>
</configuration>
<springProperty scope="context" name="LOG_HOME" source="logging.path" defaultValue="E:/log"/>
${LOG_PATH:-.} 用法
${LOG_PATH:-.}
LOG_PATH是读取了logging.path的环境变量,直接读取logging.path 的值是读取不到的。
-表示分割符,后面的参数是默认路径
.表示当前项目根路径或者可以写成 ./log
即 ${LOG_PATH:-.}
=${E:/log-当前项目根路径}
如果日志配置文件的名称是logback.xml,然后又使用了${LOG_PATH:-.}
的写法会生成两个日志路径 一个是 E:/log 另一个是在当前项目根路径生成的日志 因为spring比logback先启动 所以会在项目根目录生成一个spring.log的日志(我的配置文件已经修改了文件名,所以会在根目录生成logback.2021-04-20.0.log) ,如果想把目录生成在一起,使用${LOG_PATH:- }
默认路径设置成空格这样就不会在你的项目根目录生成spring.log日志文件了==(会在你服务器根目录生成)==接下来系统日志就会输出到你的自定义目录了