v1.0.16.14 — rotatsionny log: latest.log + .log.gz arkhiv (Minecraft-style), no limit, legacy launcher.log removal
This commit is contained in:
@@ -54,6 +54,7 @@ public class Bootstrap {
|
|||||||
logDir = baseDir.resolve("logs");
|
logDir = baseDir.resolve("logs");
|
||||||
Files.createDirectories(logDir);
|
Files.createDirectories(logDir);
|
||||||
javafxPath = baseDir.resolve("lib").resolve("javafx");
|
javafxPath = baseDir.resolve("lib").resolve("javafx");
|
||||||
|
rotateLogs();
|
||||||
|
|
||||||
log("=== ZernMC Launcher ===");
|
log("=== ZernMC Launcher ===");
|
||||||
|
|
||||||
@@ -371,11 +372,50 @@ public class Bootstrap {
|
|||||||
return javaBin;
|
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) {
|
private static void log(String msg) {
|
||||||
String entry = "[" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + "] " + msg;
|
String entry = "[" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + "] " + msg;
|
||||||
System.out.println(entry);
|
System.out.println(entry);
|
||||||
try {
|
try {
|
||||||
Files.writeString(logDir.resolve("launcher.log"), entry + "\n",
|
Files.writeString(logDir.resolve("latest.log"), entry + "\n",
|
||||||
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
if (ui != null) ui.setStatus(msg);
|
if (ui != null) ui.setStatus(msg);
|
||||||
@@ -881,7 +921,7 @@ public class Bootstrap {
|
|||||||
// Exit
|
// Exit
|
||||||
info.put("exit_code", exitCode);
|
info.put("exit_code", exitCode);
|
||||||
info.put("stderr", stderr != null ? stderr : "");
|
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
|
// System
|
||||||
Map<String, Object> system = new HashMap<>();
|
Map<String, Object> system = new HashMap<>();
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ public class Bootstrap {
|
|||||||
String entry = "[" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + "] " + msg;
|
String entry = "[" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + "] " + msg;
|
||||||
System.out.println(entry);
|
System.out.println(entry);
|
||||||
try {
|
try {
|
||||||
Files.writeString(logDir.resolve("launcher.log"), entry + "\n",
|
Files.writeString(logDir.resolve("latest.log"), entry + "\n",
|
||||||
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
}
|
}
|
||||||
|
|||||||
+59
-4
@@ -53,11 +53,10 @@ public class LauncherLogger {
|
|||||||
try {
|
try {
|
||||||
Path logsDir = Paths.get("").toAbsolutePath().resolve("logs");
|
Path logsDir = Paths.get("").toAbsolutePath().resolve("logs");
|
||||||
Files.createDirectories(logsDir);
|
Files.createDirectories(logsDir);
|
||||||
logFile = logsDir.resolve("launcher.log");
|
rotateLogs(logsDir);
|
||||||
|
logFile = logsDir.resolve("latest.log");
|
||||||
|
|
||||||
Files.writeString(logFile,
|
Files.writeString(logFile, sessionHeader(), StandardOpenOption.CREATE);
|
||||||
"=== Launcher Log " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + " ===\n",
|
|
||||||
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
|
||||||
|
|
||||||
System.out.println("[LauncherLogger] initialized, log: " + logFile.toAbsolutePath());
|
System.out.println("[LauncherLogger] initialized, log: " + logFile.toAbsolutePath());
|
||||||
} catch (Exception e) {
|
} 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() {
|
public static Path getLogFile() {
|
||||||
return logFile;
|
return logFile;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>1.0.16</revision>
|
<revision>1.0.16</revision>
|
||||||
<hotfix>13</hotfix>
|
<hotfix>14</hotfix>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|||||||
Reference in New Issue
Block a user