package com.zy.ai.log;
|
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
import ch.qos.logback.classic.spi.ThrowableProxyUtil;
|
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<ILoggingEvent> {
|
|
// 保存最近 2000 条日志
|
private static final LinkedBlockingDeque<String> 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
|
);
|
|
String throwable = event.getThrowableProxy() != null ? ThrowableProxyUtil.asString(event.getThrowableProxy()) : null;
|
if (throwable != null && !throwable.isEmpty()) {
|
logLine = logLine + System.lineSeparator() + throwable;
|
}
|
|
// 放进环形缓冲区
|
if (LOG_BUFFER.remainingCapacity() == 0) {
|
LOG_BUFFER.pollFirst(); // 移除最旧的
|
}
|
LOG_BUFFER.offerLast(logLine);
|
}
|
|
public static List<String> getRecentLogs(int limit) {
|
int size = LOG_BUFFER.size();
|
int skip = Math.max(0, size - limit);
|
return LOG_BUFFER.stream()
|
.skip(skip)
|
.collect(Collectors.toList());
|
}
|
}
|