当前位置: 首页 > article >正文

集成Log4j2以及异步日志

文章目录

    • 1.环境搭建
        • 1.在sunrays-common下创建一个单独的模块
        • 2.依赖关系
          • 1.继承父模块的版本和通用依赖
        • 3.创建自动配置相关
          • 1.目录
          • 2.pom.xml
          • 3.Log4j2AutoConfiguration.java 自动配置类
          • 4.META-INF/spring.factories 指定自动配置类
    • 2.集成Log4j2以及异步日志
        • 1.目录
        • 2.引入依赖
        • 3.log4j2.xml
        • 4.log4j2.component.properties 开启全局异步日志
        • 5.maven下载到本地仓库
    • 3.测试
        • 1.创建一个demo模块
        • 2.目录
        • 3.pom.xml 引入自定义的log4j2模块
        • 3.启动类
        • 4.Log4j2Test.java 测试
        • 5.测试结果
          • 1.控制台
          • 2.日志输出位置

1.环境搭建

1.在sunrays-common下创建一个单独的模块

CleanShot 2024-10-24 at 10.31.46@2x

2.依赖关系
1.继承父模块的版本和通用依赖

CleanShot 2024-10-24 at 17.02.54@2x

3.创建自动配置相关
1.目录

2.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-common</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>common-log4j2-starter</artifactId>

    <dependencies>
        <!-- SpringBoot自动配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
    </dependencies>

</project>
3.Log4j2AutoConfiguration.java 自动配置类
package com.sunxiansheng.log4j2.config;

import org.springframework.context.annotation.Configuration;

/**
 * Description: Log4j2自动配置类
 *
 * @Author sun
 * @Create 2024/10/24 10:36
 * @Version 1.0
 */
@Configuration
public class Log4j2AutoConfiguration {
}
4.META-INF/spring.factories 指定自动配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.sunxiansheng.log4j2.config.Log4j2AutoConfiguration

2.集成Log4j2以及异步日志

1.目录

