Springboot2.x 使用 Log4j2 异步打印日志的实现

介绍

目前常用的 Java 日志框架有 Log4j、Logback、Log4j2 ,性能方面推荐使用异步的 Log4j2,具体对比不多做分析,前人早已完成耕荒,我们就站在巨人的肩膀上来看看如何实操。

SLF4J,简单日志门面(Simple Logging Facade for Java),是一个用于日志系统的简单 Facade,不是具体的日志解决方案,而是通过Facade Pattern提供一些Java logging API,我的理解是它和 Log4j、Logback、Log4j2 的关系类似于 Java 接口与实现类的关系。

1、pom 准备

1.1、war 包 web 工程

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 <exclusions>
  <!--排除 springboot 默认的 logback 依赖 -->
  <exclusion>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-logging</artifactId>
  </exclusion>
 </exclusions>
</dependency>
<!--引入 log4j2-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-log4j2</artifactId>
 <version>2.2.6.RELEASE</version>
</dependency>
<!--异步,使用 log4j2 的 AsyncLogger 时需要包含 disruptor-->
<dependency>
 <groupId>com.lmax</groupId>
 <artifactId>disruptor</artifactId>
 <version>3.4.2</version>
</dependency>

1.2、jar 包自启动工程

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter</artifactId>
 <exclusions>
  <!--排除 springboot 默认的 logback 依赖 -->
  <exclusion>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-logging</artifactId>
  </exclusion>
 </exclusions>
</dependency>
<!--引入 log4j2-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-log4j2</artifactId>
 <version>2.2.6.RELEASE</version>
</dependency>
<!--异步,使用 log4j2 的 AsyncLogger 时需要包含 disruptor-->
<dependency>
 <groupId>com.lmax</groupId>
 <artifactId>disruptor</artifactId>
 <version>3.4.2</version>
</dependency>

2、application.yml 配置

# 引入日志配置文件
logging:
 config: classpath:log4j2.xml

3、log4j2.xml 配置

classpath:log4j2.xml 的话,log4j2.xml 放在目录 resources 下即可

<?xml version="1.0" encoding="UTF-8"?>
<!--Configuration 后面的 status,这个用于设置 log4j2 自身内部的信息输出级别,可以不设置,当设置成 trace 时,你会看到 log4j2 内部各种详细输出-->
<!--monitorInterval:Log4j2 能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="error" monitorInterval="30">
 <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->

 <!--变量配置-->
 <Properties>
  <!-- 格式化输出:%date 表示日期,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度 %msg:日志消息,%n 是换行符-->
  <!-- %logger{36} 表示 Logger 名字最长 36 个字符 -->
  <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level [%logger{50}:%L] - %msg%n" />
  <!-- 定义日志存储的路径 -->
  <property name="FILE_PATH" value="/var/log/songo" />
  <property name="FILE_NAME" value="songo" />
 </Properties>

 <appenders>

  <console name="Console" target="SYSTEM_OUT">
   <!--输出日志的格式-->
   <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
  </console>

  <!-- 这个会打印出所有的info及以上级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
  <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/${FILE_NAME}/${FILE_NAME}.log" filePattern="${FILE_PATH}/${FILE_NAME}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz" append="true">
   <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
   <Policies>
    <!-- 基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。有两个参数:
    interval,integer型,指定两次封存动作之间的时间间隔。单位:以日志的命名精度来确定单位,
     比如yyyy-MM-dd-HH 单位为小时,yyyy-MM-dd-HH-mm 单位为分钟
    modulate,boolean型,说明是否对封存时间进行调制。若modulate=true,
     则封存时间将以0点为边界进行偏移计算。比如,modulate=true,interval=4hours,
     那么假设上次封存日志的时间为00:00,则下次封存日志的时间为04:00,
     之后的封存时间依次为08:00,12:00,16:00-->
    <TimeBasedTriggeringPolicy interval="1"/>
    <SizeBasedTriggeringPolicy size="10MB"/>
   </Policies>
   <!-- DefaultRolloverStrategy 属性如不设置,则默认为最多同一文件夹下当天 7 个文件后开始覆盖-->
   <DefaultRolloverStrategy max="30">
    <!-- 删除处理策略,在配置的路径中搜索,maxDepth 表示往下搜索的最大深度 -->
    <Delete basePath="${FILE_PATH}/${FILE_NAME}/" maxDepth="2">
     <!-- 文件名搜索匹配,支持正则 -->
     <IfFileName glob="*.log.gz" />
     <!--!Note: 这里的 age 必须和 filePattern 协调, 后者是精确到 dd, 这里就要写成 xd, xD 就不起作用
     另外, 数字最好 >2, 否则可能造成删除的时候, 最近的文件还处于被占用状态,导致删除不成功!-->
     <!--7天-->
     <IfLastModified age="7d" />
    </Delete>
   </DefaultRolloverStrategy>
  </RollingFile>
 </appenders>

 <!--Logger 节点用来单独指定日志的形式,比如要为指定包下的 class 指定不同的日志级别等。-->
 <!--然后定义 loggers,只有定义了 logger 并引入的 appender,appender 才会生效-->
 <loggers>
  <!--若是 additivity 设为 false,则子 Logger 只会在自己的 appender 里输出,而不会在父 Logger 的 appender 里输出。-->
  <!--Console、RollingFileInfo 没有配置 ThresholdFilter,默认走的是 AsyncRoot 的 level 级别,
   com.songo.mapper 为我项目 mapper 的包路径,级别设为 debug,可以打印 sql 语句-->
  <AsyncLogger name="com.songo.mapper" level="debug" additivity="false">
   <appender-ref ref="Console"/>
   <appender-ref ref="RollingFileInfo"/>
  </AsyncLogger>
  <AsyncLogger name="org.springframework" level="warn" additivity="false">
   <appender-ref ref="Console"/>
   <appender-ref ref="RollingFileInfo"/>
  </AsyncLogger>
  <AsyncRoot level="info" includeLocation="true">
   <AppenderRef ref="Console"/>
   <AppenderRef ref="RollingFileInfo" />
  </AsyncRoot>
 </loggers>
