1 module log; 2 3 import std.stdio; 4 5 alias trace = log!(Level.trace); 6 alias info = log!(Level.info); 7 alias warn = log!(Level.warn); 8 alias error = log!(Level.error); 9 alias fatal = log!(Level.fatal); 10 11 template log(Level level) 12 { 13 void log(string fmt, string file = __FILE__, size_t line = __LINE__, A...)(lazy A args) 14 { 15 import std.format : format; 16 17 if (level & levels) 18 logger.log(level, file, line, format!fmt(args)); 19 } 20 } 21 22 static this() 23 { 24 logger = Logger(stderr); 25 levels = Level.info | Level.warn | Level.error | Level.fatal; 26 } 27 28 Logger logger; 29 30 struct Logger 31 { 32 private File file; 33 34 this(File file) 35 { 36 this.file = file; 37 } 38 39 void log(Level level, string file, size_t line, string message) @safe 40 { 41 import std.conv : to; 42 43 auto writer = this.file.lockingTextWriter; 44 45 writer.put(level.to!string); 46 writer.put(": "); 47 writer.put(message); 48 writer.put('\n'); 49 } 50 } 51 52 uint levels; 53 54 enum Level 55 { 56 trace = 1, // detailed tracing 57 info = 2, // useful information 58 warn = 4, // potential problem 59 error = 8, // recoverable error 60 fatal = 16, // fatal failure 61 }