Some refactoring in pandalib-util

This commit is contained in:
2023-08-27 13:37:17 +02:00
parent 463a4d7e78
commit bd3bea8381
59 changed files with 176 additions and 182 deletions

View File

@@ -0,0 +1,120 @@
package fr.pandacube.lib.util.log;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.ErrorManager;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.zip.GZIPOutputStream;
/**
* 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 String currentFileDate = getCurrentDay();
private boolean closed = false;
@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);
new Thread(() -> compress(fileNewName), "Log compress Thread").start();
}
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.toPath(), os);
} catch (IOException e) {
if (destFile.exists())
destFile.delete();
throw new RuntimeException(e);
}
sourceFile.delete();
}
}

View File

@@ -0,0 +1,162 @@
package fr.pandacube.lib.util.log;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Utility class to easily log info into a provided logger. This class avoid the needs to fetch the logger everytime it
* is needed.
*
* For instance, this piece of code:
* <pre>
* getTheLoggerFromSomewhere().info(message);
* </pre>
*
* Can be simplified by one line to put in the startup code of the application:
* <pre>
* Log.setLogger(getTheLoggerFromSomewhere());
* </pre>
* And this code everywhere the application needs to log something:
* <pre>
* Log.info(message);
* </pre>
*
* This the {@link #setLogger(Logger)} method is not called, thi class will use the logger returned by
* {@link Logger#getGlobal()}.
*/
public final class Log {
private static Logger logger = Logger.getGlobal();
private static final AtomicBoolean logDebug = new AtomicBoolean(false);
/**
* Determine if {@link #debug(Throwable)}, {@link #debug(String)} and {@link #debug(String, Throwable)} will actually
* log a message or not.
* @param debug true to enable debug, false otherwise
*/
public static void setDebug(boolean debug) {
logDebug.set(debug);
}
/**
* Tells if the debug mode is enabled or not.
* @return true if debug is enabled, false otherwise.
*/
public static boolean isDebugEnabled() {
return logDebug.get();
}
/**
* Get the backend logger of this class.
* @return the logger.
*/
public static Logger getLogger() {
return logger;
}
/**
* Set the backend logger of this class.
* @param logger the logger to use.
*/
public static void setLogger(Logger logger) {
Log.logger = logger;
}
/**
* Log the provided message using logger level {@link Level#INFO}.
* @param message the message to log
* @see Logger#info(String)
*/
public static void info(String message) {
logger.info(message);
}
/**
* Log the provided message and throwable using logger level {@link Level#WARNING}.
* @param message the message to log
* @param throwable the throwable to log
*/
public static void warning(String message, Throwable throwable) {
logger.log(Level.WARNING, message, throwable);
}
/**
* Log the provided throwable using logger level {@link Level#WARNING}.
* @param throwable the throwable to log
*/
public static void warning(Throwable throwable) {
logger.log(Level.WARNING, "", throwable);
}
/**
* Log the provided message using logger level {@link Level#WARNING}.
* @param message the message to log
* @see Logger#warning(String)
*/
public static void warning(String message) {
logger.warning(message);
}
/**
* Log the provided message and throwable using logger level {@link Level#SEVERE}.
* @param message the message to log
* @param throwable the throwable to log
*/
public static void severe(String message, Throwable throwable) {
logger.log(Level.SEVERE, message, throwable);
}
/**
* Log the provided throwable using logger level {@link Level#SEVERE}.
* @param throwable the throwable to log
*/
public static void severe(Throwable throwable) {
logger.log(Level.SEVERE, "", throwable);
}
/**
* Log the provided message using logger level {@link Level#SEVERE}.
* @param message the message to log
* @see Logger#severe(String)
*/
public static void severe(String message) {
logger.severe(message);
}
/**
* Log the provided message and throwable using logger level {@link Level#INFO}, if the debug mode is enabled.
* @param message the message to log
* @param throwable the throwable to log
* @see #isDebugEnabled()
* @see #setDebug(boolean)
*/
public static void debug(String message, Throwable throwable) {
if (!logDebug.get()) return;
logger.log(Level.INFO, message, throwable);
}
/**
* Log the provided throwable using logger level {@link Level#INFO}, if the debug mode is enabled.
* @param throwable the throwable to log
* @see #isDebugEnabled()
* @see #setDebug(boolean)
*/
public static void debug(Throwable throwable) {
if (!logDebug.get()) return;
logger.log(Level.INFO, "", throwable);
}
/**
* Log the provided message using logger level {@link Level#INFO}, if the debug mode is enabled.
* @param message the message to log
* @see #isDebugEnabled()
* @see #setDebug(boolean)
* @see Logger#info(String)
*/
public static void debug(String message) {
if (!logDebug.get()) return;
logger.info(message);
}
}