2.引入依赖
<!-- log4j2日志 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- 异步日志 -->
<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.4.2</version>
</dependency>
3.log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Log4j2 配置的根元素 -->
<Configuration status="INFO" monitorInterval="30">
    <!--
        status="INFO":设置 Log4j2 内部日志的输出级别为 INFO,用于调试配置问题。
        monitorInterval="30":Log4j2 将每 30 秒检查一次配置文件的变化,实现热加载配置。
    -->

    <!-- 定义全局属性,可在整个配置文件中使用 -->
    <Properties>
        <!-- 日志文件存储的根目录 -->
        <Property name="LOG_HOME">./logs</Property>
        <!-- 日志文件的名称前缀 -->
        <Property name="LOG_NAME">sunrays-framework</Property>
        <!-- 控制台日志输出格式,带颜色 -->
        <Property name="CONSOLE_LOG_PATTERN">
            %style{%d{yyyy-MM-dd HH:mm:ss.SSS}}{green} %style{[%t]}{blue} %highlight{%p}{STYLE=LOGBACK} %style{[PFTID:%X{PFTID}]}{magenta} %style{%logger{36}}{cyan} - %msg%n%throwable
        </Property>

        <!-- 文件日志输出格式,不带颜色 -->
        <Property name="FILE_LOG_PATTERN">
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5p [PFTID:%X{PFTID}] %logger{36} - %msg%n%throwable
        </Property>

    </Properties>

    <!-- 定义日志输出目的地(Appender) -->
    <Appenders>
        <!-- 控制台输出 -->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 使用带颜色的布局模式 -->
            <PatternLayout pattern="${CONSOLE_LOG_PATTERN}"/>
            <!-- 设置日志级别过滤器,只允许 INFO 及以上级别 -->
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
        </Console>

        <!-- INFO 级别日志文件输出 -->
        <RollingFile name="InfoFile"
                     fileName="${LOG_HOME}/unarchived/info/${date:yyyy-MM-dd}/current.log"
                     filePattern="${LOG_HOME}/archived/info/${date:yyyy-MM-dd}/${LOG_NAME}-info-%d{yyyy-MM-dd-HH-mm-ss}-%i.log.gz">
            <!-- 使用不带颜色的布局模式 -->
            <PatternLayout pattern="${FILE_LOG_PATTERN}"/>
            <Policies>
                <!-- 使用 Cron 表达式,每2小时归档一次 -->
                <CronTriggeringPolicy schedule="0 0 0/2 * * ?"/>
                <!-- 文件大小超过 50MB 时归档 -->
                <SizeBasedTriggeringPolicy size="50MB"/>
            </Policies>
            <DefaultRolloverStrategy>
                <!-- 删除超过7天的归档日志 -->
                <Delete basePath="${LOG_HOME}/archived/info" maxDepth="2">
                    <IfFileName glob="*.log.gz"/>                        <!-- 匹配 .log.gz 的文件 -->
                    <IfLastModified age="7d"/>                           <!-- 文件修改时间超过7天 -->
                </Delete>
            </DefaultRolloverStrategy>
            <Filters>
                <!-- 只接受 INFO 及以上级别的日志 -->
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </RollingFile>

        <!-- WARN 级别日志文件输出 -->
        <RollingFile name="WarnFile"
                     fileName="${LOG_HOME}/unarchived/warn/${date:yyyy-MM-dd}/current.log"
                     filePattern="${LOG_HOME}/archived/warn/${date:yyyy-MM-dd}/${LOG_NAME}-warn-%d{yyyy-MM-dd-HH-mm-ss}-%i.log.gz">
            <PatternLayout pattern="${FILE_LOG_PATTERN}"/>
            <Policies>
                <CronTriggeringPolicy schedule="0 0 0/2 * * ?"/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            </Policies>
            <DefaultRolloverStrategy>
                <Delete basePath="${LOG_HOME}/archived/warn" maxDepth="2">
                    <IfFileName glob="*.log.gz"/>
                    <IfLastModified age="7d"/>
                </Delete>
            </DefaultRolloverStrategy>
            <Filters>
                <!-- 只接受 WARN 及以上级别的日志 -->
                <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </RollingFile>

        <!-- ERROR 级别日志文件输出 -->
        <RollingFile name="ErrorFile"
                     fileName="${LOG_HOME}/unarchived/error/${date:yyyy-MM-dd}/current.log"
                     filePattern="${LOG_HOME}/archived/error/${date:yyyy-MM-dd}/${LOG_NAME}-error-%d{yyyy-MM-dd-HH-mm-ss}-%i.log.gz">
            <PatternLayout pattern="${FILE_LOG_PATTERN}"/>
            <Policies>
                <CronTriggeringPolicy schedule="0 0 0/2 * * ?"/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            </Policies>
            <DefaultRolloverStrategy>
                <Delete basePath="${LOG_HOME}/archived/error" maxDepth="2">
                    <IfFileName glob="*.log.gz"/>
                    <IfLastModified age="7d"/>
                </Delete>
            </DefaultRolloverStrategy>
            <Filters>
                <!-- 只接受 ERROR 及以上级别的日志 -->
                <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </RollingFile>

        <!-- 全部级别日志文件输出(包含 DEBUG 及以上) -->
        <RollingFile name="AllFile"
                     fileName="${LOG_HOME}/unarchived/all/${date:yyyy-MM-dd}/current.log"
                     filePattern="${LOG_HOME}/archived/all/${date:yyyy-MM-dd}/${LOG_NAME}-all-%d{yyyy-MM-dd-HH-mm-ss}-%i.log.gz">
            <PatternLayout pattern="${FILE_LOG_PATTERN}"/>
            <Policies>
                <CronTriggeringPolicy schedule="0 0 0/2 * * ?"/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            </Policies>
            <DefaultRolloverStrategy>
                <Delete basePath="${LOG_HOME}/archived/all" maxDepth="2">
                    <IfFileName glob="*.log.gz"/>
                    <IfLastModified age="7d"/>
                </Delete>
            </DefaultRolloverStrategy>
            <!-- 不添加 ThresholdFilter,接受所有级别的日志 -->
        </RollingFile>
    </Appenders>

    <!-- 配置日志记录器(Logger),定义日志的输出规则和级别 -->
    <Loggers>
        <!--
            以下是针对特定模块的日志配置,目前被注释掉了。
            可以根据需要取消注释,定制化模块的日志级别和输出。
        -->

        <!-- 配置指定模块的异步日志 -->
        <!--
        <AsyncLogger name="com.sunxiansheng" level="DEBUG" additivity="false" includeLocation="false">
            <AppenderRef ref="Console"/>
        </AsyncLogger>
        -->
        <!--
            name="com.sunxiansheng":指定包名或类名,针对该模块进行配置。
            level="DEBUG":设置日志级别为 DEBUG,记录 DEBUG 及以上级别的日志。
            additivity="false":不向父 Logger 传递,防止日志重复输出。
            includeLocation="false":不包含代码位置信息,提高性能。
            <AppenderRef ref="Console"/>:将日志输出到 Console Appender。
        -->

        <!-- 配置其他特定模块的日志 -->
        <!--
        <Logger name="com.moduleA" level="INFO" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
        -->
        <!--
            针对 com.moduleA 包,设置日志级别为 INFO,日志只输出到 Console,不向上级传播。
        -->

        <!-- 根日志记录器,处理未被其他 Logger 捕获的日志 -->
        <Root level="DEBUG">
            <!-- 引用之前定义的所有 Appender -->
            <AppenderRef ref="Console"/>
            <AppenderRef ref="InfoFile"/>
            <AppenderRef ref="WarnFile"/>
            <AppenderRef ref="ErrorFile"/>
            <AppenderRef ref="AllFile"/>
        </Root>
        <!--
            level="DEBUG":设置根日志级别为 DEBUG,记录 DEBUG 及以上级别的日志。
            所有未被特定 Logger 处理的日志,都会按照根日志器的配置输出。
        -->
    </Loggers>
