edelib logging
This tutorial will show you how to log common values and how to write custom loging backend.
Introduction
edelib use logging facility similar to Qt and glib implementations, but simplified a little bit. However, this doesn't make it less flexible.
Three macros are provided for this task:
- E_DEBUG - should be used for debug messages
- E_WARNING - is for warnings user should be aware of
- E_FATAL - fatal errors where program will probably end up in inconsistent state
E_FATAL will also call abort()
which will quit your program.
All macros provide printf
-like functionality, so you are able to
use custom placeholders. Also, internal buffer where message is stored
is limited on 1024 bytes, so any message larger than this will be
discarded to this size.
If the program was compiled with 'E_LOG_DOMAIN
' flag set, output will
have domain name so you can easily deduce from which application the
message is coming. Here is the small demo program that will show usage of
given features; we will call it logger.cpp
:
/* logger.cpp */ #include <edelib/Debug.h> /* all logging facility is here */ int main() { int n = 1; E_DEBUG("This is %i time you are calling this program.\n", n); return 0; }
and you compile it and run it:
> g++ logger.cpp -o logger `pkg-config edelib --cflags --libs` > ./logger This is 1 time you are calling this program. >
By adding log domain, you can see from which place you are receiving the message:
> g++ -DE_LOG_DOMAIN=\"logger\" logger.cpp -o logger `pkg-config edelib --cflags --libs` > ./logger [logger] This is 1 time you are calling this program. >
When you setup E_LOG_DOMAIN value, you must add escaped quotes; this value is used as C string.
If you use E_WARNING
instead of E_DEBUG
you will get the same
output. By default, edelib shows warnings and debug messages in the
same way. However, if your program wants to show it differently, or
you are going to store output in some file (or syslog) read bellow.
Locating log lines
Sometimes you want to see from which file (and line) log string
came. edelib provides convinient macro for this, named E_STRLOC
,
which expands to __FILE__ and __LINE__ hints. Here is example how
it can be used (including program name set with E_LOG_DOMAIN
):
// ... E_DEBUG(E_STRLOC ": this is debug output with line and file where is written\n"); // ...
and the output will look like:
> ./your-program [your-program] somepath/Source.cpp:10: this is debug output with line and file where is written
Custom output
With 'edelib_error_message_handler_install()
' you install custom
handler (or callback): all output will be redirected to given function
with message type, domain and content.
(!) All debug functionality is compiled as C code so this can be used
from C programs too. This is why above function starts with
edelib_
and is not part of edelib::
C++ namespace.
Here is small example how this feature can be used to log messages via
syslog
:
#include <edelib/Debug.h> #include <syslog.h> static void syslog_logger(int type, const char *domain, const char *msg) { int pr; const char *str; switch(type) { case EDELIB_ERROR_MESSAGE_WARNING: pr = LOG_WARNING; str = "warning"; break; case EDELIB_ERROR_MESSAGE_FATAL: pr = LOG_CRIT; str = "fatal"; break; case EDELIB_ERROR_MESSAGE_DEBUG: default: pr = LOG_INFO; str = "debug"; break; } if(domain) syslog(pr, "[%s] (%s) %s", domain, str, msg); else syslog(pr, "(%s) %s", str, msg); } int main(int argc, char **argv) { /* open the log first */ setlogmask(LOG_UPTO (LOG_INFO)); openlog("sample-app", LOG_CONS | LOG_PID, LOG_USER); edelib_error_message_handler_install(syslog_logger); /* ... your application code ... */ /* close the log when is done */ closelog(); return 0; }
Now all messages, warning and errors will be logged in
/var/log/messages
, or whatever syslog output file is configured on
your system.