Слияние ui -> main #1
@@ -54,6 +54,7 @@ public class Bootstrap {
|
||||
logDir = baseDir.resolve("logs");
|
||||
Files.createDirectories(logDir);
|
||||
javafxPath = baseDir.resolve("lib").resolve("javafx");
|
||||
rotateLogs();
|
||||
|
||||
log("=== ZernMC Launcher ===");
|
||||
|
||||
@@ -371,11 +372,50 @@ public class Bootstrap {
|
||||
return javaBin;
|
||||
}
|
||||
|
||||
private static void rotateLogs() {
|
||||
// Minecraft-style: archive previous latest.log as .log.gz, keep unlimited.
|
||||
try {
|
||||
Path latest = logDir.resolve("latest.log");
|
||||
if (Files.exists(latest) && Files.size(latest) > 0) {
|
||||
String ts = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"));
|
||||
int n = 1;
|
||||
Path archive;
|
||||
do {
|
||||
archive = logDir.resolve(ts + (n == 1 ? "" : "-" + n) + ".log.gz");
|
||||
n++;
|
||||
} while (Files.exists(archive));
|
||||
gzip(archive, latest);
|
||||
Files.deleteIfExists(latest);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("[Bootstrap] rotate error: " + e.getMessage());
|
||||
}
|
||||
// Migrate old unlimited log.
|
||||
try {
|
||||
Files.deleteIfExists(logDir.resolve("launcher.log"));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static void gzip(Path archive, Path source) {
|
||||
try (java.io.InputStream in = Files.newInputStream(source);
|
||||
java.io.OutputStream out = Files.newOutputStream(archive);
|
||||
java.util.zip.GZIPOutputStream gz = new java.util.zip.GZIPOutputStream(out)) {
|
||||
byte[] buf = new byte[65536];
|
||||
int n;
|
||||
while ((n = in.read(buf)) > 0) {
|
||||
gz.write(buf, 0, n);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("[Bootstrap] gzip error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void log(String msg) {
|
||||
String entry = "[" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + "] " + msg;
|
||||
System.out.println(entry);
|
||||
try {
|
||||
Files.writeString(logDir.resolve("launcher.log"), entry + "\n",
|
||||
Files.writeString(logDir.resolve("latest.log"), entry + "\n",
|
||||
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||
} catch (Exception ignored) {}
|
||||
if (ui != null) ui.setStatus(msg);
|
||||
@@ -881,7 +921,7 @@ public class Bootstrap {
|
||||
// Exit
|
||||
info.put("exit_code", exitCode);
|
||||
info.put("stderr", stderr != null ? stderr : "");
|
||||
info.put("launcher_log", readFileSafe(logDir.resolve("launcher.log"), 200));
|
||||
info.put("launcher_log", readFileSafe(logDir.resolve("latest.log"), 200));
|
||||
|
||||
// System
|
||||
Map<String, Object> system = new HashMap<>();
|
||||
|
||||
@@ -211,7 +211,7 @@ public class Bootstrap {
|
||||
String entry = "[" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + "] " + msg;
|
||||
System.out.println(entry);
|
||||
try {
|
||||
Files.writeString(logDir.resolve("launcher.log"), entry + "\n",
|
||||
Files.writeString(logDir.resolve("latest.log"), entry + "\n",
|
||||
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
+59
-4
@@ -53,11 +53,10 @@ public class LauncherLogger {
|
||||
try {
|
||||
Path logsDir = Paths.get("").toAbsolutePath().resolve("logs");
|
||||
Files.createDirectories(logsDir);
|
||||
logFile = logsDir.resolve("launcher.log");
|
||||
rotateLogs(logsDir);
|
||||
logFile = logsDir.resolve("latest.log");
|
||||
|
||||
Files.writeString(logFile,
|
||||
"=== Launcher Log " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + " ===\n",
|
||||
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||
Files.writeString(logFile, sessionHeader(), StandardOpenOption.CREATE);
|
||||
|
||||
System.out.println("[LauncherLogger] initialized, log: " + logFile.toAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
@@ -66,6 +65,62 @@ public class LauncherLogger {
|
||||
}
|
||||
}
|
||||
|
||||
private static String sessionHeader() {
|
||||
String ts = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
String os = System.getProperty("os.name") + " " + System.getProperty("os.version")
|
||||
+ " " + System.getProperty("os.arch");
|
||||
String java = System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ")";
|
||||
String mem = (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " MB";
|
||||
return "== ZernMC Launcher =======================================================\n"
|
||||
+ "== Started: " + ts + "\n"
|
||||
+ "== OS: " + os + "\n"
|
||||
+ "== Java: " + java + "\n"
|
||||
+ "== Max memory: " + mem + "\n"
|
||||
+ "====================================================================\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Minecraft-style rotation: compress the previous latest.log into a dated
|
||||
* .log.gz archive (unlimited history), then remove the legacy launcher.log.
|
||||
*/
|
||||
private static void rotateLogs(Path logsDir) {
|
||||
// Legacy one-instance log from older builds: delete it, it is replaced by latest.log.
|
||||
try {
|
||||
Files.deleteIfExists(logsDir.resolve("launcher.log"));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
Path latest = logsDir.resolve("latest.log");
|
||||
try {
|
||||
if (Files.exists(latest) && Files.size(latest) > 0) {
|
||||
String ts = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"));
|
||||
int n = 1;
|
||||
Path archive;
|
||||
do {
|
||||
archive = logsDir.resolve(ts + (n == 1 ? "" : "-" + n) + ".log.gz");
|
||||
n++;
|
||||
} while (Files.exists(archive));
|
||||
gzip(logsDir, archive, latest);
|
||||
Files.deleteIfExists(latest);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("[LauncherLogger] rotate error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void gzip(Path logsDir, Path archive, Path source) {
|
||||
try (var in = Files.newInputStream(source);
|
||||
var gz = new java.util.zip.GZIPOutputStream(Files.newOutputStream(archive))) {
|
||||
byte[] buf = new byte[65536];
|
||||
int n;
|
||||
while ((n = in.read(buf)) > 0) {
|
||||
gz.write(buf, 0, n);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("[LauncherLogger] gzip error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static Path getLogFile() {
|
||||
return logFile;
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
|
||||
<properties>
|
||||
<revision>1.0.16</revision>
|
||||
<hotfix>13</hotfix>
|
||||
<hotfix>14</hotfix>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
Reference in New Issue
Block a user