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 }