</Configuration>
4.log4j2.component.properties 开启全局异步日志
# 开启全局异步日志
log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
5.maven下载到本地仓库

clean-install

3.测试

1.创建一个demo模块

CleanShot 2024-10-24 at 17.16.48@2x

2.目录

CleanShot 2024-10-24 at 17.25.18@2x

3.pom.xml 引入自定义的log4j2模块
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>common-log4j2-starter-demo</artifactId>

    <dependencies>
        <!-- common-log4j2-starter -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>common-log4j2-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <!-- 排除掉logging -->
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>
3.启动类
package com.sunxiansheng.log4j2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/10/24 17:22
 * @Version 1.0
 */
@SpringBootApplication
public class Log4j2Application {

    public static void main(String[] args) {
        SpringApplication.run(Log4j2Application.class, args);
    }
}
4.Log4j2Test.java 测试
package com.sunxiansheng.log4j2;

import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.async.AsyncLoggerContext;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/10/24 17:20
 * @Version 1.0
 */
@SpringBootTest
@Slf4j
public class Log4j2Test {

    @Test
    public void test() {
        log.info("info");
        log.warn("warn");
        log.error("error");
        // 输出当前的工作目录
        System.out.println("Current Working Directory: " + System.getProperty("user.dir"));
        // 测试是否是异步模式
        if (LogManager.getContext(false) instanceof AsyncLoggerContext) {
            // 异步模式
            System.out.println("Log4j2 is running in asynchronous mode.");
        } else {
            // 同步模式
            System.out.println("Log4j2 is running in synchronous mode.");
        }
    }
}
5.测试结果
1.控制台

CleanShot 2024-10-24 at 17.26.45@2x

2.日志输出位置

CleanShot 2024-10-24 at 17.27.55@2x


http://www.kler.cn/a/487928.html

相关文章:

  • js代理模式
  • 统计模型的Flops和Params
  • 人工智能与物联网:智慧城市的未来
  • C#中的常用集合
  • VSCode 在Windows下开发时使用Cmake Tools时输出Log乱码以及CPP文件乱码的终极解决方案
  • Spring Boot教程之四十九:Spring Boot – MongoRepository 示例
  • C++ 各标准的新特性
  • 【Oracle专栏】实用SQL、查询处理
  • 【update 更新数据语法合集】.NET开源ORM框架 SqlSugar 系列
  • 跨域问题,开发
  • QML states和transitions的使用
  • 油猴支持阿里云自动登陆插件
  • kotlin项目无法访问Java类的问题
  • 龙蜥Linux系统部署docker21.1.3版本
  • 同域名前后端分离项目 nginx配置实践
  • LCE(Local Cascade Ensemble)预测模型和LSTM(Long Short-Term Memory)模型在效果和特点上存在显著差异
  • 3D目标检测数据集——kitti数据集
  • 计算机网络之---HTTP协议
  • TDengine + MQTT :车联网时序数据库如何高效接入
  • 第一天 了解HarmonyOS的起源、发展、核心特性
  • 每天40分玩转Django:Django 实操图书管理系统
  • 一款面向数字孪生的数据中台
  • QT 常用控件的常用方法
  • Zookeeper 集群安装
  • 机房预约系统|Java|SSM|JSP|
  • 在 Vivado 的 Block Design 中,如果你不想让某个 IP 核的引脚连接到外部引脚,可以通过以下几种方法来处理: