package com.zy.ai.log; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.AppenderBase; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.concurrent.LinkedBlockingDeque; import java.util.stream.Collectors; public class AiLogAppender extends AppenderBase { // 保存最近 2000 条日志 private static final LinkedBlockingDeque LOG_BUFFER = new LinkedBlockingDeque<>(2000); private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS") .withZone(ZoneId.systemDefault()); @Override protected void append(ILoggingEvent event) { String time = TIME_FORMATTER.format(Instant.ofEpochMilli(event.getTimeStamp())); String thread = event.getThreadName(); String level = event.getLevel().toString(); String loggerName = event.getLoggerName(); String message = event.getFormattedMessage(); String logLine = String.format( "%s [%s] %-5s %s - %s", time, thread, level, loggerName, message ); // 放进环形缓冲区 if (LOG_BUFFER.remainingCapacity() == 0) { LOG_BUFFER.pollFirst(); // 移除最旧的 } LOG_BUFFER.offerLast(logLine); } public static List getRecentLogs(int limit) { int size = LOG_BUFFER.size(); int skip = Math.max(0, size - limit); return LOG_BUFFER.stream() .skip(skip) .collect(Collectors.toList()); } }