Last active
October 9, 2016 13:37
-
-
Save matshou/3e34ece0378ff777e812160f6d8351c7 to your computer and use it in GitHub Desktop.
Custom Logger for Minecraft (1.10) Modders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.user.genericmod.common; | |
import java.io.File; | |
import java.io.IOException; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import org.apache.logging.log4j.Level; | |
import org.apache.logging.log4j.Marker; | |
/** | |
* A custom wrapper for the log4j Logger. It also has an implementation <br> | |
* for creating and reading from a custom secondary mod log file. <p> | |
* | |
* <i>Whenever you log an event (except INFO) using this logger, <br> | |
* a copy of that log will be stored in a custom mod log file. </i><p> | |
* | |
* <i>Thanks to Choonster for writing the original wrapper.</i> | |
*/ | |
public class Logger | |
{ | |
private static org.apache.logging.log4j.Logger logger; | |
static final java.text.DateFormat dateFormat = new java.text.SimpleDateFormat("[yyyy/MM/dd][HH:mm:ss]"); | |
public static final String modLogFileName = "generic-mod-logger.log"; | |
public static final String modLogFileDirName = "logs"; | |
/** A string representation of the mod log Path, here for convenience. */ | |
private static String modLogFilePath; | |
/** A file instance of the mod log file. Used to access file properties. */ | |
private static File modLogFile; | |
/** Any event level that has a value below this will not be logged. */ | |
private static Level threshold = Level.DEBUG; | |
private static void log(Level level, String format, Object... data) | |
{ | |
logger.printf(level, format, data); | |
} | |
private static void log(Level level, Throwable throwable, String format, Object... data) | |
{ | |
logger.log(level, String.format(format, data), throwable); | |
} | |
private static void log(Level level, Marker marker, String format, Object... data) | |
{ | |
logger.printf(level, marker, format, data); | |
} | |
private static void log(Level level, Marker marker, Throwable throwable, String format, Object... data) | |
{ | |
logger.log(level, marker, String.format(format, data), throwable); | |
} | |
public static void fatal(String format, Object... data) | |
{ | |
log(Level.FATAL, format, data); | |
writeToModLogFile(Level.FATAL, format, null); | |
} | |
public static void fatal(Marker marker, String format, Object... data) | |
{ | |
log(Level.FATAL, marker, format, data); | |
} | |
public static void fatal(Throwable throwable, String format, Object... data) | |
{ | |
log(Level.FATAL, throwable, format, data); | |
} | |
public static void fatal(Marker marker, Throwable throwable, String format, Object... data) | |
{ | |
log(Level.FATAL, marker, throwable, format, data); | |
} | |
public static void error(String format, Object... data) | |
{ | |
log(Level.ERROR, format, data); | |
writeToModLogFile(Level.ERROR, format, null); | |
} | |
public static void error(Marker marker, String format, Object... data) | |
{ | |
log(Level.ERROR, marker, format, data); | |
} | |
public static void error(Throwable throwable, String format, Object... data) | |
{ | |
log(Level.ERROR, throwable, format, data); | |
writeToModLogFile(Level.ERROR, format, throwable); | |
} | |
public static void error(Marker marker, Throwable throwable, String format, Object... data) | |
{ | |
log(Level.ERROR, marker, throwable, format, data); | |
} | |
public static void warn(String format, Object... data) | |
{ | |
log(Level.WARN, format, data); | |
writeToModLogFile(Level.WARN, format, null); | |
} | |
public static void warn(Marker marker, String format, Object... data) | |
{ | |
log(Level.WARN, marker, format, data); | |
} | |
public static void info(String format, Object... data) | |
{ | |
log(Level.INFO, format, data); | |
} | |
public static void info(Marker marker, String format, Object... data) | |
{ | |
log(Level.INFO, marker, format, data); | |
} | |
public static void info(Throwable throwable, String format, Object... data) | |
{ | |
log(Level.INFO, throwable, format, data); | |
} | |
public static void info(Marker marker, Throwable throwable, String format, Object... data) | |
{ | |
log(Level.INFO, marker, throwable, format, data); | |
} | |
public static void debug(String format, Object... data) | |
{ | |
log(Level.DEBUG, format, data); | |
writeToModLogFile(Level.DEBUG, format, null); | |
} | |
public static void debug(Marker marker, String format, Object... data) | |
{ | |
log(Level.DEBUG, marker, format, data); | |
} | |
public static void debug(Marker marker, Throwable throwable, String format, Object... data) | |
{ | |
log(Level.DEBUG, marker, throwable, format, data); | |
} | |
public static void setLogger(org.apache.logging.log4j.Logger logger) | |
{ | |
if (Logger.logger != null) | |
throw new IllegalStateException("Attempt to replace logger"); | |
Logger.logger = logger; | |
} | |
/** Sets the maximum event level that will be logged in the secondary mod log file. */ | |
public static void setLevel(Level level) | |
{ | |
threshold = level; | |
} | |
/** | |
* Create a log file for this mod, if one doesn't already exist. | |
* | |
* @author yooksi | |
* @throws IOException only if a serious I/O error occurs (no exception if files already exist). | |
*/ | |
public static void createModLogFile() throws IOException | |
{ | |
Path modLogFileDir = null; | |
Path pModLogFilePath = null; | |
try | |
{ | |
modLogFileDir = Paths.get(modLogFileDirName); | |
pModLogFilePath = Paths.get(modLogFileDirName, modLogFileName); | |
modLogFilePath = pModLogFilePath.toString(); | |
} | |
catch (java.nio.file.InvalidPathException e) | |
{ | |
log(Level.ERROR, e.fillInStackTrace(), "Unable to create modLogFile."); | |
return; // Files.exists will throw a NPE if we don't. | |
} | |
if (!Files.exists(modLogFileDir)) | |
Files.createDirectory(modLogFileDir); | |
if (!Files.exists(pModLogFilePath)) | |
Files.createFile(pModLogFilePath); | |
modLogFile = new File(modLogFilePath); | |
modLogFile.setWritable(true); | |
} | |
/** | |
* Write a line of text to out custom log file. | |
* | |
* @author yooksi | |
* @param level the logger event level (used to print it's name) | |
* @param message the String line we want to print to the file | |
*/ | |
private static void writeToModLogFile(Level level, String message, Throwable throwable) | |
{ | |
if (!modLogFile.exists() || level.intLevel() > threshold.intLevel()) | |
return; | |
java.io.BufferedReader buffReader = null; | |
java.io.FileWriter fileWriter = null; | |
java.io.BufferedWriter buffWriter = null; | |
java.io.PrintWriter printWriter = null; | |
try // The FileWriter is the only element that can throw an exception here. | |
{ | |
String timeStamp = dateFormat.format(java.util.Calendar.getInstance().getTime()); | |
buffReader = new java.io.BufferedReader(new java.io.FileReader(modLogFilePath.toString())); | |
fileWriter = new java.io.FileWriter(modLogFilePath.toString(), true); | |
buffWriter= new java.io.BufferedWriter(fileWriter); | |
printWriter = new java.io.PrintWriter(buffWriter); | |
String throwableName = throwable != null ? " " + throwable.getClass().getSimpleName() + ":" : ""; | |
// Write a new line only if the file is NOT empty. | |
if (buffReader != null && buffReader.readLine() != null) | |
buffWriter.newLine(); | |
printWriter.printf("%s [%s]%s %s", timeStamp, level.name(), throwableName, message).flush(); | |
} | |
catch (IOException e) | |
{ | |
if (!modLogFile.canWrite()) | |
log(Level.ERROR, "Unable to write to modLogFile, the file is marked as read-only."); | |
else log(Level.ERROR, e.fillInStackTrace(), "Unable to write to modLogFile, reason unknown."); | |
} | |
finally // Be sure to flush and close the open streams. | |
{ | |
if (printWriter != null) | |
printWriter.close(); | |
try { if (buffReader != null) buffReader.close(); } | |
catch (IOException e) { log(Level.FATAL, e.fillInStackTrace(), "Unable to close BufferedReader."); } | |
try { if (fileWriter != null) fileWriter.close(); } | |
catch (IOException e) { log(Level.FATAL, e.fillInStackTrace(), "Unable to close FileWriter."); } | |
try { if (buffWriter != null) buffWriter.close(); } | |
catch (IOException e) { log(Level.FATAL, e.fillInStackTrace(), "Unable to close BufferedWriter."); } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment