常用日志框架
常见的日志框架
- slf4j是一个日志输出接口,其本身是没有具体实现的,必须的借助日志框架(Log4j、LogBack、Log4j2)才能更好的实现日志输出。使用slf4j能够更好的让用户进行日志框架的切换而无需修改代码。
- Log4j:Apache的一个开源项目,可以控制日志信息输送的目的地是控制台、文件、GUI组件等,可以控制每一条日志的输出格式,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用代码。虽然已经停止维护了,但目前绝大部分企业都是用的log4j。
- LogBack:是Log4j的一个改良版本,spring默认使用的就是logback
- Log4j2:Log4j2已经不仅仅是Log4j的一个升级版本了,它从头到尾都被重写了。
我们平时使用的springboot中内置的是logback
spring-boot-starter ->
spring-boot-starter-logging -> 内置的logback
日志级别
trace<debug<info<warn<error
log4j日志详解
Log4j由三个重要的组件构成:日志信息的优先级(Logger),日志信息的输出目的地(Appender),日志信息的输出格式(Layout)。
日志信息的级别分为四级,优先级从高到低有DEBUG、INFO、WARN、ERROR,用来指定这条日志信息的重要程度;
日志信息的输出目的地指定了日志将打印到控制台还是文件中;
日志信息的输出格式则控制了日志信息的显示内容
注意:Log4j日志级别是定义在org.apache.log4j.Level类中,可以看源码。Log4j只建议使用4个级别,优先级从高到低分别是error,warn,info和debug。
A:off 最高等级,用于关闭所有日志记录。
B:fatal 指出每个严重的错误事件将会导致应用程序的退出。
C:error 指出虽然发生错误事件,但仍然不影响系统的继续运行。
D:warm 表明会出现潜在的错误情形。
E:info 一般和在粗粒度级别上,强调应用程序的运行全程。
F:debug 一般用于细粒度级别上,对调试应用程序非常有帮助。
G:TRACE 一般用于更细粒度级别上,比debug级别更低
H:all 最低等级,用于打开所有日志记录。
使用log4j替换掉spring的默认框架:
- 导入依赖
因为springboot的启动依赖会引入SLF4J的日志依赖,因此想要用log4j,就要先把slf4j的依赖去掉,然后再引入log4j的启动依赖。
- 去掉slf4j的依赖
在web的启动依赖spring-boot-starter-web下去掉
spring-boot-starter-logging,结果运行的时候,控制台上打印的是一对红色的开头为SLF4J的东东,根本没用到log4j。这是因为在spring-boot-starter里仍然引用了slf4j,因此需要在spring-boot-starter下去掉logging依赖。那么有些小伙伴会觉得奇怪的地方来了,项目里面根本没有引入spring-boot-starter依赖,只有spring-boot-starter-web,要怎么搞?没有就引入啊。如果说引入了会不会造成啥冲突的,不会!因为就算你不引入项目也会用到,springboot的定时器包就引用了spring-boot-starter。也就是说在spring-boot-starter下去一定要去掉logging依赖,spring-boot-starter-web下不去掉也行。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
- 引入log4j的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
- log4j的配置
log4j的配置文件分为两种, log4j.xml 和 log4j.properties,推荐使用log4j.xml。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">
<log4j:configuration>
<!-- ========================== 自定义输出格式说明================================ -->
<!-- %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL -->
<!-- %r 输出自应用启动到输出该log信息耗费的毫秒数 -->
<!-- %c 输出所属的类目,通常就是所在类的全名 -->
<!-- %t 输出产生该日志事件的线程名 -->
<!-- %n 输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n” -->
<!-- %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921 -->
<!-- %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10) -->
<!-- ========================================================================== -->
<!-- ========================== 输出方式说明================================ -->
<!-- Log4j提供的appender有以下几种: -->
<!-- org.apache.log4j.ConsoleAppender(控制台), -->
<!-- org.apache.log4j.FileAppender(文件), -->
<!-- org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件), -->
<!-- org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件), -->
<!-- org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方) -->
<!-- ========================================================================== -->
<!--输出到控制台-->
<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
<!--Threshold是个全局的过滤器,他将把低于所设置的level的信息过滤不显示出来-->
<param name="Threshold" value="DEBUG" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy.MM.dd HH:mm:ss SS} %5p [%t] %C{1}.%M(%L) | %m%n" />
</layout>
</appender>
<!-- 系统应用级别日志,日志达到一定大小后,产生新的问题 -->
<appender name="fileMaxAppenderAll" class="org.apache.log4j.RollingFileAppender">
<param name="threshold" value="error" />
<param name="file" value="E:/logs/all.sys.log" />
<param name="maxFileSize" value="10M" />
<param name="maxBackupIndex" value="5" />
<!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
<param name="append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p][%d{yyyy-MM-dd HH:mm:ss,SSS}][%c] :%m%n" />
</layout>
</appender>
<!--输出到文件 所有日志,根据name='DatePattern'设置每隔多久分割成一个新文件 -->
<appender name="fileAppenderAll" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="E:/logs/all.log" />
<!-- value的格式,(天,小时,分钟), 控制每隔多久分割成一个新文件 -->
<param name="DatePattern" value=".yyyy-MM-dd-HH" />
<!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
<param name="append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy.MM.dd HH:mm:ss SS} %5p [%t] %C{1}.%M(%L) | %m%n" />
</layout>
</appender>
<!--输出到错误日志文件,只要加上filter过滤标签即可输出指定级别的日志 -->
<appender name="fileAppenderError" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="E:/logs/error.log" />
<param name="DatePattern" value=".yyyy-MM-dd-HH" />
<param name="Append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy.MM.dd HH:mm:ss SS} %5p [%t] %C{1}.%M(%L) | %m%n" />
</layout>
<!-- 日志级别,必须LevelMin <= LevelMax ,否则不输出日志 -->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="ERROR" />
<param name="LevelMax" value="ERROR" />
</filter>
</appender>
<!-- HTML形式的错误日志,<layout>标签中使用org.apache.log4j.HTMLLayout -->
<appender name="fileHTMLAppender" class="org.apache.log4j.RollingFileAppender">
<param name="threshold" value="error" />
<param name="file" value="E:/logs/all.log.html" />
<param name="maxFileSize" value="10M" />
<param name="maxBackupIndex" value="5" />
<param name="append" value="true" />
<layout class="org.apache.log4j.HTMLLayout" />
</appender>
<!-- XML形式错误日志 <layout>标签中使用org.apache.log4j.xml.XMLLayout -->
<appender name="fileXMLAppender" class="org.apache.log4j.RollingFileAppender">
<param name="threshold" value="error" />
<param name="file" value="E:/logs/all.log.xml" />
<param name="maxFileSize" value="10M" />
<param name="maxBackupIndex" value="5" />
<param name="append" value="true" />
<layout class="org.apache.log4j.xml.XMLLayout" />
</appender>
<!-- 邮件日志,添加发送和接收日志的邮箱地址 -->
<appender name="mailMAILAppender" class="org.apache.log4j.net.SMTPAppender">
<param name="threshold" value="debug" />
<param name="BufferSize" value="10" />
<param name="From" value="1076242265@163.com" />
<param name="SMTPHost" value="www.baidu.com" />
<param name="Subject" value="1076242265-log4j-Message" />
<param name="To" value="1076242265@163.com" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p][%d{yyyy-MM-dd HH:mm:ss,SSS}][%c] :%m%n" />
</layout>
</appender>
<!-- SOCKET日志 -->
<appender name="remoteSocketAppender" class="org.apache.log4j.net.SocketAppender">
<param name="threshold" value="fatal" />
<param name="remoteHost" value="localhost" />
<param name="port" value="18845" />
<param name="locationInfo" value="true" />
</appender>
<!-- 输出sql日志文件 -->
<appender name="fileSql" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="E:/logs/sql.log" />
<param name="DatePattern" value=".yyyy-MM-dd-HH" />
<param name="Append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy.MM.dd HH:mm:ss SS} %5p [%t] %C{1}.%M(%L) | %m%n" />
</layout>
<!-- 日志级别,必须LevelMin <= LevelMax ,否则不输出日志 -->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="DEBUG" />
<param name="LevelMax" value="ERROR" />
</filter>
</appender>
<!-- 指定接口日志,接口1,name可以按接口名进行自定义命名 -->
<appender name="INTERFACE-METHOD-ONE" class="org.apache.log4j.DailyRollingFileAppender" >
<param name="DatePattern" value=".yyyy-MM-dd-HH" />
<param name="Append" value="true"/>
<param name="file" value="E:/logs/interfaceMethodOne.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy.MM.dd HH:mm:ss SS} %5p [%t] %C{1}.%M(%L) | %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="INFO" />
<param name="LevelMax" value="ERROR" />
</filter>
</appender>
<!-- 指定接口日志,接口2,name可以按接口名进行自定义命名 -->
<appender name="INTERFACE-METHOD-TWO" class="org.apache.log4j.DailyRollingFileAppender">
<param name="DatePattern" value=".yyyy-MM-dd-HH" />
<param name="Append" value="true"/>
<param name="file" value="E:/logs/interfaceMethodTwo.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy.MM.dd HH:mm:ss SS} %5p [%t] %C{1}.%M(%L) | %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="INFO" />
<param name="LevelMax" value="ERROR" />
</filter>
</appender>
<!-- 指定logger的设置,additivity指示是否叠加输出log,
如果是false,在INTERFACE-METHOD-ONE-PARTONE logger中日志不会被其它logger满足条件的logger(比如root)输出
将名称为INTERFACE-METHOD-ONE-PARTONE的logger,输出到“interfaceMethodOne”的appender
category的属性additivity="false"表示在category中定义日志输在root中过滤掉
如果不想过滤掉,就设置为true
所谓logger的名字也就是,在定义Logger时,构造函数的参数
Logger log = Logger.getLogger("INTERFACE-METHOD-ONE-PARTONE");
注意:<logger>和<category>的区别
logger是category的子类,category现在已经不提倡使用。
-->
<logger name="INTERFACE-METHOD-ONE-PARTONE" additivity="true">
<level class="org.apache.log4j.Level" value="DEBUG"/>
<!-- 指向上面定义的appender中的name,日志则会输出到指定文件中 -->
<appender-ref ref="INTERFACE-METHOD-ONE"/>
</logger>
<category name="INTERFACE-METHOD-TWO-PARTONE" additivity="true">
<appender-ref ref="INTERFACE-METHOD-TWO"/>
</category>
<!-- 打印sql文件 -->
<category name="com.yw.mapper" additivity="true">
<priority value="DEBUG" />
<appender-ref ref="fileSql" />
</category>
<!--
<category name="org.apache.mybatis">
<priority value="DEBUG" />
<appender-ref ref="fileSql" />
</category>
<category name="org.mybatis.spring">
<priority value="DEBUG" />
<appender-ref ref="fileSql" />
</category>
-->
<root>
<priority value="INFO" />
<appender-ref ref="consoleAppender" />
<appender-ref ref="fileAppenderAll" />
<appender-ref ref="fileAppenderError" />
</root>
</log4j:configuration>
######################
## set log levels
######################
log4j.rootLogger=DEBUG,CONSOLE,FILEOUT
#DEBUG,CONSOLE,FILE,ROLLING_FILE,MAIL,DATABASE
log4j.addivity.org.apache=true
######################
## CONSOLE Appender ##
######################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c] \:%m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n\u00A0
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
######################
## Rolling File Appender
######################
log4j.appender.FILEOUT=org.apache.log4j.RollingFileAppender
log4j.appender.FILEOUT.File=E:/logs/allError.log
#log4j.appender.FILEOUT.Threshold=ALL
log4j.appender.FILEOUT.Threshold=INFO
log4j.appender.FILEOUT.Append=true
log4j.appender.fileout.MaxFileSize=1000KB
#log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.FILEOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.FILEOUT.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c] \:%m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n\u00A0
#######################
### File Appender
#######################
#log4j.appender.FILE=org.apache.log4j.FileAppender
#log4j.appender.FILE.File=E:/logs/all.log
#log4j.appender.FILE.Append=true
#log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
#log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c] \:%m%n
##log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n\u00A0
#####################
## Socket Appender
#####################
#log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
#log4j.appender.SOCKET.RemoteHost=localhost
#log4j.appender.SOCKET.Port=5001
#log4j.appender.SOCKET.LocationInfo=true
## Set up for Log Facter 5
#log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
#log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
#########################
## Log Factor 5 Appender
#########################
#log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
#log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
########################
## SMTP Appender
########################
#log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
#log4j.appender.MAIL.Threshold=FATAL
#log4j.appender.MAIL.BufferSize=10
#log4j.appender.MAIL.From=openwolfl@163.com
#log4j.appender.MAIL.SMTPHost=mail.openwolf.com
#log4j.appender.MAIL.Subject=Log4J Message
#log4j.appender.MAIL.To=openwolfl@163.com
#log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
#log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#########################
## JDBC Appender
########################
#log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
#log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
#log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
#log4j.appender.DATABASE.user=root
#log4j.appender.DATABASE.password=root
#log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
#log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
#log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
#log4j.appender.A1.File=SampleMessages.log4j
#log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
#log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
####################
### myself Appender
####################
#log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
#log4j.appender.im.host = mail.cybercorlin.net
#log4j.appender.im.username = username
#log4j.appender.im.password = password
#log4j.appender.im.recipient = corlin@yeqiangwei.com
#log4j.appender.im.layout=org.apache.log4j.PatternLayout
#log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
logbak日志详解
logback日志框架由三部分组成:logback-core、logback-access、logback-classic。使用起来也很方便需要在项目目录下增加logback.xml文件。在springboot项目,框架已经集成了logback(默认的日志框架),只需要在项目resource下配置logback.xml文件或者logback-spring.xml文件。这里主要记录的是logback配置文件的内容部分。
- 日志输出方式:
控制台日志和写入文件日志分开
日志本身是可追加写入的,定义为追加器:appender,控制台和写入文件日志分别有ConsleAppdender和 FileAppender两个追加器处理。
<!--控制台输出-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5level][%thread][%class{1}.%method:%line]====%boldMagenta([%X{trcId}][%X{ctxTag}])====%m%n</pattern>
</encoder>
</appender>
<!--文件输出-->
<!--每天打印一个log, yyyy/MM/dd 树形目录-->
<appender name="ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--<fileNamePattern>${SYS_LOG_DIR}/${HOSTNAME}${LOG_FILE}%d{yyyy-MM-dd}.log</fileNamePattern>
日志文件保留天数<maxhistory>30</maxhistory>-->
<fileNamePattern>${log.path}/${log.context}/${HOSTNAME}-%d{yyyyMMdd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5level][%thread][%class{1}.%method:%line]=====[%X{trcId}][%X{ctxTag}]=====%m%n</pattern>
</encoder>
<prudent>true</prudent>-->
</appender>
- 日志打印的内容可以控制参数格式
打印出的日志一定是规整的,便于开发跟踪问题。例如:问题发生的时间,由于大部分程序都是多线程运行的,则需要知道每个业务请求的线程号,出问题的使用到的类名等等.
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5level][%thread][%class{1}.%method:%line]=====[%X{trcId}][%X{ctxTag}]=====%m%n</pattern>
- 日志应该可以灵活指定输出级别
针对“ com.sports ”包下的日志,控制台和日志文件都使用debug级别。
必须对主体日志指定输出级别
虽然我们会对不同的包或者框架下日志设置输出级别,但不可缺少主体日志输出级别:root
<logger name="com.sports" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="LOG_FILE"/>
<!--<appender-ref ref="myAppender"/>-->
</logger>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="LOG_FILE"/>
<!--<appender-ref ref="mqAppender"/>-->
</root>
- logbak的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 用来定义变量值,它有两个属性name和value,通过<property>定义的值会被插入到logger上下文中,可以使“${}”来使用变量-->
<property name="log.path" value="./logs"/>
<property name="log.context" value="sky-business-server"/>
<!-- 区分应用程序名称-->
<contextName>${log.context}</contextName>
<!-- appender: 负责写日志的组件,它有两个必要属性name和class。name指定appender名称,class指定appender的全限定名-->
<!-- ConsoleAppender:负责把日志输出到控制台-->
<!--控制台输出-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5level][%thread][%X{showTex}][%class.%method:%line]:%m%n</pattern>-->
<!-- %d 表示日期-->
<!-- %thread 表示线程名-->
<!-- %-5level 日志级别,从左显示5个字符宽度-->
<!-- %logger{56} 日志打印所属的类名,限定长度56个字符-->
<!-- %m 日志消息-->
<!-- %n 是换行符-->
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %highlight([%-5level]) %boldYellow([%thread]) [%class{1}.%method:%line]======|%boldMagenta([%X{trcId}][%X{ctxTag}])|======%m%n</pattern>
</encoder>
</appender>
<!-- FileAppender: 把日志添加到文件-->
<!-- RollingFileAppender: 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件-->
<!--每天打印一个log, yyyy/MM/dd 树形目录-->
<appender name="ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当发生滚动时,决定RollingFileAppender的行为-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.context}/${HOSTNAME}-%d{yyyyMMdd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<!-- 用来设置日志的输入格式-->
<!--<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5level][%thread][%class.%method:%line][%X{trcId}][%X{ctxTag}]%m%n</pattern>-->
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5level][%thread][%class{1}.%method:%line][%X{trcId}][%X{ctxTag}]%m%n</pattern>
</encoder>
<!--<append>true</append>
<prudent>true</prudent>-->
</appender>
<!--打印任意包日志-->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ALL"/>
</root>
</configuration>
什么是异步日志
传统日志打印:当应用程序调用日志记录函数时,日志消息被直接写入到日志文件或其他输出目标,然后等待写入操作完成后,应用程序才能继续执行。这种同步方式可能会导致阻塞,尤其是在写入磁盘或网络操作较慢的情况下,会对主线程的执行速度产生较大的影响。
异步日志打印:日志消息的写入操作被放置在后台线程中进行,主线程不需要等待写入操作完成,可以继续执行其他任务。后台线程负责将日志消息缓冲起来,并在适当的时候进行写入操作,通常使用高效的数据结构和线程安全的队列来实现。这种方式可以显著减少对主线程的阻塞时间,提高应用程序的性能和响应速度。
异步日志记录的优点包括:
- 提高系统性能:减少了对主线程的阻塞时间,使主线程能够更快地执行其他任务,提高系统的吞吐量和响应性能。
- 降低延迟:由于日志写入操作在后台线程中进行,应用程序可以立即继续执行,而不需要等待写入操作完成,从而降低了日志记录引入的延迟。
- 缓冲日志消息:异步日志记录通常使用缓冲区来存储日志消息,可以一次性写入多个日志消息,提高了写入效率。
需要注意的是,异步日志记录需要合理的配置和管理,包括缓冲区大小、线程池的大小和资源占用等。此外,对于一些对日志顺序和实时性要求较高的场景,异步日志记录可能不是最佳选择,因为它可能会引入一定的延迟和日志消息的乱序。因此,在选择日志记录方式时,需要根据具体的应用需求进行权衡和选择。
logbak异步配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!---日志存放位置-->
<!--
1. ${user.dir}对应tomcat的bin目录
2. ${user.home}对应操作系统当前用户目录
3. ${webApp.root}对应当前应用根目录
-->
<property name="LOG_PATH" value="${user.home}/log/"/>
<!-- 读取spring的application.yaml 的变量 -->
<springProperty scope="context" name="apppName" source="spring.application.name" />
<property name="LOG_NAME" value="${apppName}"/>
<!-- 不带彩色的日志在控制台输出时候的设置 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<!-- %-5level 代表日志取五个字符,INFO 会变为 INFO加一个空格 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<File>${LOG_PATH}/${LOG_NAME}.log</File>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | [%thread] %level %logger{50} - %msg%n</pattern>
<!-- 此处设置字符集,防止中文乱码 -->
<charset>UTF-8</charset>
</encoder>
<!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2023-10-18日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而023-10-18的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${LOG_NAME}_%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过10M,若超过10M,日志文件会以索引0开始,
命名日志文件,例如log-2023-10-18.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志保留10天-->
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<appender name="ASYNC_INFO" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<appender-ref ref="LOG_FILE" />
</appender>
<root level="info">
<!-- 异步日志 -->
<!--<appender-ref ref="ASYNC_INFO"/>
</root>
</configuration>