1 /** 2 * Logger module. 3 * 4 * License: 5 * MIT. See LICENSE for full details. 6 */ 7 module tkd.interpreter.logger; 8 9 /** 10 * Imports. 11 */ 12 import std.datetime; 13 import std.process; 14 import std.stdio; 15 import std.string; 16 17 /** 18 * A simple class to provide logging support. 19 */ 20 class Logger 21 { 22 /** 23 * Level of importance of the text to write to the logger. 24 */ 25 private enum Level 26 { 27 /** 28 * The eval level is for evaluated commands. 29 */ 30 eval, 31 32 /** 33 * The information level used for info messages. 34 */ 35 information, 36 37 /** 38 * The warning level used for warning messages. 39 */ 40 warning, 41 42 /** 43 * The error level used for error messages. 44 */ 45 error, 46 } 47 48 /** 49 * The open log file. 50 */ 51 private File _log; 52 53 /** 54 * Constructor. 55 * 56 * If a log file is not passed, log instead to stdout. 57 * 58 * Params: 59 * logFile = The log file for logging. 60 */ 61 final public this(string logFile = null) nothrow 62 { 63 try 64 { 65 if (logFile is null) 66 { 67 this._log = stdout; 68 } 69 else 70 { 71 this._log = File(logFile, "w"); 72 } 73 } 74 catch (Exception ex) 75 { 76 assert(false, ex.msg); 77 } 78 } 79 80 /** 81 * Get the current timestamp for the log. 82 * 83 * Returns: 84 * The current timestamp. 85 */ 86 final private string getTimestamp() nothrow 87 { 88 try 89 { 90 auto time = Clock.currTime(); 91 return format("%d/%02d/%02d %d:%02d:%02d", time.year, time.month, time.day, time.hour, time.minute, time.second); 92 } 93 catch (Exception ex) 94 { 95 assert(false, ex.msg); 96 } 97 } 98 99 /** 100 * Write text to the log. 101 * 102 * Params: 103 * text = The text to write to the log. 104 * level = The level of the text. 105 */ 106 final private void log(A...)(Level level, string text, A args) nothrow 107 { 108 string levelText; 109 110 switch(level) 111 { 112 case Level.eval: 113 levelText = "EVAL"; 114 break; 115 116 case Level.warning: 117 levelText = "WARN"; 118 break; 119 120 case Level.error: 121 levelText = "ERROR"; 122 break; 123 124 default: 125 levelText = "INFO"; 126 break; 127 } 128 129 try 130 { 131 static if (A.length) 132 { 133 text = format(text, args); 134 } 135 136 this._log.writefln("%s %s: %s", this.getTimestamp(), levelText, text); 137 this._log.flush(); 138 } 139 catch (Exception ex) 140 { 141 assert(false, ex.msg); 142 } 143 } 144 145 /** 146 * Write eval text to the log. 147 * 148 * Params: 149 * text = The format of the text to write to the log. 150 * args = The arguments that the format defines (if any). 151 */ 152 final public void eval(A...)(string text, A args) nothrow 153 { 154 this.log(Level.eval, text, args); 155 } 156 157 /** 158 * Write info text to the log. 159 * 160 * Params: 161 * text = The format of the text to write to the log. 162 * args = The arguments that the format defines (if any). 163 */ 164 final public void info(A...)(string text, A args) nothrow 165 { 166 this.log(Level.information, text, args); 167 } 168 169 /** 170 * Write warning text to the log. 171 * 172 * Params: 173 * text = The format of the text to write to the log. 174 * args = The arguments that the format defines (if any). 175 */ 176 final public void warning(A...)(string text, A args) nothrow 177 { 178 this.log(Level.warning, text, args); 179 } 180 181 /** 182 * Write error text to the log. 183 * 184 * Params: 185 * text = The format of the text to write to the log. 186 * args = The arguments that the format defines (if any). 187 */ 188 final public void error(A...)(string text, A args) nothrow 189 { 190 this.log(Level.error, text, args); 191 } 192 193 }