1 /** 2 * Defines some basic message 3 * types, filters and handlers 4 * that may be of use in 5 * some combination or 6 * seperate 7 * 8 * Authors: Tristan Brice Velloza Kildaire (deavmi) 9 */ 10 module dlog.basic; 11 12 import dlog.core; 13 import std.stdio : File; 14 15 /** 16 * Represents a basic message 17 * with log level information 18 * associated with it as well 19 * as text 20 */ 21 public class BasicMessage : Message 22 { 23 /** 24 * The text message 25 */ 26 private string text; 27 28 /** 29 * Log level 30 */ 31 private Level level; 32 33 /** 34 * Constructs a new `BasicMessage` 35 * with the given text and log level 36 * 37 * Params: 38 * text = the message text 39 * level = the log level (default 40 * is `Level.INFO`) 41 */ 42 this(string text, Level level = Level.INFO) 43 { 44 this.text = text; 45 this.level = level; 46 } 47 48 /** 49 * Constructs an empty message 50 * with the highest log level 51 * (least verbose) 52 */ 53 this() 54 { 55 56 } 57 58 /** 59 * Sets the text 60 * 61 * Params: 62 * text = the message's 63 * text 64 */ 65 public void setText(string text) 66 { 67 this.text = text; 68 } 69 70 /** 71 * Returns the text 72 * 73 * Returns: the text 74 */ 75 public string getText() 76 { 77 return this.text; 78 } 79 80 /** 81 * Returns the log level 82 * 83 * Returns: the level 84 */ 85 public Level getLevel() 86 { 87 return this.level; 88 } 89 90 /** 91 * Sets the log level 92 * 93 * Params: 94 * level = the level 95 */ 96 public void setLevel(Level level) 97 { 98 this.level = level; 99 } 100 } 101 102 /** 103 * A file-based handler which 104 * writes `BasicMessage`(s) 105 * to a provided file 106 */ 107 public class FileHandler : Handler 108 { 109 /** 110 * File to write to 111 */ 112 private File file; 113 114 /** 115 * Constrtucts a new 116 * `FileHandler` with 117 * the given file 118 * 119 * Params: 120 * file = the file 121 */ 122 this(File file) 123 { 124 this.file = file; 125 } 126 127 /** 128 * Handles the message, does a 129 * no-op if the message is 130 * not a kind-of `BasicMessage` 131 * 132 * Params: 133 * message = the message 134 */ 135 public void handle(Message message) 136 { 137 // Only handle BasicMessage(s) 138 BasicMessage bmesg = cast(BasicMessage)message; 139 if(bmesg) 140 { 141 file.write(bmesg.getText()); 142 } 143 } 144 } 145 146 /** 147 * Logging level 148 */ 149 public enum Level 150 { 151 /** 152 * Error message 153 */ 154 ERROR, 155 156 /** 157 * Informative message 158 */ 159 INFO, 160 161 /** 162 * Warning message 163 */ 164 WARN, 165 166 /** 167 * Debugging message 168 */ 169 DEBUG 170 } 171 172 /** 173 * A level-based filter which 174 * has a predicate which operates 175 * on the value of a pointed-to 176 * `Level` variable 177 */ 178 private class LevelFilter : Filter 179 { 180 /** 181 * Address of the level var 182 */ 183 private Level* level; 184 185 /** 186 * Constructs a new `LevelFilter` 187 * with the given `Level*` 188 * 189 * Params: 190 * level = the level address 191 */ 192 this(Level* level) 193 { 194 this.level = level; 195 } 196 197 /** 198 * Filters the given message according 199 * to the current level. This will no-op 200 * and always return `true` if the message 201 * is not a kind-of `BasicMessage` 202 * 203 * Params: 204 * message = the message 205 * Returns: the verdict 206 */ 207 public bool filter(Message message) 208 { 209 // Only handle BasicMessage(s) 210 BasicMessage bmesg = cast(BasicMessage)message; 211 if(bmesg) 212 { 213 return bmesg.getLevel() <= *this.level; 214 } 215 216 return true; 217 } 218 } 219 220 /** 221 * A basic logger which has support 222 * for log levels 223 */ 224 public class BasicLogger : Logger 225 { 226 /** 227 * The current log level 228 */ 229 private Level level; 230 231 /** 232 * Constructs a new `BasicLogger` 233 */ 234 this() 235 { 236 // Attach a new level-filter 237 // with access to our current 238 // level 239 addFilter(new LevelFilter(&level)); 240 } 241 242 /** 243 * Sets the log level 244 * 245 * Params: 246 * level = the new 247 * level 248 */ 249 public final void setLevel(Level level) 250 { 251 this.level = level; 252 } 253 254 /** 255 * Obtains the current log 256 * level 257 * 258 * Returns: the current level 259 */ 260 public final Level getLevel() 261 { 262 return this.level; 263 } 264 }