This commit is contained in:
2025-12-21 17:24:54 +08:00
commit e8c50a3d78
660 changed files with 29599 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
package com.inmind.student.杨靖宇;
import java.io.*;
import java.net.Socket;
import java.util.*;
import java.net.*;
public class LogAnalyzer {
private static final String LOG_DIR = "D:\\io_test";
private static final String SERVER_HOST = "localhost";
private static final int SERVER_PORT = 8080;
private final List<Log> logs = Collections.synchronizedList(new ArrayList<>());
private final List<Thread> threads = new ArrayList<>();
public static void main(String[] args) {
LogAnalyzer analyzer = new LogAnalyzer();
try {
analyzer.analyze();
} catch (FileNotFoundException e) {
System.err.println("[错误] 日志目录不存在: " + e.getMessage());
} catch (Exception e) {
System.err.println("[错误] 分析过程中出现异常: " + e.getMessage());
e.printStackTrace();
}
}
public void analyze() throws FileNotFoundException {
// 1. 检查并创建日志目录
ensureLogDirectoryExists();
// 2. 读取日志文件
readLogFiles();
// 3. 等待所有线程完成
waitForThreads();
if (logs.isEmpty()) {
System.out.println("[提示] 没有解析到任何有效日志");
return;
}
// 4. 统计日志数据
Map<String, Integer> levelStats = countByLevel();
Map<String, Integer> moduleErrorStats = countModuleErrors();
List<Log> earliestLogs = getEarliestLogs(3);
// 5. 上报统计结果
reportToServer(levelStats, moduleErrorStats, earliestLogs);
}
private void ensureLogDirectoryExists() throws FileNotFoundException {
File logDir = new File(LOG_DIR);
if (!logDir.exists()) {
System.out.println("[提示] 日志目录不存在,尝试创建...");
if (!logDir.mkdirs()) {
throw new FileNotFoundException("无法创建日志目录: " + LOG_DIR);
}
System.out.println("[成功] 已创建日志目录: " + LOG_DIR);
}
}
private void readLogFiles() throws FileNotFoundException {
File logDir = new File(LOG_DIR);
File[] logFiles = logDir.listFiles((dir, name) -> name.endsWith(".log"));
if (logFiles == null || logFiles.length == 0) {
System.out.println("[提示] 目录中没有找到.log文件");
return;
}
System.out.printf("[信息] 找到 %d 个日志文件\n", logFiles.length);
for (File file : logFiles) {
Thread thread = new Thread(() -> parseLogFile(file));
threads.add(thread);
thread.start();
}
}
private void waitForThreads() {
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
System.err.println("[警告] 线程等待被中断");
Thread.currentThread().interrupt();
break;
}
}
}
private void parseLogFile(File file) {
System.out.printf("[信息] 开始解析文件: %s\n", file.getName());
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
int lineNum = 0;
int successCount = 0;
while ((line = reader.readLine()) != null) {
lineNum++;
try {
Log log = parseLogLine(line);
logs.add(log);
successCount++;
} catch (NumberFormatException e) {
System.err.printf("[警告] %s 第 %d 行: 时间戳格式错误\n",
file.getName(), lineNum);
} catch (IllegalArgumentException e) {
System.err.printf("[警告] %s 第 %d 行: 日志格式错误\n",
file.getName(), lineNum);
}
}
System.out.printf("[成功] 文件 %s 解析完成: 总行数 %d, 成功 %d, 失败 %d\n",
file.getName(), lineNum, successCount, lineNum - successCount);
} catch (FileNotFoundException e) {
System.err.printf("[错误] 文件不存在: %s\n", file.getPath());
} catch (IOException e) {
System.err.printf("[错误] 读取文件 %s 失败: %s\n", file.getName(), e.getMessage());
}
}
private Log parseLogLine(String line) throws IllegalArgumentException, NumberFormatException {
String[] parts = line.split(",", 4);
if (parts.length != 4) {
throw new IllegalArgumentException("需要4个字段但找到" + parts.length);
}
long timestamp = Long.parseLong(parts[0].trim());
return new Log(timestamp, parts[1].trim(), parts[2].trim(), parts[3].trim());
}
private Map<String, Integer> countByLevel() {
Map<String, Integer> stats = new HashMap<>();
synchronized (logs) {
for (Log log : logs) {
stats.merge(log.getLevel(), 1, Integer::sum);
}
}
return stats;
}
private Map<String, Integer> countModuleErrors() {
Map<String, Integer> stats = new HashMap<>();
synchronized (logs) {
for (Log log : logs) {
if ("ERROR".equals(log.getLevel())) {
stats.merge(log.getModule(), 1, Integer::sum);
}
}
}
return stats;
}
private List<Log> getEarliestLogs(int count) {
List<Log> copy;
synchronized (logs) {
copy = new ArrayList<>(logs);
}
if (copy.isEmpty()) {
return Collections.emptyList();
}
copy.sort(Comparator.comparingLong(Log::getTimestamp));
return new ArrayList<>(copy.subList(0, Math.min(count, copy.size())));
}
private void reportToServer(Map<String, Integer> levelStats,
Map<String, Integer> moduleErrorStats,
List<Log> earliestLogs) {
final int maxRetries = 3;
int attempt = 0;
while (attempt < maxRetries) {
attempt++;
try (Socket socket = new Socket()) {
// 设置连接和读取超时
socket.connect(new InetSocketAddress(SERVER_HOST, SERVER_PORT), 5000);
socket.setSoTimeout(10000);
try (ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
// 确保发送的是可序列化的ArrayList
oos.writeObject(new HashMap<>(levelStats));
oos.writeObject(new HashMap<>(moduleErrorStats));
oos.writeObject(new ArrayList<>(earliestLogs));
oos.flush();
String response = (String) ois.readObject();
System.out.println("[成功] 服务器响应: " + response);
return;
}
} catch (ConnectException e) {
System.err.printf("[错误] 连接失败(尝试 %d/%d): %s\n",
attempt, maxRetries, e.getMessage());
if (attempt >= maxRetries) {
System.err.println("[错误] 达到最大重试次数,放弃连接");
} else {
try {
Thread.sleep(1000 * attempt);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
return;
}
}
} catch (SocketTimeoutException e) {
System.err.println("[错误] 连接或读取超时");
} catch (EOFException e) {
System.err.println("[错误] 连接意外中断");
} catch (UnknownHostException e) {
System.err.println("[错误] 未知主机: " + SERVER_HOST);
break;
} catch (IOException e) {
System.err.println("[错误] 通信错误: " + e.getMessage());
break;
} catch (ClassNotFoundException e) {
System.err.println("[错误] 协议错误: 收到未知响应类型");
break;
}
}
}
}