Skip to content

Instantly share code, notes, and snippets.

@Xyene
Created October 14, 2012 02:03
Show Gist options
  • Select an option

  • Save Xyene/3886997 to your computer and use it in GitHub Desktop.

Select an option

Save Xyene/3886997 to your computer and use it in GitHub Desktop.
Compact Error Logger
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLogger;
import java.io.*;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import static java.lang.System.getProperty;
/**
* Custom logger to save errors.
*
* @author Icyene
*/
public class ErrorLogger extends PluginLogger {
static ArrayList<Pair<String, ArrayList<String>>> registered = new ArrayList<Pair<String, ArrayList<String>>>();
public ErrorLogger(Plugin context) {
super(context);
register("NULL", "NULL", "NULL", "NULL");
}
public ErrorLogger(final Plugin context, final String name, final String pack, final String tracker) {
super(context);
String endl = "";
StringBuilder temp = new StringBuilder();
for (int i = 0; i < name.length(); ++i)
temp.append('=');
endl = endl + temp.toString();
register(name, pack, tracker, endl);
}
private void register(final String name, final String pack, final String tracker, final String endl) {
//This line is horrendously hard to read. It works, though.
registered.add(
new Pair<String, ArrayList<String>>(name,
new ArrayList<String>() {
{
add(pack);
add(tracker);
add(endl);
}
}
)
);
}
@Override
public void log(LogRecord logRecord) {
if (!generateErrorLog(logRecord))
super.log(logRecord);
}
private boolean generateErrorLog(LogRecord record) {
Server server = Bukkit.getServer();
Throwable thrown;
if ((thrown = record.getThrown()) == null)
return false;
String ERROR = ExceptionUtils.getStackTrace(thrown), NAME = "", TICKETS = "", PACKAGE = "", ENDL = "";
Plugin PLUGIN = null;
for (Pair par : registered) {
ArrayList<String> data = (ArrayList) par.RIGHT;
if (ERROR.contains((PACKAGE = data.get(0)))) { //If the ERROR contains the package
NAME = (String) par.LEFT;
PLUGIN = Bukkit.getPluginManager().getPlugin(NAME);
TICKETS = data.get(1);
ENDL = data.get(2);
}
}
if (!ERROR.contains(NAME + " has encountered an error!") && !ERROR.contains(this.getClass().getName())) //Check if its not our own
return false;
PluginDescriptionFile pdf = PLUGIN.getDescription();
StringBuilder err = new StringBuilder();
boolean disable = false;
err.append("\n=============" + NAME + " has encountered an error!=============");
err.append("\nStacktrace:\n" + ERROR);
err.append("\n" + NAME + " version: " + pdf.getVersion());
err.append("\nBukkit message: " + record.getMessage());
err.append("\nPlugins loaded: " + Arrays.asList(server.getPluginManager().getPlugins()));
err.append("\nCraftBukkit version: " + server.getBukkitVersion());
err.append("\nJava version: " + getProperty("java.version"));
err.append("\nOS info: " + getProperty("os.arch") + " " + getProperty("os.name") + ", " + getProperty("os.version"));
err.append("\nPlease report this error to the " + NAME + " ticket tracker (" + TICKETS + ")!");
ERROR = ERROR.toLowerCase();
if (ERROR.contains("nullpointerexception") || ERROR.contains("stackoverflowexception")) {
err.append("\nA critical error has been thrown. " + NAME + " has been disabled to prevent further damage.");
disable = true;
} else {
err.append("\nError was minor; " + NAME + " will continue operating.");
}
String name = NAME + "_" + md5(err).substring(0, 6) + ".error.log"; //Name is PLUGIN_NAME with first 6 chars of md5 appended
File root = new File(PLUGIN.getDataFolder(), "errors");
if (!root.exists())
root.mkdir();
File dump = new File(root.getAbsoluteFile(), name);
if (!dump.exists()) {
try {
dump.createNewFile();
BufferedWriter writer = new BufferedWriter(new FileWriter(dump));
writer.write((err.toString() + ENDL).substring(1)); //Remove the extra /n
writer.close();
err.append("\nThis has been saved to the file ./" + PLUGIN.getName() + "/errors/" + name);
} catch (Exception e) {
System.err.println("Ehm, errors occured while displaying an error >.< Stacktrace:\n");
e.printStackTrace();
}
}
err.append(ENDL);
System.err.println(err);
if (disable)
Bukkit.getServer().getPluginManager().disablePlugin(PLUGIN);
return true;
}
public void initErrorHandler() {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
LogRecord o_u_screwd = new LogRecord(Level.SEVERE, "Uhoh");
o_u_screwd.setThrown(throwable);
generateErrorLog(o_u_screwd);
}
});
}
private String md5(StringBuilder builder) {
String hash = "";
try {
MessageDigest m = MessageDigest.getInstance("MD5");
m.reset();
m.update(builder.toString().getBytes());
hash = new BigInteger(1, m.digest()).toString(16);
while (hash.length() < 32) {
hash = 0 + hash;
}
} catch (NoSuchAlgorithmException e) {
}
return hash;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment