Java日志异常检测案例

wen java案例 2

本文目录导读:

Java日志异常检测案例

  1. 项目结构
  2. 核心实现代码
  3. 运行说明
  4. 功能特性

我来为您提供一个完整的Java日志异常检测案例,包含实时监控和异常分析功能。

项目结构

log-anomaly-detector/
├── src/main/java/com/example/logdetector/
│   ├── model/
│   │   ├── LogEntry.java
│   │   └── AnomalyEvent.java
│   ├── detector/
│   │   ├── LogAnalyzer.java
│   │   └── AnomalyDetector.java
│   ├── parser/
│   │   └── LogParser.java
│   ├── storage/
│   │   └── LogStorage.java
│   └── alert/
│       └── AlertManager.java
└── pom.xml

核心实现代码

1 日志模型

// LogEntry.java
package com.example.logdetector.model;
import java.time.LocalDateTime;
public class LogEntry {
    private LocalDateTime timestamp;
    private String level;
    private String logger;
    private String message;
    private String threadName;
    private String exceptionType;
    private String stackTrace;
    // 构造函数
    public LogEntry(LocalDateTime timestamp, String level, String logger, 
                   String message, String threadName) {
        this.timestamp = timestamp;
        this.level = level;
        this.logger = logger;
        this.message = message;
        this.threadName = threadName;
    }
    // Getters and Setters
    public LocalDateTime getTimestamp() { return timestamp; }
    public void setTimestamp(LocalDateTime timestamp) { this.timestamp = timestamp; }
    public String getLevel() { return level; }
    public void setLevel(String level) { this.level = level; }
    public String getLogger() { return logger; }
    public void setLogger(String logger) { this.logger = logger; }
    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }
    public String getThreadName() { return threadName; }
    public void setThreadName(String threadName) { this.threadName = threadName; }
    public String getExceptionType() { return exceptionType; }
    public void setExceptionType(String exceptionType) { this.exceptionType = exceptionType; }
    public String getStackTrace() { return stackTrace; }
    public void setStackTrace(String stackTrace) { this.stackTrace = stackTrace; }
    @Override
    public String toString() {
        return String.format("[%s] [%s] [%s] %s - %s", 
            timestamp, level, threadName, logger, message);
    }
}
// AnomalyEvent.java
package com.example.logdetector.model;
import java.time.LocalDateTime;
import java.util.List;
public class AnomalyEvent {
    private String id;
    private LocalDateTime detectedTime;
    private String anomalyType;
    private String severity;
    private String description;
    private List<LogEntry> relatedLogs;
    private String suggestedAction;
    // 构造函数
    public AnomalyEvent(String anomalyType, String severity, String description) {
        this.detectedTime = LocalDateTime.now();
        this.anomalyType = anomalyType;
        this.severity = severity;
        this.description = description;
        this.id = generateId();
    }
    private String generateId() {
        return "ANOM-" + System.currentTimeMillis() + "-" + 
               (int)(Math.random() * 1000);
    }
    // Getters and Setters
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public LocalDateTime getDetectedTime() { return detectedTime; }
    public String getAnomalyType() { return anomalyType; }
    public void setAnomalyType(String anomalyType) { this.anomalyType = anomalyType; }
    public String getSeverity() { return severity; }
    public void setSeverity(String severity) { this.severity = severity; }
    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
    public List<LogEntry> getRelatedLogs() { return relatedLogs; }
    public void setRelatedLogs(List<LogEntry> relatedLogs) { this.relatedLogs = relatedLogs; }
    public String getSuggestedAction() { return suggestedAction; }
    public void setSuggestedAction(String suggestedAction) { this.suggestedAction = suggestedAction; }
}

2 日志解析器

