1 module re.util.logger; 2 3 import std.stdio; 4 import std.format; 5 import std.conv; 6 import std.datetime; 7 import datefmt; 8 import colorize; 9 10 /// a utility class for displaying diagnostic messages 11 class Logger { 12 /// how verbose the messages are 13 enum Verbosity { 14 Trace = 4, 15 Information = 3, 16 Warning = 2, 17 Error = 1, 18 Critical = 0 19 } 20 21 /// maximum message verbosity 22 public Verbosity verbosity; 23 /// message output targets 24 public ILogSink[] sinks; 25 26 /** 27 initialize a logger with a given verbosity 28 */ 29 this(Verbosity verbosity) { 30 this.verbosity = verbosity; 31 } 32 33 /// writes a message 34 public void write_line(string log, Verbosity level) { 35 if (level <= verbosity) { 36 foreach (sink; sinks) { 37 sink.write_line(log, level); 38 } 39 } 40 } 41 42 /// writes a message at TRACE verbosity 43 public void trace(string log) { 44 write_line(log, Verbosity.Trace); 45 } 46 47 /// writes a message at INFO verbosity 48 public void info(string log) { 49 write_line(log, Verbosity.Information); 50 } 51 52 /// writes a message at WARNING verbosity 53 public void warn(string log) { 54 write_line(log, Verbosity.Warning); 55 } 56 57 /// writes a message at ERROR verbosity 58 public void err(string log) { 59 write_line(log, Verbosity.Error); 60 } 61 62 /// writes a message at CRITICAL verbosity 63 public void crit(string log) { 64 write_line(log, Verbosity.Critical); 65 } 66 67 private static string shortVerbosity(Verbosity level) { 68 switch (level) { 69 case Verbosity.Trace: 70 return "trce"; 71 case Verbosity.Information: 72 return "info"; 73 case Verbosity.Warning: 74 return "warn"; 75 case Verbosity.Error: 76 return "err!"; 77 case Verbosity.Critical: 78 return "crit"; 79 default: 80 return to!string(level); 81 } 82 } 83 84 private static string formatMeta(Verbosity level) { 85 auto time = Clock.currTime(); 86 return format("[%s/:%s]", shortVerbosity(level), time.format("%H:%M:%S")); 87 } 88 89 /// a sink that accepts log messages 90 public interface ILogSink { 91 /// writes a message to the sink 92 void write_line(string log, Verbosity level); 93 } 94 95 /// a sink that outputs to the console 96 public static class ConsoleSink : ILogSink { 97 public void write_line(string log, Verbosity level) { 98 auto col = colorFor(level); 99 colorize.cwritef(formatMeta(level).color(col, colorize.bg.black)); 100 colorize.cwritefln(" %s", log); 101 } 102 103 private colorize.fg colorFor(Verbosity level) { 104 switch (level) { 105 case Verbosity.Trace: 106 return colorize.fg.light_black; 107 case Verbosity.Information: 108 return colorize.fg.green; 109 case Verbosity.Warning: 110 return colorize.fg.yellow; 111 case Verbosity.Error: 112 return colorize.fg.light_red; 113 case Verbosity.Critical: 114 return colorize.fg.red; 115 default: 116 return colorize.fg.white; 117 } 118 } 119 } 120 121 /// a sink that outputs to a file 122 public static class FileSink : ILogSink { 123 public string path; 124 private File of; 125 126 this(string path) { 127 this.path = path; 128 this.of = File(path, "a"); 129 } 130 131 public void write_line(string log, Verbosity level) { 132 of.write(formatMeta(level)); 133 of.writeln(" {log}"); 134 of.flush(); 135 } 136 } 137 }