日志打印包括 数据库操作记录,日常run日志,接口调用记录(分布式系统中会有更详细的接口日志)
1 日志框架选择
常见的日志框架无外乎Log4j、Logback、Log4j2。Spring Boot 默认的日志记录框架使用的是 Logback,Log4j已过时且停止更新,性能最好的还属 Log4j2(优点:高吞吐量、低延迟)
看图说话:64线程的log4j2异步日志处理能力最强,达到了1800万+/秒;同步异步混用次之。
2 log4j2框架引用
Spring Boot中spring-boot-starter-web 下的spring-boot-starter已集成了logback日志框架,要用log4j2的话需要先手ban掉这伙计,再检查下有没有其他日志框架的冲突问题。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
3 日志框架使用之怎样查字典(基础)
3.1 日志分类
TRACE:追踪。一般上对核心系统进行性能调试或者跟踪问题时有用,此级别很低,一般上是不开启的,开启后日志会很快就打满磁盘的。
DEBUG:调试。这个大家应该不陌生了。开发过程中主要是打印记录一些运行信息之类的。
INFO:信息。这个是最常见的了,大部分默认就是这个级别的日志。一般上记录了一些交互信息,一些请求参数等等。可方便定位问题,或者还原现场环境的时候使用。此日志相对来说是比较重要的。
WARN:警告。这个一般上是记录潜在的可能会引发错误的信息。比如启动时,某某配置文件不存在或者某个参数未设置之类的。
ERROR:错误。这个也是比较常见的,一般上是在捕获异常时输出,虽然发生了错误,但不影响系统的正常运行。但可能会导致系统出错或是宕机等。
3.2 日志文件中部分字段含义
appender:主要控制日志输出到哪里,比如:文件、数据库、控制台打印等
logger: 用来设置某一个包或者具体某一个类的日志打印级别、以及指定appender
root:也是一个logger,是一个特殊的父logger。所有的子logger最终都会将输出流交给root,除非在子logger中配置了additivity="false"。
rollingPolicy:所有日志都放在一个文件是不好的,所以可以指定滚动策略,按照一定周期或文件大小切割存放日志文件。
RolloverStrategy:日志清理策略。通常是指日志保留的时间。
异步日志:单独开一个线程做日志的写操作,达到不阻塞主线程的目的。
同步日志,主线程要等到日志写磁盘完成之后,才能继续向下执行
3.3 划重点,下面这句话是异步日志的核心,谨记
异步日志,主线程写日志只是将日志消息放入一个队列,之后就继续向下执行,这个过程是在内存层面完成的。之后由专门的线程从队列中获取日志数据写入磁盘,所以不阻塞主线程。主线程(核心业务代码)执行效率很高。
4 日志文件配置
提供一份日志配置(全局异步模式、异步/同步混合双打模式),包含接口访问、mysql(一般数据库日志量很大,但用于定位SB问题贼有效,普通场景打印warn或error即可)、run运行(单服务的日志场景较少,后面梳理分布式的时候再系统考虑)的日志配置log4j2.xml,谨送给拿来主义的精神胜利者!
4.1 日志配置:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<properties>
<!--日志输出位置,尽量把文件夹定义的好认-->
<property name="log_home">D:/logs</property>
<property name="module">module_name</property>
</properties>
<Appenders><!--针对日志的功能进行分类-->
<!-- 将日志输出到控制台-->
<Console name="CONSOLE" target="SYSTEM_OUT">
<!--设置日志格式及颜色-->
<PatternLayout
pattern="[%style{%d}{bright,green}][%highlight{%p}][%style{%t}{bright,blue}][%style{%C}{bright,yellow}]: %msg%n%style{%throwable}{red}"
disableAnsi="false" noConsoleNoAnsi="false"/>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"></ThresholdFilter>
</Console>
<!-- run.log (接口日志雷同,不再赘述)-->
<RollingRandomAccessFile name="ASKY_RUN"
fileName="${LOG_HOME}/${FILE_FOLDER}/asky_run.log"
filePattern="${LOG_HOME}/${FILE_FOLDER}/log4j2-demo-%d{yyyy-MM-dd}-%i.log.gz">
<!--设置日志格式-->
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS}(%r):%4p%X[%t](%F:%L)-->%m%n" />
<Policies>
<!-- 设置日志文件切分参数 -->
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="100 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
<!--设置最大存档数-->
<DefaultRolloverStrategy max="20"/>
<Filters>
<ThresholdFilter level="info" onMismatch="DENY" onMatch="accept" />
</Filters>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="INFO"><!--定义根目录日志打印级别-->
<AppenderRef ref="CONSOLE" level="debug"/>
<AppenderRef ref="ASKY_RUN" level="info"/>
</Root>
<!--spring日志-->
<Logger name="org.springframework" level="info"/>
<!-- mybatis日志 -->
<Logger name="com.mybatis" level="warn"/>
</Loggers>
</configuration>
<SizeBasedTriggeringPolicy size="100 MB"/> 当文件大小到100MB的时候,切分一个新的日志文件
<DefaultRolloverStrategy max="20"/>表示文件最大的存档数量,多余的将被删除
5 异步日志
异步日志要引用的jar
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.6</version>
</dependency>
<Loggers>
<!-- 针对com.asky包下面的日志采用异步日志 -->
<AsyncLogger name="com.asky" level="debug" additivity="false">
<AppenderRef ref="CONSOLE" level="debug"/>
<AppenderRef ref="ASKY_RUN" level="info"/>
</AsyncLogger>
<!-- 系统默认日志设置 -->
<Root level="debug">
<AppenderRef ref="CONSOLE" level="debug"/>
<AppenderRef ref="ASKY_RUN" level="info"/>
</Root>
</Loggers>
日志使用:
注:本文部分知识点来源自字母哥的springboot2.0教学,个人推荐地址:https://www.kancloud.cn/hanxt/springboot2/1871650