Skip to content

Instantly share code, notes, and snippets.

@Xyene
Created October 14, 2012 14:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xyene/3888824 to your computer and use it in GitHub Desktop.
Save Xyene/3888824 to your computer and use it in GitHub Desktop.
ErrorLogger
/**
* Custom logger to save errors.
*
* @author Icyene
*/
public class ErrorLogger extends PluginLogger {
String PLUGIN_NAME = "NULL", TICKET_TRACKER = "NULL", PLUGIN_PACKAGE = "NULL", ENDL = "\n=====================================================";
Plugin PLUGIN = null;
public ErrorLogger(Plugin context) {
super(context);
this.PLUGIN = context;
}
public ErrorLogger(Plugin context, String name, String pack, String tracker) {
super(context);
this.PLUGIN_NAME = name;
this.PLUGIN_PACKAGE = pack;
this.TICKET_TRACKER = tracker;
StringBuilder temp = new StringBuilder();
for (int i = 0; i < name.length(); ++i)
temp.append('=');
this.ENDL = this.ENDL + temp.toString();
}
public void setName(String name) {
this.PLUGIN_NAME = name;
}
public void setPackage(String pack) {
this.PLUGIN_PACKAGE = pack;
}
public void setTracker(String tracker) {
this.TICKET_TRACKER = tracker;
}
@Override
public void log(LogRecord logRecord) {
if(!generateErrorLog(logRecord))
super.log(logRecord);
}
private boolean generateErrorLog(LogRecord record) {
PluginDescriptionFile pdf = PLUGIN.getDescription();
Server server = Bukkit.getServer();
Throwable thrown;
if((thrown=record.getThrown()) == null)
return false;
String error = ExceptionUtils.getStackTrace(thrown);
if (!error.contains(PLUGIN_PACKAGE) && !error.contains(PLUGIN_NAME + " has encountered an error!") && !error.contains(this.getClass().getName())) //Check if its not our own
return false;
StringBuilder err = new StringBuilder();
boolean disable = false;
err.append("\n=============" + PLUGIN_NAME + " has encountered an error!=============");
err.append("\nStacktrace:\n" + error);
err.append("\n" + PLUGIN_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 " + PLUGIN_NAME + " ticket tracker (" + TICKET_TRACKER + ")!");
error = error.toLowerCase();
if (error.contains("nullpointerexception") || error.contains("stackoverflowexception")) {
err.append("\nA critical error has been thrown. " + PLUGIN_NAME + " has been disabled to prevent further damage.");
disable = true;
} else {
err.append("\nError was minor; " + PLUGIN_NAME + " will continue operating.");
}
String name = PLUGIN_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;
}
}
@Xyene
Copy link
Author

Xyene commented Oct 14, 2012

Updated to use ExceptionUtils from Apache instead of my own getStackTrace.

@Xyene
Copy link
Author

Xyene commented Oct 14, 2012

Has variable number of '=' to ENDL!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment