From ea7fea654cb09ee2ad6b29c2d597e7c51061bc6c Mon Sep 17 00:00:00 2001 From: Alyssa Date: Sun, 29 Sep 2024 18:47:39 +0100 Subject: [PATCH] plug logging console back in --- client/src/main/java/EntropyMain.java | 4 +- .../src/main/java/bean/AbstractDevScreen.java | 5 +-- client/src/main/java/bean/FileUploader.java | 3 +- client/src/main/java/object/ReplayTable.java | 6 +-- client/src/main/java/object/RoomTable.java | 2 +- .../src/main/java/online/screen/GameRoom.java | 2 +- .../online/util/DesktopEntropyClient.java | 2 +- .../java/online/util/HeartbeatRunnable.java | 2 +- .../java/online/util/ResponseHandler.java | 2 +- client/src/main/java/screen/GameScreen.java | 2 +- client/src/main/java/screen/MainScreen.java | 13 +++--- .../src/main/java/screen/ReplayInterface.java | 2 +- .../main/java/screen/SimulationDialog.java | 2 +- client/src/main/java/util/CpuStrategies.java | 2 +- client/src/main/java/util/DialogUtil.java | 2 +- .../src/main/java/util/ReplayConverter.java | 2 +- .../java/util/ReplayConverterVersion0.java | 2 +- client/src/main/kotlin/MainUtil.kt | 12 ++++-- client/src/main/kotlin/help/HelpPanel.kt | 2 +- client/src/main/kotlin/http/HttpClient.kt | 2 +- client/src/main/kotlin/http/SessionApi.kt | 4 +- client/src/main/kotlin/screen/HelpDialog.kt | 2 +- .../src/main/kotlin/screen}/LoggingConsole.kt | 42 +++++++++++++++---- client/src/main/kotlin/screen/SimpleDialog.kt | 2 +- .../kotlin/screen/online/PlayOnlineDialog.kt | 4 +- .../util/{Globals.kt => ClientGlobals.kt} | 6 ++- client/src/main/kotlin/util/DialogUtilNew.kt | 2 +- client/src/main/kotlin/util/UpdateManager.kt | 2 +- client/src/main/kotlin/util/UrlUtil.kt | 2 +- client/src/test/kotlin/http/SessionApiTest.kt | 20 +++++---- .../test/kotlin/screen}/LoggingConsoleTest.kt | 26 ++++++------ .../screen/online/PlayOnlineDialogTest.kt | 10 ++--- .../src/test/kotlin/util/DialogUtilNewTest.kt | 8 ++-- .../src/test/kotlin/util/UpdateManagerTest.kt | 10 ++--- core/src/main/java/util/AbstractClient.java | 2 +- core/src/main/java/util/FileUtil.java | 17 +------- core/src/main/java/util/KeyGeneratorUtil.java | 2 +- core/src/main/java/util/MessageSender.java | 2 +- core/src/main/java/util/MessageUtil.java | 2 +- core/src/main/kotlin/bean/FocusableWindow.kt | 4 +- ...gDestination.kt => ILogContextListener.kt} | 4 +- .../kotlin/logging/LogDestinationSystemOut.kt | 11 ----- core/src/main/kotlin/logging/LogRecord.kt | 30 ------------- core/src/main/kotlin/logging/Logger.kt | 17 +++++--- .../logging/LoggerUncaughtExceptionHandler.kt | 2 +- core/src/main/kotlin/logging/LoggingKeys.kt | 3 +- .../{InjectedThings.kt => CoreGlobals.kt} | 5 +-- core/src/main/kotlin/utils/ThreadUtil.kt | 2 +- .../test/kotlin/bean/FocusableWindowTest.kt | 10 +++-- core/src/test/kotlin/logging/LoggerTest.kt | 27 ++++++++++-- .../LoggerUncaughtExceptionHandlerTest.kt | 2 +- server/src/main/java/object/BidHistory.java | 4 +- server/src/main/java/object/GameWrapper.java | 4 +- server/src/main/java/object/Room.java | 6 +-- .../src/main/java/server/EntropyServer.java | 14 +++---- .../java/server/InactiveCheckRunnable.java | 6 +-- .../java/server/MessageHandlerRunnable.java | 6 +-- .../java/server/NotificationRunnable.java | 2 +- .../java/util/EntropyThreadPoolExecutor.java | 4 +- server/src/main/java/util/LoggingUtil.kt | 2 +- .../src/main/java/util/XmlBuilderServer.java | 2 +- server/src/main/kotlin/plugins/Monitoring.kt | 4 +- server/src/main/kotlin/plugins/Routing.kt | 2 +- .../src/main/kotlin/routes/dev/DevService.kt | 8 ++-- .../routes/session/SessionController.kt | 4 +- .../kotlin/routes/session/SessionService.kt | 4 +- .../util/{Globals.kt => ServerGlobals.kt} | 2 +- .../routes/session/SessionControllerTest.kt | 2 +- .../routes/session/SessionServiceTest.kt | 2 +- .../src/main/kotlin/testCore/AbstractTest.kt | 5 ++- .../testCore/BeforeAllTestsExtension.kt | 8 ++-- .../src/main/kotlin/testCore/TestUtils.kt | 26 +++++++++--- 72 files changed, 240 insertions(+), 230 deletions(-) rename {core/src/main/kotlin/logging => client/src/main/kotlin/screen}/LoggingConsole.kt (69%) rename client/src/main/kotlin/util/{Globals.kt => ClientGlobals.kt} (64%) rename {core/src/test/kotlin/logging => client/src/test/kotlin/screen}/LoggingConsoleTest.kt (84%) rename core/src/main/kotlin/logging/{ILogDestination.kt => ILogContextListener.kt} (53%) delete mode 100644 core/src/main/kotlin/logging/LogDestinationSystemOut.kt delete mode 100644 core/src/main/kotlin/logging/LogRecord.kt rename core/src/main/kotlin/utils/{InjectedThings.kt => CoreGlobals.kt} (75%) rename server/src/main/kotlin/util/{Globals.kt => ServerGlobals.kt} (97%) diff --git a/client/src/main/java/EntropyMain.java b/client/src/main/java/EntropyMain.java index 5c6f0cc..c30db2e 100644 --- a/client/src/main/java/EntropyMain.java +++ b/client/src/main/java/EntropyMain.java @@ -10,7 +10,7 @@ import screen.ScreenCache; import util.*; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class EntropyMain implements Registry { @@ -23,7 +23,7 @@ public static void main(String[] args) //Initialise interfaces etc Debug.initialise(new DebugOutputSystemOut()); Thread.setDefaultUncaughtExceptionHandler(new LoggerUncaughtExceptionHandler()); - MainUtilKt.setLoggingContextFields(); + MainUtilKt.configureLogging(); AbstractClient.setInstance(new DesktopEntropyClient()); //Dev mode diff --git a/client/src/main/java/bean/AbstractDevScreen.java b/client/src/main/java/bean/AbstractDevScreen.java index a948cf0..f42b108 100644 --- a/client/src/main/java/bean/AbstractDevScreen.java +++ b/client/src/main/java/bean/AbstractDevScreen.java @@ -3,12 +3,9 @@ import java.awt.event.InputEvent; import java.awt.event.KeyEvent; -import javax.swing.JFrame; import javax.swing.KeyStroke; -import util.Debug; - -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public abstract class AbstractDevScreen extends FocusableWindow { diff --git a/client/src/main/java/bean/FileUploader.java b/client/src/main/java/bean/FileUploader.java index 4e1caba..8653b47 100644 --- a/client/src/main/java/bean/FileUploader.java +++ b/client/src/main/java/bean/FileUploader.java @@ -14,10 +14,9 @@ import javax.swing.border.EmptyBorder; import javax.swing.filechooser.FileFilter; -import util.Debug; import util.DialogUtil; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class FileUploader extends JPanel implements ActionListener diff --git a/client/src/main/java/object/ReplayTable.java b/client/src/main/java/object/ReplayTable.java index fc284c9..7cdc8ad 100644 --- a/client/src/main/java/object/ReplayTable.java +++ b/client/src/main/java/object/ReplayTable.java @@ -10,10 +10,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -31,7 +28,6 @@ import screen.ReplayDialog; import screen.ReplayFilterPanel; import screen.ScreenCache; -import util.Debug; import util.DialogUtil; import util.EntropyColour; import util.FileUtil; @@ -41,7 +37,7 @@ import util.ReplayRowWrapper; import util.TableUtil; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class ReplayTable extends JTable implements MouseListener, diff --git a/client/src/main/java/object/RoomTable.java b/client/src/main/java/object/RoomTable.java index 09f121a..2e4cadc 100644 --- a/client/src/main/java/object/RoomTable.java +++ b/client/src/main/java/object/RoomTable.java @@ -27,7 +27,7 @@ import util.MessageUtil; import util.TableUtil; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public final class RoomTable extends JTable implements MouseListener diff --git a/client/src/main/java/online/screen/GameRoom.java b/client/src/main/java/online/screen/GameRoom.java index baf68a6..dc3f687 100644 --- a/client/src/main/java/online/screen/GameRoom.java +++ b/client/src/main/java/online/screen/GameRoom.java @@ -20,7 +20,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.prefs.Preferences; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; /** * This is an actual room as seen by the player diff --git a/client/src/main/java/online/util/DesktopEntropyClient.java b/client/src/main/java/online/util/DesktopEntropyClient.java index c85ce93..0ae487a 100644 --- a/client/src/main/java/online/util/DesktopEntropyClient.java +++ b/client/src/main/java/online/util/DesktopEntropyClient.java @@ -83,6 +83,6 @@ public String sendSyncOnDevice(MessageSender runnable) @Override public void checkForUpdates() { - Globals.INSTANCE.getUpdateManager().checkForUpdates(OnlineConstants.ENTROPY_VERSION_NUMBER); + ClientGlobals.INSTANCE.getUpdateManager().checkForUpdates(OnlineConstants.ENTROPY_VERSION_NUMBER); } } diff --git a/client/src/main/java/online/util/HeartbeatRunnable.java b/client/src/main/java/online/util/HeartbeatRunnable.java index c511074..7841afb 100644 --- a/client/src/main/java/online/util/HeartbeatRunnable.java +++ b/client/src/main/java/online/util/HeartbeatRunnable.java @@ -7,7 +7,7 @@ import util.AbstractClient; import util.MessageUtil; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class HeartbeatRunnable implements Runnable { diff --git a/client/src/main/java/online/util/ResponseHandler.java b/client/src/main/java/online/util/ResponseHandler.java index 0efe2ed..76abac1 100644 --- a/client/src/main/java/online/util/ResponseHandler.java +++ b/client/src/main/java/online/util/ResponseHandler.java @@ -18,7 +18,7 @@ import java.util.HashMap; import java.util.List; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class ResponseHandler implements XmlConstants { diff --git a/client/src/main/java/screen/GameScreen.java b/client/src/main/java/screen/GameScreen.java index 429272c..aed29d6 100644 --- a/client/src/main/java/screen/GameScreen.java +++ b/client/src/main/java/screen/GameScreen.java @@ -10,7 +10,7 @@ import java.util.Timer; import java.util.*; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public abstract class GameScreen extends TransparentPanel implements BidListener, diff --git a/client/src/main/java/screen/MainScreen.java b/client/src/main/java/screen/MainScreen.java index b0041b2..6207990 100644 --- a/client/src/main/java/screen/MainScreen.java +++ b/client/src/main/java/screen/MainScreen.java @@ -8,9 +8,8 @@ import online.screen.TestHarness; import online.util.XmlBuilderDesktop; import org.w3c.dom.Document; -import screen.online.PlayOnlineDialog; import util.*; -import utils.InjectedThings; +import utils.CoreGlobals; import javax.swing.*; import javax.swing.border.BevelBorder; @@ -28,7 +27,7 @@ import java.util.prefs.Preferences; import static screen.online.PlayOnlineDialogKt.showPlayOnlineDialog; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; import static utils.ThreadUtilKt.dumpThreadStacks; public final class MainScreen extends AbstractDevScreen @@ -678,10 +677,10 @@ public String processCommand(String command) } if (command.equals("health")) { - Globals.INSTANCE.getHealthCheckApi().doHealthCheck(); + ClientGlobals.INSTANCE.getHealthCheckApi().doHealthCheck(); } else if (command.startsWith("server ")) { var serverCommand = command.replace("server ", ""); - Globals.INSTANCE.getDevApi().doServerCommand(serverCommand); + ClientGlobals.INSTANCE.getDevApi().doServerCommand(serverCommand); } else if (command.equals("keygen")) { var key = KeyGeneratorUtil.generateSymmetricKey(); textToShow = EncryptionUtil.convertSecretKeyToString(key); @@ -922,8 +921,8 @@ else if (source == mntmReportBug) } else if (source == mntmViewLogs) { - InjectedThings.loggingConsole.setVisible(true); - InjectedThings.loggingConsole.toFront(); + ClientGlobals.loggingConsole.setVisible(true); + ClientGlobals.loggingConsole.toFront(); } else if (source == mntmPreferences) { diff --git a/client/src/main/java/screen/ReplayInterface.java b/client/src/main/java/screen/ReplayInterface.java index 4ed4479..84c5d06 100644 --- a/client/src/main/java/screen/ReplayInterface.java +++ b/client/src/main/java/screen/ReplayInterface.java @@ -19,7 +19,7 @@ import java.awt.event.WindowListener; import java.io.File; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class ReplayInterface extends JFrame implements ListSelectionListener, diff --git a/client/src/main/java/screen/SimulationDialog.java b/client/src/main/java/screen/SimulationDialog.java index 6fac756..444c9ab 100644 --- a/client/src/main/java/screen/SimulationDialog.java +++ b/client/src/main/java/screen/SimulationDialog.java @@ -10,7 +10,7 @@ import java.util.HashMap; import java.util.Vector; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class SimulationDialog extends JDialog { diff --git a/client/src/main/java/util/CpuStrategies.java b/client/src/main/java/util/CpuStrategies.java index 4cd74dd..5102dac 100644 --- a/client/src/main/java/util/CpuStrategies.java +++ b/client/src/main/java/util/CpuStrategies.java @@ -6,7 +6,7 @@ import java.util.Random; import java.util.Vector; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class CpuStrategies { diff --git a/client/src/main/java/util/DialogUtil.java b/client/src/main/java/util/DialogUtil.java index f00f3f6..b7f3c9c 100644 --- a/client/src/main/java/util/DialogUtil.java +++ b/client/src/main/java/util/DialogUtil.java @@ -3,7 +3,7 @@ import javax.swing.JOptionPane; import javax.swing.SwingUtilities; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; @Deprecated() public class DialogUtil diff --git a/client/src/main/java/util/ReplayConverter.java b/client/src/main/java/util/ReplayConverter.java index 4b33edf..45e0e6d 100644 --- a/client/src/main/java/util/ReplayConverter.java +++ b/client/src/main/java/util/ReplayConverter.java @@ -11,7 +11,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class ReplayConverter implements Registry { diff --git a/client/src/main/java/util/ReplayConverterVersion0.java b/client/src/main/java/util/ReplayConverterVersion0.java index 32b63e4..9ac186e 100644 --- a/client/src/main/java/util/ReplayConverterVersion0.java +++ b/client/src/main/java/util/ReplayConverterVersion0.java @@ -11,7 +11,7 @@ import org.w3c.dom.Element; import org.w3c.dom.NodeList; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class ReplayConverterVersion0 { diff --git a/client/src/main/kotlin/MainUtil.kt b/client/src/main/kotlin/MainUtil.kt index 6979c3a..e0cbf1b 100644 --- a/client/src/main/kotlin/MainUtil.kt +++ b/client/src/main/kotlin/MainUtil.kt @@ -5,18 +5,24 @@ import logging.KEY_DEV_MODE import logging.KEY_OPERATING_SYSTEM import logging.KEY_USERNAME import util.AbstractClient +import util.ClientGlobals import util.CoreRegistry.INSTANCE_STRING_DEVICE_ID import util.CoreRegistry.instance import util.OnlineConstants -import utils.InjectedThings.logger +import utils.CoreGlobals +import utils.CoreGlobals.logger import utils.getUsername -fun setLoggingContextFields() { +fun configureLogging() { + CoreGlobals.slf4jLogger.addAppender(ClientGlobals.consoleAppender) + ClientGlobals.consoleAppender.start() + logger.addContextListener(ClientGlobals.loggingConsole) + logger.addToContext(KEY_USERNAME, getUsername()) logger.addToContext(KEY_APP_VERSION, OnlineConstants.ENTROPY_VERSION_NUMBER) logger.addToContext(KEY_OPERATING_SYSTEM, AbstractClient.operatingSystem) logger.addToContext(KEY_DEVICE_ID, getDeviceId()) - logger.addToContext(KEY_DEV_MODE, AbstractClient.devMode) + logger.addToContext(KEY_DEV_MODE, AbstractClient.devMode.toString()) } fun getDeviceId() = instance.get(INSTANCE_STRING_DEVICE_ID, null) ?: setDeviceId() diff --git a/client/src/main/kotlin/help/HelpPanel.kt b/client/src/main/kotlin/help/HelpPanel.kt index 19ab4ab..1ff56d4 100644 --- a/client/src/main/kotlin/help/HelpPanel.kt +++ b/client/src/main/kotlin/help/HelpPanel.kt @@ -12,7 +12,7 @@ import javax.swing.text.DefaultHighlighter.DefaultHighlightPainter import javax.swing.text.Highlighter import screen.ScreenCache import util.Registry -import utils.InjectedThings.logger +import utils.CoreGlobals.logger import utils.getAllChildComponentsForType /** Object representing a 'page' of the help dialog. */ diff --git a/client/src/main/kotlin/http/HttpClient.kt b/client/src/main/kotlin/http/HttpClient.kt index 04cfc39..f9369ba 100644 --- a/client/src/main/kotlin/http/HttpClient.kt +++ b/client/src/main/kotlin/http/HttpClient.kt @@ -9,7 +9,7 @@ import kong.unirest.JsonObjectMapper import kong.unirest.Unirest import kong.unirest.UnirestException import org.apache.http.HttpHeaders -import utils.InjectedThings.logger +import utils.CoreGlobals.logger class HttpClient(private val baseUrl: String) { private val jsonObjectMapper = JsonObjectMapper() diff --git a/client/src/main/kotlin/http/SessionApi.kt b/client/src/main/kotlin/http/SessionApi.kt index c84bd5c..b70ddb7 100644 --- a/client/src/main/kotlin/http/SessionApi.kt +++ b/client/src/main/kotlin/http/SessionApi.kt @@ -6,8 +6,8 @@ import javax.swing.JOptionPane import javax.swing.SwingUtilities import kong.unirest.HttpMethod import screen.ScreenCache +import util.ClientGlobals import util.DialogUtilNew -import util.Globals import util.OnlineConstants class SessionApi(private val httpClient: HttpClient) { @@ -47,7 +47,7 @@ class SessionApi(private val httpClient: HttpClient) { ) if (ans == JOptionPane.YES_OPTION) { - Globals.updateManager.checkForUpdates( + ClientGlobals.updateManager.checkForUpdates( OnlineConstants.ENTROPY_VERSION_NUMBER ) } diff --git a/client/src/main/kotlin/screen/HelpDialog.kt b/client/src/main/kotlin/screen/HelpDialog.kt index ca9811e..5d9a124 100644 --- a/client/src/main/kotlin/screen/HelpDialog.kt +++ b/client/src/main/kotlin/screen/HelpDialog.kt @@ -42,7 +42,7 @@ import javax.swing.tree.TreeSelectionModel import kotlin.math.max import util.AchievementsUtil.UnlockAchievementTask import util.Registry -import utils.InjectedThings.logger +import utils.CoreGlobals.logger class HelpDialog : JFrame(), TreeSelectionListener, WindowListener, Registry { private val fundamentalsTheDeck = FundamentalsTheDeck() diff --git a/core/src/main/kotlin/logging/LoggingConsole.kt b/client/src/main/kotlin/screen/LoggingConsole.kt similarity index 69% rename from core/src/main/kotlin/logging/LoggingConsole.kt rename to client/src/main/kotlin/screen/LoggingConsole.kt index 21a6008..c9f902a 100644 --- a/core/src/main/kotlin/logging/LoggingConsole.kt +++ b/client/src/main/kotlin/screen/LoggingConsole.kt @@ -1,11 +1,16 @@ -package logging +package screen import bean.FocusableWindow import bean.WrapLayout import ch.qos.logback.classic.Level +import ch.qos.logback.classic.spi.ILoggingEvent +import ch.qos.logback.core.AppenderBase import java.awt.BorderLayout import java.awt.Color import java.awt.Component +import java.time.ZoneId +import java.time.format.DateTimeFormatter +import java.util.* import javax.swing.JComponent import javax.swing.JLabel import javax.swing.JPanel @@ -18,9 +23,22 @@ import javax.swing.text.BadLocationException import javax.swing.text.DefaultStyledDocument import javax.swing.text.StyleConstants import javax.swing.text.StyleContext +import logging.ILogContextListener +import logging.KEY_STACK +import logging.errorObject +import logging.extractStackTrace +import logging.findLogField +import logging.loggingCode +import utils.CoreGlobals import utils.runOnEventThread -class LoggingConsole : FocusableWindow(), ILogDestination { +class LoggingConsoleAppender(private val console: LoggingConsole) : AppenderBase() { + override fun append(p0: ILoggingEvent) { + console.log(p0) + } +} + +class LoggingConsole : FocusableWindow(), ILogContextListener { override val windowName = "Console" val doc = DefaultStyledDocument() @@ -45,20 +63,20 @@ class LoggingConsole : FocusableWindow(), ILogDestination { contextPanel.layout = WrapLayout() } - override fun log(record: LogRecord) { + fun log(record: ILoggingEvent) { val cx = StyleContext() - val text = record.toString() + val text = record.toConsoleString() val style = cx.addStyle(text, null) - if (record.severity == Level.ERROR) { + if (record.level == Level.ERROR) { StyleConstants.setForeground(style, Color.RED) } try { doc.insertString(doc.length, "\n$text", style) - record.getThrowableStr()?.let { doc.insertString(doc.length, "\n$it", style) } + record.errorObject()?.let { doc.insertString(doc.length, "\n$it", style) } - val threadStack = record.keyValuePairs[KEY_STACK] + val threadStack = record.findLogField(KEY_STACK) threadStack?.let { doc.insertString(doc.length, "\n$it", style) } textArea.select(doc.length, doc.length) @@ -80,6 +98,16 @@ class LoggingConsole : FocusableWindow(), ILogDestination { } } + private fun ILoggingEvent.toConsoleString(): String { + val dateStr = + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + .withLocale(Locale.UK) + .withZone(ZoneId.systemDefault()) + .format(CoreGlobals.clock.instant()) + + return "$dateStr [$loggingCode] $message" + } + private fun factoryLabelForContext(field: Map.Entry): Component { val label = JLabel("${field.key}: ${field.value}") label.foreground = Color.GREEN diff --git a/client/src/main/kotlin/screen/SimpleDialog.kt b/client/src/main/kotlin/screen/SimpleDialog.kt index 7bb1321..9d2c79f 100644 --- a/client/src/main/kotlin/screen/SimpleDialog.kt +++ b/client/src/main/kotlin/screen/SimpleDialog.kt @@ -6,7 +6,7 @@ import java.awt.event.ActionListener import javax.swing.JButton import javax.swing.JDialog import javax.swing.JPanel -import utils.InjectedThings.logger +import utils.CoreGlobals.logger abstract class SimpleDialog : JDialog(), ActionListener { protected val panelOkCancel = JPanel() diff --git a/client/src/main/kotlin/screen/online/PlayOnlineDialog.kt b/client/src/main/kotlin/screen/online/PlayOnlineDialog.kt index d3da9b2..cdf6231 100644 --- a/client/src/main/kotlin/screen/online/PlayOnlineDialog.kt +++ b/client/src/main/kotlin/screen/online/PlayOnlineDialog.kt @@ -8,8 +8,8 @@ import javax.swing.JTextField import javax.swing.border.EmptyBorder import screen.ScreenCache import screen.SimpleDialog +import util.ClientGlobals import util.DialogUtilNew -import util.Globals class PlayOnlineDialog : SimpleDialog() { private val lblName = JLabel("Name") @@ -45,7 +45,7 @@ class PlayOnlineDialog : SimpleDialog() { ScreenCache.showConnectingDialog() try { - Globals.sessionApi.beginSession(textFieldUsername.text) + ClientGlobals.sessionApi.beginSession(textFieldUsername.text) } finally { ScreenCache.dismissConnectingDialog() } diff --git a/client/src/main/kotlin/util/Globals.kt b/client/src/main/kotlin/util/ClientGlobals.kt similarity index 64% rename from client/src/main/kotlin/util/Globals.kt rename to client/src/main/kotlin/util/ClientGlobals.kt index 27a99df..c4d517c 100644 --- a/client/src/main/kotlin/util/Globals.kt +++ b/client/src/main/kotlin/util/ClientGlobals.kt @@ -4,10 +4,14 @@ import http.DevApi import http.HealthCheckApi import http.HttpClient import http.SessionApi +import screen.LoggingConsole +import screen.LoggingConsoleAppender -object Globals { +object ClientGlobals { private val baseUrl = "http://localhost:8080" private val httpClient = HttpClient(baseUrl) + @JvmField val loggingConsole = LoggingConsole() + val consoleAppender = LoggingConsoleAppender(loggingConsole) val healthCheckApi = HealthCheckApi(httpClient) val devApi = DevApi(httpClient) var sessionApi = SessionApi(httpClient) diff --git a/client/src/main/kotlin/util/DialogUtilNew.kt b/client/src/main/kotlin/util/DialogUtilNew.kt index 929e30f..7200f43 100644 --- a/client/src/main/kotlin/util/DialogUtilNew.kt +++ b/client/src/main/kotlin/util/DialogUtilNew.kt @@ -7,7 +7,7 @@ import javax.swing.JOptionPane import javax.swing.SwingUtilities import screen.LoadingDialog import screen.ScreenCache -import utils.InjectedThings.logger +import utils.CoreGlobals.logger object DialogUtilNew { private var loadingDialog: LoadingDialog? = null diff --git a/client/src/main/kotlin/util/UpdateManager.kt b/client/src/main/kotlin/util/UpdateManager.kt index 77886e8..65d2f20 100644 --- a/client/src/main/kotlin/util/UpdateManager.kt +++ b/client/src/main/kotlin/util/UpdateManager.kt @@ -9,7 +9,7 @@ import javax.swing.JPanel import kong.unirest.Unirest import kong.unirest.json.JSONObject import kotlin.system.exitProcess -import utils.InjectedThings.logger +import utils.CoreGlobals.logger /** * Automatically check for and download updates using the Github API diff --git a/client/src/main/kotlin/util/UrlUtil.kt b/client/src/main/kotlin/util/UrlUtil.kt index e8c0a2f..b6396e1 100644 --- a/client/src/main/kotlin/util/UrlUtil.kt +++ b/client/src/main/kotlin/util/UrlUtil.kt @@ -1,6 +1,6 @@ package util -import utils.InjectedThings.logger +import utils.CoreGlobals.logger /** N.B. will likely only work on linux */ fun launchUrl(url: String, runtime: Runtime = Runtime.getRuntime()) { diff --git a/client/src/test/kotlin/http/SessionApiTest.kt b/client/src/test/kotlin/http/SessionApiTest.kt index 85d501a..f13da50 100644 --- a/client/src/test/kotlin/http/SessionApiTest.kt +++ b/client/src/test/kotlin/http/SessionApiTest.kt @@ -13,15 +13,15 @@ import io.mockk.verify import java.util.UUID import kong.unirest.HttpMethod import kong.unirest.UnirestException -import main.kotlin.testCore.getDialogMessage -import main.kotlin.testCore.getErrorDialog -import main.kotlin.testCore.getQuestionDialog -import main.kotlin.testCore.verifyNotCalled import online.screen.EntropyLobby import org.junit.jupiter.api.Test import screen.ScreenCache import testCore.AbstractTest -import util.Globals +import testCore.getDialogMessage +import testCore.getErrorDialog +import testCore.getQuestionDialog +import testCore.verifyNotCalled +import util.ClientGlobals import util.OnlineConstants class SessionApiTest : AbstractTest() { @@ -43,7 +43,7 @@ class SessionApiTest : AbstractTest() { @Test fun `should handle a response indicating an update is required and check for updates`() { - Globals.updateManager = mockk(relaxed = true) + ClientGlobals.updateManager = mockk(relaxed = true) val httpClient = mockHttpClient(FailureResponse(422, UPDATE_REQUIRED, "oh no")) SessionApi(httpClient).beginSession("alyssa") @@ -54,12 +54,14 @@ class SessionApiTest : AbstractTest() { "Your client must be updated to connect. Check for updates now?" questionDialog.clickYes() - verify { Globals.updateManager.checkForUpdates(OnlineConstants.ENTROPY_VERSION_NUMBER) } + verify { + ClientGlobals.updateManager.checkForUpdates(OnlineConstants.ENTROPY_VERSION_NUMBER) + } } @Test fun `should not check for updates if 'No' is answered`() { - Globals.updateManager = mockk(relaxed = true) + ClientGlobals.updateManager = mockk(relaxed = true) val httpClient = mockHttpClient(FailureResponse(422, UPDATE_REQUIRED, "oh no")) SessionApi(httpClient).beginSession("alyssa") @@ -70,7 +72,7 @@ class SessionApiTest : AbstractTest() { "Your client must be updated to connect. Check for updates now?" questionDialog.clickNo() - verifyNotCalled { Globals.updateManager.checkForUpdates(any()) } + verifyNotCalled { ClientGlobals.updateManager.checkForUpdates(any()) } } @Test diff --git a/core/src/test/kotlin/logging/LoggingConsoleTest.kt b/client/src/test/kotlin/screen/LoggingConsoleTest.kt similarity index 84% rename from core/src/test/kotlin/logging/LoggingConsoleTest.kt rename to client/src/test/kotlin/screen/LoggingConsoleTest.kt index 39b0257..e9c41e0 100644 --- a/core/src/test/kotlin/logging/LoggingConsoleTest.kt +++ b/client/src/test/kotlin/screen/LoggingConsoleTest.kt @@ -1,4 +1,4 @@ -package logging +package screen import ch.qos.logback.classic.Level import com.github.alyssaburlton.swingtest.flushEdt @@ -10,29 +10,31 @@ import io.kotest.matchers.string.shouldContain import java.awt.Color import javax.swing.JLabel import javax.swing.text.StyleConstants -import main.kotlin.testCore.makeLogRecord +import logging.KEY_STACK import org.junit.jupiter.api.Test import testCore.AbstractTest +import testCore.makeLoggingEvent import utils.getAllChildComponentsForType class LoggingConsoleTest : AbstractTest() { @Test fun `Should separate log records with a new line`() { - val recordOne = makeLogRecord(loggingCode = "foo", message = "log one") - val recordTwo = makeLogRecord(loggingCode = "bar", message = "log two") + val recordOne = makeLoggingEvent(loggingCode = "foo", message = "log one") + val recordTwo = makeLoggingEvent(loggingCode = "bar", message = "log two") val console = LoggingConsole() console.log(recordOne) console.log(recordTwo) - val text = console.getText() - text shouldBe "\n$recordOne\n$recordTwo" + val text = console.getText().split("\n") + text[1] shouldBe "2020-04-13 12:04:00 [foo] log one" + text[2] shouldBe "2020-04-13 12:04:00 [bar] log two" } @Test fun `Should log a regular INFO log in green`() { val console = LoggingConsole() - val infoLog = makeLogRecord(severity = Level.INFO) + val infoLog = makeLoggingEvent(severity = Level.INFO) console.log(infoLog) console.getTextColour() shouldBe Color.GREEN @@ -41,7 +43,7 @@ class LoggingConsoleTest : AbstractTest() { @Test fun `Should log an ERROR log in red`() { val console = LoggingConsole() - val errorLog = makeLogRecord(severity = Level.ERROR) + val errorLog = makeLoggingEvent(severity = Level.ERROR) console.log(errorLog) console.getTextColour() shouldBe Color.RED @@ -53,7 +55,7 @@ class LoggingConsoleTest : AbstractTest() { val t = Throwable("Boom") val errorLog = - makeLogRecord( + makeLoggingEvent( severity = Level.ERROR, message = "Failed to load screen", errorObject = t @@ -72,7 +74,7 @@ class LoggingConsoleTest : AbstractTest() { val console = LoggingConsole() val threadStackLock = - makeLogRecord( + makeLoggingEvent( severity = Level.INFO, message = "AWT Thread", keyValuePairs = mapOf(KEY_STACK to "at Foo.bar(58)") @@ -89,7 +91,7 @@ class LoggingConsoleTest : AbstractTest() { console.pack() console.scrollPane.verticalScrollBar.value shouldBe 0 - repeat(50) { console.log(makeLogRecord()) } + repeat(50) { console.log(makeLoggingEvent()) } flushEdt() console.scrollPane.verticalScrollBar.value shouldBeGreaterThan 0 @@ -98,7 +100,7 @@ class LoggingConsoleTest : AbstractTest() { @Test fun `Should support clearing the logs`() { val console = LoggingConsole() - console.log(makeLogRecord()) + console.log(makeLoggingEvent()) console.clear() diff --git a/client/src/test/kotlin/screen/online/PlayOnlineDialogTest.kt b/client/src/test/kotlin/screen/online/PlayOnlineDialogTest.kt index 70b08f3..35b0a5c 100644 --- a/client/src/test/kotlin/screen/online/PlayOnlineDialogTest.kt +++ b/client/src/test/kotlin/screen/online/PlayOnlineDialogTest.kt @@ -8,12 +8,12 @@ import io.kotest.matchers.shouldBe import io.mockk.mockk import io.mockk.verify import javax.swing.JTextField -import main.kotlin.testCore.getDialogMessage -import main.kotlin.testCore.getErrorDialog import org.junit.jupiter.api.Test import screen.ScreenCache import testCore.AbstractTest -import util.Globals +import testCore.getDialogMessage +import testCore.getErrorDialog +import util.ClientGlobals class PlayOnlineDialogTest : AbstractTest() { @Test @@ -29,7 +29,7 @@ class PlayOnlineDialogTest : AbstractTest() { @Test fun `Should invoke the session API`() { - Globals.sessionApi = mockk(relaxed = true) + ClientGlobals.sessionApi = mockk(relaxed = true) val dlg = PlayOnlineDialog() dlg.isVisible = true @@ -37,7 +37,7 @@ class PlayOnlineDialogTest : AbstractTest() { dlg.clickOk() dlg.shouldNotBeVisible() - verify { Globals.sessionApi.beginSession("Alyssa") } + verify { ClientGlobals.sessionApi.beginSession("Alyssa") } ScreenCache.getConnectingDialog().shouldNotBeVisible() } } diff --git a/client/src/test/kotlin/util/DialogUtilNewTest.kt b/client/src/test/kotlin/util/DialogUtilNewTest.kt index 69283fd..b75f938 100644 --- a/client/src/test/kotlin/util/DialogUtilNewTest.kt +++ b/client/src/test/kotlin/util/DialogUtilNewTest.kt @@ -11,12 +11,12 @@ import com.github.alyssaburlton.swingtest.purgeWindows import io.kotest.matchers.shouldBe import javax.swing.JDialog import javax.swing.SwingUtilities -import main.kotlin.testCore.getErrorDialog -import main.kotlin.testCore.getInfoDialog -import main.kotlin.testCore.getQuestionDialog -import main.kotlin.testCore.runAsync import org.junit.jupiter.api.Test import testCore.AbstractTest +import testCore.getErrorDialog +import testCore.getInfoDialog +import testCore.getQuestionDialog +import testCore.runAsync class DialogUtilNewTest : AbstractTest() { @Test diff --git a/client/src/test/kotlin/util/UpdateManagerTest.kt b/client/src/test/kotlin/util/UpdateManagerTest.kt index 1e35131..4faf3ab 100644 --- a/client/src/test/kotlin/util/UpdateManagerTest.kt +++ b/client/src/test/kotlin/util/UpdateManagerTest.kt @@ -26,11 +26,6 @@ import kong.unirest.json.JSONException import kong.unirest.json.JSONObject import logging.errorObject import logging.findLogField -import main.kotlin.testCore.getDialogMessage -import main.kotlin.testCore.getErrorDialog -import main.kotlin.testCore.getInfoDialog -import main.kotlin.testCore.getQuestionDialog -import main.kotlin.testCore.runAsync import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test @@ -38,6 +33,11 @@ import screen.LoadingDialog import testCore.AbstractTest import testCore.assertDoesNotExit import testCore.assertExits +import testCore.getDialogMessage +import testCore.getErrorDialog +import testCore.getInfoDialog +import testCore.getQuestionDialog +import testCore.runAsync class UpdateManagerTest : AbstractTest() { @BeforeEach diff --git a/core/src/main/java/util/AbstractClient.java b/core/src/main/java/util/AbstractClient.java index aeb7332..ce6dbfd 100644 --- a/core/src/main/java/util/AbstractClient.java +++ b/core/src/main/java/util/AbstractClient.java @@ -5,7 +5,7 @@ import java.util.ArrayList; import java.util.Locale; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; /** * Interface used by Entropy Android & Desktop for anything to do with the online session diff --git a/core/src/main/java/util/FileUtil.java b/core/src/main/java/util/FileUtil.java index 95b8711..5f83a25 100644 --- a/core/src/main/java/util/FileUtil.java +++ b/core/src/main/java/util/FileUtil.java @@ -1,28 +1,13 @@ package util; -import java.awt.Component; -import java.awt.Dimension; import java.io.BufferedWriter; -import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.MessageDigest; -import java.util.Iterator; -import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.stream.FileImageInputStream; -import javax.imageio.stream.ImageInputStream; -import javax.swing.JFileChooser; - -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class FileUtil { diff --git a/core/src/main/java/util/KeyGeneratorUtil.java b/core/src/main/java/util/KeyGeneratorUtil.java index ffb556e..35e8870 100644 --- a/core/src/main/java/util/KeyGeneratorUtil.java +++ b/core/src/main/java/util/KeyGeneratorUtil.java @@ -3,7 +3,7 @@ import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class KeyGeneratorUtil { diff --git a/core/src/main/java/util/MessageSender.java b/core/src/main/java/util/MessageSender.java index b91b85c..551a0ec 100644 --- a/core/src/main/java/util/MessageSender.java +++ b/core/src/main/java/util/MessageSender.java @@ -12,7 +12,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class MessageSender implements Runnable { diff --git a/core/src/main/java/util/MessageUtil.java b/core/src/main/java/util/MessageUtil.java index fffc2fe..be7cf76 100644 --- a/core/src/main/java/util/MessageUtil.java +++ b/core/src/main/java/util/MessageUtil.java @@ -9,7 +9,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class MessageUtil implements OnlineConstants { diff --git a/core/src/main/kotlin/bean/FocusableWindow.kt b/core/src/main/kotlin/bean/FocusableWindow.kt index 3fe8b14..533f171 100644 --- a/core/src/main/kotlin/bean/FocusableWindow.kt +++ b/core/src/main/kotlin/bean/FocusableWindow.kt @@ -4,7 +4,7 @@ import java.awt.event.WindowEvent import java.awt.event.WindowFocusListener import javax.swing.JFrame import logging.KEY_ACTIVE_WINDOW -import utils.InjectedThings +import utils.CoreGlobals abstract class FocusableWindow : JFrame(), WindowFocusListener { abstract val windowName: String @@ -14,7 +14,7 @@ abstract class FocusableWindow : JFrame(), WindowFocusListener { } override fun windowGainedFocus(e: WindowEvent?) { - InjectedThings.logger.addToContext(KEY_ACTIVE_WINDOW, windowName) + CoreGlobals.logger.addToContext(KEY_ACTIVE_WINDOW, windowName) } override fun windowLostFocus(e: WindowEvent?) {} diff --git a/core/src/main/kotlin/logging/ILogDestination.kt b/core/src/main/kotlin/logging/ILogContextListener.kt similarity index 53% rename from core/src/main/kotlin/logging/ILogDestination.kt rename to core/src/main/kotlin/logging/ILogContextListener.kt index 982b242..8a63dd3 100644 --- a/core/src/main/kotlin/logging/ILogDestination.kt +++ b/core/src/main/kotlin/logging/ILogContextListener.kt @@ -1,7 +1,5 @@ package logging -interface ILogDestination { - fun log(record: LogRecord) - +interface ILogContextListener { fun contextUpdated(context: Map) } diff --git a/core/src/main/kotlin/logging/LogDestinationSystemOut.kt b/core/src/main/kotlin/logging/LogDestinationSystemOut.kt deleted file mode 100644 index 51dfd74..0000000 --- a/core/src/main/kotlin/logging/LogDestinationSystemOut.kt +++ /dev/null @@ -1,11 +0,0 @@ -package logging - -class LogDestinationSystemOut : ILogDestination { - override fun log(record: LogRecord) { - println(record) - record.getThrowableStr()?.let { println(it) } - record.keyValuePairs[KEY_STACK]?.let { println(it) } - } - - override fun contextUpdated(context: Map) {} -} diff --git a/core/src/main/kotlin/logging/LogRecord.kt b/core/src/main/kotlin/logging/LogRecord.kt deleted file mode 100644 index a8f4075..0000000 --- a/core/src/main/kotlin/logging/LogRecord.kt +++ /dev/null @@ -1,30 +0,0 @@ -package logging - -import ch.qos.logback.classic.Level -import java.time.Instant -import java.time.ZoneId -import java.time.format.DateTimeFormatter -import java.util.* - -data class LogRecord( - val timestamp: Instant, - val severity: Level, - val loggingCode: String, - val message: String, - val errorObject: Throwable?, - val keyValuePairs: Map -) { - private val dateStr = - DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") - .withLocale(Locale.UK) - .withZone(ZoneId.systemDefault()) - .format(timestamp) - - override fun toString(): String { - val durationStr = keyValuePairs[KEY_DURATION]?.let { " (${it}ms) " }.orEmpty() - val rowCountStr = keyValuePairs[KEY_ROW_COUNT]?.let { " ($it rows) " }.orEmpty() - return "$dateStr [$loggingCode] $durationStr$rowCountStr$message" - } - - fun getThrowableStr() = errorObject?.let { "$dateStr ${extractStackTrace(errorObject)}" } -} diff --git a/core/src/main/kotlin/logging/Logger.kt b/core/src/main/kotlin/logging/Logger.kt index a60608c..0c8e7de 100644 --- a/core/src/main/kotlin/logging/Logger.kt +++ b/core/src/main/kotlin/logging/Logger.kt @@ -12,10 +12,17 @@ import net.logstash.logback.marker.Markers import org.slf4j.Marker class Logger(private val slf4jLogger: org.slf4j.Logger) { - val loggingContext = ConcurrentHashMap() + private val globalContext = ConcurrentHashMap() + private val contextListeners = mutableListOf() fun addToContext(loggingKey: String, value: Any?) { - loggingContext[loggingKey] = value ?: "" + globalContext[loggingKey] = value ?: "" + + contextListeners.forEach { it.contextUpdated(globalContext.toMap()) } + } + + fun addContextListener(listener: ILogContextListener) { + contextListeners.add(listener) } @JvmOverloads @@ -65,7 +72,7 @@ class Logger(private val slf4jLogger: org.slf4j.Logger) { errorObject: Throwable?, keyValuePairs: Map ) { - val combinedKeys = loggingContext + keyValuePairs + ("loggingCode" to code) + val combinedKeys = globalContext + keyValuePairs + (KEY_LOGGING_CODE to code) val marker = combinedKeys.filterValues { it != null }.let(Markers::appendEntries) getLogMethod(severity).invoke(marker, message, errorObject) } @@ -84,7 +91,7 @@ class Logger(private val slf4jLogger: org.slf4j.Logger) { } val ILoggingEvent.loggingCode: String? - get() = findLogField("loggingCode") as? String + get() = findLogField(KEY_LOGGING_CODE) as? String fun ILoggingEvent.findLogField(key: String): Any? = getLogFields()[key] @@ -94,7 +101,7 @@ private val mapEntriesAppendingMarkerField: Field = fun ILoggingEvent.getLogFields(): Map { val marker = this.markerList?.firstOrNull() return if (marker is MapEntriesAppendingMarker) { - mapEntriesAppendingMarkerField.get(marker) as Map + mapEntriesAppendingMarkerField.get(marker) as Map + this.mdcPropertyMap } else { emptyMap() } diff --git a/core/src/main/kotlin/logging/LoggerUncaughtExceptionHandler.kt b/core/src/main/kotlin/logging/LoggerUncaughtExceptionHandler.kt index 508623f..60a203e 100644 --- a/core/src/main/kotlin/logging/LoggerUncaughtExceptionHandler.kt +++ b/core/src/main/kotlin/logging/LoggerUncaughtExceptionHandler.kt @@ -1,7 +1,7 @@ package logging import java.lang.Thread.UncaughtExceptionHandler -import utils.InjectedThings.logger +import utils.CoreGlobals.logger class LoggerUncaughtExceptionHandler : UncaughtExceptionHandler { override fun uncaughtException(arg0: Thread, arg1: Throwable) { diff --git a/core/src/main/kotlin/logging/LoggingKeys.kt b/core/src/main/kotlin/logging/LoggingKeys.kt index 926cc7e..093ae49 100644 --- a/core/src/main/kotlin/logging/LoggingKeys.kt +++ b/core/src/main/kotlin/logging/LoggingKeys.kt @@ -9,8 +9,7 @@ const val KEY_DEV_MODE = "devMode" const val KEY_ACTIVE_WINDOW = "activeWindow" // Other -const val KEY_DURATION = "duration" -const val KEY_ROW_COUNT = "rowCount" +const val KEY_LOGGING_CODE = "loggingCode" const val KEY_EXCEPTION_MESSAGE = "exceptionMessage" const val KEY_THREAD = "currentThread" const val KEY_STACK = "stackTrace" diff --git a/core/src/main/kotlin/utils/InjectedThings.kt b/core/src/main/kotlin/utils/CoreGlobals.kt similarity index 75% rename from core/src/main/kotlin/utils/InjectedThings.kt rename to core/src/main/kotlin/utils/CoreGlobals.kt index 5f3d37e..2081552 100644 --- a/core/src/main/kotlin/utils/InjectedThings.kt +++ b/core/src/main/kotlin/utils/CoreGlobals.kt @@ -3,12 +3,9 @@ package utils import ch.qos.logback.classic.Logger as LogbackLogger import java.time.Clock import logging.Logger -import logging.LoggingConsole import org.slf4j.LoggerFactory -object InjectedThings { - @JvmField val loggingConsole = LoggingConsole() - +object CoreGlobals { val slf4jLogger: LogbackLogger = LoggerFactory.getLogger("entropy") as LogbackLogger @JvmField var logger: Logger = Logger(slf4jLogger) var clock: Clock = Clock.systemUTC() diff --git a/core/src/main/kotlin/utils/ThreadUtil.kt b/core/src/main/kotlin/utils/ThreadUtil.kt index 6dbe42f..4e73337 100644 --- a/core/src/main/kotlin/utils/ThreadUtil.kt +++ b/core/src/main/kotlin/utils/ThreadUtil.kt @@ -3,7 +3,7 @@ package utils import javax.swing.SwingUtilities import logging.KEY_STACK import logging.extractThreadStack -import utils.InjectedThings.logger +import utils.CoreGlobals.logger fun dumpThreadStacks() { logger.info("threadStacks", "Dumping thread stacks") diff --git a/core/src/test/kotlin/bean/FocusableWindowTest.kt b/core/src/test/kotlin/bean/FocusableWindowTest.kt index 7297db9..e592af2 100644 --- a/core/src/test/kotlin/bean/FocusableWindowTest.kt +++ b/core/src/test/kotlin/bean/FocusableWindowTest.kt @@ -3,18 +3,20 @@ package bean import io.kotest.matchers.shouldBe import io.mockk.mockk import logging.KEY_ACTIVE_WINDOW +import logging.findLogField import org.junit.jupiter.api.Test import testCore.AbstractTest -import utils.InjectedThings.logger +import utils.CoreGlobals.logger class FocusableWindowTest : AbstractTest() { @Test fun `Should update logging context when gains focus`() { val window = FakeFocusableWindow() - - logger.addToContext(KEY_ACTIVE_WINDOW, "Foo") window.windowGainedFocus(mockk()) - logger.loggingContext[KEY_ACTIVE_WINDOW] shouldBe "Fake Window" + + logger.info("some.code", "some message") + + getLastLog().findLogField(KEY_ACTIVE_WINDOW) shouldBe "Fake Window" } private inner class FakeFocusableWindow : FocusableWindow() { diff --git a/core/src/test/kotlin/logging/LoggerTest.kt b/core/src/test/kotlin/logging/LoggerTest.kt index 1949d60..c805d1f 100644 --- a/core/src/test/kotlin/logging/LoggerTest.kt +++ b/core/src/test/kotlin/logging/LoggerTest.kt @@ -3,10 +3,13 @@ package logging import ch.qos.logback.classic.Level import io.kotest.matchers.collections.shouldBeEmpty import io.kotest.matchers.shouldBe -import main.kotlin.testCore.shouldContainKeyValues +import io.mockk.mockk +import io.mockk.verify import org.junit.jupiter.api.Test +import org.slf4j.MDC import testCore.AbstractTest -import utils.InjectedThings.slf4jLogger +import testCore.shouldContainKeyValues +import utils.CoreGlobals.slf4jLogger class LoggerTest : AbstractTest() { @Test @@ -21,7 +24,7 @@ class LoggerTest : AbstractTest() { record.loggingCode shouldBe loggingCode record.message shouldBe "A thing happened" record.errorObject() shouldBe null - record.shouldContainKeyValues("loggingCode" to "some.event") + record.shouldContainKeyValues(KEY_LOGGING_CODE to "some.event") } @Test @@ -87,9 +90,25 @@ class LoggerTest : AbstractTest() { val logger = Logger(slf4jLogger) logger.addToContext("appVersion", "4.1.1") + MDC.put("threadContext", "test thread") logger.info("foo", "a thing happened", "otherKey" to "otherValue") val record = getLastLog() - record.shouldContainKeyValues("appVersion" to "4.1.1", "otherKey" to "otherValue") + record.shouldContainKeyValues( + "appVersion" to "4.1.1", + "threadContext" to "test thread", + "otherKey" to "otherValue" + ) + } + + @Test + fun `Should update listeners when global log context changes`() { + val logger = Logger(slf4jLogger) + val mockListener = mockk(relaxed = true) + + logger.addContextListener(mockListener) + logger.addToContext("client.ip", "1.2.3.4") + + verify { mockListener.contextUpdated(mapOf("client.ip" to "1.2.3.4")) } } } diff --git a/core/src/test/kotlin/logging/LoggerUncaughtExceptionHandlerTest.kt b/core/src/test/kotlin/logging/LoggerUncaughtExceptionHandlerTest.kt index a118295..d902e24 100644 --- a/core/src/test/kotlin/logging/LoggerUncaughtExceptionHandlerTest.kt +++ b/core/src/test/kotlin/logging/LoggerUncaughtExceptionHandlerTest.kt @@ -4,9 +4,9 @@ import ch.qos.logback.classic.Level import io.kotest.matchers.maps.shouldNotContainKey import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldContain -import main.kotlin.testCore.shouldContainKeyValues import org.junit.jupiter.api.Test import testCore.AbstractTest +import testCore.shouldContainKeyValues class LoggerUncaughtExceptionHandlerTest : AbstractTest() { @Test diff --git a/server/src/main/java/object/BidHistory.java b/server/src/main/java/object/BidHistory.java index 9e2e520..43d9567 100644 --- a/server/src/main/java/object/BidHistory.java +++ b/server/src/main/java/object/BidHistory.java @@ -3,9 +3,7 @@ import java.util.ArrayList; import java.util.HashMap; -import util.Debug; - -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class BidHistory { diff --git a/server/src/main/java/object/GameWrapper.java b/server/src/main/java/object/GameWrapper.java index 328b7e1..aeaeef3 100644 --- a/server/src/main/java/object/GameWrapper.java +++ b/server/src/main/java/object/GameWrapper.java @@ -2,9 +2,7 @@ import java.util.concurrent.ConcurrentHashMap; -import util.Debug; - -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; /** * Wrap up a single game diff --git a/server/src/main/java/object/Room.java b/server/src/main/java/object/Room.java index b3d6e21..580a2af 100644 --- a/server/src/main/java/object/Room.java +++ b/server/src/main/java/object/Room.java @@ -159,7 +159,7 @@ private void notifyAllUsersViaGameSocket(Document notification, String userToExc usersToNotify.remove(userToExclude); } - List uscs = Globals.INSTANCE.getUscStore().getAllForNames(usersToNotify); + List uscs = ServerGlobals.INSTANCE.getUscStore().getAllForNames(usersToNotify); server.sendViaNotificationSocket(uscs, notification, XmlConstants.SOCKET_NAME_GAME, blocking); } @@ -414,7 +414,7 @@ private void saveStatistics(String winningPlayer, int roundNumber) //Push out a stats notification Document statsNotification = XmlBuilderServer.factoryStatisticsNotification(player); - UserConnection usc = Globals.INSTANCE.getUscStore().findForName(player); + UserConnection usc = ServerGlobals.INSTANCE.getUscStore().findForName(player); usc.sendNotificationInWorkerPool(statsNotification, server, XmlConstants.SOCKET_NAME_LOBBY, null); } } @@ -545,7 +545,7 @@ public void addToChatHistoryAndNotifyUsers(OnlineMessage message) Document chatMessage = XmlBuilderServer.getChatNotification(roomName, message); HashSet users = getAllUsersInRoom(); - List uscs = Globals.INSTANCE.getUscStore().getAllForNames(users); + List uscs = ServerGlobals.INSTANCE.getUscStore().getAllForNames(users); server.sendViaNotificationSocket(uscs, chatMessage, XmlConstants.SOCKET_NAME_CHAT, false); } public ArrayList getChatHistory() diff --git a/server/src/main/java/server/EntropyServer.java b/server/src/main/java/server/EntropyServer.java index 0e0f3ba..503b1fa 100644 --- a/server/src/main/java/server/EntropyServer.java +++ b/server/src/main/java/server/EntropyServer.java @@ -15,7 +15,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public final class EntropyServer implements OnlineConstants { //Caches @@ -31,7 +31,7 @@ public static void main() { //Initialise interfaces etc Debug.initialise(new DebugOutputSystemOut()); - Globals.INSTANCE.getServer().onStart(); + ServerGlobals.INSTANCE.getServer().onStart(); } private void onStart() { @@ -127,7 +127,7 @@ private void startListenerThreads() { } public void executeInWorkerPool(ServerRunnable runnable) { - Globals.workerPool.executeServerRunnable(runnable); + ServerGlobals.workerPool.executeServerRunnable(runnable); } public void removeFromUsersOnline(UserConnection usc) { @@ -150,8 +150,8 @@ public void removeFromUsersOnline(UserConnection usc) { } //Now remove the user connection. - Globals.INSTANCE.getUscStore().remove(usc.getIpAddress()); - if (Globals.INSTANCE.getUscStore().getAll().size() == 0 + ServerGlobals.INSTANCE.getUscStore().remove(usc.getIpAddress()); + if (ServerGlobals.INSTANCE.getUscStore().getAll().size() == 0 && username != null) { resetLobby(); return; @@ -202,7 +202,7 @@ public void addAdminMessage(String message) { private void addToChatHistory(String name, OnlineMessage message) { if (name.equals(LOBBY_ID)) { lobbyMessages.add(message); - List usersToNotify = Globals.INSTANCE.getUscStore().getAll(); + List usersToNotify = ServerGlobals.INSTANCE.getUscStore().getAll(); Document chatMessage = XmlBuilderServer.getChatNotification(name, message); sendViaNotificationSocket(usersToNotify, chatMessage, XmlConstants.SOCKET_NAME_CHAT); @@ -217,7 +217,7 @@ public void lobbyChanged() { } public void lobbyChanged(UserConnection userToExclude) { - List usersToNotify = new ArrayList<>(Globals.INSTANCE.getUscStore().getAll()); + List usersToNotify = new ArrayList<>(ServerGlobals.INSTANCE.getUscStore().getAll()); if (userToExclude != null) { usersToNotify.remove(userToExclude); } diff --git a/server/src/main/java/server/InactiveCheckRunnable.java b/server/src/main/java/server/InactiveCheckRunnable.java index 1221c15..dc58368 100644 --- a/server/src/main/java/server/InactiveCheckRunnable.java +++ b/server/src/main/java/server/InactiveCheckRunnable.java @@ -5,9 +5,9 @@ import auth.UserConnection; import object.ServerRunnable; import util.Debug; -import util.Globals; +import util.ServerGlobals; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class InactiveCheckRunnable implements ServerRunnable { @@ -40,7 +40,7 @@ public void run() private void runInactiveCheck() throws InterruptedException { - List userConnections = Globals.INSTANCE.getUscStore().getAll(); + List userConnections = ServerGlobals.INSTANCE.getUscStore().getAll(); int size = userConnections.size(); statusText = "Running for " + size + " uscs"; diff --git a/server/src/main/java/server/MessageHandlerRunnable.java b/server/src/main/java/server/MessageHandlerRunnable.java index 3aa6565..f60c5cd 100644 --- a/server/src/main/java/server/MessageHandlerRunnable.java +++ b/server/src/main/java/server/MessageHandlerRunnable.java @@ -21,7 +21,7 @@ import org.w3c.dom.Element; import util.*; -import utils.InjectedThings; +import utils.CoreGlobals; public class MessageHandlerRunnable implements ServerRunnable, XmlConstants @@ -141,7 +141,7 @@ private void initVariablesFromSocket() { InetAddress address = clientSocket.getInetAddress(); ipAddress = address.getHostAddress(); - usc = Globals.INSTANCE.getUscStore().find(ipAddress); + usc = ServerGlobals.INSTANCE.getUscStore().find(ipAddress); if (usc != null) { @@ -190,7 +190,7 @@ private Document handleUnencryptedMessage(Document message) Element root = message.getDocumentElement(); String name = root.getNodeName(); - InjectedThings.logger.info("unencrypted.message", "Received unencrypted " + name + " message. Probably using out of date version? " + CoreGlobals.logger.info("unencrypted.message", "Received unencrypted " + name + " message. Probably using out of date version? " + "Message: " + messageStr); return null; } diff --git a/server/src/main/java/server/NotificationRunnable.java b/server/src/main/java/server/NotificationRunnable.java index 4468c52..f615253 100644 --- a/server/src/main/java/server/NotificationRunnable.java +++ b/server/src/main/java/server/NotificationRunnable.java @@ -15,7 +15,7 @@ import util.EncryptionUtil; import util.XmlUtil; -import static utils.InjectedThings.logger; +import static utils.CoreGlobals.logger; public class NotificationRunnable implements ServerRunnable { diff --git a/server/src/main/java/util/EntropyThreadPoolExecutor.java b/server/src/main/java/util/EntropyThreadPoolExecutor.java index 4b525f8..003fe8f 100644 --- a/server/src/main/java/util/EntropyThreadPoolExecutor.java +++ b/server/src/main/java/util/EntropyThreadPoolExecutor.java @@ -57,7 +57,7 @@ import auth.UserConnection; import object.ServerRunnable; import object.ServerThread; -import utils.InjectedThings; +import utils.CoreGlobals; /** * An {@link ExecutorService} that executes each submitted task using @@ -1936,7 +1936,7 @@ protected void terminated() { } private class RejectedThreadHandler { public void rejectedExecution(Runnable arg0) { - InjectedThings.logger.warn("rejected.execution", "Too many functions queued - throwing away runnable " + arg0); + CoreGlobals.logger.warn("rejected.execution", "Too many functions queued - throwing away runnable " + arg0); } } diff --git a/server/src/main/java/util/LoggingUtil.kt b/server/src/main/java/util/LoggingUtil.kt index 0c6c886..8bb0be6 100644 --- a/server/src/main/java/util/LoggingUtil.kt +++ b/server/src/main/java/util/LoggingUtil.kt @@ -1,7 +1,7 @@ package util import `object`.ServerThread -import utils.InjectedThings.logger +import utils.CoreGlobals.logger fun dumpServerThreads() { val sb = StringBuilder() diff --git a/server/src/main/java/util/XmlBuilderServer.java b/server/src/main/java/util/XmlBuilderServer.java index 2a27846..98962f1 100644 --- a/server/src/main/java/util/XmlBuilderServer.java +++ b/server/src/main/java/util/XmlBuilderServer.java @@ -249,7 +249,7 @@ private static void appendChatMessage(Document response, Element root, OnlineMes public static Document appendLobbyResponse(Document message, EntropyServer server) { List rooms = server.getRooms(); - List userConnections = Globals.INSTANCE.getUscStore().getAll(); + List userConnections = ServerGlobals.INSTANCE.getUscStore().getAll(); Element root = message.getDocumentElement(); Element rootElement = message.createElement(RESPONSE_TAG_LOBBY_NOTIFICATION); diff --git a/server/src/main/kotlin/plugins/Monitoring.kt b/server/src/main/kotlin/plugins/Monitoring.kt index a053549..cda4bfd 100644 --- a/server/src/main/kotlin/plugins/Monitoring.kt +++ b/server/src/main/kotlin/plugins/Monitoring.kt @@ -7,12 +7,12 @@ import io.ktor.server.plugins.callid.* import io.ktor.server.plugins.callloging.* import io.ktor.server.request.* import org.slf4j.event.* -import utils.InjectedThings +import utils.CoreGlobals fun Application.configureMonitoring() { install(CallLogging) { level = Level.INFO - logger = InjectedThings.slf4jLogger + logger = CoreGlobals.slf4jLogger filter { false } callIdMdc("call-id") diff --git a/server/src/main/kotlin/plugins/Routing.kt b/server/src/main/kotlin/plugins/Routing.kt index 0da6534..7d6c01c 100644 --- a/server/src/main/kotlin/plugins/Routing.kt +++ b/server/src/main/kotlin/plugins/Routing.kt @@ -11,7 +11,7 @@ import routes.ClientException import routes.dev.DevController import routes.health.HealthCheckController import routes.session.SessionController -import utils.InjectedThings.logger +import utils.CoreGlobals.logger fun Application.configureRouting() { install(StatusPages) { diff --git a/server/src/main/kotlin/routes/dev/DevService.kt b/server/src/main/kotlin/routes/dev/DevService.kt index 372eace..61d4113 100644 --- a/server/src/main/kotlin/routes/dev/DevService.kt +++ b/server/src/main/kotlin/routes/dev/DevService.kt @@ -6,9 +6,9 @@ import io.ktor.http.* import java.lang.management.ManagementFactory import java.util.concurrent.TimeUnit import routes.ClientException -import util.Globals +import util.ServerGlobals import util.dumpServerThreads -import utils.InjectedThings.logger +import utils.CoreGlobals.logger import utils.dumpThreadStacks class DevService { @@ -32,13 +32,13 @@ class DevService { } private fun dumpUsers() { - val uscs = Globals.uscStore.getAll() + val uscs = ServerGlobals.uscStore.getAll() logger.info("usc.count", "${uscs.size} user(s) online.") uscs.forEach { logger.info("usc", it.toString()) } } private fun dumpPoolStats() { - val workerPool = Globals.workerPool + val workerPool = ServerGlobals.workerPool val blockQueue = workerPool.queue logger.info( diff --git a/server/src/main/kotlin/routes/session/SessionController.kt b/server/src/main/kotlin/routes/session/SessionController.kt index 3d88105..5f6cdf1 100644 --- a/server/src/main/kotlin/routes/session/SessionController.kt +++ b/server/src/main/kotlin/routes/session/SessionController.kt @@ -7,10 +7,10 @@ import io.ktor.server.plugins.* import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* -import util.Globals +import util.ServerGlobals object SessionController { - private val sessionService = SessionService(Globals.sessionStore, Globals.uscStore) + private val sessionService = SessionService(ServerGlobals.sessionStore, ServerGlobals.uscStore) fun installRoutes(application: Application) { application.routing { post(Routes.BEGIN_SESSION) { beginSession(call) } } diff --git a/server/src/main/kotlin/routes/session/SessionService.kt b/server/src/main/kotlin/routes/session/SessionService.kt index 5027029..65155cb 100644 --- a/server/src/main/kotlin/routes/session/SessionService.kt +++ b/server/src/main/kotlin/routes/session/SessionService.kt @@ -12,8 +12,8 @@ import io.ktor.http.* import java.util.* import routes.ClientException import store.Store -import util.Globals import util.OnlineConstants +import util.ServerGlobals class SessionService( private val sessionStore: Store, @@ -52,7 +52,7 @@ class SessionService( val usc = UserConnection(ip, LegacyConstants.SYMMETRIC_KEY, name) usc.setLastActiveNow() uscStore.put(ip, usc) - Globals.server.lobbyChanged(usc) + ServerGlobals.server.lobbyChanged(usc) return BeginSessionResponse(session.name, session.id) } diff --git a/server/src/main/kotlin/util/Globals.kt b/server/src/main/kotlin/util/ServerGlobals.kt similarity index 97% rename from server/src/main/kotlin/util/Globals.kt rename to server/src/main/kotlin/util/ServerGlobals.kt index e1aaeea..ffc2ee7 100644 --- a/server/src/main/kotlin/util/Globals.kt +++ b/server/src/main/kotlin/util/ServerGlobals.kt @@ -14,7 +14,7 @@ private const val MAX_POOL_SIZE = 500 private const val MAX_QUEUE_SIZE = 100 private const val KEEP_ALIVE_TIME = 20 -object Globals { +object ServerGlobals { val uscStore: UserConnectionStore = MemoryUserConnectionStore() val sessionStore: Store = SessionStore() diff --git a/server/src/test/kotlin/routes/session/SessionControllerTest.kt b/server/src/test/kotlin/routes/session/SessionControllerTest.kt index 0f86277..626740b 100644 --- a/server/src/test/kotlin/routes/session/SessionControllerTest.kt +++ b/server/src/test/kotlin/routes/session/SessionControllerTest.kt @@ -10,8 +10,8 @@ import io.ktor.server.testing.* import org.junit.jupiter.api.Test import testCore.AbstractTest import testCore.shouldMatchJson -import util.Globals.sessionStore import util.OnlineConstants +import util.ServerGlobals.sessionStore class SessionControllerTest : AbstractTest() { @Test diff --git a/server/src/test/kotlin/routes/session/SessionServiceTest.kt b/server/src/test/kotlin/routes/session/SessionServiceTest.kt index 2e23a2c..445c902 100644 --- a/server/src/test/kotlin/routes/session/SessionServiceTest.kt +++ b/server/src/test/kotlin/routes/session/SessionServiceTest.kt @@ -10,13 +10,13 @@ import io.kotest.matchers.collections.shouldBeEmpty import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder import io.kotest.matchers.shouldBe import io.ktor.http.* -import main.kotlin.testCore.only import org.junit.jupiter.api.Test import routes.ClientException import store.MemoryUserConnectionStore import store.SessionStore import store.UserConnectionStore import testCore.AbstractTest +import testCore.only import util.OnlineConstants class SessionServiceTest : AbstractTest() { diff --git a/test-core/src/main/kotlin/testCore/AbstractTest.kt b/test-core/src/main/kotlin/testCore/AbstractTest.kt index d8f4568..456db31 100644 --- a/test-core/src/main/kotlin/testCore/AbstractTest.kt +++ b/test-core/src/main/kotlin/testCore/AbstractTest.kt @@ -13,10 +13,11 @@ import logging.loggingCode import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.extension.ExtendWith +import org.slf4j.MDC import util.AbstractClient import util.Debug import util.DebugOutputSystemOut -import utils.InjectedThings.slf4jLogger +import utils.CoreGlobals.slf4jLogger val logger = Logger(slf4jLogger) private var checkedForExceptions = false @@ -32,7 +33,7 @@ open class AbstractTest { Debug.initialise(DebugOutputSystemOut()) AbstractClient.devMode = false - logger.loggingContext.clear() + MDC.clear() } @AfterEach diff --git a/test-core/src/main/kotlin/testCore/BeforeAllTestsExtension.kt b/test-core/src/main/kotlin/testCore/BeforeAllTestsExtension.kt index 52be3a4..94c84b9 100644 --- a/test-core/src/main/kotlin/testCore/BeforeAllTestsExtension.kt +++ b/test-core/src/main/kotlin/testCore/BeforeAllTestsExtension.kt @@ -6,8 +6,8 @@ import logging.LoggerUncaughtExceptionHandler import main.kotlin.testCore.CURRENT_TIME import org.junit.jupiter.api.extension.BeforeAllCallback import org.junit.jupiter.api.extension.ExtensionContext -import utils.InjectedThings -import utils.InjectedThings.slf4jLogger +import utils.CoreGlobals +import utils.CoreGlobals.slf4jLogger var doneOneTimeSetup = false @@ -22,8 +22,8 @@ class BeforeAllTestsExtension : BeforeAllCallback { private fun doOneTimeSetup() { Thread.setDefaultUncaughtExceptionHandler(LoggerUncaughtExceptionHandler()) - InjectedThings.logger = logger - InjectedThings.clock = Clock.fixed(CURRENT_TIME, ZoneId.of("UTC")) + CoreGlobals.logger = logger + CoreGlobals.clock = Clock.fixed(CURRENT_TIME, ZoneId.of("UTC")) listAppender.start() slf4jLogger.addAppender(listAppender) diff --git a/test-core/src/main/kotlin/testCore/TestUtils.kt b/test-core/src/main/kotlin/testCore/TestUtils.kt index ceeaaf4..ee458fd 100644 --- a/test-core/src/main/kotlin/testCore/TestUtils.kt +++ b/test-core/src/main/kotlin/testCore/TestUtils.kt @@ -1,32 +1,46 @@ -package main.kotlin.testCore +package testCore import ch.qos.logback.classic.Level import ch.qos.logback.classic.spi.ILoggingEvent +import ch.qos.logback.classic.spi.LoggingEvent import com.github.alyssaburlton.swingtest.findAll import com.github.alyssaburlton.swingtest.findWindow import com.github.alyssaburlton.swingtest.flushEdt import io.kotest.matchers.maps.shouldContainAll import io.kotest.matchers.shouldBe import io.mockk.verify -import java.time.Instant import javax.swing.JDialog import javax.swing.JLabel import javax.swing.SwingUtilities -import logging.LogRecord +import logging.KEY_LOGGING_CODE import logging.getLogFields +import net.logstash.logback.marker.MapEntriesAppendingMarker +import utils.CoreGlobals fun ILoggingEvent.shouldContainKeyValues(vararg values: Pair) { this.getLogFields().shouldContainAll(mapOf(*values)) } -fun makeLogRecord( - timestamp: Instant = CURRENT_TIME, +fun makeLoggingEvent( severity: Level = Level.INFO, loggingCode: String = "log", message: String = "A thing happened", errorObject: Throwable? = null, keyValuePairs: Map = mapOf(), -) = LogRecord(timestamp, severity, loggingCode, message, errorObject, keyValuePairs) +): LoggingEvent { + val event = + LoggingEvent( + "entropy", + CoreGlobals.slf4jLogger, + severity, + message, + errorObject, + emptyArray() + ) + + event.addMarker(MapEntriesAppendingMarker(keyValuePairs + (KEY_LOGGING_CODE to loggingCode))) + return event +} fun getInfoDialog() = getOptionPaneDialog("Information")