diff --git a/sources/Core/Logger/LoggerAPI.uc b/sources/Core/Logger/LoggerAPI.uc new file mode 100644 index 0000000..8b2f5d8 --- /dev/null +++ b/sources/Core/Logger/LoggerAPI.uc @@ -0,0 +1,92 @@ +/** + * API that provides functions quick access to Acedia's + * logging functionality. + * Copyright 2020 Anton Tarasenko + *------------------------------------------------------------------------------ + * This file is part of Acedia. + * + * Acedia is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License, or + * (at your option) any later version. + * + * Acedia is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Acedia. If not, see . + */ +class LoggerAPI extends Singleton; + +var private LoggerService logService; + +protected function OnCreated() +{ + logService = LoggerService(class'LoggerService'.static.Require()); +} + +public final function Track(string message) +{ + if (logService == none) + { + class'LoggerService'.static.LogMessageToKFLog(LOG_Track, message); + return; + } + logService.LogMessage(LOG_Track, message); +} + +public final function Debug(string message) +{ + if (logService == none) + { + class'LoggerService'.static.LogMessageToKFLog(LOG_Debug, message); + return; + } + logService.LogMessage(LOG_Debug, message); +} + +public final function Info(string message) +{ + if (logService == none) + { + class'LoggerService'.static.LogMessageToKFLog(LOG_Info, message); + return; + } + logService.LogMessage(LOG_Info, message); +} + +public final function Warning(string message) +{ + if (logService == none) + { + class'LoggerService'.static.LogMessageToKFLog(LOG_Warning, message); + return; + } + logService.LogMessage(LOG_Warning, message); +} + +public final function Failure(string message) +{ + if (logService == none) + { + class'LoggerService'.static.LogMessageToKFLog(LOG_Failure, message); + return; + } + logService.LogMessage(LOG_Failure, message); +} + +public final function Fatal(string message) +{ + if (logService == none) + { + class'LoggerService'.static.LogMessageToKFLog(LOG_Fatal, message); + return; + } + logService.LogMessage(LOG_Fatal, message); +} + +defaultproperties +{ +} \ No newline at end of file diff --git a/sources/Core/Logger/LoggerService.uc b/sources/Core/Logger/LoggerService.uc new file mode 100644 index 0000000..3dd8d85 --- /dev/null +++ b/sources/Core/Logger/LoggerService.uc @@ -0,0 +1,166 @@ +/** + * Logger that allows to separate log messages into several levels of + * significance and lets users and admins to access only the ones they want + * and/or receive notifications when they happen. + * Copyright 2020 Anton Tarasenko + *------------------------------------------------------------------------------ + * This file is part of Acedia. + * + * Acedia is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License, or + * (at your option) any later version. + * + * Acedia is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Acedia. If not, see . + */ +class LoggerService extends Service + config(AcediaLogger); + +// Log levels, available in Acedia. +enum LogLevel +{ + // For the purposes of "tracing" the code, when trying to figure out + // where exactly problems occurred. + // Should not be used in any released version of + // your packages/mutators. + LOG_Track, + // Information that can be used to track down errors that occur on + // other people's systems, that developer cannot otherwise pinpoint. + // Should be used with purpose of tracking a certain issue and + // not "just in case". + LOG_Debug, + // Information about important events that should be occurring under + // normal conditions, such as initializations/shutdowns, + // successful completion of significant events, configuration assumptions. + // Should not occur too often. + LOG_Info, + // For recoverable issues, anything that might cause errors or + // oddities in behavior. + // Should be used sparingly, i.e. player disconnecting might cause + // interruption in some logic, but should not cause a warning, + // since it is something expected to happen normally. + LOG_Warning, + // Use this for errors, - events that some operation cannot recover from, + // but still does not require your module to shut down. + LOG_Failure, + // Anything that does not allow your module or game to function, + // completely irrecoverable failure state. + LOG_Fatal +}; + +var private const string kfLogPrefix; +var private const string traceLevelName; +var private const string DebugLevelName; +var private const string infoLevelName; +var private const string warningLevelName; +var private const string errorLevelName; +var private const string fatalLevelName; + +var private config array< class > registeredManifests; +var private config bool logTraceInKFLog; +var private config bool logDebugInKFLog; +var private config bool logInfoInKFLog; +var private config bool logWarningInKFLog; +var private config bool logErrorInKFLog; +var private config bool logFatalInKFLog; + +var private array traceMessages; +var private array debugMessages; +var private array infoMessages; +var private array warningMessages; +var private array errorMessages; +var private array fatalMessages; + +public final function bool ShouldAddToKFLog(LogLevel messageLevel) +{ + if (messageLevel == LOG_Trace && logTraceInKFLog) return true; + if (messageLevel == LOG_Debug && logDebugInKFLog) return true; + if (messageLevel == LOG_Info && logInfoInKFLog) return true; + if (messageLevel == LOG_Warning && logWarningInKFLog) return true; + if (messageLevel == LOG_Error && logErrorInKFLog) return true; + if (messageLevel == LOG_Fatal && logFatalInKFLog) return true; + return false; +} + +public final static function LogMessageToKFLog +( + LogLevel messageLevel, + string message +) +{ + local string levelPrefix; + levelPrefix = default.kfLogPrefix; + switch (messageLevel) + { + case LOG_Trace: + levelPrefix = levelPrefix $ default.traceLevelName; + break; + case LOG_Debug: + levelPrefix = levelPrefix $ default.debugLevelName; + break; + case LOG_Info: + levelPrefix = levelPrefix $ default.infoLevelName; + break; + case LOG_Warning: + levelPrefix = levelPrefix $ default.warningLevelName; + break; + case LOG_Error: + levelPrefix = levelPrefix $ default.errorLevelName; + break; + case LOG_Fatal: + levelPrefix = levelPrefix $ default.fatalLevelName; + break; + default: + } + Log(levelPrefix @ message); +} + +public final function LogMessage(LogLevel messageLevel, string message) +{ + switch (messageLevel) + { + case LOG_Trace: + traceMessages[traceMessages.length] = message; + case LOG_Debug: + debugMessages[debugMessages.length] = message; + case LOG_Info: + infoMessages[infoMessages.length] = message; + case LOG_Warning: + warningMessages[warningMessages.length] = message; + case LOG_Error: + errorMessages[errorMessages.length] = message; + case LOG_Fatal: + fatalMessages[fatalMessages.length] = message; + default: + } + if (ShouldAddToKFLog(messageLevel)) + { + LogMessageToKFLog(messageLevel, message); + } +} + +defaultproperties +{ + // Log everything by default, if someone does not like it - + // he/she can disable it themselves. + logTraceInKFLog = true + logDebugInKFLog = true + logInfoInKFLog = true + logWarningInKFLog = true + logErrorInKFLog = true + logFatalInKFLog = true + // Parts of the prefix for our log messages, redirected into kf log file. + kfLogPrefix = "Acedia:" + traceLevelName = "Trace" + debugLevelName = "Debug" + infoLevelName = "Info" + warningLevelName = "Warning" + errorLevelName = "Error" + fatalLevelName = "Fatal" +} \ No newline at end of file