Reduce code duplication of DailyLogRotateFileHandler + generalize logs compression

This commit is contained in:
Marc Baloup 2023-05-10 10:26:02 +02:00
parent 1cd3749d7d
commit 913d5d91dd
5 changed files with 86 additions and 158 deletions

View File

@ -1,6 +1,6 @@
package fr.pandacube.lib.bungee; package fr.pandacube.lib.bungee;
import fr.pandacube.lib.bungee.util.DailyLogRotateFileHandler; import fr.pandacube.lib.bungee.util.BungeeDailyLogRotateFileHandler;
import fr.pandacube.lib.bungee.util.PluginMessagePassthrough; import fr.pandacube.lib.bungee.util.PluginMessagePassthrough;
import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.api.plugin.Plugin;
@ -15,7 +15,7 @@ public class PandaLibBungee {
public static void onEnable() { public static void onEnable() {
PluginMessagePassthrough.init(plugin); PluginMessagePassthrough.init(plugin);
DailyLogRotateFileHandler.init(true); BungeeDailyLogRotateFileHandler.init(true);
} }

View File

@ -0,0 +1,44 @@
package fr.pandacube.lib.bungee.util;
import fr.pandacube.lib.util.logs.DailyLogRotateFileHandler;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.log.ConciseFormatter;
import java.util.logging.Filter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
/**
* A log rotate that extends the functionnalities of {@link DailyLogRotateFileHandler}
* to adapt with bungee specificities.
*/
public class BungeeDailyLogRotateFileHandler extends DailyLogRotateFileHandler {
/**
* Initialize this file handler.
* @param hideInitialHandlerLogEntries true if we want to hide some InitialHandler log entries
*/
public static void init(boolean hideInitialHandlerLogEntries) {
ProxyServer.getInstance().getLogger().addHandler(new BungeeDailyLogRotateFileHandler(hideInitialHandlerLogEntries));
}
private BungeeDailyLogRotateFileHandler(boolean hideInitialHandlerLogEntries) {
if (hideInitialHandlerLogEntries)
setFilter(new InitialHandlerLogRemover());
setFormatter(new ConciseFormatter(false));
setLevel(Level.parse(System.getProperty("net.md_5.bungee.file-log-level", "INFO")));
}
private class InitialHandlerLogRemover implements Filter {
@Override
public boolean isLoggable(LogRecord record) {
String formattedRecord = getFormatter().format(record);
if (formattedRecord.contains("<-> InitialHandler has connected")) return false;
if (formattedRecord.contains("<-> InitialHandler has pinged")) return false;
return true;
}
}
}

View File

@ -1,147 +0,0 @@
package fr.pandacube.lib.bungee.util;
import com.google.common.io.Files;
import fr.pandacube.lib.bungee.PandaLibBungee;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.log.ConciseFormatter;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.ErrorManager;
import java.util.logging.Filter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.zip.GZIPOutputStream;
public class DailyLogRotateFileHandler extends Handler {
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
public static void init(boolean hideInitialHandlerLogEntries) {
ProxyServer.getInstance().getLogger().addHandler(new DailyLogRotateFileHandler(hideInitialHandlerLogEntries));
}
private BufferedWriter currentFile = null;
private String currentFileDate = getCurrentDay();
private boolean closed = false;
private DailyLogRotateFileHandler(boolean hideInitialHandlerLogEntries) {
if (hideInitialHandlerLogEntries)
setFilter(new InitialHandlerLogRemover());
setFormatter(new ConciseFormatter(false));
setLevel(Level.parse(System.getProperty("net.md_5.bungee.file-log-level", "INFO")));
}
@Override
public synchronized void close() throws SecurityException {
closed = true;
if (currentFile != null) try {
currentFile.close();
} catch (IOException ignored) {
}
}
@Override
public synchronized void flush() {
if (closed) return;
if (currentFile == null) return;
try {
currentFile.flush();
} catch (IOException ignored) {
}
}
@Override
public synchronized void publish(LogRecord record) {
if (closed || !isLoggable(record))
return;
if (currentFile == null || !currentFileDate.equals(getCurrentDay()))
changeFile();
if (currentFile == null)
return;
String formattedMessage;
try {
formattedMessage = getFormatter().format(record);
} catch (Exception ex) {
reportError(null, ex, ErrorManager.FORMAT_FAILURE);
return;
}
try {
currentFile.write(formattedMessage);
currentFile.flush();
} catch (Exception ex) {
reportError(null, ex, ErrorManager.WRITE_FAILURE);
}
}
private void changeFile() {
if (currentFile != null) {
try {
currentFile.flush();
currentFile.close();
} catch (IOException ignored) {
}
File fileNewName = new File("logs/" + currentFileDate + ".log");
new File("logs/latest.log").renameTo(fileNewName);
ProxyServer.getInstance().getScheduler().runAsync(PandaLibBungee.getPlugin(), () -> compress(fileNewName));
}
currentFileDate = getCurrentDay();
try {
File logDir = new File("logs");
logDir.mkdir();
currentFile = new BufferedWriter(new FileWriter("logs/latest.log", true));
} catch (SecurityException | IOException e) {
reportError("Erreur lors de l'initialisation d'un fichier log", e, ErrorManager.OPEN_FAILURE);
currentFile = null;
}
}
private String getCurrentDay() {
return dateFormat.format(new Date());
}
private void compress(File sourceFile) {
File destFile = new File(sourceFile.getParentFile(), sourceFile.getName() + ".gz");
if (destFile.exists())
destFile.delete();
try (GZIPOutputStream os = new GZIPOutputStream(new FileOutputStream(destFile))) {
Files.copy(sourceFile, os);
} catch (IOException e) {
if (destFile.exists())
destFile.delete();
throw new RuntimeException(e);
}
sourceFile.delete();
}
private class InitialHandlerLogRemover implements Filter {
@Override
public boolean isLoggable(LogRecord record) {
String formattedRecord = getFormatter().format(record);
if (formattedRecord.contains("<-> InitialHandler has connected")) return false;
if (formattedRecord.contains("<-> InitialHandler has pinged")) return false;
return true;
}
}
}

View File

@ -3,6 +3,7 @@ package fr.pandacube.lib.cli.log;
import fr.pandacube.lib.cli.CLI; import fr.pandacube.lib.cli.CLI;
import fr.pandacube.lib.util.Log; import fr.pandacube.lib.util.Log;
import fr.pandacube.lib.util.ThrowableUtil; import fr.pandacube.lib.util.ThrowableUtil;
import fr.pandacube.lib.util.logs.DailyLogRotateFileHandler;
import net.md_5.bungee.log.ColouredWriter; import net.md_5.bungee.log.ColouredWriter;
import net.md_5.bungee.log.ConciseFormatter; import net.md_5.bungee.log.ConciseFormatter;

View File

@ -1,18 +1,30 @@
package fr.pandacube.lib.cli.log; package fr.pandacube.lib.util.logs;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.logging.ErrorManager; import java.util.logging.ErrorManager;
import java.util.logging.Handler; import java.util.logging.Handler;
import java.util.logging.LogRecord; import java.util.logging.LogRecord;
import java.util.zip.GZIPOutputStream;
class DailyLogRotateFileHandler extends Handler { /**
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); * A log handler that log file rotation in a specified folder.
* The current log file is latest.log, and the logs from previous days
* are in dated gzipped files in the same folder.
*/
public class DailyLogRotateFileHandler extends Handler {
/**
* The format of the date to name the file.
*/
protected static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
private BufferedWriter currentFile = null; private BufferedWriter currentFile = null;
private String currentFileDate = getCurrentDay(); private String currentFileDate = getCurrentDay();
@ -38,12 +50,14 @@ class DailyLogRotateFileHandler extends Handler {
@Override @Override
public synchronized void publish(LogRecord record) { public synchronized void publish(LogRecord record) {
if (closed) return; if (closed || !isLoggable(record))
if (!isLoggable(record)) return; return;
if (currentFile == null || !currentFileDate.equals(getCurrentDay())) changeFile(); if (currentFile == null || !currentFileDate.equals(getCurrentDay()))
changeFile();
if (currentFile == null) return; if (currentFile == null)
return;
String formattedMessage; String formattedMessage;
@ -59,7 +73,6 @@ class DailyLogRotateFileHandler extends Handler {
currentFile.flush(); currentFile.flush();
} catch (Exception ex) { } catch (Exception ex) {
reportError(null, ex, ErrorManager.WRITE_FAILURE); reportError(null, ex, ErrorManager.WRITE_FAILURE);
} }
} }
@ -69,7 +82,9 @@ class DailyLogRotateFileHandler extends Handler {
currentFile.flush(); currentFile.flush();
currentFile.close(); currentFile.close();
} catch (IOException ignored) {} } catch (IOException ignored) {}
new File("logs/latest.log").renameTo(new File("logs/" + currentFileDate + ".log")); File fileNewName = new File("logs/" + currentFileDate + ".log");
new File("logs/latest.log").renameTo(fileNewName);
new Thread(() -> compress(fileNewName), "Log compress Thread").start();
} }
currentFileDate = getCurrentDay(); currentFileDate = getCurrentDay();
@ -87,4 +102,19 @@ class DailyLogRotateFileHandler extends Handler {
private String getCurrentDay() { private String getCurrentDay() {
return dateFormat.format(new Date()); return dateFormat.format(new Date());
} }
private void compress(File sourceFile) {
File destFile = new File(sourceFile.getParentFile(), sourceFile.getName() + ".gz");
if (destFile.exists())
destFile.delete();
try (GZIPOutputStream os = new GZIPOutputStream(new FileOutputStream(destFile))) {
Files.copy(sourceFile.toPath(), os);
} catch (IOException e) {
if (destFile.exists())
destFile.delete();
throw new RuntimeException(e);
}
sourceFile.delete();
}
} }