1 /** 2 * Copyright: Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved 3 * Authors: $(Gabriel Gheorghe) 4 * License: $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007) 5 * Source: $(LINK2 https://github.com/GabyForceQ/LibertyEngine/blob/master/source/liberty/logger/impl.d) 6 * Documentation: 7 * Coverage: 8 * 9 * TODO: 10 * - Add 'current platform' on log message. 11 **/ 12 module liberty.logger.impl; 13 14 import std.stdio : writeln, File; 15 import std.datetime.systime : SysTime, Clock; 16 import std.array : split; 17 18 import liberty.core.engine; 19 import liberty.logger.constants; 20 21 /** 22 * Logger class is used for logging a message. 23 * You can log a message to the system console or to a file: "logs.txt". 24 * You can change the log file name. 25 * You can activate or deactivate logger any time. 26 **/ 27 final abstract class Logger { 28 private { 29 static File logFile; 30 31 version (Win32) 32 static string platformName = " [Win_x86]"; 33 else version (Win64) 34 static string platformName = " [Win_x64]"; 35 } 36 37 /** 38 * 39 **/ 40 static void initialize() { 41 logFile = File(logFileName, "a"); 42 } 43 44 /** 45 * 46 **/ 47 static void deinitialize() { 48 logFile.close(); 49 } 50 51 /** 52 * Set false if you don't want logger to run. 53 **/ 54 static bool isActive = true; 55 56 /** 57 * Log file name. 58 **/ 59 static string logFileName = "logs.txt"; 60 61 /** 62 * Log an information message. 63 * It starts with the current time + " -> LOG_INFO: " 64 * Params: 65 * message = the information message 66 * obj = current class reference, mostly you pass 'this' 67 **/ 68 static void info(string message, string objectName, bool onlyToConsole = false) { 69 log(LogType.Info, objectName ~ " -> " ~ message, onlyToConsole); 70 } 71 72 /** 73 * Log a warning message. 74 * It starts with the current time + " -> LOG_WARNING: " 75 * Params: 76 * message = the warning message 77 * obj = current class reference, mostly you pass 'this' 78 **/ 79 static void warning(string message, string objectName, bool onlyToConsole = false) { 80 log(LogType.Warning, objectName ~ " -> " ~ message, onlyToConsole); 81 } 82 83 /** 84 * Log an error message. 85 * The type of the error is fatal so the program will exit with a status code of 1. 86 * It starts with the current time + " -> LOG_ERROR: " 87 * Params: 88 * message = the error message 89 * obj = current class reference, mostly you pass 'this' 90 **/ 91 static void error(string message, string objectName, bool onlyToConsole = false) { 92 log(LogType.Error, objectName ~ " -> " ~ message, onlyToConsole); 93 version (unittest) {} 94 else 95 CoreEngine.forceShutDown(true); 96 } 97 98 /** 99 * Log an exception message. 100 * It starts with the current time + " -> LOG_EXCEPTION: " 101 * Params: 102 * message = the exception message 103 **/ 104 static void exception(string message, bool onlyToConsole = false) { 105 log(LogType.Exception, message, onlyToConsole); 106 } 107 108 /** 109 * Log a debug information message. 110 * It starts with the current time + " -> LOG_DEBUG: " 111 * Only works in debug mode. 112 * Params: 113 * message = the debug information message 114 * obj = current class reference, mostly you pass 'this' 115 **/ 116 static void console(string message, string objectName, bool onlyToConsole = false) { 117 log(LogType.Debug, objectName ~ " -> " ~ message, onlyToConsole); 118 } 119 120 /** 121 * Log a todo message. 122 * It starts with the current time + " -> LOG_TODO: " 123 * Params: 124 * message = the todo message 125 * obj = current class reference, mostly you pass 'this' 126 **/ 127 static void todo(string message, string objectName, bool onlyToConsole = false) { 128 log(LogType.Todo, objectName ~ " -> " ~ message, onlyToConsole); 129 } 130 131 /** 132 * Log a message using LogType. 133 **/ 134 static void log(LogType type, string message, bool onlyToConsole = false) { 135 if (isActive) { 136 string currentTime = Clock.currTime().toString().split(".")[0] ~ platformName; 137 final switch (type) with (LogType) { 138 case Info: 139 debug writeln(currentTime ~ " -> LOG_INFO: " ~ message); 140 if (!onlyToConsole) 141 logFile.writeln(currentTime ~ " -> LOG_INFO: " ~ message); 142 break; 143 case Warning: 144 debug writeln(currentTime ~ " -> LOG_WARNING: " ~ message); 145 if (!onlyToConsole) 146 logFile.writeln(currentTime ~ " -> LOG_WARNING: " ~ message); 147 break; 148 case Error: 149 debug writeln(currentTime ~ " -> LOG_ERROR: " ~ message); 150 if (!onlyToConsole) 151 logFile.writeln(currentTime ~ " -> LOG_ERROR: " ~ message); 152 break; 153 case Exception: 154 debug writeln(currentTime ~ " -> LOG_EXCEPTION: " ~ message); 155 if (!onlyToConsole) 156 logFile.writeln(currentTime ~ " -> LOG_EXCEPTION: " ~ message); 157 break; 158 case Debug: 159 debug writeln(currentTime ~ " -> LOG_DEBUG: " ~ message); 160 if (!onlyToConsole) 161 debug logFile.writeln(currentTime ~ " -> LOG_DEBUG: " ~ message); 162 break; 163 case Todo: 164 debug writeln(currentTime ~ " -> LOG_TODO: " ~ message); 165 if (!onlyToConsole) 166 logFile.writeln(currentTime ~ " -> LOG_TODO: " ~ message); 167 break; 168 } 169 } 170 } 171 } 172 173 /** 174 * Example for Logger usage: 175 **/ 176 unittest { 177 class LogClass { 178 this() { 179 Logger.initialize(); 180 scope(exit) Logger.deinitialize(); 181 Logger.console("Test message!", typeof(this).stringof); 182 Logger.info("Info test message!", typeof(this).stringof); 183 Logger.warning("Warning test message!", typeof(this).stringof); 184 Logger.error("Error test message!", typeof(this).stringof); 185 try { 186 immutable int x = 5; 187 if (x == 5) 188 throw new Exception("x cannot be 5!"); 189 } catch (Exception e) { 190 Logger.exception("Exception test message!"); 191 } 192 Logger.todo("Todo test message!", typeof(this).stringof); 193 } 194 } 195 196 new LogClass(); 197 }