Some refactoring in pandalib-util
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
162
pandalib-util/src/main/java/fr/pandacube/lib/util/log/Log.java
Normal file
162
pandalib-util/src/main/java/fr/pandacube/lib/util/log/Log.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user