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