fix(ccdi-project): initialize file upload log context
This commit is contained in:
@@ -1,21 +1,20 @@
|
||||
package com.ruoyi.ccdi.project.log;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.classic.PatternLayout;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.FileAppender;
|
||||
import ch.qos.logback.core.UnsynchronizedAppenderBase;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.ILoggerFactory;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 文件上传批次日志Appender
|
||||
* 为每个批次创建独立的日志文件
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-03-05
|
||||
* File upload batch log appender.
|
||||
*/
|
||||
@Slf4j
|
||||
public class FileUploadLogAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
|
||||
@@ -26,10 +25,12 @@ public class FileUploadLogAppender extends UnsynchronizedAppenderBase<ILoggingEv
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
// 初始化日志格式
|
||||
LoggerContext loggerContext = resolveLoggerContext();
|
||||
setContext(loggerContext);
|
||||
|
||||
this.layout = new PatternLayout();
|
||||
this.layout.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n");
|
||||
this.layout.setContext(getContext());
|
||||
this.layout.setContext(loggerContext);
|
||||
this.layout.start();
|
||||
|
||||
super.start();
|
||||
@@ -45,52 +46,50 @@ public class FileUploadLogAppender extends UnsynchronizedAppenderBase<ILoggingEv
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定批次创建独立的日志文件
|
||||
* Create a dedicated batch log file.
|
||||
*
|
||||
* @param uploadPath ruoyi.profile配置的上传路径
|
||||
* @param projectId 项目ID
|
||||
* @param batchId 批次ID
|
||||
* @param uploadPath upload root path from ruoyi.profile
|
||||
* @param projectId project id
|
||||
* @param batchId batch id
|
||||
*/
|
||||
public static void createBatchLogFile(String uploadPath, Long projectId, String batchId) {
|
||||
try {
|
||||
// 构建日志文件路径: {ruoyi.profile}/logs/file-upload/{projectId}/{timestamp}.log
|
||||
LoggerContext loggerContext = resolveLoggerContext();
|
||||
|
||||
String timestamp = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date());
|
||||
String logDirPath = uploadPath + File.separator + "logs" + File.separator
|
||||
+ "file-upload" + File.separator + projectId;
|
||||
+ "file-upload" + File.separator + projectId;
|
||||
|
||||
// 确保目录存在
|
||||
File logDir = new File(logDirPath);
|
||||
if (!logDir.exists()) {
|
||||
logDir.mkdirs();
|
||||
if (!logDir.exists() && !logDir.mkdirs()) {
|
||||
throw new IllegalStateException("无法创建批次日志目录: " + logDirPath);
|
||||
}
|
||||
|
||||
String logFilePath = logDirPath + File.separator + timestamp + ".log";
|
||||
|
||||
// 创建FileAppender
|
||||
FileAppender<ILoggingEvent> appender = new FileAppender<>();
|
||||
appender.setContext(loggerContext);
|
||||
appender.setFile(logFilePath);
|
||||
|
||||
PatternLayout layout = new PatternLayout();
|
||||
layout.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n");
|
||||
layout.setContext(appender.getContext());
|
||||
layout.setContext(loggerContext);
|
||||
layout.start();
|
||||
|
||||
appender.setLayout(layout);
|
||||
appender.setAppend(true);
|
||||
appender.setContext(appender.getContext());
|
||||
appender.start();
|
||||
|
||||
currentAppender.set(appender);
|
||||
|
||||
log.info("【文件上传日志】创建批次日志文件: path={}, batchId={}", logFilePath, batchId);
|
||||
|
||||
log.info("【文件上传日志】创建批次日志文件成功: path={}, batchId={}", logFilePath, batchId);
|
||||
} catch (Exception e) {
|
||||
log.error("【文件上传日志】创建批次日志文件失败: projectId={}, batchId={}", projectId, batchId, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭当前批次的日志文件
|
||||
* Close the current batch log file.
|
||||
*/
|
||||
public static void closeBatchLogFile() {
|
||||
FileAppender<ILoggingEvent> appender = currentAppender.get();
|
||||
@@ -100,4 +99,12 @@ public class FileUploadLogAppender extends UnsynchronizedAppenderBase<ILoggingEv
|
||||
log.info("【文件上传日志】关闭批次日志文件");
|
||||
}
|
||||
}
|
||||
|
||||
private static LoggerContext resolveLoggerContext() {
|
||||
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
|
||||
if (loggerFactory instanceof LoggerContext loggerContext) {
|
||||
return loggerContext;
|
||||
}
|
||||
throw new IllegalStateException("SLF4J logger factory is not a Logback LoggerContext");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.ruoyi.ccdi.project.log;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.FileAppender;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class FileUploadLogAppenderTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
FileUploadLogAppender.closeBatchLogFile();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createBatchLogFile_shouldInitializeAppenderWithLoggerContext() throws Exception {
|
||||
FileUploadLogAppender.createBatchLogFile(tempDir.toString(), 32L, "batch-1");
|
||||
|
||||
FileAppender<ILoggingEvent> appender = currentAppender();
|
||||
|
||||
assertNotNull(appender);
|
||||
assertNotNull(appender.getContext());
|
||||
assertTrue(appender.isStarted());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private FileAppender<ILoggingEvent> currentAppender() throws Exception {
|
||||
Field field = FileUploadLogAppender.class.getDeclaredField("currentAppender");
|
||||
field.setAccessible(true);
|
||||
ThreadLocal<FileAppender<ILoggingEvent>> threadLocal =
|
||||
(ThreadLocal<FileAppender<ILoggingEvent>>) field.get(null);
|
||||
return threadLocal.get();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user