C - gtk Logging overriding
Share
Logging
When things go wrong in your application, it's nice to have a way to communicate with
your users about the problem. Some of this communication will take the form of graphical
dialog boxes (see Chapter 7). These pop-up windows are good for warnings, error messages,
and spontaneous data gathering, but by their nature they don't leave a trace of their
passing. If something goes horribly awry and the only response is an error dialog, the
user will have to quickly grab a piece of paper and write down the error before closing
the window. Sometimes you just want to output text messages to stdout (the text console),
or permanently to a log file. GLib has a nice, configurable set of logging func- tions
that allow you to do this in a flexible, portable way.
Traditionally, C applications use some form of the printf( ) function to write messages
to the console. Alternatively, variations of write( ) and fprintf( ) can send the same
messages to a file. If you wanted to reroute your logging messages between these two
output styles at runtime, you would have to write a wrapper logging function to handle
the logic, and call the wrapper instead of calling printf( ) and write( ) directly. This
is exactly what GLib does.
The four main logging functions are, in increasing order of severity,
void g_print(const gchar *format, ...);
void g_message(const gchar *format, ...);
void g_warning(const gchar *format, ...);
void g_error(const gchar *format, ...);
They behave just like a normal printf( ) statement:
g_message("%d bottles of beer left in the fridge", num_bottles);
Notice that for g_message( ), g_warning( ), and g_error( ), you don't need to worry about
line breaks. If you include the character "\n" at the end of your format strings, you'll
end up with double spacing between log messages.
Each of these four logging channels handles its formatted messages in its own particular
way. By default, all four channels write to the stdout of the console the application was
run from. The g_print( ) function passes the text on without changing it; the other three
add a little extra formatting to indicate the severity of the message to the user. In
addition to printing a logging message, the g_error( ( )) function calls abort( ), which
brings your program to a screeching halt.
It's also possible to intercept these logging messages and handle them in a custom
manner, most likely sending them to a file rather than to stdout. You can override each
logging channel separately-for example, if you want to send the output of only g_message(
) to a file, leaving the other channels alone. The handler function prototype and the
GLib function you call to set it up look like this:
typedef void (*GLogFunc)(const gchar *log_domain,
GLogLevelFlags log_level, const gchar *message,
gpointer user_data);
guint g_log_set_handler(const gchar *log_domain,
GLogLevelFlags log_levels, GLogFunc log_func,
gpointer user_data);
The GLogLevelFlags parameter is an enum of bit flags that define the character and
specific channel of a logging message. The three you'll most likely use with logging
handlers are G_LOG_LEVEL_MESSAGE, G_LOG_LEVEL_WARNING, and G_LOG_LEVEL_ERROR. Since they
are bit flags, you can use a binary OR operator to combine more than one channel into a
single handler. Listing 2.1 shows how to send g_message( ) and g_warning( ) to a log
file, myapp.log.
Listing 2.1 Overriding a Logging Handler
void LogToFile (const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, gpointer user_data)
{
FILE *logfile = fopen ("myapp.log", "a");
if (logfile == NULL)
{
/* Fall back to console output if unable to open file */
printf ("Rerouted to console: %s\n", message);
return;
}
fprintf (logfile, "%s\n", message);
fclose (logfile);
}
int main(int argc, char *argv[])
{
...
/* Send g_message( ) and g_warning( ) to the file */
g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE |
G_LOG_LEVEL_WARNING, LogToFile, NULL);
...
}
The g_print( ) function has its own set of override functions, which behave pretty much
the same. The g_set_print_handler( ) function returns the old g_print( ) handler, in case
you want to restore it later.
typedef void (*GPrintFunc)(const gchar *string);
GPrintFunc g_set_print_handler(GPrintFunc func);
http://developer.gnome.org/doc/books/WGA/gtk-gnome-intro.html
Comments:
|
Submitted By:
Prof: Software Engineer
Tech: C ,Cpp
|