-
Notifications
You must be signed in to change notification settings - Fork 1
/
README
183 lines (128 loc) · 5.73 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
Copyright (c) 2011 Seiya Tokui <[email protected]>. All Rights Reserved.
eLog is a header only logging library for C++.
This library is distributed under MIT License, which is available as the file
of name 'LICENSE'.
==============================================================================
features
- Header only library.
- Portable: it runs on both POSIX-like systems and Windows.
- Syntax like google-glog. eLog has a simpler syntax and limited methods.
- Multi-thread ready.
- Supports g++ 4.2.1+ (using GNU extension) and VC++ 2010.
- Typed and verbose logging with different verbosity for each type.
- Simple benchmark that counts and logs the time duration of processing.
==============================================================================
install
If you have python, type `[sudo] ./waf install'. It will install all headers to
/usr/local/include/elog/. Just copying elog/*.h to /usr/local/include/elog/ is
also ok.
==============================================================================
usage
You can start using eLog by including <elog/elog.h> or, if you want to use
benchmark utilities, <elog/benchmark.h>.
------------------------------------------------------------------------------
simple logging
Basic logging syntax is similar to that of the famous logging library, glog:
LOG(INFO) << "some message or value like " << 123;
operator<< of LOG(...) accepts any value that ostream accepts. There are four
levels of log: INFO, WARN, ERROR and FATAL. Especially, INFO can be omitted:
LOG() << "INFO level message";
Logger emits any level message by default. You can restrict messages by
setting level. If the default logger is the current global one, then eigher of
below changes the level of logger.
LOG::Singleton<LOG::StreamLogger>::Get().set_level(LOG::ERROR);
of
LOG::SetDefaultLoggerLevel(LOG::ERROR);
After this line is executed, messages of level INFO and WARN are ignored.
NOTE: LOG becomes a namespace of eLog when used without trailing parentheses.
LOG(...) is a variadic macro.
LOG(FATAL) is special; it throws an exception of type LOG::FatalLogError after
outputing the message. eLog currently does not have stack-trace feature like
google-glog.
LOG(...) emits messages to std::clog by default. LOG::Logger is the interface
of log emission, and global logger can be exchanged by LOG::SetLogger.
std::ostream& my_stream = ...;
LOG::Logger* my_logger = new LOG::StreamLogger(my_stream);
LOG::SetLogger(*my_logger);
SetLogger gives a reference to *my_logger to the global logger holder, so you
must keep my_logger alive while it is used as a global logger.
------------------------------------------------------------------------------
Typed and verbose logging
eLog has another syntax: typed and verbose logging.
LOG(SomeType, 1) << "typed log with verbosity 1";
The first argument, called 'message type', can be any type. Typically user-
defined class is used.
class KeyInput {}; // Message type cannot be incomplete.
...
LOG(KeyInput, 1) << "verbose log about key input";
Another typical usage is set the message type to the class of the method in
which the LOG(...) statement is written.
class Keyboard {
void Method() {
LOG(Keyboard, 0) << "verbose log from Keyboard";
}
};
The second argument is verbosity of the message. LOG(type, N) emits the message
if N is not greater than the verbosity of 'type' under the current global
logger. Default verbosity of each type is 0. You can modify verbosity of each
type. If default logger is the global one, then either of below changes the
verbosity of SomeType.
LOG::Singleton<LOG::StreamLogger>::Get().SetTypeVerbosity(
LOG::TypeInfo(LOG::Type<SomeType>()), 2);
or
LOG::SetDefaultLoggerVerbosity<SomeType>(2);
After this line is executed, LOG(SomeType, N) will emit messages only if N <= 2.
------------------------------------------------------------------------------
Assertion
eLog also has assertion syntax:
CHECK(!some_critical_condition) << "some_critical_condition occured";
It emits messages only if the operand is false, and after that it throws an
exception of type LOG::CheckError.
------------------------------------------------------------------------------
Benchmark
Benchmark utilities are useful to measure and output the time to execute code
fragment. For instance, unary BENCHMARK(...) is useful to quickly measure some
code:
BENCHMARK(bench_heavy_method) {
SomeHeavyMethod1();
SomeHeavyMethod2();
}
At the top of the clause, it outputs 'bench_heavy_method...' to the current
global logger, executes inside of braces, and outputs total execution time in
second.
In case that you want to measure many code fragments, you can use
LOG::BenchmarkSuite to bundle all results. You can outputs results to the
current global logger by calling LogChart.
LOG::BenchmarkSuite suite("my experiments");
BENCHMARK(suite, first_exp) {
...
}
...
BENCHMARK(suite, second_exp) {
...
}
...
...
BENCHMARK(suite, nth_exp) {
...
}
suite.LogChart(); // outputs results
It will emits chart of results.
BENCHMARK macro also has typed versions.
struct Keyboard {};
// Benchmark of Keyboard with verbosity 1
BENCHMARK(Keyboard, 1, bench_kb) {
...
}
LOG::BenchmarkSuite suite("keyboard bench");
BENCHMARK(suite, Keyboard, 1, bench_kb) {
...
}
------------------------------------------------------------------------------
Debug versions
There are similar macro of LOG and CHECK, named DLOG and DCHECK. These are debug
version macro. DLOG and DCHECK do nothing if NDEBUG is defined. Otherwise these
are exactly same as LOG and CHECK, respectively.
------------------------------------------------------------------------------
Other note
NOTE(g++): LOG(...) and BENCHMARK(...) uses compiler extensions.