// LogParser.java
package com.example.logdetector.parser;
import com.example.logdetector.model.LogEntry;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LogParser {
    // 日志模式匹配 - 支持多种格式
    private static final Pattern LOG_PATTERN = 
        Pattern.compile("(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3})\\s+" +
                       "\\[(\\w+)\\]\\s+" +
                       "\\[(\\w+)\\]\\s+" +
                       "(\\S+)\\s+" +
                       "\\-\\s+" +
                       "(.*)");
    private static final DateTimeFormatter FORMATTER = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
    public LogEntry parse(String logLine) {
        if (logLine == null || logLine.trim().isEmpty()) {
            return null;
        }
        Matcher matcher = LOG_PATTERN.matcher(logLine);
        if (matcher.matches()) {
            LocalDateTime timestamp = LocalDateTime.parse(matcher.group(1), FORMATTER);
            String level = matcher.group(2);
            String threadName = matcher.group(3);
            String logger = matcher.group(4);
            String message = matcher.group(5);
            LogEntry entry = new LogEntry(timestamp, level, logger, message, threadName);
            // 检测异常信息
            detectException(entry, message);
            return entry;
        }
        return null;
    }
    private void detectException(LogEntry entry, String message) {
        // 常见的异常类型
        String[] exceptionPatterns = {
            "Exception", "Error", "NullPointer", "ArrayIndexOutOfBounds",
            "ClassNotFoundException", "IOException", "SQLException",
            "NumberFormatException", "IllegalArgumentException"
        };
        for (String pattern : exceptionPatterns) {
            if (message.contains(pattern)) {
                entry.setExceptionType(pattern);
                // 提取堆栈跟踪信息
                extractStackTrace(entry, message);
                break;
            }
        }
    }
    private void extractStackTrace(LogEntry entry, String message) {
        // 简化的堆栈跟踪提取
        if (entry.getExceptionType() != null) {
            int startIndex = message.indexOf("at ");
            if (startIndex > 0) {
                entry.setStackTrace(message.substring(startIndex));
            }
        }
    }
}

3 异常检测器

// AnomalyDetector.java
package com.example.logdetector.detector;
import com.example.logdetector.model.AnomalyEvent;
import com.example.logdetector.model.LogEntry;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
public class AnomalyDetector {
    private static final int ERROR_THRESHOLD = 5; // 错误阈值
    private static final int TIME_WINDOW_MINUTES = 1; // 时间窗口
    private Map<String, List<LocalDateTime>> recentErrors = new HashMap<>();
    private Map<String, Integer> errorCounts = new HashMap<>();
    public List<AnomalyEvent> detectAnomalies(List<LogEntry> logs) {
        List<AnomalyEvent> anomalies = new ArrayList<>();
        for (LogEntry log : logs) {
            // 检测异常
            AnomalyEvent anomaly = analyzeLog(log);
            if (anomaly != null) {
                anomalies.add(anomaly);
            }
        }
        // 检测模式异常
        anomalies.addAll(detectPatternAnomalies(logs));
        return anomalies;
    }
    private AnomalyEvent analyzeLog(LogEntry log) {
        // 1. 检测错误级别日志
        if ("ERROR".equals(log.getLevel()) || "FATAL".equals(log.getLevel())) {
            return createErrorAnomaly(log);
        }
        // 2. 检测异常类型
        if (log.getExceptionType() != null) {
            return createExceptionAnomaly(log);
        }
        // 3. 检测关键错误信息
        if (containsCriticalKeywords(log.getMessage())) {
            return createCriticalAnomaly(log);
        }
        return null;
    }
    private AnomalyEvent createErrorAnomaly(LogEntry log) {
        AnomalyEvent anomaly = new AnomalyEvent("ERROR_LOG", "HIGH", 
            "Detected error: " + log.getMessage());
        anomaly.setSuggestedAction("Check the application logs for more details");
        anomaly.setRelatedLogs(Collections.singletonList(log));
        return anomaly;
    }
    private AnomalyEvent createExceptionAnomaly(LogEntry log) {
        AnomalyEvent anomaly = new AnomalyEvent("EXCEPTION", "CRITICAL", 
            "Exception '" + log.getExceptionType() + "' detected: " + log.getMessage());
        anomaly.setSuggestedAction("Review stack trace and fix the issue");
        anomaly.setRelatedLogs(Collections.singletonList(log));
        return anomaly;
    }
    private AnomalyEvent createCriticalAnomaly(LogEntry log) {
        AnomalyEvent anomaly = new AnomalyEvent("CRITICAL_KEYWORD", "HIGH", 
            "Critical keyword detected: " + log.getMessage());
        anomaly.setSuggestedAction("Immediate investigation required");
        anomaly.setRelatedLogs(Collections.singletonList(log));
        return anomaly;
    }
    private boolean containsCriticalKeywords(String message) {
        String[] keywords = {"out of memory", "connection refused", "deadlock", 
                            "disk full", "system crash"};
        if (message != null) {
            String lowerMessage = message.toLowerCase();
            return Arrays.stream(keywords).anyMatch(lowerMessage::contains);
        }
        return false;
    }
    private List<AnomalyEvent> detectPatternAnomalies(List<LogEntry> logs) {
        List<AnomalyEvent> anomalies = new ArrayList<>();
        // 1. 检测错误频率异常
        AnomalyEvent frequencyAnomaly = detectErrorFrequencyAnomaly(logs);
        if (frequencyAnomaly != null) {
            anomalies.add(frequencyAnomaly);
        }
        // 2. 检测特定模式
        AnomalyEvent patternAnomaly = detectSpecificPatterns(logs);
        if (patternAnomaly != null) {
            anomalies.add(patternAnomaly);
        }
        return anomalies;
    }
    private AnomalyEvent detectErrorFrequencyAnomaly(List<LogEntry> logs) {
        // 统计时间窗口内的错误数量
        long recentErrorCount = logs.stream()
            .filter(log -> "ERROR".equals(log.getLevel()) || "FATAL".equals(log.getLevel()))
            .count();
        if (recentErrorCount >= ERROR_THRESHOLD) {
            AnomalyEvent anomaly = new AnomalyEvent("HIGH_ERROR_RATE", "CRITICAL",
                String.format("High error rate detected: %d errors in recent logs", 
                            recentErrorCount));
            anomaly.setSuggestedAction("Investigate system stability immediately");
            anomaly.setRelatedLogs(logs.stream()
                .filter(log -> "ERROR".equals(log.getLevel()))
                .collect(Collectors.toList()));
            return anomaly;
        }
        return null;
    }
    private AnomalyEvent detectSpecificPatterns(List<LogEntry> logs) {
        // 检测连续失败模式
        String lastLogger = null;
        int consecutiveFailures = 0;
        for (LogEntry log : logs) {
            if (log.getExceptionType() != null || "ERROR".equals(log.getLevel())) {
                if (log.getLogger().equals(lastLogger)) {
                    consecutiveFailures++;
                    if (consecutiveFailures >= 3) {
                        AnomalyEvent anomaly = new AnomalyEvent("CONSECUTIVE_FAILURES", "HIGH",
                            String.format("Consecutive failures detected in %s: %d times", 
                                        log.getLogger(), consecutiveFailures));
                        anomaly.setSuggestedAction("Check the component for bugs");
                        return anomaly;
                    }
                } else {
                    lastLogger = log.getLogger();
                    consecutiveFailures = 1;
                }
            }
        }
        return null;
    }
}

