From 449d4fb751c515680f4bf4a9d582810427e1e658 Mon Sep 17 00:00:00 2001 From: "Alex J Hawk (HMS)" <51409174+alexjhawk@users.noreply.github.com> Date: Wed, 13 Dec 2023 08:08:28 -0500 Subject: [PATCH 1/3] Add log once methods to Logger.java Added methods to the Logger.java class which allow for logging an event only once. This is tracked internally by the logger using a specified key value. This facilitates the implementation of a mechanism which logs missing fields at most once. --- .../sc/extensions/logging/Logger.java | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/src/main/java/com/hms_networks/americas/sc/extensions/logging/Logger.java b/src/main/java/com/hms_networks/americas/sc/extensions/logging/Logger.java index b3097760..2708bce7 100644 --- a/src/main/java/com/hms_networks/americas/sc/extensions/logging/Logger.java +++ b/src/main/java/com/hms_networks/americas/sc/extensions/logging/Logger.java @@ -6,6 +6,8 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.HashSet; +import java.util.Set; /** * Logger.java @@ -80,6 +82,17 @@ public class Logger { /** Queue of unprinted logs. */ private static LogQueue logQueue; + /** + * Set for tracking whether a specific log has been outputted. This is used to prevent spamming + * the log with the same message. + * + *
If the log has already been outputted, its key will be in the set, otherwise it will not be
+ * present.
+ *
+ * @since 1.15.9
+ */
+ private static final Set logOnceList = new HashSet(); // Set The specified log key must be unique for each log event that should only be logged once. If
+ * the same log key is used for multiple log events, only the first log event will be logged,
+ * regardless of the message.
+ *
+ * @param logKey key for the log event
+ * @param logString string to log
+ * @since 1.15.9
+ */
+ public static void LOG_DEBUG_ONCE(String logKey, String logString) {
+ if (!getLoggedOnce(logKey)) {
+ setLoggedOnce(logKey, true);
+ LOG(LOG_LEVEL_DEBUG, logString);
+ }
+ }
+
/**
* Log a string and exception with the debug log level.
*
@@ -348,6 +379,24 @@ public static void LOG_INFO(String logString) {
LOG(LOG_LEVEL_INFO, logString);
}
+ /**
+ * Log a string with the info log level at most once (tracked by specified log key).
+ *
+ * The specified log key must be unique for each log event that should only be logged once. If
+ * the same log key is used for multiple log events, only the first log event will be logged,
+ * regardless of the message.
+ *
+ * @param logKey key for the log event
+ * @param logString string to log
+ * @since 1.15.9
+ */
+ public static void LOG_INFO_ONCE(String logKey, String logString) {
+ if (!getLoggedOnce(logKey)) {
+ setLoggedOnce(logKey, true);
+ LOG(LOG_LEVEL_INFO, logString);
+ }
+ }
+
/**
* Log a string and exception with the info log level.
*
@@ -384,6 +433,24 @@ public static void LOG_WARN(String logString) {
LOG(LOG_LEVEL_WARN, logString);
}
+ /**
+ * Log a string with the warning log level at most once (tracked by specified log key).
+ *
+ * The specified log key must be unique for each log event that should only be logged once. If
+ * the same log key is used for multiple log events, only the first log event will be logged,
+ * regardless of the message.
+ *
+ * @param logKey key for the log event
+ * @param logString string to log
+ * @since 1.15.9
+ */
+ public static void LOG_WARN_ONCE(String logKey, String logString) {
+ if (!getLoggedOnce(logKey)) {
+ setLoggedOnce(logKey, true);
+ LOG(LOG_LEVEL_WARN, logString);
+ }
+ }
+
/**
* Log a string and exception with the warning log level.
*
@@ -420,6 +487,24 @@ public static void LOG_SERIOUS(String logString) {
LOG(LOG_LEVEL_SERIOUS, logString);
}
+ /**
+ * Log a string with the serious log level at most once (tracked by specified log key).
+ *
+ * The specified log key must be unique for each log event that should only be logged once. If
+ * the same log key is used for multiple log events, only the first log event will be logged,
+ * regardless of the message.
+ *
+ * @param logKey key for the log event
+ * @param logString string to log
+ * @since 1.15.9
+ */
+ public static void LOG_SERIOUS_ONCE(String logKey, String logString) {
+ if (!getLoggedOnce(logKey)) {
+ setLoggedOnce(logKey, true);
+ LOG(LOG_LEVEL_SERIOUS, logString);
+ }
+ }
+
/**
* Log a string and exception with the serious log level.
*
@@ -457,6 +542,24 @@ public static void LOG_CRITICAL(String logString) {
LOG(LOG_LEVEL_CRITICAL, logString);
}
+ /**
+ * Log a string with the critical log level at most once (tracked by specified log key).
+ *
+ * The specified log key must be unique for each log event that should only be logged once. If
+ * the same log key is used for multiple log events, only the first log event will be logged,
+ * regardless of the message.
+ *
+ * @param logKey key for the log event
+ * @param logString string to log
+ * @since 1.15.9
+ */
+ public static void LOG_CRITICAL_ONCE(String logKey, String logString) {
+ if (!getLoggedOnce(logKey)) {
+ setLoggedOnce(logKey, true);
+ LOG(LOG_LEVEL_CRITICAL, logString);
+ }
+ }
+
/**
* Log a string and exception with the critical log level.
*
@@ -491,4 +594,40 @@ public static void DUMP_LOG_QUEUE() {
LOG(LOG_LEVEL_CRITICAL, logQueue.poll());
}
}
+
+ /**
+ * Sets whether a specific log has been outputted. This is used to prevent spamming the log with
+ * the same message.
+ *
+ * The specified log key must be unique for each log event that should only be logged once. If
+ * the same log key is used for multiple log events, only the first log event will be logged,
+ * regardless of the message.
+ *
+ * @param logKey key for the log event
+ * @param logOutputted boolean representing whether the log has been output (true) or not (false)
+ * @since 1.15.9
+ */
+ public static void setLoggedOnce(String logKey, boolean logOutputted) {
+ if (logOutputted) {
+ logOnceList.add(logKey);
+ } else {
+ logOnceList.remove(logKey);
+ }
+ }
+
+ /**
+ * Gets a boolean indicating whether a specific log has been outputted. This is used to prevent
+ * spamming the log with the same message.
+ *
+ * The specified log key must be unique for each log event that should only be logged once. If
+ * the same log key is used for multiple log events, only the first log event will be logged,
+ * regardless of the message.
+ *
+ * @param logKey key for the log event
+ * @return {@code true} if the log has been outputted, {@code false} otherwise
+ * @since 1.15.9
+ */
+ public static boolean getLoggedOnce(String logKey) {
+ return logOnceList.contains(logKey);
+ }
}
From 38a30a5851d8aeb947a26a5a05343695f2e30146 Mon Sep 17 00:00:00 2001
From: "Alex J Hawk (HMS)" <51409174+alexjhawk@users.noreply.github.com>
Date: Wed, 13 Dec 2023 08:08:40 -0500
Subject: [PATCH 2/3] Update abstract connector framework config
Updated the AbstractConnectorConfig.java class so that
it provides overloads of the #logMissingField() method
which allow for suppressing the log after one time.
---
.../framework/AbstractConnectorConfig.java | 56 ++++++++++++++++++-
1 file changed, 53 insertions(+), 3 deletions(-)
diff --git a/src/main/java/com/hms_networks/americas/sc/extensions/connectors/framework/AbstractConnectorConfig.java b/src/main/java/com/hms_networks/americas/sc/extensions/connectors/framework/AbstractConnectorConfig.java
index e47ceadf..a80f8b1a 100644
--- a/src/main/java/com/hms_networks/americas/sc/extensions/connectors/framework/AbstractConnectorConfig.java
+++ b/src/main/java/com/hms_networks/americas/sc/extensions/connectors/framework/AbstractConnectorConfig.java
@@ -24,6 +24,16 @@
*/
public abstract class AbstractConnectorConfig extends ConfigFile {
+ /**
+ * The uniqueness prefix appended to the key of a missing field to ensure that the log event is
+ * uniquely keyed in the log once system.
+ *
+ * ACCLMF = Abstract Connector Config Log Missing Field
+ *
+ * @since 1.15.9
+ */
+ private static final String LOG_ONCE_UNIQUENESS_PREFIX_ACCLMF = "ACCLMF_";
+
/**
* The path to the configuration file.
*
@@ -538,12 +548,33 @@ public JSONObject getDefaultConfigurationObject() throws JSONException {
* @since 1.15.2
*/
protected void logMissingField(String missingKey, String defaultValue) {
- Logger.LOG_WARN(
+ final boolean suppressAdditional = false;
+ logMissingField(missingKey, defaultValue, suppressAdditional);
+ }
+
+ /**
+ * Logs a missing field in the configuration file along with the default value that will be used.
+ * If the specified {@code suppressAdditional} boolean is {@code true}, the event will only be
+ * logged once (tracked by the key).
+ *
+ * @param missingKey the JSON key of the field that was missing/could not be found
+ * @param defaultValue the default value that will be used
+ * @param logOnce whether to log only once and suppress additional log events for the same key
+ * @since 1.15.9
+ */
+ protected void logMissingField(String missingKey, String defaultValue, boolean logOnce) {
+ String logMessage =
"The "
+ missingKey
+ " option was not found in the configuration file. Using default value of "
+ defaultValue
- + ".");
+ + ".";
+ if (logOnce) {
+ final String logOnceKey = LOG_ONCE_UNIQUENESS_PREFIX_ACCLMF + missingKey;
+ Logger.LOG_WARN_ONCE(logOnceKey, logMessage);
+ } else {
+ Logger.LOG_WARN(logMessage);
+ }
}
/**
@@ -553,7 +584,26 @@ protected void logMissingField(String missingKey, String defaultValue) {
* @since 1.15.2
*/
protected void logMissingField(String missingKey) {
- Logger.LOG_WARN("The " + missingKey + " option was not found in the configuration file.");
+ final boolean suppressAdditional = false;
+ logMissingField(missingKey, suppressAdditional);
+ }
+
+ /**
+ * Logs a missing field in the configuration file. If the specified {@code suppressAdditional}
+ * boolean is {@code true}, the event will only be logged once (tracked by the key).
+ *
+ * @param missingKey the JSON key of the field that was missing/could not be found
+ * @param logOnce whether to log only once and suppress additional log events for the same key
+ * @since 1.15.9
+ */
+ protected void logMissingField(String missingKey, boolean logOnce) {
+ String logMessage = "The " + missingKey + " option was not found in the configuration file.";
+ if (logOnce) {
+ final String logOnceKey = LOG_ONCE_UNIQUENESS_PREFIX_ACCLMF + missingKey;
+ Logger.LOG_WARN_ONCE(logOnceKey, logMessage);
+ } else {
+ Logger.LOG_WARN(logMessage);
+ }
}
/**
From 010a3a2a9fe3379878d0887f29607d69c501c49a Mon Sep 17 00:00:00 2001
From: "Alex J Hawk (HMS)" <51409174+alexjhawk@users.noreply.github.com>
Date: Wed, 13 Dec 2023 08:15:11 -0500
Subject: [PATCH 3/3] RELEASE: v1.15.9
---
pom.xml | 2 +-
.../com/hms_networks/americas/sc/extensions/package.html | 2 +-
starting-files/jvmrun | 2 +-
web-docs/docs/02-CHANGELOG.mdx | 5 +++++
web-docs/docs/_partial/_pom_library.mdx | 2 +-
5 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/pom.xml b/pom.xml
index 03679cf6..38f74345 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@