From 8ee334716e5580eb6e159b13c32202c6e37fd21a Mon Sep 17 00:00:00 2001 From: Henry Kupty Date: Sat, 23 Mar 2024 21:35:52 +0100 Subject: [PATCH] feat: Introduce `penna.api.audit` This should allow for better logging in exceptional cases without the need for the proper logging infrastructure. Since the logger won't be available during runtime, we should use this as a direct means of notifying stdout of important events. --- penna-api/src/main/java/module-info.java | 1 + .../src/main/java/penna/api/audit/Logger.java | 32 ++++++++++++ .../java/penna/api/audit/PseudoLogger.java | 22 +++++++++ .../api/audit/internal/StdoutLogger.java | 49 +++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 penna-api/src/main/java/penna/api/audit/Logger.java create mode 100644 penna-api/src/main/java/penna/api/audit/PseudoLogger.java create mode 100644 penna-api/src/main/java/penna/api/audit/internal/StdoutLogger.java diff --git a/penna-api/src/main/java/module-info.java b/penna-api/src/main/java/module-info.java index 6d4edfc0..01398327 100644 --- a/penna-api/src/main/java/module-info.java +++ b/penna-api/src/main/java/module-info.java @@ -13,4 +13,5 @@ exports penna.api.models; exports penna.api.config; + exports penna.api.audit; } \ No newline at end of file diff --git a/penna-api/src/main/java/penna/api/audit/Logger.java b/penna-api/src/main/java/penna/api/audit/Logger.java new file mode 100644 index 00000000..caf999ff --- /dev/null +++ b/penna-api/src/main/java/penna/api/audit/Logger.java @@ -0,0 +1,32 @@ +package penna.api.audit; + +import penna.api.audit.internal.StdoutLogger; + +/** + * This class provides static methods for the logger to report back, specially during initialization. + * It is supposed to be as simple as possible and as minimally used as possible. + */ +public class Logger { + private Logger() {} + private static final PseudoLogger impl = new StdoutLogger(); + + /** + * Reports through the underlying logger some important event. To be used sparingly. + * @param level The target level. + * @param event The message to be printed. + */ + public static void report(String level, String event) { + impl.report(level, event); + } + + /** + * Reports an error, usually in the form of an {@link Exception}. To be used sparingly, in situations + * where the logger malfunctions and needs to explain upstream why it didn't work. + * @param level The target level. + * @param event The message to be printed. + * @param throwable The exception or error that caused the report. + */ + public static void reportError(String level, String event, Throwable throwable) { + impl.reportError(level, event, throwable); + } +} diff --git a/penna-api/src/main/java/penna/api/audit/PseudoLogger.java b/penna-api/src/main/java/penna/api/audit/PseudoLogger.java new file mode 100644 index 00000000..c639dc99 --- /dev/null +++ b/penna-api/src/main/java/penna/api/audit/PseudoLogger.java @@ -0,0 +1,22 @@ +package penna.api.audit; + +/** + * This is the internal logging mechanism, so we can still log important messages if something fails on initialization. + */ +public interface PseudoLogger { + /** + * This method should be used to notify an event; + * @param level How critical this event is; + * @param event The event as a short string; + */ + void report(String level, String event); + + + /** + * This method should be used to notify a failure or an exception, handled or not; + * @param level How critical is the situation + * @param event The event as a short string; + * @param throwable The error that happened + */ + void reportError(String level, String event, Throwable throwable); +} diff --git a/penna-api/src/main/java/penna/api/audit/internal/StdoutLogger.java b/penna-api/src/main/java/penna/api/audit/internal/StdoutLogger.java new file mode 100644 index 00000000..a2b767e4 --- /dev/null +++ b/penna-api/src/main/java/penna/api/audit/internal/StdoutLogger.java @@ -0,0 +1,49 @@ +package penna.api.audit.internal; + +import penna.api.audit.PseudoLogger; + +/** + * Simple string-concat based logger just to print important messages to stdout. + * See {@link PseudoLogger} for more information. + */ +public class StdoutLogger implements PseudoLogger { + private final String version = StdoutLogger.class.getPackage().getImplementationVersion(); + + /** + * Builds an audit logger instance. + * See {@link PseudoLogger} for more information. + */ + public StdoutLogger() {} + + @Override + public void report(String level, String event) { + String sb = "{\"logger\":\"penna.api.audit.Logger\",\"level\":\"" + + level + + "\",\"message\":\"" + + event + + "\",\"pennaVersion\":\"" + + version + + "\"}"; + System.out.println(sb); + } + + @Override + public void reportError(String level, String event, Throwable throwable) { + StringBuilder sb = new StringBuilder(); + sb.append("{\"logger\":\"penna.api.audit.Logger\",\"level\":\""); + sb.append(level); + sb.append("\",\"message\":\""); + sb.append(event); + sb.append("\",\"error\":\""); + sb.append(throwable.getMessage()); + sb.append("\",\"stacktrace\":\""); + for (StackTraceElement stackTraceElement : throwable.getStackTrace()) { + sb.append(stackTraceElement.toString()); + sb.append("\\n"); + } + sb.append("\",\"pennaVersion\":\""); + sb.append(version); + sb.append("\"}"); + System.out.println(sb); + } +}