From caf7d0a9adf6b1676c84d33544dca93ff226e99b Mon Sep 17 00:00:00 2001 From: snowleo Date: Sat, 28 May 2011 03:29:11 +0000 Subject: First code for the update and error report stuff. Disabled until finished. git-svn-id: https://svn.java.net/svn/essentials~svn/trunk@1545 e251c2fe-e539-e718-e476-b85c1f46cddb --- .../src/com/earth2me/essentials/Essentials.java | 52 +++++++-- .../essentials/EssentialsErrorHandler.java | 121 +++++++++++++++++++++ .../earth2me/essentials/EssentialsUpdateTimer.java | 68 ++++++++++++ Essentials/src/com/earth2me/essentials/Util.java | 4 +- 4 files changed, 231 insertions(+), 14 deletions(-) create mode 100644 Essentials/src/com/earth2me/essentials/EssentialsErrorHandler.java create mode 100644 Essentials/src/com/earth2me/essentials/EssentialsUpdateTimer.java diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java index 2a09ab76b..86a9f040d 100644 --- a/Essentials/src/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -27,6 +27,7 @@ import org.bukkit.command.CommandSender; import com.earth2me.essentials.commands.IEssentialsCommand; import com.earth2me.essentials.commands.NotEnoughArgumentsException; import com.earth2me.essentials.register.payment.Methods; +import java.math.BigInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.bukkit.craftbukkit.entity.CraftPlayer; @@ -60,8 +61,11 @@ public class Essentials extends JavaPlugin private Backup backup; private Map users = new HashMap(); private EssentialsTimer timer; + private EssentialsUpdateTimer updateTimer; private boolean registerFallback = true; private Methods paymentMethod = new Methods(); + private boolean enableErrorLogging = false; + private EssentialsErrorHandler errorHandler = new EssentialsErrorHandler(); public Essentials() { @@ -96,6 +100,10 @@ public class Essentials extends JavaPlugin public void onEnable() { + if (enableErrorLogging) + { + logger.addHandler(errorHandler); + } setStatic(); EssentialsUpgrade upgrade = new EssentialsUpgrade(this.getDescription().getVersion(), this); upgrade.beforeSettings(); @@ -184,13 +192,18 @@ public class Essentials extends JavaPlugin timer = new EssentialsTimer(this); getScheduler().scheduleSyncRepeatingTask(this, timer, 1, 50); - + if (enableErrorLogging) + { + updateTimer = new EssentialsUpdateTimer(this); + getScheduler().scheduleAsyncRepeatingTask(this, updateTimer, 50, 50 * 60 * (this.getDescription().getVersion().startsWith("Dev") ? 60 : 360)); + } logger.info(Util.format("loadinfo", this.getDescription().getName(), this.getDescription().getVersion(), AUTHORS)); } public void onDisable() { instance = null; + logger.removeHandler(errorHandler); } public void reload() @@ -201,7 +214,7 @@ public class Essentials extends JavaPlugin { iConf.reloadConfig(); } - + Util.updateLocale(settings.getLocale(), this.getDataFolder()); for (User user : users.values()) @@ -451,10 +464,20 @@ public class Essentials extends JavaPlugin } catch (Throwable ex) { - sender.sendMessage(Util.format("errorWithMessage", ex.getMessage())); + sender.sendMessage(Util.format("errorWithMessage", ex.getMessage())); + LogRecord lr = new LogRecord(Level.WARNING, Util.format("errorCallingCommand", commandLabel)); + lr.setThrown(ex); if (getSettings().isDebug()) { - logger.log(Level.WARNING, Util.format("errorCallingCommand", commandLabel), ex); + logger.log(lr); + } + else + { + if (enableErrorLogging) + { + errorHandler.publish(lr); + errorHandler.flush(); + } } return true; } @@ -658,18 +681,25 @@ public class Essentials extends JavaPlugin { return paymentMethod; } - - public int broadcastMessage(String name, String message) { - Player[] players = getServer().getOnlinePlayers(); - for (Player player : players) { + public int broadcastMessage(String name, String message) + { + Player[] players = getServer().getOnlinePlayers(); + + for (Player player : players) + { User u = getUser(player); if (!u.isIgnoredPlayer(name)) { player.sendMessage(message); } - } + } - return players.length; - } + return players.length; + } + + public Map getErrors() + { + return errorHandler.errors; + } } diff --git a/Essentials/src/com/earth2me/essentials/EssentialsErrorHandler.java b/Essentials/src/com/earth2me/essentials/EssentialsErrorHandler.java new file mode 100644 index 000000000..60512737b --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/EssentialsErrorHandler.java @@ -0,0 +1,121 @@ +package com.earth2me.essentials; + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + + +class EssentialsErrorHandler extends Handler +{ + HashMap errors = new HashMap(); + private final LinkedList records = new LinkedList(); + + public EssentialsErrorHandler() + { + } + + @Override + public void publish(LogRecord lr) + { + if (lr.getThrown() == null || lr.getLevel().intValue() < Level.WARNING.intValue()) + { + return; + } + synchronized (records) + { + records.add(lr); + } + } + + @Override + public void flush() + { + synchronized (records) + { + sortRecords(); + } + } + + @Override + public void close() throws SecurityException + { + synchronized (records) + { + sortRecords(); + } + } + + private void sortRecords() + { + for (LogRecord lr : records) + { + try + { + if (lr.getThrown() == null) + { + return; + } + Throwable tr = lr.getThrown(); + StackTraceElement[] elements = tr.getStackTrace(); + if (elements == null || elements.length <= 0) + { + return; + } + boolean essentialsFound = false; + for (StackTraceElement stackTraceElement : elements) + { + if (stackTraceElement.getClassName().contains("com.earth2me.essentials")) + { + essentialsFound = true; + break; + } + } + if (essentialsFound == false && tr.getCause() != null) + { + Throwable cause = tr.getCause(); + StackTraceElement[] elements2 = cause.getStackTrace(); + if (elements2 != null) + { + for (StackTraceElement stackTraceElement : elements2) + { + if (stackTraceElement.getClassName().contains("com.earth2me.essentials")) + { + essentialsFound = true; + break; + } + } + } + } + StringBuilder sb = new StringBuilder(); + sb.append("[").append(lr.getLevel().getName()).append("] ").append(lr.getMessage()).append("\n"); + sb.append(tr.getMessage()).append("\n"); + for (StackTraceElement stackTraceElement : tr.getStackTrace()) + { + sb.append(stackTraceElement.toString()).append("\n"); + } + if (tr.getCause() != null && tr.getCause().getStackTrace() != null) + { + sb.append(tr.getCause().getMessage()).append("\n"); + for (StackTraceElement stackTraceElement : tr.getCause().getStackTrace()) + { + sb.append(stackTraceElement.toString()).append("\n"); + } + } + String errorReport = sb.toString(); + byte[] bytesOfMessage = errorReport.getBytes("UTF-8"); + MessageDigest md = MessageDigest.getInstance("MD5"); + BigInteger bi = new BigInteger(md.digest(bytesOfMessage)); + errors.put(bi, errorReport); + } + catch (Throwable t) + { + //Ignore all exceptions inside the exception handler + } + } + records.clear(); + } +} diff --git a/Essentials/src/com/earth2me/essentials/EssentialsUpdateTimer.java b/Essentials/src/com/earth2me/essentials/EssentialsUpdateTimer.java new file mode 100644 index 000000000..1659bcc5c --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/EssentialsUpdateTimer.java @@ -0,0 +1,68 @@ +package com.earth2me.essentials; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.util.logging.Level; +import java.util.logging.Logger; + + +class EssentialsUpdateTimer implements Runnable +{ + private URL url; + private Essentials ess; + private static final Logger logger = Logger.getLogger("Minecraft"); + + public EssentialsUpdateTimer(Essentials ess) + { + this.ess = ess; + try + { + url = new URL("http://127.0.0.1:8080/check"); + } + catch (MalformedURLException ex) + { + logger.log(Level.SEVERE, "Invalid url!", ex); + } + } + + public void run() + { + try + { + StringBuilder sb = new StringBuilder(); + sb.append("v=").append(URLEncoder.encode(ess.getDescription().getVersion(),"UTF-8")); + sb.append("&b=").append(URLEncoder.encode(ess.getServer().getVersion(),"UTF-8")); + sb.append("&jv=").append(URLEncoder.encode(System.getProperty("java.version"),"UTF-8")); + sb.append("&l=").append(URLEncoder.encode(Util.currentLocale.toString(),"UTF-8")); + sb.append("&on=").append(URLEncoder.encode(System.getProperty("os.name"),"UTF-8")); + sb.append("&ov=").append(URLEncoder.encode(System.getProperty("os.version"),"UTF-8")); + for (BigInteger bigInteger : ess.getErrors().keySet()) + { + sb.append("&e[]=").append(bigInteger.toString(36)); + } + URLConnection conn = url.openConnection(); + conn.setConnectTimeout(10000); + conn.setDoOutput(true); + conn.connect(); + OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); + wr.write(sb.toString()); + wr.flush(); + BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String ret = br.readLine(); + wr.close(); + br.close(); + logger.log(Level.INFO, ret); + } + catch (IOException ex) + { + logger.log(Level.SEVERE, "Failed to open connection", ex); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/Util.java b/Essentials/src/com/earth2me/essentials/Util.java index bd68d19cb..81447d8e9 100644 --- a/Essentials/src/com/earth2me/essentials/Util.java +++ b/Essentials/src/com/earth2me/essentials/Util.java @@ -14,11 +14,9 @@ import java.text.MessageFormat; import java.util.Calendar; import java.util.Enumeration; import java.util.GregorianCalendar; -import java.util.HashSet; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; -import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -400,7 +398,7 @@ public class Util } catch (MissingResourceException ex) { - logger.log(Level.WARNING, String.format("Missing translation key \"%s\" in translation file %s", ex.getKey(), bundle.getLocale().toString())); + logger.log(Level.WARNING, String.format("Missing translation key \"%s\" in translation file %s", ex.getKey(), bundle.getLocale().toString()), ex); return defaultBundle.getString(string); } } -- cgit v1.2.3