From 91fa61542d5bb1be5f6484f07a978e5dd498100e Mon Sep 17 00:00:00 2001 From: Vankka Date: Thu, 9 Nov 2023 23:52:29 +0200 Subject: [PATCH] Add logging of group synchronization and executing console commands, improve how log writing is scheduled --- .../commands/subcommand/ExecuteCommand.java | 6 +-- .../game/executor/CommandExecutor.java | 10 ++++ .../common/console/SingleConsoleHandler.java | 2 +- .../common/groupsync/GroupSyncModule.java | 9 +++- .../groupsync/SynchronizationSummary.java | 9 ++++ .../groupsync/enums/GroupSyncResult.java | 18 +++++-- .../common/logging/impl/DiscordSRVLogger.java | 52 +++++++++++++++---- 7 files changed, 86 insertions(+), 20 deletions(-) diff --git a/common/src/main/java/com/discordsrv/common/command/discord/commands/subcommand/ExecuteCommand.java b/common/src/main/java/com/discordsrv/common/command/discord/commands/subcommand/ExecuteCommand.java index 567e7b71..13ac1d24 100644 --- a/common/src/main/java/com/discordsrv/common/command/discord/commands/subcommand/ExecuteCommand.java +++ b/common/src/main/java/com/discordsrv/common/command/discord/commands/subcommand/ExecuteCommand.java @@ -89,7 +89,7 @@ public class ExecuteCommand implements Consumer new ExecutionContext(discordSRV, ih, config.outputMode, ephemeral).run(command)); + .queue(ih -> new ExecutionContext(discordSRV, ih, config.outputMode, ephemeral).run(event.getUser(), command)); } @Override @@ -194,10 +194,10 @@ public class ExecuteCommand implements Consumer { for (Map.Entry> entry : pairs.entrySet()) { summary.add(entry.getKey(), entry.getValue().join()); } - logger().debug(summary.toString()); + + String finalSummary = summary.toString(); + logger().debug(finalSummary); + + if (summary.anySuccess()) { + // If anything was changed as a result of synchronization, log to file + discordSRV.logger().writeLogForCurrentDay("groupsync", finalSummary); + } }); } diff --git a/common/src/main/java/com/discordsrv/common/groupsync/SynchronizationSummary.java b/common/src/main/java/com/discordsrv/common/groupsync/SynchronizationSummary.java index 6076a1bc..23231591 100644 --- a/common/src/main/java/com/discordsrv/common/groupsync/SynchronizationSummary.java +++ b/common/src/main/java/com/discordsrv/common/groupsync/SynchronizationSummary.java @@ -44,6 +44,15 @@ public class SynchronizationSummary { pairs.computeIfAbsent(result, key -> new LinkedHashSet<>()).add(config); } + public boolean anySuccess() { + for (GroupSyncResult result : pairs.keySet()) { + if (result.isSuccess()) { + return true; + } + } + return false; + } + @Override public String toString() { int count = pairs.size(); diff --git a/common/src/main/java/com/discordsrv/common/groupsync/enums/GroupSyncResult.java b/common/src/main/java/com/discordsrv/common/groupsync/enums/GroupSyncResult.java index bdc96aa3..72aeeff4 100644 --- a/common/src/main/java/com/discordsrv/common/groupsync/enums/GroupSyncResult.java +++ b/common/src/main/java/com/discordsrv/common/groupsync/enums/GroupSyncResult.java @@ -21,10 +21,10 @@ package com.discordsrv.common.groupsync.enums; public enum GroupSyncResult { // Something happened - ADD_GROUP("Success (group add)"), - REMOVE_GROUP("Success (group remove)"), - ADD_ROLE("Success (role add)"), - REMOVE_ROLE("Success (role remove)"), + ADD_GROUP("Success (group add)", true), + REMOVE_GROUP("Success (group remove)", true), + ADD_ROLE("Success (role add)", true), + REMOVE_ROLE("Success (role remove)", true), // Nothing done ALREADY_IN_SYNC("Already in sync"), @@ -44,9 +44,19 @@ public enum GroupSyncResult { ; final String prettyResult; + final boolean success; GroupSyncResult(String prettyResult) { + this(prettyResult, false); + } + + GroupSyncResult(String prettyResult, boolean success) { this.prettyResult = prettyResult; + this.success = success; + } + + public boolean isSuccess() { + return success; } @Override diff --git a/common/src/main/java/com/discordsrv/common/logging/impl/DiscordSRVLogger.java b/common/src/main/java/com/discordsrv/common/logging/impl/DiscordSRVLogger.java index 48488d5f..644a0f11 100644 --- a/common/src/main/java/com/discordsrv/common/logging/impl/DiscordSRVLogger.java +++ b/common/src/main/java/com/discordsrv/common/logging/impl/DiscordSRVLogger.java @@ -42,22 +42,31 @@ import java.util.Collections; import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class DiscordSRVLogger implements Logger { - private static final DateFormat DATE_TIME_FORMATTER = new SimpleDateFormat("EEE HH:mm:ss z"); - private static final String LOG_LINE_FORMAT = "[%s] [%s] %s"; + private static final DateFormat ROTATED_DATE_TIME_FORMATTER = new SimpleDateFormat("EEE HH:mm:ss z"); + private static final DateFormat DAY_DATE_TIME_FORMATTER = new SimpleDateFormat("HH:mm:ss z"); + private static final DateFormat DAY = new SimpleDateFormat("yyyy-MM-dd"); + private static final String ROTATED_LOG_LINE_FORMAT = "[%s] [%s] %s"; + private static final String DAY_LOG_LINE_FORMAT = "[%s] %s"; private static final String LOG_FILE_NAME_FORMAT = "%s-%s.log"; private static final List DISABLE_DEBUG_BY_DEFAULT = Collections.singletonList("Hikari"); - private final Queue linesToAdd = new ConcurrentLinkedQueue<>(); - private final DiscordSRV discordSRV; + + // Files private final Path logsDirectory; private final List debugLogs; + // File writing + private final Queue linesToWrite = new ConcurrentLinkedQueue<>(); + private final Object lineProcessingLock = new Object(); + private Future lineProcessingFuture; + public DiscordSRVLogger(DiscordSRV discordSRV) { this.discordSRV = discordSRV; this.logsDirectory = discordSRV.dataDirectory().resolve("logs"); @@ -70,13 +79,17 @@ public class DiscordSRVLogger implements Logger { } this.debugLogs = rotateLog("debug", 3); - discordSRV.scheduler().runAtFixedRate(this::processLines, 0, 2, TimeUnit.SECONDS); } public List getDebugLogs() { return debugLogs; } + public void writeLogForCurrentDay(String label, String message) { + Path log = logsDirectory.resolve(label + "_" + DAY.format(System.currentTimeMillis()) + ".log"); + scheduleWrite(new LogEntry(log, null, System.currentTimeMillis(), null, message, null)); + } + @SuppressWarnings("SameParameterValue") private List rotateLog(String label, int amount) { try { @@ -128,6 +141,7 @@ public class DiscordSRVLogger implements Logger { } private void doLog(String loggerName, LogLevel logLevel, String message, Throwable throwable) { + long time = System.currentTimeMillis(); MainConfig config = discordSRV.config(); DebugConfig debugConfig = config != null ? config.debug : null; @@ -158,13 +172,22 @@ public class DiscordSRVLogger implements Logger { if (debugLog == null) { return; } - long time = System.currentTimeMillis(); - linesToAdd.add(new LogEntry(debugLog, loggerName, time, logLevel, message, throwable)); + + scheduleWrite(new LogEntry(debugLog, loggerName, time, logLevel, message, throwable)); + } + + private void scheduleWrite(LogEntry entry) { + linesToWrite.add(entry); + synchronized (lineProcessingLock) { + if (lineProcessingFuture == null || lineProcessingFuture.isDone()) { + lineProcessingFuture = discordSRV.scheduler().runLater(this::processLines, TimeUnit.SECONDS.toMillis(2)); + } + } } private void processLines() { LogEntry entry; - while ((entry = linesToAdd.poll()) != null) { + while ((entry = linesToWrite.poll()) != null) { writeToFile(entry.log(), entry.loggerName(), entry.time(), entry.logLevel(), entry.message(), entry.throwable()); } } @@ -178,8 +201,15 @@ public class DiscordSRVLogger implements Logger { message = "[" + loggerName + "] " + message; } - String timestamp = DATE_TIME_FORMATTER.format(time); - String line = String.format(LOG_LINE_FORMAT, timestamp, logLevel.name(), message) + "\n"; + String line; + if (logLevel == null) { + String timestamp = DAY_DATE_TIME_FORMATTER.format(time); + line = String.format(DAY_LOG_LINE_FORMAT, timestamp, message) + "\n"; + } else { + String timestamp = ROTATED_DATE_TIME_FORMATTER.format(time); + line = String.format(ROTATED_LOG_LINE_FORMAT, timestamp, logLevel.name(), message) + "\n"; + } + if (throwable != null) { line += ExceptionUtils.getStackTrace(throwable) + "\n"; } @@ -199,7 +229,7 @@ public class DiscordSRVLogger implements Logger { if (discordSRV.status() == DiscordSRV.Status.SHUTDOWN) { return; } - discordSRV.platformLogger().error("Failed to write to debug log", e); + discordSRV.platformLogger().error("Failed to write to log", e); } catch (Throwable ignored) {} } }