4 日志分析器组合

// LogAnalyzer.java
package com.example.logdetector.detector;
import com.example.logdetector.model.AnomalyEvent;
import com.example.logdetector.model.LogEntry;
import com.example.logdetector.parser.LogParser;
import com.example.logdetector.storage.LogStorage;
import com.example.logdetector.alert.AlertManager;
import java.io.*;
import java.nio.file.*;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
public class LogAnalyzer {
    private final LogParser parser;
    private final AnomalyDetector detector;
    private final LogStorage storage;
    private final AlertManager alertManager;
    private ScheduledExecutorService scheduler;
    private long lastFileSize = 0;
    private Path logFilePath;
    public LogAnalyzer() {
        this.parser = new LogParser();
        this.detector = new AnomalyDetector();
        this.storage = new LogStorage();
        this.alertManager = new AlertManager();
    }
    public void startMonitoring(String logFilePath) throws IOException {
        this.logFilePath = Paths.get(logFilePath);
        this.scheduler = Executors.newScheduledThreadPool(1);
        // 每5秒检查一次新日志
        scheduler.scheduleAtFixedRate(() -> {
            try {
                analyzeNewLogs();
            } catch (Exception e) {
                System.err.println("Error analyzing logs: " + e.getMessage());
            }
        }, 0, 5, TimeUnit.SECONDS);
        System.out.println("Log monitoring started for: " + logFilePath);
    }
    private void analyzeNewLogs() throws IOException {
        File logFile = logFilePath.toFile();
        if (!logFile.exists()) {
            System.err.println("Log file not found: " + logFilePath);
            return;
        }
        long currentSize = logFile.length();
        // 只读取新增的内容
        if (currentSize > lastFileSize) {
            try (RandomAccessFile file = new RandomAccessFile(logFile, "r")) {
                file.seek(lastFileSize);
                String line;
                List<LogEntry> newLogs = new ArrayList<>();
                while ((line = file.readLine()) != null) {
                    LogEntry entry = parser.parse(line);
                    if (entry != null) {
                        newLogs.add(entry);
                        storage.storeLog(entry);
                    }
                }
                if (!newLogs.isEmpty()) {
                    // 检测异常
                    List<AnomalyEvent> anomalies = detector.detectAnomalies(newLogs);
                    // 处理异常
                    for (AnomalyEvent anomaly : anomalies) {
                        storage.storeAnomaly(anomaly);
                        alertManager.sendAlert(anomaly);
                    }
                    // 生成报告
                    if (!anomalies.isEmpty()) {
                        generateReport(anomalies);
                    }
                }
                lastFileSize = currentSize;
            }
        }
    }
    public void analyzeBatch(List<String> logLines) {
        List<LogEntry> logs = logLines.stream()
            .map(parser::parse)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
        System.out.println("Analyzing " + logs.size() + " log entries...");
        // 存储所有日志
        logs.forEach(storage::storeLog);
        // 检测异常
        List<AnomalyEvent> anomalies = detector.detectAnomalies(logs);
        // 输出结果
        System.out.println("\n=== Anomaly Detection Results ===");
        System.out.println("Total log entries: " + logs.size());
        System.out.println("Anomalies detected: " + anomalies.size());
        for (AnomalyEvent anomaly : anomalies) {
            System.out.println("\n" + anomaly.getId());
            System.out.println("Type: " + anomaly.getAnomalyType());
            System.out.println("Severity: " + anomaly.getSeverity());
            System.out.println("Time: " + anomaly.getDetectedTime());
            System.out.println("Description: " + anomaly.getDescription());
            System.out.println("Suggested Action: " + anomaly.getSuggestedAction());
            if (anomaly.getRelatedLogs() != null) {
                System.out.println("Related logs:");
                anomaly.getRelatedLogs().forEach(log -> 
                    System.out.println("  - " + log));
            }
        }
    }
    private void generateReport(List<AnomalyEvent> anomalies) {
        System.out.println("\n=== Real-time Anomaly Report ===");
        System.out.println("Time: " + LocalDateTime.now());
        long criticalCount = anomalies.stream()
            .filter(a -> "CRITICAL".equals(a.getSeverity()))
            .count();
        long highCount = anomalies.stream()
            .filter(a -> "HIGH".equals(a.getSeverity()))
            .count();
        System.out.println("Critical anomalies: " + criticalCount);
        System.out.println("High severity anomalies: " + highCount);
        System.out.println("Total anomalies: " + anomalies.size());
        // 按类型统计
        Map<String, Long> typeStats = anomalies.stream()
            .collect(Collectors.groupingBy(AnomalyEvent::getAnomalyType, 
                                          Collectors.counting()));
        System.out.println("\nAnomaly type statistics:");
        typeStats.forEach((type, count) -> 
            System.out.println("  " + type + ": " + count));
    }
    public void stopMonitoring() {
        if (scheduler != null) {
            scheduler.shutdown();
        }
        System.out.println("Log monitoring stopped.");
    }
}

