diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/Towny.java b/Towny/src/main/java/com/palmergames/bukkit/towny/Towny.java index 6bf6d6c5fb..c2f22c01f5 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/Towny.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/Towny.java @@ -234,7 +234,7 @@ public void loadFoundation(boolean reload) { TownBlockTypeHandler.initialize(); // Initialize the special log4j hook logger. - TownyLogger.getInstance(); + TownyLogger.initialize(); // Clear all objects from the TownyUniverse class. townyUniverse.clearAllObjects(); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/TownyLogger.java b/Towny/src/main/java/com/palmergames/bukkit/towny/TownyLogger.java index 1b07819958..e280d68db9 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/TownyLogger.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/TownyLogger.java @@ -1,15 +1,19 @@ package com.palmergames.bukkit.towny; import com.palmergames.bukkit.towny.object.economy.Account; + import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.appender.FileAppender; import org.apache.logging.log4j.core.config.AppenderRef; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.LoggerConfig; +import org.apache.logging.log4j.core.filter.CompositeFilter; +import org.apache.logging.log4j.core.filter.LevelMatchFilter; import org.apache.logging.log4j.core.layout.PatternLayout; import java.io.File; @@ -18,40 +22,48 @@ /** * @author Articdive */ -public class TownyLogger { - private static final TownyLogger instance = new TownyLogger(); - private static final Logger LOGGER_MONEY = LogManager.getLogger("com.palmergames.bukkit.towny.money"); - - @SuppressWarnings("deprecation") // Until Mojang updates their log4j included with minecraft we have to use the deprecated methods. +public final class TownyLogger { private TownyLogger() { + + } + + private static final Logger LOGGER_MONEY = LogManager.getLogger("Towny-Money"); + + private static Appender townyDebugAppender; + + @SuppressWarnings("deprecation") + public static void initialize() { LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration config = ctx.getConfiguration(); // Get log location. String logFolderName = TownyUniverse.getInstance().getRootFolder() + File.separator + "logs"; - + Appender townyMainAppender = FileAppender.newBuilder() .withFileName(logFolderName + File.separator + "towny.log") - .withName("Towny-Main-Log") + .setName("Towny-Main-Log") .withAppend(TownySettings.isAppendingToLog()) - .withIgnoreExceptions(false) + .setIgnoreExceptions(false) .withBufferedIo(false) .withBufferSize(0) + .withLocking(false) .setConfiguration(config) - .withLayout(PatternLayout.newBuilder() + .setLayout(PatternLayout.newBuilder() .withCharset(StandardCharsets.UTF_8) - .withPattern("%d [%t]: %m%n") + .withPattern("%d{dd MMM yyyy HH:mm:ss} [%t]: %m%n") .withConfiguration(config) .build()) .build(); + Appender townyMoneyAppender = FileAppender.newBuilder() .withFileName(logFolderName + File.separator + "money.csv") - .withName("Towny-Money") + .setName("Towny-Money") .withAppend(TownySettings.isAppendingToLog()) - .withIgnoreExceptions(false) + .setIgnoreExceptions(false) .withBufferedIo(false) .withBufferSize(0) + .withLocking(false) .setConfiguration(config) - .withLayout(PatternLayout.newBuilder() + .setLayout(PatternLayout.newBuilder() // The comma after the date is to seperate it in CSV, this is a really nice workaround // And avoids having to use apache-csv to make it work with Log4J .withCharset(StandardCharsets.UTF_8) @@ -59,103 +71,116 @@ private TownyLogger() { .withConfiguration(config) .build()) .build(); - Appender townyDebugAppender = FileAppender.newBuilder() + + townyDebugAppender = FileAppender.newBuilder() .withFileName(logFolderName + File.separator + "debug.log") - .withName("Towny-Debug") + .setName("Towny-Debug") .withAppend(TownySettings.isAppendingToLog()) - .withIgnoreExceptions(false) + .setIgnoreExceptions(false) .withBufferedIo(false) .withBufferSize(0) + .withLocking(false) .setConfiguration(config) - .withLayout(PatternLayout.newBuilder() + .setLayout(PatternLayout.newBuilder() .withCharset(StandardCharsets.UTF_8) - .withPattern("%d [%t]: %m%n") + .withPattern("%d{dd MMM yyyy HH:mm:ss} [%t]: %m%n") .withConfiguration(config) .build()) .build(); - Appender townyDatabaseAppender = FileAppender.newBuilder() - .withFileName(logFolderName + File.separator + "database.log") - .withName("Towny-Database") - .withAppend(TownySettings.isAppendingToLog()) - .withIgnoreExceptions(false) - .withBufferedIo(false) - .withBufferSize(0) - .setConfiguration(config) - .withLayout(PatternLayout.newBuilder() - .withCharset(StandardCharsets.UTF_8) - .withPattern("%d [%t]: %m%n") - .withConfiguration(config) - .build()) - .build(); - + +// Appender townyDatabaseAppender = FileAppender.newBuilder() +// .withFileName(logFolderName + File.separator + "database.log") +// .setName("Towny-Database") +// .withAppend(TownySettings.isAppendingToLog()) +// .setIgnoreExceptions(false) +// .withBufferedIo(false) +// .withBufferSize(0) +// .withLocking(false) +// .setConfiguration(config) +// .setLayout(PatternLayout.newBuilder() +// .withCharset(StandardCharsets.UTF_8) +// .withPattern("%d{dd MMM yyyy HH:mm:ss} [%t]: %m%n") +// .withConfiguration(config) +// .build()) +// .build(); + townyMainAppender.start(); - townyMoneyAppender.start(); townyDebugAppender.start(); - townyDatabaseAppender.start(); - + townyMoneyAppender.start(); +// townyDatabaseAppender.start(); + // Towny Main LoggerConfig townyMainConfig = LoggerConfig.createLogger(true, Level.ALL, "Towny", null, new AppenderRef[0], null, config, null); - townyMainConfig.addAppender(townyMainAppender, Level.ALL, null); - config.addLogger(Towny.class.getName(), townyMainConfig); - - // Debug - LoggerConfig townyDebugConfig = LoggerConfig.createLogger(TownySettings.getDebug(), Level.ALL, "Towny-Debug", null, new AppenderRef[0], null, config, null); - townyDebugConfig.addAppender(townyDebugAppender, Level.ALL, null); - config.addLogger("com.palmergames.bukkit.towny.debug", townyDebugConfig); - + townyMainConfig.addAppender(townyMainAppender, Level.INFO, null); + // Spigot/Paper decided to name the loggers with their plugin's simple name. + config.addLogger("Towny", townyMainConfig); + // Money LoggerConfig townyMoneyConfig = LoggerConfig.createLogger(false, Level.ALL, "Towny-Money", null, new AppenderRef[0], null, config, null); townyMoneyConfig.addAppender(townyMoneyAppender, Level.ALL, null); - config.addLogger("com.palmergames.bukkit.towny.money", townyMoneyConfig); - + config.addLogger("Towny-Money", townyMoneyConfig); + // Database - LoggerConfig townyDatabaseConfig = LoggerConfig.createLogger(false, Level.ALL, "Towny-Database", null, new AppenderRef[0], null, config, null); - townyDatabaseConfig.addAppender(townyDatabaseAppender, Level.ALL, null); - +// LoggerConfig townyDatabaseConfig = LoggerConfig.createLogger(false, Level.ALL, "Towny-Database", null, new AppenderRef[0], null, config, null); +// townyDatabaseConfig.addAppender(townyDatabaseAppender, Level.ALL, null); + ctx.updateLoggers(); + refreshDebugLogger(); } - - public void refreshDebugLogger() { + + public static void refreshDebugLogger() { LoggerContext ctx = (LoggerContext) LogManager.getContext(false); - Configuration config = ctx.getConfiguration(); - LoggerConfig townyDebugConfig = config.getLoggerConfig("com.palmergames.bukkit.towny.debug"); - townyDebugConfig.setAdditive(TownySettings.getDebug()); + LoggerConfig loggerConfig = ctx.getConfiguration().getLoggerConfig("Towny"); + Appender console = ctx.getConfiguration().getAppender("TerminalConsole"); + + if (TownySettings.getDebug()) { + // Make sure we don't add more appenders than necessary. + loggerConfig.removeAppender("Towny-Debug"); + loggerConfig.removeAppender("TerminalConsole"); + loggerConfig.addAppender(townyDebugAppender, Level.DEBUG, null); + // only accept debug and trace messages for the debug console. + loggerConfig.addAppender(console, Level.DEBUG, CompositeFilter.createFilters( + new Filter[]{ + LevelMatchFilter.newBuilder().setLevel(Level.DEBUG).setOnMatch(Filter.Result.ACCEPT).setOnMismatch(Filter.Result.DENY).build(), + LevelMatchFilter.newBuilder().setLevel(Level.TRACE).setOnMatch(Filter.Result.ACCEPT).setOnMismatch(Filter.Result.DENY).build() + } + )); + } else { + loggerConfig.removeAppender("Towny-Debug"); + loggerConfig.removeAppender("TerminalConsole"); + } ctx.updateLoggers(); } - - public void logMoneyTransaction(Account a, double amount, Account b, String reason) { - + + public static void logMoneyTransaction(Account a, double amount, Account b, String reason) { + String sender; String receiver; - + if (a == null) { sender = "None"; } else { sender = a.getName(); } - + if (b == null) { receiver = "None"; } else { receiver = b.getName(); } - + if (reason == null) { LOGGER_MONEY.info(String.format("%s,%s,%s,%s", "Unknown Reason", sender, amount, receiver)); } else { LOGGER_MONEY.info(String.format("%s,%s,%s,%s", reason, sender, amount, receiver)); } } - - public void logMoneyTransaction(String a, double amount, String b, String reason) { + + public static void logMoneyTransaction(String a, double amount, String b, String reason) { if (reason == null) { LOGGER_MONEY.info(String.format("%s,%s,%s,%s", "Unknown Reason", a, amount, b)); } else { LOGGER_MONEY.info(String.format("%s,%s,%s,%s", reason, a, amount, b)); } } - - public static TownyLogger getInstance() { - return instance; - } } \ No newline at end of file diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/TownyMessaging.java b/Towny/src/main/java/com/palmergames/bukkit/towny/TownyMessaging.java index 7e6aa11183..bf1800e4cd 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/TownyMessaging.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/TownyMessaging.java @@ -55,7 +55,6 @@ public class TownyMessaging { private static final Logger LOGGER = LogManager.getLogger("Towny"); - private static final Logger LOGGER_DEBUG = LogManager.getLogger("com.palmergames.bukkit.towny.debug"); /* * NON-TRANSLATABLE MESSAGING METHODS @@ -173,14 +172,13 @@ public static void sendDevMsg(String[] msg) { } /** - * Sends a message to the log and console - * prefixed by [Towny] Debug: + * Sends a message to the debug logger (and hence the console and debug.log) * * @param msg the message to be sent */ public static void sendDebugMsg(String msg) { if (TownySettings.getDebug()) { - LOGGER_DEBUG.info(Colors.strip("[Towny] Debug: " + msg)); + LOGGER.debug(Colors.strip(msg)); } sendDevMsg(msg); } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java b/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java index 10a0508f23..6a2961d055 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java @@ -2390,7 +2390,7 @@ private void adminToggleDevMode(CommandSender sender, Optional choice) private void adminToggleDebug(CommandSender sender, Optional choice) throws NoPermissionException { checkPermOrThrow(sender, PermissionNodes.TOWNY_COMMAND_TOWNYADMIN_TOGGLE_DEBUG.getNode()); TownySettings.setDebug(choice.orElse(!TownySettings.getDebug())); - TownyLogger.getInstance().refreshDebugLogger(); + TownyLogger.refreshDebugLogger(); TownyMessaging.sendMsg(sender, Translatable.of("msg_admin_toggle_debugmode", (TownySettings.getDebug() ? Translatable.literal(Colors.Green).append(Translatable.of("enabled")) : Translatable.literal(Colors.Red).append(Translatable.of("disabled"))))); } private void adminToggleTownWithDraw(CommandSender sender, Optional choice) throws NoPermissionException { diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDatabaseHandler.java b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDatabaseHandler.java index 9198598a8e..7a5b693dd4 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDatabaseHandler.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDatabaseHandler.java @@ -93,8 +93,6 @@ public abstract class TownyDatabaseHandler extends TownyDataSource { final String settingsFolderPath; final String logFolderPath; final String backupFolderPath; - - Logger logger = LogManager.getLogger(TownyDatabaseHandler.class); protected final Queue queryQueue = new ConcurrentLinkedQueue<>(); private final ScheduledTask task; @@ -343,13 +341,13 @@ public void removeTownBlock(TownBlock townBlock) { Town town = townBlock.getTownOrNull(); if (town == null) // Log as error because TownBlocks *must* have a town. - logger.error(String.format("The TownBlock at (%s, %d, %d) is not registered to a town.", townBlock.getWorld().getName(), townBlock.getX(), townBlock.getZ())); + plugin.getLogger().severe(String.format("The TownBlock at (%s, %d, %d) is not registered to a town.", townBlock.getWorld().getName(), townBlock.getX(), townBlock.getZ())); TownPreUnclaimEvent event = new TownPreUnclaimEvent(town, townBlock); if (BukkitTools.isEventCancelled(event)) { // Log as Warn because the event has been processed if (!event.getCancelMessage().isEmpty()) - logger.warn(event.getCancelMessage()); + plugin.getLogger().warning(event.getCancelMessage()); return; } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java index 3282a19bc8..72af3e79b3 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java @@ -34,6 +34,8 @@ import com.palmergames.bukkit.util.BukkitTools; import com.palmergames.util.FileMgmt; import com.palmergames.util.StringMgmt; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.World; import java.io.BufferedReader; @@ -60,7 +62,6 @@ import java.util.stream.Collectors; public final class TownyFlatFileSource extends TownyDatabaseHandler { - private final String newLine = System.lineSeparator(); public TownyFlatFileSource(Towny plugin, TownyUniverse universe) { @@ -2109,7 +2110,7 @@ public boolean savePlotGroup(PlotGroup group) { list.add("town=" + group.getTown().getName()); list.add("metadata=" + serializeMetadata(group)); } catch (Exception e) { - logger.warn("An exception occurred while saving plot group " + Optional.ofNullable(group).map(g -> g.getUUID().toString()).orElse("null") + ": ", e); + plugin.getLogger().log(Level.WARNING, "An exception occurred while saving plot group " + Optional.ofNullable(group).map(g -> g.getUUID().toString()).orElse("null") + ": ", e); } // Save file @@ -2543,14 +2544,14 @@ public boolean loadCooldowns() { try { data = new String(Files.readAllBytes(cooldownsFile), StandardCharsets.UTF_8); } catch (IOException e) { - logger.warn("An exception occurred when reading cooldowns.json", e); + plugin.getLogger().log(Level.WARNING, "An exception occurred when reading cooldowns.json", e); return true; } try { CooldownTimerTask.getCooldowns().putAll(new Gson().fromJson(data, new TypeToken>(){}.getType())); } catch (JsonSyntaxException e) { - logger.warn("Could not load saved cooldowns due to a json syntax exception", e); + plugin.getLogger().log(Level.WARNING, "Could not load saved cooldowns due to a json syntax exception", e); } catch (NullPointerException ignored) {} return true; @@ -2568,7 +2569,7 @@ public boolean saveCooldowns() { try { Files.write(Paths.get(dataFolderPath).resolve("cooldowns.json"), new GsonBuilder().setPrettyPrinting().create().toJson(object).getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); } catch (IOException e) { - logger.warn("An exception occurred when writing cooldowns.json", e); + plugin.getLogger().log(Level.WARNING, "An exception occurred when writing cooldowns.json", e); } }); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownySQLSource.java b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownySQLSource.java index fcd7be2a01..f9a0340505 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownySQLSource.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownySQLSource.java @@ -35,6 +35,9 @@ import com.palmergames.util.StringMgmt; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.World; import org.jetbrains.annotations.ApiStatus; @@ -62,7 +65,6 @@ import java.util.stream.Collectors; public final class TownySQLSource extends TownyDatabaseHandler { - private final String tb_prefix; private final HikariDataSource hikariDataSource; @@ -131,7 +133,7 @@ public TownySQLSource(Towny plugin, TownyUniverse universe) { // Initialize database schema. SQLSchema.initTables(connection); } catch (SQLException e) { - logger.error("Failed to connect to the database", e); + plugin.getLogger().log(Level.SEVERE, "Failed to connect to the database", e); } } @@ -407,7 +409,7 @@ public boolean cleanup() { try (Connection connection = getConnection()) { SQLSchema.cleanup(connection); } catch (SQLException e) { - logger.warn("An exception occurred when cleaning up SQL schema.", e); + plugin.getLogger().log(Level.WARNING, "An exception occurred when cleaning up SQL schema.", e); } return true; @@ -609,14 +611,14 @@ public boolean loadPlotGroupList() { try { universe.newPlotGroupInternal(UUID.fromString(rs.getString("groupID"))); } catch (IllegalArgumentException e) { - logger.warn("ID for plot group is not a valid uuid, skipped loading plot group {}", rs.getString("groupID")); + plugin.getLogger().log(Level.WARNING, "ID for plot group is not a valid uuid, skipped loading plot group {}", rs.getString("groupID")); } } return true; } catch (SQLException e) { - logger.error("An exception occurred while loading plot group list", e); + plugin.getLogger().log(Level.SEVERE, "An exception occurred while loading plot group list", e); } return false; @@ -635,7 +637,7 @@ public boolean loadJailList() { return true; } catch (Exception e) { - logger.error("An exception occurred while loading jail list", e); + plugin.getLogger().log(Level.SEVERE, "An exception occurred while loading jail list", e); } return false; @@ -1962,7 +1964,7 @@ public boolean loadCooldowns() { while (resultSet.next()) CooldownTimerTask.getCooldowns().put(resultSet.getString("key"), resultSet.getLong("expiry")); } catch (SQLException e) { - logger.warn("An exception occurred when loading cooldowns", e); + plugin.getLogger().log(Level.WARNING, "An exception occurred when loading cooldowns", e); return false; } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/GlobalAccountObserver.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/GlobalAccountObserver.java index 45c08a840f..86aa0c8022 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/GlobalAccountObserver.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/GlobalAccountObserver.java @@ -11,12 +11,12 @@ public final class GlobalAccountObserver implements AccountObserver { @Override - public final void withdrew(Account account, double amount, String reason) { - TownyLogger.getInstance().logMoneyTransaction(account, amount, null, reason); + public void withdrew(Account account, double amount, String reason) { + TownyLogger.logMoneyTransaction(account, amount, null, reason); } @Override - public final void deposited(Account account, double amount, String reason) { - TownyLogger.getInstance().logMoneyTransaction(account, amount, null, reason); + public void deposited(Account account, double amount, String reason) { + TownyLogger.logMoneyTransaction(account, amount, null, reason); } }