diff --git a/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/Request.java b/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/Request.java index 230e1f1fa..a0e3f1dee 100644 --- a/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/Request.java +++ b/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/Request.java @@ -116,4 +116,15 @@ public final class Request { public Request omitFirstInPath() { return new Request(method, path.omitFirst(), query, user, headers); } + + @Override + public String toString() { + return "Request{" + + "method='" + method + '\'' + + ", path=" + path + + ", query=" + query + + ", user=" + user + + ", headers=" + headers + + '}'; + } } \ No newline at end of file diff --git a/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/URIPath.java b/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/URIPath.java index 6144b1576..2f251cfcb 100644 --- a/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/URIPath.java +++ b/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/URIPath.java @@ -119,4 +119,11 @@ public final class URIPath { } return count; } + + @Override + public String toString() { + return "URIPath{" + + "path='" + path + '\'' + + '}'; + } } diff --git a/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/URIQuery.java b/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/URIQuery.java index 9b9f72dde..e50c22d73 100644 --- a/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/URIQuery.java +++ b/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/URIQuery.java @@ -94,4 +94,11 @@ public final class URIQuery { } return builder.toString(); } + + @Override + public String toString() { + return "URIQuery{" + + "byKey=" + byKey + + '}'; + } } diff --git a/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/WebUser.java b/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/WebUser.java index 35ac7f128..ccaaa7eb2 100644 --- a/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/WebUser.java +++ b/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/request/WebUser.java @@ -59,4 +59,13 @@ public final class WebUser { public String getUsername() { return username; } + + @Override + public String toString() { + return "WebUser{" + + "playerName='" + playerName + '\'' + + ", username='" + username + '\'' + + ", permissions=" + permissions + + '}'; + } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/PlanPlaceholderExtension.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/PlanPlaceholderExtension.java index 1ac11cf2a..47ad69a73 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/PlanPlaceholderExtension.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/PlanPlaceholderExtension.java @@ -18,6 +18,7 @@ package com.djrapitops.plan.addons.placeholderapi; import com.djrapitops.plan.PlanSystem; import com.djrapitops.plan.placeholder.PlanPlaceholders; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plan.version.VersionChecker; import com.djrapitops.plugin.logging.L; @@ -92,7 +93,7 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion { return value; } catch (Exception e) { - errorLogger.log(L.WARN, getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder().whatToDo("Report this").related("Placeholder Request", params).build()); return null; } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/BukkitAFKListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/BukkitAFKListener.java index f8214bd24..153d368da 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/BukkitAFKListener.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/BukkitAFKListener.java @@ -19,6 +19,7 @@ package com.djrapitops.plan.gathering.listeners.bukkit; import com.djrapitops.plan.gathering.afk.AFKTracker; import com.djrapitops.plan.settings.Permissions; import com.djrapitops.plan.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.bukkit.entity.Player; @@ -79,7 +80,7 @@ public class BukkitAFKListener implements Listener { AFK_TRACKER.performedAction(uuid, time); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/ChatListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/ChatListener.java index 61e4b6b30..abf47aad7 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/ChatListener.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/ChatListener.java @@ -21,6 +21,7 @@ import com.djrapitops.plan.gathering.cache.NicknameCache; import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.transactions.events.NicknameStoreTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.bukkit.entity.Player; @@ -66,7 +67,7 @@ public class ChatListener implements Listener { try { actOnChatEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/DeathEventListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/DeathEventListener.java index 336f0c9c5..d1b886e01 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/DeathEventListener.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/DeathEventListener.java @@ -23,6 +23,7 @@ import com.djrapitops.plan.gathering.domain.Session; import com.djrapitops.plan.processing.Processing; import com.djrapitops.plan.processing.processors.player.MobKillProcessor; import com.djrapitops.plan.processing.processors.player.PlayerKillProcessor; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.bukkit.Material; @@ -80,7 +81,7 @@ public class DeathEventListener implements Listener { UUID uuid = dead instanceof Player ? dead.getUniqueId() : null; handleKill(time, uuid, killerEntity); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event, dead).build()); } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/GameModeChangeListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/GameModeChangeListener.java index 6837159de..b99888bb2 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/GameModeChangeListener.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/GameModeChangeListener.java @@ -22,6 +22,7 @@ import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.settings.config.WorldAliasSettings; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.transactions.events.WorldNameStoreTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.bukkit.entity.Player; @@ -67,7 +68,7 @@ public class GameModeChangeListener implements Listener { try { actOnEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event, event.getPlayer().getGameMode() + "->" + event.getNewGameMode()).build()); } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/PlayerOnlineListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/PlayerOnlineListener.java index 9d07061da..1c9777539 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/PlayerOnlineListener.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/PlayerOnlineListener.java @@ -36,6 +36,7 @@ import com.djrapitops.plan.settings.config.paths.ExportSettings; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.transactions.events.*; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.bukkit.entity.Player; @@ -107,7 +108,7 @@ public class PlayerOnlineListener implements Listener { dbSystem.getDatabase().executeTransaction(new BanStatusTransaction(playerUUID, () -> banned)); dbSystem.getDatabase().executeTransaction(new OperatorStatusTransaction(playerUUID, operator)); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event, event.getResult()).build()); } } @@ -132,7 +133,7 @@ public class PlayerOnlineListener implements Listener { dbSystem.getDatabase().executeTransaction(new KickStoreTransaction(uuid)); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -141,7 +142,7 @@ public class PlayerOnlineListener implements Listener { try { actOnJoinEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -205,7 +206,7 @@ public class PlayerOnlineListener implements Listener { try { actOnQuitEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/WorldChangeListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/WorldChangeListener.java index a384ffeb5..f6529993e 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/WorldChangeListener.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/listeners/bukkit/WorldChangeListener.java @@ -22,6 +22,7 @@ import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.settings.config.WorldAliasSettings; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.transactions.events.WorldNameStoreTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.bukkit.entity.Player; @@ -59,7 +60,7 @@ public class WorldChangeListener implements Listener { try { actOnEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/BukkitPingCounter.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/BukkitPingCounter.java index 93de12942..68429589a 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/BukkitPingCounter.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/BukkitPingCounter.java @@ -89,8 +89,7 @@ public class BukkitPingCounter extends AbsRunnable implements Listener { } catch (NoSuchMethodException | IllegalAccessException | NoSuchFieldException reflectiveEx) { Logger.getGlobal().log( Level.WARNING, - "Plan: Reflective exception in static initializer of PingCountTimer", - reflectiveEx + "Plan: Could not register Ping counter due to " + reflectiveEx ); } catch (IllegalArgumentException e) { Logger.getGlobal().log( diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/listeners/bungee/PlayerOnlineListener.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/listeners/bungee/PlayerOnlineListener.java index 15e98c5ed..5d0df3b05 100644 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/listeners/bungee/PlayerOnlineListener.java +++ b/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/listeners/bungee/PlayerOnlineListener.java @@ -34,6 +34,7 @@ import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.transactions.events.GeoInfoStoreTransaction; import com.djrapitops.plan.storage.database.transactions.events.PlayerRegisterTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -92,7 +93,7 @@ public class PlayerOnlineListener implements Listener { try { actOnLogin(event); } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -142,7 +143,7 @@ public class PlayerOnlineListener implements Listener { try { actOnLogout(event); } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -179,7 +180,7 @@ public class PlayerOnlineListener implements Listener { try { actOnServerSwitch(event); } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java index f3fa4bf31..74969fb30 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java @@ -37,6 +37,7 @@ import com.djrapitops.plan.settings.SettingsSvc; import com.djrapitops.plan.settings.locale.LocaleSystem; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.file.PlanFiles; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plan.version.VersionChecker; import com.djrapitops.plugin.benchmarking.Benchmark; @@ -222,7 +223,7 @@ public class PlanSystem implements SubSystem { system.disable(); } } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder().related("Disabling PlanSystem: " + system).build()); } } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ExportScheduler.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ExportScheduler.java index b89073477..3457f8d61 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ExportScheduler.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ExportScheduler.java @@ -73,7 +73,7 @@ public class ExportScheduler { private void schedulePlayersPageExport() { long period = TimeAmount.toTicks(config.get(ExportSettings.EXPORT_PERIOD), TimeUnit.MILLISECONDS); taskSystem.registerTask("Players page export", - new ExportTask(exporter, Exporter::exportPlayersPage, logger, errorLogger) + new ExportTask(exporter, Exporter::exportPlayersPage, errorLogger) ).runTaskTimerAsynchronously(0L, period); } @@ -89,7 +89,7 @@ public class ExportScheduler { Optional proxy = servers.stream().filter(Server::isProxy).findFirst(); proxy.ifPresent(mainServer -> taskSystem.registerTask("Network export", - new ExportTask(exporter, exporter -> exporter.exportServerPage(mainServer), logger, errorLogger)) + new ExportTask(exporter, exporter -> exporter.exportServerPage(mainServer), errorLogger)) .runTaskTimerAsynchronously(0L, period) ); @@ -99,7 +99,7 @@ public class ExportScheduler { new ExportTask(exporter, same -> { same.exportServerPage(server); same.exportServerJSON(server); - }, logger, errorLogger)) + }, errorLogger)) .runTaskTimerAsynchronously(offset * offsetMultiplier, period); offsetMultiplier++; } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ExportTask.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ExportTask.java index dae6e2f90..47c769d36 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ExportTask.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ExportTask.java @@ -19,27 +19,24 @@ package com.djrapitops.plan.delivery.export; import com.djrapitops.plan.exceptions.ExportException; import com.djrapitops.plan.exceptions.database.DBOpException; import com.djrapitops.plan.utilities.java.ThrowingConsumer; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; import com.djrapitops.plugin.task.AbsRunnable; public class ExportTask extends AbsRunnable { private final Exporter exporter; private final ThrowingConsumer exportAction; - private final PluginLogger logger; private final ErrorLogger errorLogger; public ExportTask( Exporter exporter, ThrowingConsumer exportAction, - PluginLogger logger, ErrorLogger errorLogger ) { this.exporter = exporter; this.exportAction = exportAction; - this.logger = logger; this.errorLogger = errorLogger; } @@ -48,22 +45,26 @@ public class ExportTask extends AbsRunnable { try { exportAction.accept(exporter); } catch (ExportException e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder().related("Export task run").build()); } catch (DBOpException dbException) { handleDBException(dbException); } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { - logger.error("Export Task Disabled due to error, reload Plan to re-enable."); - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder() + .whatToDo("Export Task Disabled due to error - reload Plan to re-enable.") + .related("Export task run").build()); cancel(); } } private void handleDBException(DBOpException dbException) { - logger.error("Export Task Disabled due to database error, reload Plan to re-enable."); if (dbException.getMessage().contains("closed")) { - logger.warn("(Error was caused by database closing, so this error can possibly be ignored.)"); + errorLogger.log(L.ERROR, dbException, ErrorContext.builder() + .whatToDo("Export Task Disabled due to error - database is closing, so this error can be ignored.).") + .related("Export task run").build()); } else { - errorLogger.log(L.ERROR, this.getClass(), dbException); + errorLogger.log(L.ERROR, dbException, ErrorContext.builder() + .whatToDo("Export Task Disabled due to error - reload Plan to re-enable.") + .related("Export task run").build()); } cancel(); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/DebugPage.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/DebugPage.java index ebfae5866..5bcad8459 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/DebugPage.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/DebugPage.java @@ -31,6 +31,7 @@ import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.identification.properties.ServerProperties; import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.file.ResourceCache; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plan.version.VersionChecker; import com.djrapitops.plugin.benchmarking.Benchmark; @@ -135,7 +136,7 @@ public class DebugPage implements Page { } content.append(""); } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder().related("/debug page access, resource cache").build()); } } @@ -151,7 +152,7 @@ public class DebugPage implements Page { } content.append(""); } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder().related("/debug page access, JSON cache").build()); } } @@ -172,7 +173,7 @@ public class DebugPage implements Page { } content.append(""); } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder().related("/debug page access, Session cache").build()); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/web/ResourceSvc.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/web/ResourceSvc.java index f95a45f93..9d7e4b3f7 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/web/ResourceSvc.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/web/ResourceSvc.java @@ -23,6 +23,7 @@ import com.djrapitops.plan.settings.locale.Locale; import com.djrapitops.plan.settings.locale.lang.PluginLang; import com.djrapitops.plan.storage.file.PlanFiles; import com.djrapitops.plan.storage.file.Resource; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -145,7 +146,9 @@ public class ResourceSvc implements ResourceService { return getOrWriteCustomized(fileName, source); } } catch (IOException e) { - errorLogger.log(L.WARN, getClass(), e.getCause()); + errorLogger.log(L.WARN, e, ErrorContext.builder() + .whatToDo("Report this or provide " + fileName + " in " + files.getCustomizationDirectory()) + .related("Fetching resource", "Of: " + pluginName, fileName).build()); } // Return original by default return source.get(); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/NonProxyWebserverDisableChecker.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/NonProxyWebserverDisableChecker.java index dc8e38bc2..4986d9c63 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/NonProxyWebserverDisableChecker.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/NonProxyWebserverDisableChecker.java @@ -19,6 +19,7 @@ package com.djrapitops.plan.delivery.webserver; import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.PluginSettings; import com.djrapitops.plan.settings.config.paths.WebserverSettings; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -73,9 +74,10 @@ public class NonProxyWebserverDisableChecker implements Runnable { config.set(WebserverSettings.DISABLED, true); config.save(); logger.warn("Note: Set '" + WebserverSettings.DISABLED.getPath() + "' to true"); - } catch (IOException e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder() + .whatToDo("Set '" + WebserverSettings.DISABLED.getPath() + "' to true manually.") + .related("Disabling webserver in config setting", WebserverSettings.DISABLED.getPath()).build()); } } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java index 9b1de573b..e11a867b6 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java @@ -31,6 +31,7 @@ import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.PluginSettings; import com.djrapitops.plan.settings.config.paths.WebserverSettings; import com.djrapitops.plan.storage.database.DBSystem; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -99,7 +100,10 @@ public class RequestHandler implements HttpHandler { } catch (Exception e) { if (config.isTrue(PluginSettings.DEV_MODE)) { logger.warn("THIS ERROR IS ONLY LOGGED IN DEV MODE:"); - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder() + .whatToDo("THIS ERROR IS ONLY LOGGED IN DEV MODE") + .related(exchange.getRequestMethod(), exchange.getRemoteAddress(), exchange.getRequestHeaders(), exchange.getResponseHeaders(), exchange.getRequestURI()) + .build()); } } finally { exchange.close(); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseResolver.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseResolver.java index 6172329e6..4b502c38e 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseResolver.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseResolver.java @@ -31,6 +31,7 @@ import com.djrapitops.plan.delivery.webserver.resolver.auth.*; import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver; import com.djrapitops.plan.exceptions.WebUserAuthException; import com.djrapitops.plan.exceptions.connection.ForbiddenException; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import dagger.Lazy; @@ -143,7 +144,7 @@ public class ResponseResolver { } catch (WebUserAuthException e) { throw e; // Pass along } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(request).build()); return responseFactory.internalErrorResponse(e, request.getPath().asString()); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/WebServer.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/WebServer.java index 44e2674b6..c39e76c78 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/WebServer.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/WebServer.java @@ -23,6 +23,7 @@ import com.djrapitops.plan.settings.config.paths.WebserverSettings; import com.djrapitops.plan.settings.locale.Locale; import com.djrapitops.plan.settings.locale.lang.PluginLang; import com.djrapitops.plan.storage.file.PlanFiles; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -145,7 +146,9 @@ public class WebServer implements SubSystem { .namingPattern("Plan WebServer Thread-%d") .uncaughtExceptionHandler((thread, throwable) -> { if (config.isTrue(PluginSettings.DEV_MODE)) { - errorLogger.log(L.WARN, WebServer.class, throwable); + errorLogger.log(L.WARN, throwable, ErrorContext.builder() + .whatToDo("THIS ERROR IS ONLY LOGGED IN DEV MODE") + .build()); } }).build() ); @@ -165,7 +168,7 @@ public class WebServer implements SubSystem { logger.error("Webserver failed to bind port: " + failedToBind.toString()); enabled = false; } catch (IllegalArgumentException | IllegalStateException | IOException e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related("Trying to enable webserver", config.get(WebserverSettings.INTERNAL_IP) + ":" + port).build()); enabled = false; } } @@ -183,7 +186,9 @@ public class WebServer implements SubSystem { } } catch (InvalidPathException e) { logger.error("WebServer: Could not find Keystore: " + e.getMessage()); - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder() + .whatToDo(e.getMessage() + ", Fix this path to point to a valid keystore file: " + keyStorePath) + .related(keyStorePath).build()); } char[] storepass = config.get(WebserverSettings.CERTIFICATE_STOREPASS).toCharArray(); @@ -232,7 +237,7 @@ public class WebServer implements SubSystem { logger.error(e.getMessage()); } catch (KeyManagementException | NoSuchAlgorithmException e) { logger.error(locale.getString(PluginLang.WEB_SERVER_FAIL_SSL_CONTEXT)); - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(keyStoreKind).build()); } catch (EOFException e) { logger.error(locale.getString(PluginLang.WEB_SERVER_FAIL_EMPTY_FILE)); } catch (FileNotFoundException e) { @@ -241,11 +246,12 @@ public class WebServer implements SubSystem { } catch (BindException e) { throw e; // Pass to above error handler } catch (IOException e) { - logger.error("WebServer: " + e); - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(config.get(WebserverSettings.INTERNAL_IP) + ":" + port).build()); } catch (KeyStoreException | CertificateException | UnrecoverableKeyException e) { logger.error(locale.getString(PluginLang.WEB_SERVER_FAIL_STORE_LOAD)); - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder() + .whatToDo("Make sure the Certificate settings are correct / You can try remaking the keystore without -passin or -passout parameters.") + .related(keyStorePath).build()); } return startSuccessful; } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/exceptions/ExceptionWithContext.java b/Plan/common/src/main/java/com/djrapitops/plan/exceptions/ExceptionWithContext.java new file mode 100644 index 000000000..f389e89dd --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/exceptions/ExceptionWithContext.java @@ -0,0 +1,25 @@ +/* + * This file is part of Player Analytics (Plan). + * + * Plan is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License v3 as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Plan is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Plan. If not, see . + */ +package com.djrapitops.plan.exceptions; + +import com.djrapitops.plan.utilities.logging.ErrorContext; + +import java.util.Optional; + +public interface ExceptionWithContext { + Optional getContext(); +} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/exceptions/database/DBOpException.java b/Plan/common/src/main/java/com/djrapitops/plan/exceptions/database/DBOpException.java index 05159056d..4f3149d97 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/exceptions/database/DBOpException.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/exceptions/database/DBOpException.java @@ -16,14 +16,20 @@ */ package com.djrapitops.plan.exceptions.database; +import com.djrapitops.plan.exceptions.ExceptionWithContext; +import com.djrapitops.plan.utilities.logging.ErrorContext; + import java.sql.SQLException; +import java.util.Optional; /** * Runtime exception for wrapping database errors. * * @author Rsl1122 */ -public class DBOpException extends IllegalStateException { +public class DBOpException extends IllegalStateException implements ExceptionWithContext { + + private ErrorContext context; public DBOpException(String message) { super(message); @@ -33,8 +39,100 @@ public class DBOpException extends IllegalStateException { super(message, cause); } - public static DBOpException forCause(String sql, SQLException e) { - return new DBOpException("SQL Failed: " + sql + "; " + e.getMessage(), e); + public DBOpException(String message, Throwable cause, ErrorContext context) { + super(message, cause); + this.context = context; } + // Checkstyle.OFF: CyclomaticComplexity + + public static DBOpException forCause(String sql, SQLException e) { + ErrorContext.Builder context = ErrorContext.builder(); + int errorCode = e.getErrorCode(); + context.related("Error code: " + errorCode) + .related(sql); + switch (errorCode) { + // SQLite Corrupt + case 10: + case 523: + context.related("SQL Corrupted") + .whatToDo("Your SQLite has corrupted. This can happen if .db-wal or .db-shm files get replaced mid operation. Restore database.db from backup."); + break; + // Syntax error codes + case 1054: // MySQL + case 1064: + case 1146: + case 42000: // H2 + case 42001: + case 42101: + case 42102: + case 42111: + case 42112: + case 42121: + case 42122: + case 42132: + context.related("SQL Grammar error") + .whatToDo("Report this, there is an SQL grammar error."); + break; + // Type mismatch + case 20: // SQLite + context.related("SQL Type mismatch") + .whatToDo("Report this, there is an SQL Type mismatch."); + break; + // Duplicate key + case 1062: + case 23001: + case 23505: + context.related("Duplicate key") + .whatToDo("Report this, duplicate key exists in SQL."); + break; + // Constraint violation + case 19: // SQLite + case 275: + case 531: + case 787: + case 1043: + case 1299: + case 1555: + case 2579: + case 1811: + case 2067: + case 2323: + case 630: // MySQL + case 839: + case 840: + case 893: + case 1169: + case 1215: + case 1216: + case 1217: + case 1364: + case 1451: + case 1557: + case 22001: // H2 + case 22003: + case 22012: + case 22018: + case 22025: + case 23000: + case 23002: + case 23502: + case 23506: + case 23507: + case 23513: + context.related("Constraint Violation") + .whatToDo("Report this, there is an SQL Constraint Violation."); + break; + default: + context.related("Unknown SQL Error code"); + } + return new DBOpException("SQL Failure: " + e.getMessage(), e, context.build()); + } + + // Checkstyle.ON: CyclomaticComplexity + + @Override + public Optional getContext() { + return Optional.ofNullable(context); + } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionSvc.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionSvc.java index e6aefa3e8..564e5f9c5 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionSvc.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionSvc.java @@ -23,12 +23,14 @@ import com.djrapitops.plan.exceptions.DataExtensionMethodCallException; import com.djrapitops.plan.extension.implementation.CallerImplementation; import com.djrapitops.plan.extension.implementation.ExtensionRegister; import com.djrapitops.plan.extension.implementation.ExtensionWrapper; +import com.djrapitops.plan.extension.implementation.providers.MethodWrapper; import com.djrapitops.plan.extension.implementation.providers.gathering.ProviderValueGatherer; import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.processing.Processing; import com.djrapitops.plan.settings.config.ExtensionSettings; import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.storage.database.DBSystem; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -88,8 +90,14 @@ public class ExtensionSvc implements ExtensionService { try { extensionRegister.registerBuiltInExtensions(config.getExtensionSettings().getDisabled()); } catch (IllegalStateException failedToRegisterOne) { - logger.warn("One or more extensions failed to register, see suppressed exceptions (They can be disabled in Plan config)."); - errorLogger.log(L.WARN, ExtensionService.class, failedToRegisterOne); + ErrorContext.Builder context = ErrorContext.builder() + .whatToDo("Report and/or disable the failed extensions. You can find the failed extensions in the error file."); + for (Throwable suppressedException : failedToRegisterOne.getSuppressed()) { + context.related(suppressedException.getMessage()); + } + + logger.warn("One or more extensions failed to register (They can be disabled in Plan config)."); + errorLogger.log(L.WARN, failedToRegisterOne, context.build()); } } @@ -130,7 +138,9 @@ public class ExtensionSvc implements ExtensionService { try { pluginsConfig.createSection(pluginName); } catch (IOException e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder() + .whatToDo("Create 'Plugins." + pluginName + ".Enabled: true' setting manually.") + .related("Section: " + pluginName).build()); logger.warn("Could not register DataExtension for " + pluginName + " due to " + e.toString()); return true; } @@ -165,21 +175,23 @@ public class ExtensionSvc implements ExtensionService { // Try again updatePlayerValues(gatherer, playerUUID, playerName, event); } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError unexpectedError) { - logger.warn("Encountered unexpected error with " + gatherer.getPluginName() + " Extension: " + unexpectedError + - " (but failed safely) when updating value for '" + playerName + - "', stack trace to follow (please report this):"); - errorLogger.log(L.WARN, gatherer.getClass(), unexpectedError); + ErrorContext.Builder context = ErrorContext.builder() + .whatToDo("Report and/or disable " + gatherer.getPluginName() + " extension in the Plan config.") + .related(gatherer.getPluginName()) + .related(event) + .related("Player: " + playerName + " " + playerUUID); + errorLogger.log(L.WARN, unexpectedError, context.build()); } } private void logFailure(String playerName, DataExtensionMethodCallException methodCallFailed) { Throwable cause = methodCallFailed.getCause(); - String causeName = cause.getClass().getSimpleName(); - logger.warn("Encountered " + causeName + " with " + methodCallFailed.getPluginName() + " Extension" + - " (failed safely) when updating value for '" + playerName + - "', the method was disabled temporarily (won't be called until next Plan reload)" + - ", stack trace to follow (please report this):"); - errorLogger.log(L.WARN, getClass(), cause); + ErrorContext.Builder context = ErrorContext.builder() + .whatToDo("Report and/or disable " + methodCallFailed.getPluginName() + " extension in the Plan config.") + .related(methodCallFailed.getPluginName()) + .related("Method:" + methodCallFailed.getMethod().map(MethodWrapper::getMethodName).orElse("-")) + .related("Player: " + playerName); + errorLogger.log(L.WARN, cause, context.build()); } public void updateServerValues(CallEvents event) { @@ -206,9 +218,12 @@ public class ExtensionSvc implements ExtensionService { // Try again updateServerValues(gatherer, event); } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError unexpectedError) { - logger.warn("Encountered unexpected error with " + gatherer.getPluginName() + " Extension: " + unexpectedError + - " (failed safely) when updating value for server, stack trace to follow (please report this):"); - errorLogger.log(L.WARN, gatherer.getClass(), unexpectedError); + ErrorContext.Builder context = ErrorContext.builder() + .whatToDo("Report and/or disable " + gatherer.getPluginName() + " extension in the Plan config.") + .related(gatherer.getPluginName()) + .related(event) + .related("Gathering for server"); + errorLogger.log(L.WARN, unexpectedError, context.build()); } } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerShutdownSave.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerShutdownSave.java index f50ec17a3..e7a0ac3f9 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerShutdownSave.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerShutdownSave.java @@ -25,6 +25,7 @@ import com.djrapitops.plan.settings.locale.lang.PluginLang; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.transactions.events.ServerShutdownTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -90,7 +91,11 @@ public abstract class ServerShutdownSave { prepareSessionsForStorage(activeSessions, System.currentTimeMillis()); return Optional.of(saveActiveSessions(activeSessions)); } catch (DBInitException e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder() + .whatToDo("Find the sessions in the error file and save them manually or ignore. Report & delete the error file after.") + .related("Shutdown save failed to init database.") + .related(activeSessions) + .build()); return Optional.empty(); } catch (IllegalStateException ignored) { /* Database is not initialized */ diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/NicknameCache.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/NicknameCache.java index f12fd23a4..343d5efca 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/NicknameCache.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/NicknameCache.java @@ -99,7 +99,7 @@ public class NicknameCache implements SubSystem { NicknameQueries.fetchLastSeenNicknameOfPlayer(uuid, serverInfo.getServerUUID()) ).map(Nickname::getName); } catch (DBOpException e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e); } return Optional.empty(); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/SystemUsageBuffer.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/SystemUsageBuffer.java index 2a6affd3a..848860519 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/SystemUsageBuffer.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/SystemUsageBuffer.java @@ -19,6 +19,7 @@ package com.djrapitops.plan.gathering.timed; import com.djrapitops.plan.gathering.SystemUsage; import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.DataGatheringSettings; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -111,7 +112,8 @@ public class SystemUsageBuffer { buffer.freeDiskSpace = SystemUsage.getFreeDiskSpace(); } catch (SecurityException noPermission) { if (!diskErrored) { - errorLogger.log(L.WARN, this.getClass(), noPermission); + errorLogger.log(L.WARN, noPermission, ErrorContext.builder() + .whatToDo("Resolve " + noPermission.getMessage() + " via OS or JVM permissions").build()); } diskErrored = true; } catch (Exception e) { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCounter.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCounter.java index c4c4cd652..fa70c093f 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCounter.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCounter.java @@ -16,6 +16,7 @@ */ package com.djrapitops.plan.gathering.timed; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -45,7 +46,7 @@ public abstract class TPSCounter extends AbsRunnable { pulse(); } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { logger.error("TPS Count Task Disabled due to error, reload Plan to re-enable."); - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().whatToDo("See if a restart fixes this or Report this").build()); cancel(); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/identification/ServerServerInfo.java b/Plan/common/src/main/java/com/djrapitops/plan/identification/ServerServerInfo.java index dd33a24b0..6db74f0ed 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/identification/ServerServerInfo.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/identification/ServerServerInfo.java @@ -27,6 +27,7 @@ import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.queries.objects.ServerQueries; import com.djrapitops.plan.storage.database.transactions.StoreServerInformationTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; @@ -113,8 +114,11 @@ public class ServerServerInfo extends ServerInfo { if (!foundServer.isPresent()) { try { server = registerServer(serverUUID); - } catch (ExecutionException | IOException e) { - errorLogger.log(L.CRITICAL, this.getClass(), e); + } catch (IOException e) { + errorLogger.log(L.CRITICAL, e, ErrorContext.builder() + .whatToDo("Grant access permissions for writing to " + serverInfoFile.getConfigFilePath()).build()); + } catch (ExecutionException e) { + errorLogger.log(L.CRITICAL, e, ErrorContext.builder().build()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/identification/UUIDUtility.java b/Plan/common/src/main/java/com/djrapitops/plan/identification/UUIDUtility.java index 650deabff..3cab1154a 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/identification/UUIDUtility.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/identification/UUIDUtility.java @@ -92,7 +92,7 @@ public class UUIDUtility { try { return dbSystem.getDatabase().query(UserIdentifierQueries.fetchPlayerUUIDOf(playerName)); } catch (DBOpException e) { - errorLogger.log(L.ERROR, UUIDUtility.class, e); + errorLogger.log(L.ERROR, e); return Optional.empty(); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/processing/Processing.java b/Plan/common/src/main/java/com/djrapitops/plan/processing/Processing.java index 3f84dc7ff..181fde9b5 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/processing/Processing.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/processing/Processing.java @@ -19,6 +19,7 @@ package com.djrapitops.plan.processing; import com.djrapitops.plan.SubSystem; import com.djrapitops.plan.settings.locale.Locale; import com.djrapitops.plan.settings.locale.lang.PluginLang; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -58,7 +59,7 @@ public class Processing implements SubSystem { new BasicThreadFactory.Builder() .namingPattern(s) .uncaughtExceptionHandler((thread, throwable) -> - errorLogger.log(L.WARN, Processing.class, throwable) + errorLogger.log(L.WARN, throwable, ErrorContext.builder().build()) ).build()); } @@ -110,14 +111,14 @@ public class Processing implements SubSystem { private T exceptionHandlerNonCritical(T t, Throwable throwable) { if (throwable != null) { - errorLogger.log(L.WARN, Processing.class, throwable.getCause()); + errorLogger.log(L.WARN, throwable.getCause(), ErrorContext.builder().build()); } return t; } private T exceptionHandlerCritical(T t, Throwable throwable) { if (throwable != null) { - errorLogger.log(L.ERROR, Processing.class, throwable.getCause()); + errorLogger.log(L.ERROR, throwable.getCause(), ErrorContext.builder().build()); } return t; } @@ -163,7 +164,7 @@ public class Processing implements SubSystem { try { runnable.run(); } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder().build()); } } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/query/QuerySvc.java b/Plan/common/src/main/java/com/djrapitops/plan/query/QuerySvc.java index a42299551..0482728d9 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/query/QuerySvc.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/query/QuerySvc.java @@ -23,6 +23,7 @@ import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.queries.QueryAPIExecutable; import com.djrapitops.plan.storage.database.queries.QueryAPIQuery; import com.djrapitops.plan.storage.database.transactions.Transaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -107,8 +108,9 @@ public class QuerySvc implements QueryService { try { subscriber.accept(playerUUID); } catch (DBOpException e) { - logger.warn("User of Query API (" + subscriber.getClass().getName() + ") ran into exception, failed safely:"); - errorLogger.log(L.WARN, QueryService.class, e); + errorLogger.log(L.WARN, e, ErrorContext.builder() + .whatToDo("Report to this Query API user " + subscriber.getClass().getName()) + .related("Subscriber: " + subscriber.getClass().getName()).build()); } }); } @@ -118,8 +120,9 @@ public class QuerySvc implements QueryService { try { function.apply(); } catch (DBOpException e) { - logger.warn("User of Query API (" + function.getClass().getName() + ") ran into exception, failed safely:"); - errorLogger.log(L.WARN, QueryService.class, e); + errorLogger.log(L.WARN, e, ErrorContext.builder() + .whatToDo("Report to this Query API user " + function.getClass().getName()) + .related("Subscriber: " + function.getClass().getName()).build()); } }); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/settings/ConfigSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/settings/ConfigSystem.java index 55905f2ae..12429a693 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/settings/ConfigSystem.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/settings/ConfigSystem.java @@ -24,6 +24,7 @@ import com.djrapitops.plan.settings.config.paths.FormatSettings; import com.djrapitops.plan.settings.config.paths.PluginSettings; import com.djrapitops.plan.settings.theme.Theme; import com.djrapitops.plan.storage.file.PlanFiles; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -86,7 +87,7 @@ public abstract class ConfigSystem implements SubSystem { checkWrongTimeZone(); } catch (IOException e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().whatToDo("Fix write permissions to " + config.getConfigFilePath()).build()); throw new EnableException("Failed to save default config: " + e.getMessage(), e); } theme.enable(); @@ -134,7 +135,7 @@ public abstract class ConfigSystem implements SubSystem { try { config.read(); } catch (IOException e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().whatToDo("Fix read permissions to " + config.getConfigFilePath()).build()); } } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/settings/SettingsSvc.java b/Plan/common/src/main/java/com/djrapitops/plan/settings/SettingsSvc.java index 668ea23fe..ef2434804 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/settings/SettingsSvc.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/settings/SettingsSvc.java @@ -18,6 +18,7 @@ package com.djrapitops.plan.settings; import com.djrapitops.plan.settings.config.ConfigNode; import com.djrapitops.plan.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; @@ -70,7 +71,7 @@ public class SettingsSvc implements SettingsService { try { config.save(); } catch (IOException e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().whatToDo("Fix write permissions to " + config.getConfigFilePath()).build()); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/settings/config/Config.java b/Plan/common/src/main/java/com/djrapitops/plan/settings/config/Config.java index 5cbc930e2..309bf5a9d 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/settings/config/Config.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/settings/config/Config.java @@ -98,4 +98,8 @@ public class Config extends ConfigNode { public int hashCode() { return Objects.hash(super.hashCode(), configFilePath); } + + public Path getConfigFilePath() { + return configFilePath; + } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/settings/config/WorldAliasSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/settings/config/WorldAliasSettings.java index 9fab3fc57..6923ca304 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/settings/config/WorldAliasSettings.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/settings/config/WorldAliasSettings.java @@ -27,6 +27,7 @@ import com.djrapitops.plan.settings.config.paths.DisplaySettings; import com.djrapitops.plan.settings.locale.Locale; import com.djrapitops.plan.settings.locale.lang.GenericLang; import com.djrapitops.plan.settings.locale.lang.HtmlLang; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.utilities.Verify; @@ -93,7 +94,7 @@ public class WorldAliasSettings { try { aliasSect.save(); } catch (IOException e) { - errorLogger.log(L.WARN, WorldAliasSettings.class, e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().whatToDo("Fix write permissions to " + config.get().getConfigFilePath()).build()); } }); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/settings/config/changes/ConfigUpdater.java b/Plan/common/src/main/java/com/djrapitops/plan/settings/config/changes/ConfigUpdater.java index d47d84d4a..f1341b59a 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/settings/config/changes/ConfigUpdater.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/settings/config/changes/ConfigUpdater.java @@ -18,6 +18,7 @@ package com.djrapitops.plan.settings.config.changes; import com.djrapitops.plan.settings.config.Config; import com.djrapitops.plan.settings.config.paths.FormatSettings; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -152,7 +153,9 @@ public class ConfigUpdater { logger.info("Config: " + change.getAppliedMessage()); } } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), new IllegalStateException("Failed to apply config update: '" + change.getAppliedMessage() + "'", e)); + errorLogger.log(L.ERROR, e, ErrorContext.builder() + .whatToDo("Fix write permissions to " + config.getConfigFilePath() + " or Report this") + .related("Attempt to change: " + change.getAppliedMessage()).build()); } } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/settings/locale/LocaleSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/settings/locale/LocaleSystem.java index 24590d6cc..a835d2a78 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/settings/locale/LocaleSystem.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/settings/locale/LocaleSystem.java @@ -22,6 +22,7 @@ import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.PluginSettings; import com.djrapitops.plan.settings.locale.lang.*; import com.djrapitops.plan.storage.file.PlanFiles; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -112,8 +113,7 @@ public class LocaleSystem implements SubSystem { } new LocaleFileWriter(writing).writeToFile(localeFile); } catch (IOException | IllegalStateException e) { - logger.error("Failed to write new Locale file at " + localeFile.getAbsolutePath()); - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().whatToDo("Fix write permissions to " + localeFile.getAbsolutePath()).build()); } resetWriteConfigSetting(); } @@ -123,8 +123,7 @@ public class LocaleSystem implements SubSystem { config.set(PluginSettings.WRITE_NEW_LOCALE, false); config.save(); } catch (IOException | IllegalStateException e) { - logger.error("Failed set WriteNewLocaleFileOnEnable back to false"); - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().whatToDo("Fix write permissions to " + config.getConfigFilePath()).build()); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/settings/upkeep/FileWatcher.java b/Plan/common/src/main/java/com/djrapitops/plan/settings/upkeep/FileWatcher.java index d12feb43f..ed0874dbe 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/settings/upkeep/FileWatcher.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/settings/upkeep/FileWatcher.java @@ -16,6 +16,7 @@ */ package com.djrapitops.plan.settings.upkeep; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.utilities.Verify; @@ -75,7 +76,7 @@ public class FileWatcher extends Thread { watchedPath.register(watcher, ENTRY_MODIFY); runLoop(watcher); } catch (IOException e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().build()); interrupt(); } catch (InterruptedException e) { interrupt(); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/MySQLDB.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/MySQLDB.java index 90541fabd..c5a963258 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/MySQLDB.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/MySQLDB.java @@ -23,6 +23,7 @@ import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.DatabaseSettings; import com.djrapitops.plan.settings.locale.Locale; import com.djrapitops.plan.settings.locale.lang.PluginLang; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -76,7 +77,7 @@ public class MySQLDB extends SQLDB { try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) { - errorLogger.log(L.CRITICAL, this.getClass(), e); + errorLogger.log(L.CRITICAL, e, ErrorContext.builder().whatToDo("Install MySQL Driver to the server").build()); } } @@ -164,7 +165,7 @@ public class MySQLDB extends SQLDB { connection.close(); } } catch (SQLException e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.CRITICAL, e, ErrorContext.builder().related("Closing connection").build()); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/SQLDB.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/SQLDB.java index ba69ebeb5..1f2ad3f2c 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/SQLDB.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/SQLDB.java @@ -31,6 +31,7 @@ import com.djrapitops.plan.storage.database.transactions.init.CreateTablesTransa import com.djrapitops.plan.storage.database.transactions.init.OperationCriticalTransaction; import com.djrapitops.plan.storage.database.transactions.patches.*; import com.djrapitops.plan.utilities.java.ThrowableUtils; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.logging.L; @@ -92,7 +93,9 @@ public abstract class SQLDB extends AbstractDatabase { .namingPattern(nameFormat) .uncaughtExceptionHandler((thread, throwable) -> { if (devMode) { - errorLogger.log(L.WARN, getClass(), throwable); + errorLogger.log(L.WARN, throwable, ErrorContext.builder() + .whatToDo("THIS ERROR IS ONLY LOGGED IN DEV MODE") + .build()); } }).build()); }; @@ -248,10 +251,10 @@ public abstract class SQLDB extends AbstractDatabase { } transaction.executeTransaction(this); return CompletableFuture.completedFuture(null); - }, getTransactionExecutor()).handle(errorHandler(origin)); + }, getTransactionExecutor()).handle(errorHandler(transaction, origin)); } - private BiFunction, Throwable, CompletableFuture> errorHandler(Exception origin) { + private BiFunction, Throwable, CompletableFuture> errorHandler(Transaction transaction, Exception origin) { return (obj, throwable) -> { if (throwable == null) { return CompletableFuture.completedFuture(null); @@ -261,7 +264,8 @@ public abstract class SQLDB extends AbstractDatabase { } ThrowableUtils.appendEntryPointToCause(throwable, origin); - errorLogger.log(L.ERROR, getClass(), throwable); + errorLogger.log(L.ERROR, throwable, ErrorContext.builder() + .related("Transaction: " + transaction.getClass()).build()); return CompletableFuture.completedFuture(null); }; } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/SQLiteDB.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/SQLiteDB.java index d8307817a..b17c8a78b 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/SQLiteDB.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/SQLiteDB.java @@ -25,6 +25,7 @@ import com.djrapitops.plan.storage.file.PlanFiles; import com.djrapitops.plan.storage.upkeep.DBKeepAliveTask; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.utilities.java.ThrowableUtils; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -80,8 +81,8 @@ public class SQLiteDB extends SQLDB { try { Class.forName("org.sqlite.JDBC"); } catch (ClassNotFoundException e) { - errorLogger.log(L.CRITICAL, this.getClass(), e); - return null; // Should never happen. + errorLogger.log(L.CRITICAL, e, ErrorContext.builder().whatToDo("Install SQLite Driver to the server").build()); + return null; } String dbFilePath = dbFile.getAbsolutePath(); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/upkeep/DBCleanTask.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/upkeep/DBCleanTask.java index 09c1b6070..f7f3fc6ec 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/upkeep/DBCleanTask.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/upkeep/DBCleanTask.java @@ -115,7 +115,7 @@ public class DBCleanTask extends AbsRunnable { } } } catch (DBOpException e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e); cancel(); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/upkeep/DBKeepAliveTask.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/upkeep/DBKeepAliveTask.java index 13ddb4bb0..5cfc59ba6 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/upkeep/DBKeepAliveTask.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/upkeep/DBKeepAliveTask.java @@ -17,6 +17,7 @@ package com.djrapitops.plan.storage.upkeep; import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; @@ -59,7 +60,8 @@ public class DBKeepAliveTask extends AbsRunnable { try { connection = iReconnect.reconnect(); } catch (SQLException reconnectionError) { - errorLogger.log(L.ERROR, this.getClass(), reconnectionError); + errorLogger.log(L.ERROR, reconnectionError, ErrorContext.builder() + .whatToDo("Reload Plan and Report this if the issue persists").build()); logger.error("SQL connection maintaining task had to be closed due to exception."); this.cancel(); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/logging/ErrorContext.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/logging/ErrorContext.java index ee65e2e42..3652179fa 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/logging/ErrorContext.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/logging/ErrorContext.java @@ -42,12 +42,17 @@ public class ErrorContext { public Collection toLines() { List lines = new ArrayList<>(); + getWhatToDo().ifPresent(lines::add); for (Object o : related) { lines.add(Objects.toString(o)); } return lines; } + public void merge(ErrorContext context) { + this.related.addAll(context.related); + } + public static class Builder { private final ErrorContext context; diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/logging/ErrorLogger.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/logging/ErrorLogger.java index 4e3c94675..aebcd8088 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/logging/ErrorLogger.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/logging/ErrorLogger.java @@ -18,6 +18,7 @@ package com.djrapitops.plan.utilities.logging; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.delivery.formatting.Formatters; +import com.djrapitops.plan.exceptions.ExceptionWithContext; import com.djrapitops.plan.identification.properties.ServerProperties; import com.djrapitops.plan.storage.file.PlanFiles; import com.djrapitops.plan.utilities.java.Lists; @@ -76,11 +77,16 @@ public class ErrorLogger implements ErrorHandler { this.formatters = formatters; } + public void log(L level, T throwable) { + log(level, (Throwable) throwable, throwable.getContext().orElse(ErrorContext.builder().related("Missing Context").build())); + } + public void log(L level, Throwable throwable, ErrorContext context) { String errorName = throwable.getClass().getSimpleName(); String hash = hash(throwable); Path logsDir = files.getLogsDirectory(); Path errorLog = logsDir.resolve(errorName + "-" + hash + ".txt"); + mergeAdditionalContext(throwable, context); if (Files.exists(errorLog)) { logExisting(errorLog, throwable, context); } else { @@ -93,6 +99,16 @@ public class ErrorLogger implements ErrorHandler { } } + public void mergeAdditionalContext(Throwable throwable, ErrorContext context) { + Throwable cause = throwable.getCause(); + while (cause != null) { + if (cause instanceof ExceptionWithContext) { + ((ExceptionWithContext) cause).getContext().ifPresent(context::merge); + } + cause = cause.getCause(); + } + } + private void logExisting(Path errorLog, Throwable throwable, ErrorContext context) { // Read existing List lines; @@ -232,6 +248,13 @@ public class ErrorLogger implements ErrorHandler { for (StackTraceElement element : e.getStackTrace()) { trace.add(" " + element); } + Throwable[] suppressed = e.getSuppressed(); + if (suppressed.length > 0) { + for (Throwable suppressedThrowable : suppressed) { + trace.add(" Suppressed:"); + buildReadableStacktrace(suppressedThrowable).stream().map(line -> " " + line).forEach(trace::add); + } + } Throwable cause = e.getCause(); if (cause != null) { trace.add("Caused by:"); diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/NukkitPlaceholderRegistrar.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/NukkitPlaceholderRegistrar.java index 47ec480b2..d9863fbb8 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/NukkitPlaceholderRegistrar.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/NukkitPlaceholderRegistrar.java @@ -24,12 +24,12 @@ import com.djrapitops.plan.delivery.domain.keys.PlayerKeys; import com.djrapitops.plan.gathering.cache.SessionCache; import com.djrapitops.plan.placeholder.PlanPlaceholders; import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import javax.inject.Inject; import javax.inject.Singleton; -import java.util.ArrayList; import java.util.UUID; /** @@ -60,9 +60,9 @@ public class NukkitPlaceholderRegistrar { placeholders.getPlaceholders().forEach((name, loader) -> api.visitorSensitivePlaceholder(name, (player, params) -> { try { - return loader.apply(getPlayer(player), new ArrayList<>(params.getAll().values())); + return loader.apply(getPlayer(player), params.get()); } catch (Exception e) { - errorLogger.log(L.WARN, getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder().related("Registering PlaceholderAPI").build()); return null; } } @@ -71,9 +71,9 @@ public class NukkitPlaceholderRegistrar { placeholders.getStaticPlaceholders().forEach((name, loader) -> api.staticPlaceholder(name, params -> { try { - return loader.apply(new ArrayList<>(params.getAll().values())); + return loader.apply(params.get()); } catch (Exception e) { - errorLogger.log(L.WARN, getClass(), e); + errorLogger.log(L.WARN, e, ErrorContext.builder().related("Registering PlaceholderAPI").build()); return null; } } diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/ChatListener.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/ChatListener.java index 5b8800bbe..381f9c97d 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/ChatListener.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/ChatListener.java @@ -26,6 +26,7 @@ import com.djrapitops.plan.gathering.cache.NicknameCache; import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.transactions.events.NicknameStoreTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; @@ -66,7 +67,7 @@ public class ChatListener implements Listener { try { actOnChatEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/DeathEventListener.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/DeathEventListener.java index facaa5d6f..73d57f10a 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/DeathEventListener.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/DeathEventListener.java @@ -35,6 +35,7 @@ import com.djrapitops.plan.gathering.domain.Session; import com.djrapitops.plan.processing.Processing; import com.djrapitops.plan.processing.processors.player.MobKillProcessor; import com.djrapitops.plan.processing.processors.player.PlayerKillProcessor; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; @@ -78,7 +79,7 @@ public class DeathEventListener implements Listener { UUID uuid = dead.getUniqueId(); handleKill(time, uuid, killerEntity); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event, dead).build()); } } @@ -98,7 +99,7 @@ public class DeathEventListener implements Listener { handleKill(time, /* Not a player */ null, killerEntity); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event, dead).build()); } } diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/GameModeChangeListener.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/GameModeChangeListener.java index b21301bc6..5a267b02b 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/GameModeChangeListener.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/GameModeChangeListener.java @@ -28,6 +28,7 @@ import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.settings.config.WorldAliasSettings; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.transactions.events.WorldNameStoreTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; @@ -68,7 +69,7 @@ public class GameModeChangeListener implements Listener { try { actOnEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event, event.getPlayer().getGamemode() + "->" + event.getNewGamemode()).build()); } } diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/NukkitAFKListener.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/NukkitAFKListener.java index d19c281a4..021850395 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/NukkitAFKListener.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/NukkitAFKListener.java @@ -24,6 +24,7 @@ import cn.nukkit.event.player.*; import com.djrapitops.plan.gathering.afk.AFKTracker; import com.djrapitops.plan.settings.Permissions; import com.djrapitops.plan.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; @@ -79,7 +80,7 @@ public class NukkitAFKListener implements Listener { AFK_TRACKER.performedAction(uuid, time); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/PlayerOnlineListener.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/PlayerOnlineListener.java index 3383d2d19..3edc5d33f 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/PlayerOnlineListener.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/PlayerOnlineListener.java @@ -45,6 +45,7 @@ import com.djrapitops.plan.settings.config.paths.ExportSettings; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.transactions.events.*; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; @@ -105,7 +106,7 @@ public class PlayerOnlineListener implements Listener { boolean operator = event.getPlayer().isOp(); dbSystem.getDatabase().executeTransaction(new OperatorStatusTransaction(playerUUID, operator)); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -130,7 +131,7 @@ public class PlayerOnlineListener implements Listener { dbSystem.getDatabase().executeTransaction(new KickStoreTransaction(uuid)); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -139,7 +140,7 @@ public class PlayerOnlineListener implements Listener { try { actOnJoinEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -204,7 +205,7 @@ public class PlayerOnlineListener implements Listener { try { actOnQuitEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/WorldChangeListener.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/WorldChangeListener.java index 9db0b87b1..30ee392a6 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/WorldChangeListener.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/listeners/nukkit/WorldChangeListener.java @@ -28,6 +28,7 @@ import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.settings.config.WorldAliasSettings; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.transactions.events.WorldNameStoreTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; @@ -61,7 +62,7 @@ public class WorldChangeListener implements Listener { try { actOnEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } } diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/PlayerOnlineListener.java b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/PlayerOnlineListener.java index dc4ed0f26..0f7117340 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/PlayerOnlineListener.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/PlayerOnlineListener.java @@ -36,6 +36,7 @@ import com.djrapitops.plan.settings.config.paths.ExportSettings; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.transactions.events.*; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.spongepowered.api.Sponge; @@ -105,7 +106,7 @@ public class PlayerOnlineListener { try { actOnLoginEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -125,7 +126,7 @@ public class PlayerOnlineListener { } dbSystem.getDatabase().executeTransaction(new KickStoreTransaction(playerUUID)); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -143,7 +144,7 @@ public class PlayerOnlineListener { try { actOnJoinEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -208,7 +209,7 @@ public class PlayerOnlineListener { try { actOnQuitEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeAFKListener.java b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeAFKListener.java index c9a6930cc..2bf9e87dd 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeAFKListener.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeAFKListener.java @@ -19,6 +19,7 @@ package com.djrapitops.plan.gathering.listeners.sponge; import com.djrapitops.plan.gathering.afk.AFKTracker; import com.djrapitops.plan.settings.Permissions; import com.djrapitops.plan.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.spongepowered.api.entity.living.player.Player; @@ -71,7 +72,7 @@ public class SpongeAFKListener { try { performedAction(event.getTargetEntity()); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeChatListener.java b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeChatListener.java index 111f48f0b..1898ac78a 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeChatListener.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeChatListener.java @@ -21,6 +21,7 @@ import com.djrapitops.plan.gathering.cache.NicknameCache; import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.transactions.events.NicknameStoreTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.spongepowered.api.entity.living.player.Player; @@ -66,7 +67,7 @@ public class SpongeChatListener { try { actOnChatEvent(player); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeDeathListener.java b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeDeathListener.java index 87495df0d..b5c49d96d 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeDeathListener.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeDeathListener.java @@ -23,6 +23,7 @@ import com.djrapitops.plan.gathering.domain.Session; import com.djrapitops.plan.processing.Processing; import com.djrapitops.plan.processing.processors.player.MobKillProcessor; import com.djrapitops.plan.processing.processors.player.PlayerKillProcessor; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.spongepowered.api.data.key.Keys; @@ -81,7 +82,7 @@ public class SpongeDeathListener { handleKill(time, dead, killerEntity); } } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event, dead).build()); } } diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeGMChangeListener.java b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeGMChangeListener.java index 1226afe99..f3348aa7e 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeGMChangeListener.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeGMChangeListener.java @@ -22,6 +22,7 @@ import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.settings.config.WorldAliasSettings; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.transactions.events.WorldNameStoreTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.spongepowered.api.entity.living.player.Player; @@ -67,7 +68,7 @@ public class SpongeGMChangeListener { try { actOnGMChangeEvent(event); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event, event.getGameMode()).build()); } } diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeWorldChangeListener.java b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeWorldChangeListener.java index 2673b0443..c25ab1d4d 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeWorldChangeListener.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeWorldChangeListener.java @@ -22,6 +22,7 @@ import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.settings.config.WorldAliasSettings; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.transactions.events.WorldNameStoreTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import org.spongepowered.api.data.key.Keys; @@ -70,7 +71,7 @@ public class SpongeWorldChangeListener { try { actOnEvent(event, player); } catch (Exception e) { - errorLogger.log(L.ERROR, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } diff --git a/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/listeners/velocity/PlayerOnlineListener.java b/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/listeners/velocity/PlayerOnlineListener.java index c98fcb1ec..f4cc648e0 100644 --- a/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/listeners/velocity/PlayerOnlineListener.java +++ b/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/listeners/velocity/PlayerOnlineListener.java @@ -34,6 +34,7 @@ import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.transactions.events.GeoInfoStoreTransaction; import com.djrapitops.plan.storage.database.transactions.events.PlayerRegisterTransaction; +import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plugin.logging.L; import com.velocitypowered.api.event.PostOrder; @@ -96,7 +97,7 @@ public class PlayerOnlineListener { try { actOnLogin(event); } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -147,7 +148,7 @@ public class PlayerOnlineListener { try { actOnLogout(event); } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } } @@ -185,7 +186,7 @@ public class PlayerOnlineListener { try { actOnServerSwitch(event); } catch (Exception e) { - errorLogger.log(L.WARN, this.getClass(), e); + errorLogger.log(L.ERROR, e, ErrorContext.builder().related(event).build()); } }