Skip to content

Instantly share code, notes, and snippets.

@quantum5
Forked from Xyene/ErrorLogger.java
Created October 14, 2012 20:06

Revisions

  1. quantum5 revised this gist Oct 14, 2012. 1 changed file with 14 additions and 27 deletions.
    41 changes: 14 additions & 27 deletions ErrorLogger.java
    Original file line number Diff line number Diff line change
    @@ -5,12 +5,10 @@
    */

    public class ErrorLogger extends PluginLogger {

    public static ArrayList<Pair<String, ArrayList<String>>> registry = new ArrayList<Pair<String, ArrayList<String>>>();
    public static Map<String, List<String>>> registry = new HashMap<String, List<String>>>();
    public static boolean inited = false;
    private static Field logger_mc, cb_mcs, logger;


    public ErrorLogger(Plugin context) {
    super(context);
    register(context, "NULL", "NULL", "NULL");
    @@ -43,27 +41,14 @@ private static void getFields() {
    }

    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.
    registry.add(
    new Pair<String, ArrayList<String>>(name,
    new ArrayList<String>() {
    {
    add(pack);
    add(tracker);
    add(endl);
    }
    }
    )
    );
    registry.put(name, Arrays.asList(pack, tracker, endl));
    }

    private static String getEndline(String name) {
    String endl = "";
    StringBuilder temp = new StringBuilder();
    for (int i = 0; i < name.length(); ++i)
    temp.append('=');
    endl = endl + temp.toString();
    return endl;
    return temp.toString(); // You actually did the same thing, but it's not intended
    }

    public void register(Plugin context, String name, String pack, String tracker) {
    @@ -75,7 +60,6 @@ public void register(Plugin context, String name, String pack, String tracker) {
    logger.set(context, log);
    if (!(logger_mc.get(cb_mcs) instanceof ErrorLogger))
    logger_mc.set(cb_mcs, log);

    register(name, pack, tracker, getEndline(name));
    } catch (Exception e) {
    e.printStackTrace();
    @@ -90,10 +74,10 @@ private static boolean generateErrorLog(LogRecord record) {
    String ERROR = ExceptionUtils.getStackTrace(thrown), NAME = "", TICKETS = "", ENDL = "";
    Plugin PLUGIN = null;

    for (Pair par : registry) {
    ArrayList<String> data = (ArrayList) par.RIGHT;
    for (Map.Entry<String, List<String>>> entry : registry) {
    List<String> data = entry.getValue();
    if (ERROR.contains(data.get(0))) { //If the ERROR contains the package
    NAME = (String) par.LEFT;
    NAME = entry.getKey();
    PLUGIN = Bukkit.getPluginManager().getPlugin(NAME);
    TICKETS = data.get(1);
    ENDL = data.get(2);
    @@ -162,17 +146,20 @@ public void uncaughtException(Thread thread, Throwable throwable) {
    }

    private static 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;
    StringBuilder hash;
    String temp = new BigInteger(1, m.digest()).toString(16);
    int iter = 32 - temp.length();
    while (iter > 0) {
    hash.append('0');
    --iter;
    }
    hash.append(temp);
    return hash.toString();
    } catch (NoSuchAlgorithmException e) {
    }
    return hash;
    }
    }
  2. @Xyene Xyene revised this gist Oct 14, 2012. 1 changed file with 44 additions and 37 deletions.
    81 changes: 44 additions & 37 deletions ErrorLogger.java
    Original file line number Diff line number Diff line change
    @@ -8,19 +8,41 @@ public class ErrorLogger extends PluginLogger {

    public static ArrayList<Pair<String, ArrayList<String>>> registry = new ArrayList<Pair<String, ArrayList<String>>>();
    public static boolean inited = false;
    private static Field logger_mc, cb_mcs, logger;


    public ErrorLogger(Plugin context) {
    super(context);
    register("NULL", "NULL", "NULL", "NULL");
    register(context, "NULL", "NULL", "NULL");
    getFields();
    }

    public ErrorLogger(final Plugin context, final String name, final String pack, final String tracker) {
    super(context);
    register(name, pack, tracker, getEndl(name));
    register(context, name, pack, tracker);
    getFields();
    }

    private void register(final String name, final String pack, final String tracker, final String endl) {
    @Override
    public void log(LogRecord logRecord) {
    if (!generateErrorLog(logRecord))
    super.log(logRecord);
    }

    private static void getFields() {
    try {
    logger_mc = MinecraftServer.class.getDeclaredField("log");
    logger_mc.setAccessible(true);
    cb_mcs = CraftServer.class.getDeclaredField("console");
    cb_mcs.setAccessible(true);
    logger = JavaPlugin.class.getDeclaredField("logger");
    logger.setAccessible(true);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    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.
    registry.add(
    new Pair<String, ArrayList<String>>(name,
    @@ -35,7 +57,7 @@ private void register(final String name, final String pack, final String tracker
    );
    }

    private String getEndl(String name) {
    private static String getEndline(String name) {
    String endl = "";
    StringBuilder temp = new StringBuilder();
    for (int i = 0; i < name.length(); ++i)
    @@ -44,38 +66,23 @@ private String getEndl(String name) {
    return endl;
    }

    public void register(Plugin context, String name, String pack, String tracker) throws NoSuchFieldException, IllegalAccessException {
    ErrorLogger log = new ErrorLogger(context, name, pack, tracker);

    if (!ErrorLogger.inited) //If Thread.setDefaultUncaughtExceptionHandler hasn't been used
    log.initErrorHandler(); //Use it

    Field logger = JavaPlugin.class.getDeclaredField("logger");
    logger.setAccessible(true);
    if (logger.get(context) instanceof ErrorLogger) {
    register(name, pack, tracker, getEndl(name));
    } else {
    logger.set(context, log);
    }

    Field logger_mc = MinecraftServer.class.getDeclaredField("log");
    logger_mc.setAccessible(true);
    Field cb_mcs = CraftServer.class.getDeclaredField("console");
    cb_mcs.setAccessible(true);
    if (logger_mc.get(cb_mcs) instanceof ErrorLogger) {
    register(name, pack, tracker, getEndl(name));
    } else {
    logger_mc.set(cb_mcs, log);
    public void register(Plugin context, String name, String pack, String tracker) {
    try {
    ErrorLogger log = new ErrorLogger(context, name, pack, tracker);
    if (!ErrorLogger.inited) //If Thread.setDefaultUncaughtExceptionHandler hasn't been used
    initErrorHandler(); //Use it
    if (!(logger.get(context) instanceof ErrorLogger))
    logger.set(context, log);
    if (!(logger_mc.get(cb_mcs) instanceof ErrorLogger))
    logger_mc.set(cb_mcs, log);

    register(name, pack, tracker, getEndline(name));
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    @Override
    public void log(LogRecord logRecord) {
    if (!generateErrorLog(logRecord))
    super.log(logRecord);
    }

    private boolean generateErrorLog(LogRecord record) {
    private static boolean generateErrorLog(LogRecord record) {
    Server server = Bukkit.getServer();
    Throwable thrown;
    if ((thrown = record.getThrown()) == null)
    @@ -85,7 +92,7 @@ private boolean generateErrorLog(LogRecord record) {

    for (Pair par : registry) {
    ArrayList<String> data = (ArrayList) par.RIGHT;
    if (ERROR.contains( = data.get(0))) { //If the ERROR contains the package
    if (ERROR.contains(data.get(0))) { //If the ERROR contains the package
    NAME = (String) par.LEFT;
    PLUGIN = Bukkit.getPluginManager().getPlugin(NAME);
    TICKETS = data.get(1);
    @@ -142,7 +149,7 @@ private boolean generateErrorLog(LogRecord record) {
    return true;
    }

    public void initErrorHandler() {
    private static void initErrorHandler() {
    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
    @@ -154,7 +161,7 @@ public void uncaughtException(Thread thread, Throwable throwable) {
    ErrorLogger.inited = true;
    }

    private String md5(StringBuilder builder) {
    private static String md5(StringBuilder builder) {
    String hash = "";
    try {
    MessageDigest m = MessageDigest.getInstance("MD5");
    @@ -168,4 +175,4 @@ private String md5(StringBuilder builder) {
    }
    return hash;
    }
    }
    }
  3. @Xyene Xyene revised this gist Oct 14, 2012. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions ErrorLogger.java
    Original file line number Diff line number Diff line change
    @@ -151,6 +151,7 @@ public void uncaughtException(Thread thread, Throwable throwable) {
    generateErrorLog(o_u_screwd);
    }
    });
    ErrorLogger.inited = true;
    }

    private String md5(StringBuilder builder) {
  4. @Xyene Xyene created this gist Oct 14, 2012.
    170 changes: 170 additions & 0 deletions ErrorLogger.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,170 @@
    /**
    * Custom logger to save errors.
    *
    * @author Icyene
    */

    public class ErrorLogger extends PluginLogger {

    public static ArrayList<Pair<String, ArrayList<String>>> registry = new ArrayList<Pair<String, ArrayList<String>>>();
    public static boolean inited = false;

    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);
    register(name, pack, tracker, getEndl(name));
    }

    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.
    registry.add(
    new Pair<String, ArrayList<String>>(name,
    new ArrayList<String>() {
    {
    add(pack);
    add(tracker);
    add(endl);
    }
    }
    )
    );
    }

    private String getEndl(String name) {
    String endl = "";
    StringBuilder temp = new StringBuilder();
    for (int i = 0; i < name.length(); ++i)
    temp.append('=');
    endl = endl + temp.toString();
    return endl;
    }

    public void register(Plugin context, String name, String pack, String tracker) throws NoSuchFieldException, IllegalAccessException {
    ErrorLogger log = new ErrorLogger(context, name, pack, tracker);

    if (!ErrorLogger.inited) //If Thread.setDefaultUncaughtExceptionHandler hasn't been used
    log.initErrorHandler(); //Use it

    Field logger = JavaPlugin.class.getDeclaredField("logger");
    logger.setAccessible(true);
    if (logger.get(context) instanceof ErrorLogger) {
    register(name, pack, tracker, getEndl(name));
    } else {
    logger.set(context, log);
    }

    Field logger_mc = MinecraftServer.class.getDeclaredField("log");
    logger_mc.setAccessible(true);
    Field cb_mcs = CraftServer.class.getDeclaredField("console");
    cb_mcs.setAccessible(true);
    if (logger_mc.get(cb_mcs) instanceof ErrorLogger) {
    register(name, pack, tracker, getEndl(name));
    } else {
    logger_mc.set(cb_mcs, log);
    }
    }

    @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 = "", ENDL = "";
    Plugin PLUGIN = null;

    for (Pair par : registry) {
    ArrayList<String> data = (ArrayList) par.RIGHT;
    if (ERROR.contains( = 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);
    break;
    }
    }

    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;
    }
    }