首页 > 编程语言 >Java程序运行时动态生成日志文件-loj4j

Java程序运行时动态生成日志文件-loj4j

时间:2025-01-16 16:12:54浏览次数:1  
标签:Java 程序运行 appender Appender loj4j logging apache org log4j

1.创建Appender;

2.logger实例和appender的绑定和解绑

3.logger实例使用 private static final Logger LOGGER = LogManager.getLogger(DeviceManagerCuppsIOHandler.class); 创建

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.17.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.17.2</version>
    </dependency>
        <!--这个需不需要引入看情况!-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-nop</artifactId>
        <version>1.7.25</version>
    </dependency>
package com.xx;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.layout.PatternLayout;

import java.util.Map;

/**
 *
 * log4j在程序运行时根据sessionId动态创建日志文件
 * <p>
 * .
 *
 * @author little_lunatic
 * @date 2025-01-14
 */
public class DynamicLogging {

    /** 获取Logger上下文 */
    private static final LoggerContext context = (LoggerContext) LogManager.getContext(false);
    /** 创建布局 */
    private static final PatternLayout layout = PatternLayout.newBuilder()
            .withPattern("[#%%&*^]%d{yyyyMMddHHmmss:SSS}.%ip:%processID,%threadID#%X{TransactionID}%%%X{CID}&%X{SessionID}*%X{CWA}^%X{serialNo}:%p>[%logger{0}:%L] %X{minaSessionId}>> %msg%n")
            .build();

    /** 创建TimeBasedTriggeringPolicy和SizeBasedTriggeringPolicy */
    private static final TimeBasedTriggeringPolicy timeBasedTriggeringPolicy = TimeBasedTriggeringPolicy.newBuilder()
            .withInterval(1)
            .withModulate(true)
            .build();
    private static final SizeBasedTriggeringPolicy sizeBasedTriggeringPolicy = SizeBasedTriggeringPolicy.createPolicy("10MB");

    /**使用CompositeTriggeringPolicy组合多个触发策略 */
    private static final CompositeTriggeringPolicy triggeringPolicy = CompositeTriggeringPolicy.createPolicy(timeBasedTriggeringPolicy, sizeBasedTriggeringPolicy);

    /** 创建DefaultRolloverStrategy */
    private static final DefaultRolloverStrategy rolloverStrategy = DefaultRolloverStrategy.newBuilder().withMax("7").build();

    /**
     * Logger实例绑定Appender
     * @param logger 需要绑定Appender的Logger实例
     * @param sessionId 会话ID,用于区分不同的日志文件
     */
    public static void createLoggerForSession(Logger logger, String sessionId) {
        // 从上下文中获取当前配置
        Configuration configuration = context.getConfiguration();

        // 读取属性
        String prefix = configuration.getStrSubstitutor().replace("${LOG_HOME}/${APP_NAME}.${MODULE_NAME}");

        // 定义日志文件名和模式
//        String fileName = prefix + ".session-" + sessionId + ".log";
//        String filePattern = prefix + ".session-" + sessionId + "_%d{yyyy-MM-dd}-%i.log.gz";
        String fileName = "logs/session-" + sessionId + ".log";
        String filePattern = "logs/session-" + sessionId + "_%d{yyyy-MM-dd}-%i.log.gz";

        // 避免未remove之前,多次创建相同的sessionid-appender
        Map<String, Appender> appenders = logger.getAppenders();
        Appender appender = appenders.get(sessionId);
        if (appender == null) {
            // 创建新的RollingFileAppender
            appender = RollingFileAppender.newBuilder()
                    .setName(sessionId)
                    .setLayout(layout)
                    .withFileName(fileName)
                    .withFilePattern(filePattern)
                    .withPolicy(triggeringPolicy)
                    .withStrategy(rolloverStrategy)
                    .build();
            // 启动Appender
            appender.start();
            // logger绑定Appender
            logger.addAppender(appender);
        }
    }

    /**
     * Logger实例解绑Appender
     * 该方法用于从Logger实例中解绑特定的Appender
     * 主要目的是在不需要保留日志输出的会话结束时,停止与该会话关联的Appender,并从Logger中移除
     *
     * @param logger Logger实例,即需要操作的日志记录器
     * @param sessionId 会话ID,用于标识特定的Appender
     */
    public static void removeLoggerForSession(Logger logger, String sessionId) {
        // 获取Logger实例中的所有Appender
        Map<String, Appender> appenderMap = logger.getAppenders();
        // 根据会话ID获取对应的Appender
        Appender appender = appenderMap.get(sessionId);
        // 检查是否找到了对应的Appender
        if (appender != null) {
            // 停止Appender,准备解绑
            appender.stop();
            // 从Logger实例中移除该Appender
            logger.removeAppender(appender);
        }
    }
}

标签:Java,程序运行,appender,Appender,loj4j,logging,apache,org,log4j
From: https://www.cnblogs.com/little-lunatic/p/18675173

相关文章

  • Java开发防止SQL注入攻击
    在Java编程过程中,防止SQL注入攻击是非常重要的安全措施。以下是常用的防注入攻击措施及其原理:1.使用预编译语句(PreparedStatement)原理:PreparedStatement是JDBC提供的一种接口,它允许SQL语句在执行前被预编译。通过使用占位符?来代替参数值,并在执行时动态设置这些参......
  • Java虚拟机堆区域的特点
    JVM(Java虚拟机)的堆(Heap)是用于存储对象实例的内存区域,是Java运行时数据区的一部分。JVM堆被划分为几个主要区域,每个区域都有特定的用途和管理方式。以下是JVM堆的主要结构及其特点:1.新生代(YoungGeneration)新生代是堆中用于存储新创建对象的区域。它被进一步划分为两个主......
  • 【开源免费】基于SpringBoot+Vue.JS林业产品推荐系统(JAVA毕业设计)
    本文项目编号T139,文末自助获取源码\color{red}{T139,文末自助获取源码}......
  • java面向对象继承
    1Java中的继承概念继承是面向对象编程(OOP)中的一个核心概念。在Java中,继承指的是一个类(子类)通过扩展(extends)另一个类(父类)来获得父类的属性和方法。继承有助于实现代码重用和扩展,也为多态性提供基础。继承使得子类能够拥有父类的所有非私有成员(字段、方法),同时子类还可以......
  • 2025年Java面试八股文合集(持续更新)
    1、并行与并发的区别并发是同一时间处理多件事的能力,比如多个线程轮流使用一个CPU并行是同一时间做多件事的能力,比如4核CPU同时执行4个线程关键区别在于是否同时执行2、创建线程的方式有哪几种?Runnable与Callable有什么区别?run方法与start方法有什么区别继承Tread类——......
  • Java内存泄漏
    内存管理基础:Java使用堆内存(Heap)来存储对象,所有通过new关键字创建的对象都会分配到堆内存中。垃圾回收(GC)是自动进行的,它负责清理那些不再被引用的对象。Java的垃圾回收机制通过标记清除(Mark-Sweep)算法来决定哪些对象可以被回收。内存泄漏的基本概念:内存泄漏指的是程序中......
  • JavaScript防抖与节流的运用
    防抖(Debounce)概念:防抖是指在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。防抖的主要目的是将多次连续触发的事件合并为一次执行,适用于例如输入框输入搜索内容时,避免频繁发送请求,只在用户停止输入一段时间后才发送请求。实现思路:创建一个定时器。......
  • 大数据学习记录,Java基础(4)
    多态多态的形式和体现1.对象的多态性对象的多态性:父类的引用指向子类的对象格式:(父类类型:指子类继承的父类类型,或者实现的接口类型)父类类型变量名=子类对象;例:Personp=newStudent();Objecto=newPerson();//Object类型的变量o,指向Person类型的对象o=newStuden......
  • 大数据学习记录,Java基础(3)
    面向对象面向对象的特征:封装随着系统越来越复杂,类会越来越多,那么类之间的访问边界必须把握好,面向对象的开发原则要遵循“高内聚、低耦合”,而“高内聚,低耦合”的体现之一:高内聚:类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用,尽量方便外部调用......
  • 【Java】若依(ruoyi-cloud)——14.Sentinel支持(服务熔断与降级)
    若依微服务版(ruoyi-Cloud)如何实现熔断和降级?知识前提:对Sentinel的使用有了解若依微服务版启动对nacos服务注册和使用有了解若依微服务版(ruoyi-cloud)中使用sentinel,进行服务熔断与降级。环境要求和前提JDK>=1.8(推荐1.8版本)Mysql>=5.7.0(推荐5.7版本)Redis>=......