</configuration>

4、使用

4.1、声明 logger 变量

package com.songo.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestService {
 private static final Logger logger = LoggerFactory.getLogger(TestService.class);

 public void Test() {
  logger.info("test...");
 }
}

4.2、简单点 lombok
引入 pom

<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <scope>provided</scope>
</dependency>
package com.songo.service;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class TestService {

 public void Test() {
  log.info("test...");
 }
}

5、验证

服务启动时,找到 log4j2 的线程,是如下内容说明 log4j2 异步日志打印配置成功

到此这篇关于Springboot2.x 使用 Log4j2 异步打印日志的实现的文章就介绍到这了,更多相关Springboot Log4j2 异步打印日志内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot2 集成log4j2日志框架的实现

    前言 Log4j2是 Log4j 的进化版本,并提供了许多 Logback 可用的改进,同时解决了 Logback 体系结构中的一些固有问题.而且日志处理中我们会用到kafka作为日志管道.而kafka客户端依赖与Logback的兼容不是很完美,你可以选择排除依赖冲突或者使用Log4j2 . <!-- more --> 排除Logback依赖 Spring Boot 2.x默认使用Logback日志框架,要使用 Log4j2必须先排除 Logback. <dependency> &

  • Springboot整合log4j2日志全解总结

    在项目推进中,如果说第一件事是搭Spring框架的话,那么第二件事情就是在Sring基础上搭建日志框架,我想很多人都知道日志对于一个项目的重要性,尤其是线上Web项目,因为日志可能是我们了解应用如何执行的唯一方式. 在18年大环境下,更多的企业使用Springboot和Springcloud来搭建他们的企业微服务项目 ,此篇文章是博主在实践中用Springboot整合log4j2日志的总结. 常用日志框架 java.util.logging:是JDK在1.4版本中引入的Java原生日志框架 Lo

  • SpringBoot集成slf4j+log4j2的示例代码

    本文介绍了SpringBoot集成slf4j+log4j2的示例代码,分享给大家,具体如下: Maven依赖 <!--增加log4j2依赖↓--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <dependency&g

  • Springboot2.x 使用 Log4j2 异步打印日志的实现

    介绍 目前常用的 Java 日志框架有 Log4j.Logback.Log4j2 ,性能方面推荐使用异步的 Log4j2,具体对比不多做分析,前人早已完成耕荒,我们就站在巨人的肩膀上来看看如何实操. SLF4J,简单日志门面(Simple Logging Facade for Java),是一个用于日志系统的简单 Facade,不是具体的日志解决方案,而是通过Facade Pattern提供一些Java logging API,我的理解是它和 Log4j.Logback.Log4j2 的关系类似

  • log4j2异步打印性能提升方式

    目录 log4j2异步打印性能提升 分析原因 解决方案 log4j2性能提升点 理解为以下三点 log4j2异步打印性能提升 压测结果发现,log4j升级成log4j2之后对系统性能影响并不大,更改打印日志方式(同步修改成异步打印) 压测结果发现TPS在开始阶段提升较快,当压力上来之后,TPS下降迅速,不如同步的数据(log4j2用的版本是2.3) 分析原因 获取压测是堆栈日志如下: 发现线程都在跑LockSupport.parkNanos也就是unsafe.park(false, 1);(pr

  • log4j2日志异步打印(实例讲解)

    log4j2支持日志的异步打印,日志异步输出的好处在于,使用单独的进程来执行日志打印的功能,可以提高日志执行效率,减少日志功能对正常业务的影响. 异步日志在程序的classpath需要加载disruptor-3.0.0.jar或者更高的版本. Asynchronous Loggers是一个新增特性在Log4j 2 ,可以实现完全异步也可以和同步混合使用,还可以只异步化Appender,以提升系统性能,官方数据显示混合没有完全异步化效果好. 1,完全异步模式: 这种异步日志方式,不需要修改原来的配

  • springboot使用log4j2异步日志提升性能的实现方式

    目录 一.引入disruptor 二. 全局异步模式 三.异步/同步混合模式 同步日志的业务流程处理和日志打印是在同一个线程,日志打印的过程实际上是写文件IO的过程,这个过程是相对耗时的,并且会阻塞主线程的执行,只有日志打印完成后才会继续执行业务处理代码.如果日志量比较大,会影响主业务流程的处理效率.异步日志实现方式:将日志存入一个单独的队列中,有一个单独的线程从队列中获取日志并写入磁盘文件. 日志放入队列的耗时,肯定比磁盘写IO文件耗时要少的多得多,所以对主业务流程影响极小. 一个单独的线程进

  • log4j2异步Logger(详解)

    1 异步Logger的意义 之前的日志框架基本都实现了AsyncAppender,被证明对性能的提升作用非常明显. 在log4j2日志框架中,增加了对Logger的异步实现.那么这一步的解耦,意义何在呢? 如图,按我目前的理解:异步Logger是让业务逻辑把日志信息放入Disruptor队列后可以直接返回(无需等待"挂载的各个Appender"都取走数据) 优点:更高吞吐.调用log方法更低的延迟. 缺点:异常处理麻烦. 可变日志消息问题.更大的CPU开销.需要等待"最慢的A

  • 详解SSM框架下结合log4j、slf4j打印日志

    本文主要介绍了详解SSM框架下结合log4j.slf4j打印日志,分享给大家,具体如下: 首先加入log4j和slf4j的jar包 <!-- 日志处理 <!-- slf4j日志包--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dep

  • 使用log4j2关闭debug日志

    目录 log4j2关闭debug日志 Log4J和slf4j的debug日志问题 log4j2关闭debug日志 最近项目引进入一个jar包,启动之之后debug日志就停不下来了,为了关闭这个日志花了半个下午.总结以下处理方式,以供大家参考: 1.如果引入了logback的jar包,排除引用(我的项目里没有引用) <exclusions> <exclusion> <groupId>ch.qos.logback</groupId> <artifactId

  • feign 打印日志不显示的问题及解决

    目录 feign打印日志不显示 feign基本使用 Feign 概述 Feign 入门案例 Feign 工作原理 feign打印日志不显示 1.是否有设置 feign 的 Logger.Level @Configuration public class FeignClientConfig {     @Bean     Logger.Level feignLogLevel() {         return Logger.Level.FULL;     } } 2.查看是否有在 yml 或者

  • Python异步发送日志到远程服务器详情

    目录 背景 StreamHandler和FileHandler 添加HTTPHandler 1使用多线程处理 2使用线程池处理 3使用异步aiohttp库来发送请求 背景 在Python中使用日志最常用的方式就是在控制台和文件中输出日志了,logging模块也很好的提供的相应 的类,使用起来也非常方便,但是有时我们可能会有一些需求,如还需要将日志发送到远端,或者直接写入数 据库,这种需求该如何实现呢? StreamHandler和FileHandler 首先我们先来写一套简单输出到cmd和文件中

  • Log4j定时打印日志及添加模块名配置的Java代码实例

    配置间隔时间,定时打印日志  接到个需求,通过log4j定时打印日志,需求描述如下:需要能够定时打印日志,时间间隔可配.说到定时,首先想到了DailyRollingFileAppender类,各种定时,根据datePattern,这个可以参考类SimpleDateFormat类,常见的一些定时设置如下: '.'yyyy-MM: 每月 '.'yyyy-ww: 每周 '.'yyyy-MM-dd: 每天 '.'yyyy-MM-dd-a: 每天两次 '.'yyyy-MM-dd-HH: 每小时 '.'yy

随机推荐