How to handle log level with GLib

Viewed 88

I want to create log level display for my C program.

For example, if launch it with ./my_program -log=warning it display my warning log on standard output. Same for ./my_program -log=debug or ./my_program -log=errors.

I first thought about doing it manually in C and just use some printf, but I also use GLib inside my program for other reasons and I am pretty sure it has its own way of handling the problem.

So my question is : How to handle debug logs in a clean and robust way with GLib ?

1 Answers

You can, but it's not direct.

Two parts:

  • debug messages
  • other messages.

debug

By default, debug messages are hidden, you can show them setting the env var G_MESSAGES_DEBUG to all

other

To hide the other message, you can define your own log function that won't show the messages using g_log_set_handler


This little code will do what you want:

#include <glib.h>

/* a log function that will eat the message without displaying it */
void log_quiet(const gchar* domain, GLogLevelFlags level, const gchar *message, gpointer user_data)
{
    // nop
}

int main(int argc, char *argv[]) 
{

    /* message filter */
    int filter = 0;

    /* decode argument given here, it's the first argument given */
    if (argc > 1)
    {
        if (0 == strcmp(argv[1], "debug")) {
            filter = G_LOG_LEVEL_DEBUG;
        } else if (0 == strcmp(argv[1], "debug")) {
            filter = G_LOG_LEVEL_DEBUG;
        } else if (0 == strcmp(argv[1], "message")) {
            filter = G_LOG_LEVEL_MESSAGE;
        } else if (0 == strcmp(argv[1], "warning")) {
            filter = G_LOG_LEVEL_WARNING;
        } else if (0 == strcmp(argv[1], "critical")) {
            filter = G_LOG_LEVEL_CRITICAL;
        } else if (0 == strcmp(argv[1], "error")) {
            filter = G_LOG_LEVEL_ERROR;
        }
    }

    
    /* set the message handler*/
    switch (filter) {
        case G_LOG_LEVEL_DEBUG:
            /* in case of debug, we must make it visible */
            setenv("G_MESSAGES_DEBUG", "all", 1);
            break;
        /* other case, hide messages progressively */
        case G_LOG_LEVEL_ERROR:
            g_log_set_handler(NULL, G_LOG_LEVEL_CRITICAL, log_quiet, NULL);
        case G_LOG_LEVEL_CRITICAL:
            g_log_set_handler(NULL, G_LOG_LEVEL_WARNING, log_quiet, NULL);
        case G_LOG_LEVEL_WARNING:
            g_log_set_handler(NULL, G_LOG_LEVEL_MESSAGE, log_quiet, NULL);
        case G_LOG_LEVEL_MESSAGE:
            g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, log_quiet, NULL);
    }

    /* test */
    g_debug("Hello from g_debug");
    g_message("Hello from g_message");
    g_warning("Hello from g_warning");
    g_critical("Hello from g_critical");
    g_error("Hello from g_error");

    return 0;
}

Related