5 存储层

// LogStorage.java
package com.example.logdetector.storage;
import com.example.logdetector.model.AnomalyEvent;
import com.example.logdetector.model.LogEntry;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public class LogStorage {
    private final Map<String, LogEntry> logStore = new ConcurrentHashMap<>();
    private final Map<String, AnomalyEvent> anomalyStore = new ConcurrentHashMap<>();
    private final int MAX_LOGS = 10000;
    private final int MAX_ANOMALIES = 1000;
    public void storeLog(LogEntry log) {
        String key = log.getTimestamp() + "-" + log.getThreadName() + "-" + 
                     System.nanoTime();
        if (logStore.size() >= MAX_LOGS) {
            // 移除最旧的日志
            String oldestKey = logStore.keySet().iterator().next();
            logStore.remove(oldestKey);
        }
        logStore.put(key, log);
    }
    public void storeAnomaly(AnomalyEvent anomaly) {
        if (anomalyStore.size() >= MAX_ANOMALIES) {
            // 移除最旧的异常
            String oldestKey = anomalyStore.keySet().iterator().next();
            anomalyStore.remove(oldestKey);
        }
        anomalyStore.put(anomaly.getId(), anomaly);
    }
    public List<LogEntry> getRecentLogs(int count) {
        return logStore.values().stream()
            .sorted((a, b) -> b.getTimestamp().compareTo(a.getTimestamp()))
            .limit(count)
            .collect(Collectors.toList());
    }
    public List<AnomalyEvent> getRecentAnomalies(int count) {
        return anomalyStore.values().stream()
            .sorted((a, b) -> b.getDetectedTime().compareTo(a.getDetectedTime()))
            .limit(count)
            .collect(Collectors.toList());
    }
    public List<LogEntry> getLogsByLevel(String level, LocalDateTime start, LocalDateTime end) {
        return logStore.values().stream()
            .filter(log -> log.getLevel().equals(level))
            .filter(log -> !log.getTimestamp().isBefore(start) && 
                          !log.getTimestamp().isAfter(end))
            .sorted((a, b) -> b.getTimestamp().compareTo(a.getTimestamp()))
            .collect(Collectors.toList());
    }
    public long getErrorCountInTimeWindow(LocalDateTime start, LocalDateTime end) {
        return logStore.values().stream()
            .filter(log -> "ERROR".equals(log.getLevel()) || 
                          "FATAL".equals(log.getLevel()))
            .filter(log -> !log.getTimestamp().isBefore(start) && 
                          !log.getTimestamp().isAfter(end))
            .count();
    }
    public Map<String, Long> getAnomalyStatistics() {
        return anomalyStore.values().stream()
            .collect(Collectors.groupingBy(AnomalyEvent::getAnomalyType, 
                                          Collectors.counting()));
    }
    public void clear() {
        logStore.clear();
        anomalyStore.clear();
    }
}

