fix(ccdi-project): initialize file upload log context

This commit is contained in:
wkc
2026-03-09 16:55:14 +08:00
parent 041974b318
commit 4148bea5a9
2 changed files with 73 additions and 22 deletions

View File

@@ -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 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");
}
}

View File

@@ -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();
}
}