1 module s2.util.log.logger;
2 
3 import std.stdio;
4 import core.vararg;
5 
6 /**
7  * The log level is used to control which log statements should result in output.
8  * Log levels are presumed to be inclusive, that is, ERROR implies FATAL and WARN
9  * implies ERROR, FATAL, etc.
10  */
11 enum LogLevel {
12   /// No events are recorded.
13   OFF,
14   // Very severe error events that will presumably cause the application to abort.
15   FATAL,
16   /// Error events that may still allow the application to continue running.
17   ERROR,
18   /// Events that indicate a potentially harmful situation.
19   WARN,
20   /// Informational messages that highlight the progress of the application at a coarse level.
21   INFO,
22   /// Fine grain informational events useful for debugging.
23   DEBUG,
24   /// Finer grain information than DEBUG.
25   TRACE
26 }
27 
28 class Logger(LogLevel LogLevelV = LogLevel.DEBUG) {
29 public:
30 
31   // TODO: Add the optional ability to write to a file.
32   this() {
33   }
34 
35   static void log(LogLevel logLevel = LogLevel.DEBUG, T...)(lazy T args) {
36     static if (logLevel <= LogLevelV) {
37       writeln(args);
38     }
39   }
40 
41   static void logFatal(T...)(lazy T args) {
42     log!(LogLevel.FATAL)(args);
43   }
44 
45   static void logError(T...)(lazy T args) {
46     log!(LogLevel.ERROR)(args);
47   }
48 
49   static void logWarn(T...)(lazy T args) {
50     log!(LogLevel.WARN)(args);
51   }
52 
53   static void logDebug(T...)(lazy T args) {
54     log!(LogLevel.DEBUG)(args);
55   }
56 
57   static void logInfo(T...)(lazy T args) {
58     log!(LogLevel.INFO)(args);
59   }
60 
61   static void logTrace(T...)(lazy T args) {
62     log!(LogLevel.TRACE)(args);
63   }
64 
65   static void logf(LogLevel logLevel = LogLevel.DEBUG, T...)(string fmt, lazy T args) {
66     static if (logLevel <= LogLevelV) {
67       writefln(fmt, args);
68     }
69   }
70 
71   static void logfFatal(T...)(lazy T args) {
72     logf!(LogLevel.FATAL)(args);
73   }
74 
75   static void logfError(T...)(lazy T args) {
76     logf!(LogLevel.ERROR)(args);
77   }
78 
79   static void logfWarn(T...)(lazy T args) {
80     logf!(LogLevel.WARN)(args);
81   }
82 
83   static void logfInfo(T...)(lazy T args) {
84     logf!(LogLevel.INFO)(args);
85   }
86 
87   static void logfDebug(T...)(lazy T args) {
88     logf!(LogLevel.DEBUG)(args);
89   }
90 
91   static void logfTrace(T...)(lazy T args) {
92     logf!(LogLevel.TRACE)(args);
93   }
94 
95 }
96 
97 unittest {
98   auto logger = new Logger!(LogLevel.DEBUG)();
99 
100   logger.log(typeid(logger));
101   int i = 0;
102   logger.logError("Hello error.", i++);
103   assert(i == 1);
104   logger.logDebug("Hello debug.", i++);
105   assert(i == 2);
106   logger.logTrace("Hello trace.", i++);
107   assert(i == 2);
108 }
109 
110 unittest {
111   auto logger = new Logger!(LogLevel.ERROR)();
112 
113   logger.log(typeid(logger));
114   int i = 0;
115   logger.logFatal("Hello fatal.", i++);
116   assert(i == 1);
117   logger.logError("Hello error.", i++);
118   assert(i == 2);
119   logger.logDebug("Hello debug.", i++);
120   assert(i == 2);
121 }
122 
123 unittest {
124   auto logger = new Logger!(LogLevel.OFF)();
125 
126   logger.log(typeid(logger));
127   int i = 0;
128   logger.logFatal("Hello fatal.", i++);
129   assert(i == 0);
130   logger.logError("Hello error.", i++);
131   assert(i == 0);
132   logger.logDebug("Hello debug.", i++);
133   assert(i == 0);
134 }