6 告警管理器

// AlertManager.java
package com.example.logdetector.alert;
import com.example.logdetector.model.AnomalyEvent;
import java.time.format.DateTimeFormatter;
import java.util.logging.Logger;
public class AlertManager {
    private static final Logger LOGGER = Logger.getLogger(AlertManager.class.getName());
    public void sendAlert(AnomalyEvent anomaly) {
        // 根据严重级别发送不同级别的告警
        switch (anomaly.getSeverity()) {
            case "CRITICAL":
                sendCriticalAlert(anomaly);
                break;
            case "HIGH":
                sendHighAlert(anomaly);
                break;
            case "MEDIUM":
                sendMediumAlert(anomaly);
                break;
            default:
                sendInfoAlert(anomaly);
        }
    }
    private void sendCriticalAlert(AnomalyEvent anomaly) {
        String alertMessage = formatAlert("CRITICAL", anomaly);
        System.err.println(alertMessage);
        sendEmail(anomaly, "CRITICAL");
        sendSMS(anomaly);
        // Log to system
        LOGGER.severe(alertMessage);
    }
    private void sendHighAlert(AnomalyEvent anomaly) {
        String alertMessage = formatAlert("HIGH", anomaly);
        System.out.println(alertMessage);
        sendEmail(anomaly, "HIGH");
        LOGGER.warning(alertMessage);
    }
    private void sendMediumAlert(AnomalyEvent anomaly) {
        String alertMessage = formatAlert("MEDIUM", anomaly);
        System.out.println(alertMessage);
        LOGGER.info(alertMessage);
    }
    private void sendInfoAlert(AnomalyEvent anomaly) {
        String alertMessage = formatAlert("INFO", anomaly);
        System.out.println(alertMessage);
        LOGGER.fine(alertMessage);
    }
    private String formatAlert(String severity, AnomalyEvent anomaly) {
        StringBuilder sb = new StringBuilder();
        sb.append("\n=== ").append(severity).append(" ALERT ===");
        sb.append("\nTime: ").append(anomaly.getDetectedTime()
            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        sb.append("\nType: ").append(anomaly.getAnomalyType());
        sb.append("\nDescription: ").append(anomaly.getDescription());
        sb.append("\nSuggested Action: ").append(anomaly.getSuggestedAction());
        sb.append("\n====================================\n");
        return sb.toString();
    }
    // 模拟邮件发送
    private void sendEmail(AnomalyEvent anomaly, String severity) {
        System.out.println("[EMAIL] Sending " + severity + " alert email for: " + 
                         anomaly.getAnomalyType());
        // 实际实现中应该使用邮件API
    }
    // 模拟短信发送(仅严重告警)
    private void sendSMS(AnomalyEvent anomaly) {
        System.out.println("[SMS] Sending critical alert SMS for: " + 
                         anomaly.getAnomalyType());
        // 实际实现中应该使用短信API
    }
    // Webhook通知
    public void sendWebhook(AnomalyEvent anomaly, String webhookUrl) {
        System.out.println("[WEBHOOK] Sending notification to: " + webhookUrl);
        // 实际实现中应该发送HTTP请求
    }
}

7 主程序和测试

// Main.java
package com.example.logdetector;
import com.example.logdetector.detector.LogAnalyzer;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class Main {
    public static void main(String[] args) {
        LogAnalyzer analyzer = new LogAnalyzer();
        // 测试数据 - 模拟日志行
        List<String> testLogs = Arrays.asList(
            "2024-01-15 10:30:45.123 [INFO] [main] com.example.service.UserService - User login successful: user123",
            "2024-01-15 10:30:46.234 [WARN] [http-nio-8080-exec-1] com.example.service.PaymentService - Payment processing delay detected",
            "2024-01-15 10:30:47.345 [ERROR] [http-nio-8080-exec-2] com.example.controller.OrderController - NullPointerException occurred while processing order",
            "2024-01-15 10:30:48.456 [ERROR] [http-nio-8080-exec-3] com.example.service.DatabaseService - Connection refused to database server",
            "2024-01-15 10:30:49.567 [FATAL] [main] com.example.Application - System crash detected: out of memory",
            "2024-01-15 10:30:50.678 [ERROR] [pool-1-thread-1] com.example.service.DataSyncService - IOException: File not found",
            "2024-01-15 10:30:51.789 [INFO] [http-nio-8080-exec-4] com.example.service.UserService - User logout: user456",
            "2024-01-15 10:30:52.890 [ERROR] [http-nio-8080-exec-5] com.example.controller.OrderController - SQLException: Deadlock detected",
            "2024-01-15 10:30:53.901 [ERROR] [http-nio-8080-exec-6] com.example.controller.OrderController - SQLException: Transaction rollback",
            "2024-01-15 10:30:54.012 [ERROR] [http-nio-8080-exec-7] com.example.controller.OrderController - SQLException: Connection timeout"
        );
        System.out.println("=== Java Log Anomaly Detection Demo ===\n");
        // 执行批量分析
        analyzer.analyzeBatch(testLogs);
        // 演示实时监控
        System.out.println("\n=== Starting Real-time Monitoring Demo ===");
        try {
            // 创建一个临时日志文件用于演示
            java.nio.file.Path tempFile = java.nio.file.Files.createTempFile("test-log", ".log");
            System.out.println("Monitoring log file: " + tempFile);
            analyzer.startMonitoring(tempFile.toString());
            // 模拟实时日志写入
            Thread.sleep(2000);
            java.nio.file.Files.write(tempFile, Arrays.asList(
                "2024-01-15 11:00:00.000 [ERROR] [main] com.example.service.CriticalService - Connection refused to external API"
            ));
            Thread.sleep(2000);
            java.nio.file.Files.write(tempFile, Arrays.asList(
                "2024-01-15 11:00:05.000 [FATAL] [main] com.example.Application - System resources exhausted"
            ));
            // 等待处理
            Thread.sleep(3000);
            // 停止监控
            analyzer.stopMonitoring();
            // 清理临时文件
            java.nio.file.Files.deleteIfExists(tempFile);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("\n=== Demo Completed ===");
    }
}

8 Maven依赖配置

<!-- pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>log-anomaly-detector</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- 日志框架 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.11</version>
        </dependency>
        <!-- JSON处理 -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.0</version>
        </dependency>
        <!-- 邮件发送 -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>
        <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

运行说明

  1. 编译项目

    mvn clean compile
  2. 运行测试

    mvn exec:java -Dexec.mainClass="com.example.logdetector.Main"
  3. 监控真实日志文件

    // 修改日志文件路径
    analyzer.startMonitoring("/var/log/application/app.log");

功能特性

检测能力:

  • 错误级别日志检测
  • 异常类型识别
  • 错误频率分析
  • 连续失败模式检测
  • 关键字匹配

告警级别:

  • CRITICAL: 系统崩溃、资源耗尽
  • HIGH: 数据库连接失败、死锁
  • MEDIUM: 性能问题、警告
  • INFO: 普通信息

扩展功能:

  • 实时日志监控
  • 邮件/SMS告警
  • 异常统计报告
  • 日志存储与查询

这个案例展示了完整的Java日志异常检测系统,可以直接运行和扩展使用。

抱歉,评论功能暂时关闭!