Package com.ultikits.ultitools.handler
Class SystemLogHandler
java.lang.Object
java.util.logging.Handler
com.ultikits.ultitools.handler.SystemLogHandler
System log handler.
Captures all system log records and forwards them to the UltiPanel backend.
- Version:
- 1.0.0
- Author:
- UltiKits
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final UltiPanelLogTransmitterprivate Levelprivate static final ThreadLocal<Boolean> Reentrancy guard forpublish(LogRecord)(Gate-2 finding, round 9). -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidaddEnabledLevel(String level) Adds an enabled log level.voidaddExcludedLogger(String loggerName) Adds an excluded logger.private StringcapitalizeFirst(String str) Capitalizes the first letter.voidclose()private StringdetermineLogSource(LogRecord record) Determines the log-source identifier.private StringextractModuleFromSource(String source) Extract module name from the log source string (e.g., "plugin:UltiChat" -> "UltiChat").private StringextractPluginName(String loggerName) Extracts a plugin name from a logger name.voidflush()private StringformatLogMessage(LogRecord record) Formats a log message.Gets a configuration-info string.private TriggerContextinferTriggerFromStackTrace(Throwable throwable) Infer trigger context from exception stack trace.private voidInitializes the default configuration.voidLoads configuration from the config file.private StringmapLogLevel(Level level) Maps a Java log level to the UltiPanel level vocabulary.voidvoidremoveEnabledLevel(String level) Removes an enabled log level.voidremoveExcludedLogger(String loggerName) Removes an excluded logger.voidsetEnabledLevels(Set<String> enabledLevels) Sets the panel-facing set of enabled log levels, and re-synchronises this handler's ownjava.util.logginglevel floor to match (syncHandlerLevelWithEnabledLevels()).private booleanshouldProcessRecord(LogRecord record) Checks whether this log record should be processed.private voidGate-2 finding:shouldProcessRecord(LogRecord)callsHandler.isLoggable(LogRecord)-- the baseHandler's own check againstHandler.getLevel()-- BEFORE this class's ownenabledLevelsfilter ever runs.Methods inherited from class java.util.logging.Handler
getEncoding, getErrorManager, getFilter, getFormatter, getLevel, isLoggable, reportError, setEncoding, setErrorManager, setFilter, setFormatter, setLevel
-
Field Details
-
PUBLISHING
Reentrancy guard forpublish(LogRecord)(Gate-2 finding, round 9). Loop-prevention in this class was, until now, done entirely by matching the RECORD's ownloggerNameagainst a small set of known class-name substrings (shouldProcessRecord(java.util.logging.LogRecord)below) -- but every diagnostic this framework logs through the SHARED plugin logger (UltiTools.getInstance().getLogger()) carries that shared logger's own name, not the calling class's, so the substring check can never catch any of them. Round 6/7 found and removed two individual instances of this (a transmitter diagnostic, then a WebSocket-send diagnostic); round 9 found a THIRD, in an exception handler that cannot simply be deleted (reporting a genuine send failure has real value). Rather than keep chasing individual call sites the review keeps finding new instances of, this ThreadLocal closes the whole class at its root: ifpublishis entered while ALREADY running on the SAME thread (which is exactly what happens when delivering/draining record N synchronously produces record N+1 on the same call stack -- every reachable recursion in this subsystem is same-thread, since none of the delivery/drain paths hand off to a different thread before logging), the re-entrant call is dropped instead of recursing. A single dropped self-referential diagnostic is an acceptable cost for eliminating an entire StackOverflowError defect class. -
logTransmitter
-
enabledLevels
-
excludedLoggers
-
minimumLevel
-
-
Constructor Details
-
SystemLogHandler
Constructor.- Parameters:
logTransmitter- the log transmitter
-
-
Method Details
-
initializeDefaultConfiguration
private void initializeDefaultConfiguration()Initializes the default configuration. -
setEnabledLevels
Sets the panel-facing set of enabled log levels, and re-synchronises this handler's ownjava.util.logginglevel floor to match (syncHandlerLevelWithEnabledLevels()).- Parameters:
enabledLevels- the new enabled-level set
-
syncHandlerLevelWithEnabledLevels
private void syncHandlerLevelWithEnabledLevels()Gate-2 finding:shouldProcessRecord(LogRecord)callsHandler.isLoggable(LogRecord)-- the baseHandler's own check againstHandler.getLevel()-- BEFORE this class's ownenabledLevelsfilter ever runs.Handler.getLevel()defaults toLevel.INFO(minimumLevel), which rejects JULFINE/FINER/FINESTrecords outright -- the levelsmapLogLevel(Level)maps to"debug". So a panel request enabling"debug"inenabledLevelsused to have no effect: no debug-shaped record could ever reach the mapping step that would have recognised it. Called after every mutation ofenabledLevels(the setter above,addEnabledLevel(String),removeEnabledLevel(String), andloadConfiguration()'s own direct mutation) so the handler's own floor tracks whether"debug"is currently enabled. -
loadConfiguration
public void loadConfiguration()Loads configuration from the config file. -
publish
-
shouldProcessRecord
Checks whether this log record should be processed. -
mapLogLevel
Maps a Java log level to the UltiPanel level vocabulary. -
formatLogMessage
Formats a log message. -
determineLogSource
Determines the log-source identifier. -
extractPluginName
Extracts a plugin name from a logger name. -
capitalizeFirst
Capitalizes the first letter. -
extractModuleFromSource
Extract module name from the log source string (e.g., "plugin:UltiChat" -> "UltiChat"). -
inferTriggerFromStackTrace
Infer trigger context from exception stack trace. -
addEnabledLevel
Adds an enabled log level. -
removeEnabledLevel
Removes an enabled log level. -
addExcludedLogger
Adds an excluded logger. -
removeExcludedLogger
Removes an excluded logger. -
flush
public void flush() -
close
- Specified by:
closein classHandler- Throws:
SecurityException
-
getConfigurationInfo
Gets a configuration-info string.
-