Introduction
One night when I could not sleep, I was thinking about that I really needed a
small utility for logging. It should be easy to use,
nothing more than an #include "AMLog.h"
in
StdAfx.h. I also wanted it to be able to log line-numbers and filenames, so it
needed to be done with macro's, and not functions, because I didn't want to
write __FILE__
and __LINE__
every time I called a
logging function. I also wanted different log-levels, that could be changed by
the user. I make a lot of server applications, and if a client has a problem
with one of my applications, I just tell him to set the log-level to "Developer
Log", and send me the log-file. One last thing I really really wanted
was to be able to log using printf
-style.
All the logging functions supports this, so you can write an log-entry like this:
AMLOGINFO("The value of i is: %d, and s is: %s", i, s)
It also works with UNICODE, because I do a lot of work with Unicode enabled
applications. The logging functions are thread-safe.
All logging is synchronized through a Critical Section, so
it's completely safe to use in multithreaded applications.
How To Use
AMLog is actually easy to use. Just #include "AMLog.h"
in StdAfx.h, and call
AMLOG_SETFILENAME("test.log")
, and you are
ready to go. The AMLOG_SETFILENAME
macro just needs a filename,
then it append the complete path where the executable file is.
Default there is no logging done. AMLog supports four different
log-levels that you can shift between by runtime:
Nothing
, Error
, Info
and DeveloperInfo
.
There are 3 different macro's you can use to log stuff
to the log-file: AMLOGINFO
, AMLOGERROR
and AMLOGDEVINFO
.
AMLOGERROR
always writes to the log file if log level is different from
Nothing
. AMLOGINFO
only writes to the log if log level is
Info
or DeveloperInfo
.
AMLOGDEVINFO
only writes to the log if log-level is DeveloperInfo
.
You can use the following macro's to set the loglevel, AMLOG_SETLOGLEVEL_NOTHING,
AMLOG_SETLOGLEVEL_ERROR, AMLOG_SETLOGLEVEL_INFO, AMLOG_SETLOGLEVEL_DEVELOPERINFO
.
Just write AMLOG_SETLOGLEVEL_ERROR;
if you just want to log errors.
If you want the stuff you log also to go to the debuggers "out" window,
like TRACE()
statements do, you just have to define #define AMLOG_TRACE
in StdAfx.h, before you include AmLog.h.
You can also get the output written to stdout
,
if you make console applications, just define #define AMLOG_STDOUT
.
The Log Format
The log format is pretty basic,
it converts all CRLF pairs to a "|" to keep
each log entry on a single line. If log-level is
DeveloperInfo
, source filenames and line numbers are added to the log file
for making debugging more easy. Here is the output from the
test program included with the source.
Note that the output below has been wrapped to prevent scrolling. The
actual output will not wrap.
2002-05-14 21:39:08 Error "i" is now: 0, Loglevel is: Error
2002-05-14 21:39:08 Error "i" is now: 1, Loglevel is: Error
2002-05-14 21:39:08 Error "i" is now: 2, Loglevel is: Error
2002-05-14 21:39:08 Error "i" is now: 3, Loglevel is: Error
2002-05-14 21:39:08 Error "i" is now: 4, Loglevel is: Error
2002-05-14 21:39:08 Info "i" is now: 0, Loglevel is: Info
2002-05-14 21:39:08 Error "i" is now: 0, Loglevel is: Info
2002-05-14 21:39:08 Info "i" is now: 1, Loglevel is: Info
2002-05-14 21:39:08 Error "i" is now: 1, Loglevel is: Info
2002-05-14 21:39:08 Info "i" is now: 2, Loglevel is: Info
2002-05-14 21:39:08 Error "i" is now: 2, Loglevel is: Info
2002-05-14 21:39:08 Info "i" is now: 3, Loglevel is: Info
2002-05-14 21:39:08 Error "i" is now: 3, Loglevel is: Info
2002-05-14 21:39:08 Info "i" is now: 4, Loglevel is: Info
2002-05-14 21:39:08 Error "i" is now: 4, Loglevel is: Info
2002-05-14 21:39:08 Info amlogtestapp.cpp, 10
"i" is now: 0, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 Error amlogtestapp.cpp, 11
"i" is now: 0, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 DevInfo amlogtestapp.cpp, 12
"i" is now: 0, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 Info amlogtestapp.cpp, 10
"i" is now: 1, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 Error amlogtestapp.cpp, 11
"i" is now: 1, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 DevInfo amlogtestapp.cpp, 12
"i" is now: 1, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 Info amlogtestapp.cpp, 10
"i" is now: 2, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 Error amlogtestapp.cpp, 11
"i" is now: 2, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 DevInfo amlogtestapp.cpp, 12
"i" is now: 2, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 Info amlogtestapp.cpp, 10
"i" is now: 3, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 Error amlogtestapp.cpp, 11
"i" is now: 3, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 DevInfo amlogtestapp.cpp, 12
"i" is now: 3, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 Info amlogtestapp.cpp, 10
"i" is now: 4, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 Error amlogtestapp.cpp, 11
"i" is now: 4, Loglevel is: DeveloperInfo
2002-05-14 21:39:08 DevInfo amlogtestapp.cpp, 12
"i" is now: 4, Loglevel is: DeveloperInfo
The last 15 lines is written with Loglevel
DeveloperInfo
.
Well, that's all there is to it.