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 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 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 private void log(string text, Level level) 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 this._log.writefln("%s %s: %s", this.getTimestamp(), levelText, text); 132 this._log.flush(); 133 } 134 catch (Exception ex) 135 { 136 assert(false, ex.msg); 137 } 138 } 139 140 /** 141 * Write eval text to the log. 142 * 143 * Params: 144 * text = The format of the text to write to the log. 145 * args = The arguments that the format defines (if any). 146 */ 147 public void eval(A...)(string text, A args) nothrow 148 { 149 try 150 { 151 this.log(format(text, args), Level.eval); 152 } 153 catch (Exception ex) 154 { 155 assert(false, ex.msg); 156 } 157 } 158 159 /** 160 * Write info text to the log. 161 * 162 * Params: 163 * text = The format of the text to write to the log. 164 * args = The arguments that the format defines (if any). 165 */ 166 public void info(A...)(string text, A args) nothrow 167 { 168 try 169 { 170 this.log(format(text, args), Level.information); 171 } 172 catch (Exception ex) 173 { 174 assert(false, ex.msg); 175 } 176 } 177 178 /** 179 * Write warning text to the log. 180 * 181 * Params: 182 * text = The format of the text to write to the log. 183 * args = The arguments that the format defines (if any). 184 */ 185 public void warning(A...)(string text, A args) nothrow 186 { 187 try 188 { 189 this.log(format(text, args), Level.warning); 190 } 191 catch (Exception ex) 192 { 193 assert(false, ex.msg); 194 } 195 } 196 197 /** 198 * Write error text to the log. 199 * 200 * Params: 201 * text = The format of the text to write to the log. 202 * args = The arguments that the format defines (if any). 203 */ 204 public void error(A...)(string text, A args) nothrow 205 { 206 try 207 { 208 this.log(format(text, args), Level.error); 209 } 210 catch (Exception ex) 211 { 212 assert(false, ex.msg); 213 } 214 } 215 216 }