Differences
This shows you the differences between two versions of the page.
edeliblogging [2015/10/03 14:54] |
edeliblogging [2015/10/03 14:54] (current) |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== 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 [[http://qt.nokia.com|Qt]] and | ||
+ | [[http://developer.gnome.org/glib|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'': | ||
+ | |||
+ | <code 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; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | and you compile it and run it: | ||
+ | |||
+ | <code> | ||
+ | > g++ logger.cpp -o logger `pkg-config edelib --cflags --libs` | ||
+ | > ./logger | ||
+ | This is 1 time you are calling this program. | ||
+ | > | ||
+ | </code> | ||
+ | |||
+ | By adding log domain, you can see from which place you are receiving the message: | ||
+ | |||
+ | <code> | ||
+ | > 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. | ||
+ | > | ||
+ | </code> | ||
+ | |||
+ | :!: 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''): | ||
+ | |||
+ | <code cpp> | ||
+ | // ... | ||
+ | E_DEBUG(E_STRLOC ": this is debug output with line and file where is written\n"); | ||
+ | // ... | ||
+ | </code> | ||
+ | |||
+ | and the output will look like: | ||
+ | |||
+ | <code> | ||
+ | > ./your-program | ||
+ | [your-program] somepath/Source.cpp:10: this is debug output with line and file where is written | ||
+ | </code> | ||
+ | |||
+ | ===== 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'': | ||
+ | |||
+ | <code cpp> | ||
+ | #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; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Now all messages, warning and errors will be logged in | ||
+ | ''/var/log/messages'', or whatever syslog output file is configured on | ||
+ | your system. | ||