#AI
Junjie
8 小时以前 a7e973a98babb7804de5c0e162804bceab64d5c5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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());
    }
}