1 // Written in the D programming language.
2 
3 /**
4 This module provides logging utilities.
5 
6 Use Log class static methods.
7 
8 Synopsis:
9 
10 ----
11 import exlib.logger;
12 
13 // setup:
14 
15 // use stderror for logging
16 setStderrLogger();
17 // set log level
18 setLogLevel(LogLeve.Debug);
19 
20 // usage:
21 
22 // log debug message
23 Log.d("mouse clicked at ", x, ",", y);
24 // log error message
25 Log.e("exception while reading file", e);
26 ----
27 
28 Copyright: Vadim Lopatin, 2014
29 License:   Boost License 1.0
30 Authors:   Vadim Lopatin, coolreader.org@gmail.com
31 */
32 module exlib.logger;
33 
34 import std.stdio;
35 import std.datetime;
36 
37 /// Log levels
38 enum LogLevel : int {
39     /// Fatal error, cannot resume
40 	Fatal,
41     /// Error
42 	Error,
43     /// Warning
44 	Warn,
45     /// Informational message
46 	Info,
47     /// Debug message
48 	Debug,
49     /// Tracing message
50 	Trace
51 }
52 
53 /// Returns timestamp in milliseconds since 1970 UTC similar to Java System.currentTimeMillis()
54 long currentTimeMillis() {
55     return std.datetime.Clock.currStdTime / 10000;
56 }
57 
58 /** 
59     
60     Logging utilities
61 
62 Setup example:
63 ----
64 // use stderror for logging
65 setStderrLogger();
66 // set log level
67 setLogLevel(LogLeve.Debug);
68 ----
69 
70 Logging example:
71 ----
72 // log debug message
73 Log.d("mouse clicked at ", x, ",", y);
74 // log error message
75 Log.e("exception while reading file", e);
76 ----
77 
78 */
79 synchronized class Log {
80     static:
81     private LogLevel logLevel = LogLevel.Info;
82     private std.stdio.File logFile;
83         
84     /// Redirects output to stdout
85     void setStdoutLogger() {
86         logFile = stdout;
87     }
88 
89     /// Redirects output to stderr
90     void setStderrLogger() {
91         logFile = stderr;
92     }
93 
94     /// Redirects output to file
95     void setFileLogger(File file) {
96         logFile = file;
97     }
98 
99     /// Sets log level (one of LogLevel)
100     void setLogLevel(LogLevel level) {
101         logLevel = level;
102     }
103 
104     /// Log level to name helper function
105     string logLevelName(LogLevel level) {
106         switch (level) {
107             case LogLevel.Fatal: return "F";
108             case LogLevel.Error: return "E";
109             case LogLevel.Warn: return "W";
110             case LogLevel.Info: return "I";
111             case LogLevel.Debug: return "D";
112             case LogLevel.Trace: return "V";
113             default: return "?";
114         }
115     }
116     /// Log message with arbitrary log level
117     void log(S...)(LogLevel level, S args) {
118         if (logLevel >= level && logFile.isOpen) {
119             SysTime ts = Clock.currTime();
120             logFile.writef("%04d-%02d-%02d %02d:%02d:%02d.%03d %s  ", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second, ts.fracSec.msecs, logLevelName(level));
121             logFile.writeln(args);
122             logFile.flush();
123         }
124     }
125     /// Log verbose / trace message
126     void v(S...)(S args) {
127         if (logLevel >= LogLevel.Trace && logFile.isOpen)
128             log(LogLevel.Trace, args);
129     }
130     /// Log debug message
131     void d(S...)(S args) {
132         if (logLevel >= LogLevel.Debug && logFile.isOpen)
133             log(LogLevel.Debug, args);
134     }
135     /// Log info message
136     void i(S...)(S args) {
137         if (logLevel >= LogLevel.Info && logFile.isOpen)
138             log(LogLevel.Info, args);
139     }
140     /// Log warn message
141     void w(S...)(S args) {
142         if (logLevel >= LogLevel.Warn && logFile.isOpen)
143             log(LogLevel.Warn, args);
144     }
145     /// Log error message
146     void e(S...)(S args) {
147         if (logLevel >= LogLevel.Error && logFile.isOpen)
148             log(LogLevel.Error, args);
149     }
150     /// Log fatal error message
151     void f(S...)(S args) {
152         if (logLevel >= LogLevel.Fatal && logFile.isOpen)
153             log(LogLevel.Fatal, args);
154     }
155 }