I am a new user of the GLib C library, which I have started using recently for a new project. Let me first say that it is awesome, thanks A LOT to the devs for this.
I have a few questions about the logging features of GLib. What I have understood so far is that it is better to use the structured logs, because it allows for better filtering. So what I am currently doing is to define G_LOG_STRUCTURED before including the headers, then I use g_info(), g_debug(), g_error(), etc. to avoid using directly g_log_structured().
My main confusion is on filtering the output of my program depending on the log level I need. I understand that by default, info and debug logs are not displayed, unless setting G_MESSAGES_DEBUG=all at runtime. What I could not figure out however, is how to show the info logs, but not the debug logs. And in general, I can’t figure out how to set the log level of my program’s output. Can someone give some pointers on how to set the output log level inside the source code, as well as at runtime ? For example, I’m looking for a behavior similar to GStreamer’s GST_DEBUG environment variable, as described here : https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html?gi-language=c
Second question : when I use g_log_set_writer_func() by passing it either g_log_writer_standard_streams, or g_log_writer_journald, it looks like the info and debug logs are always outputted, no matter the value of G_DEBUG_MESSAGES. Is that an expected behavior ?
And my last question : If I leave the log writer func to g_log_writer_default(), I understand from the documentation that it should decide on its own whether to output to stdout/stderr or to journald. On what basis does it decide to switch to journald ? I could only get stdout/stderr output so far. But I may not have tried all the possible ways of launching my programs.
Structured logging is definitely the way to go. I assume you’ve read the docs, including the HOWTO, and the intro at the top of the API docs. If you haven’t seen it, this blog post is useful as well.
Anyway, to answer your questions:
If you have a look at the source for g_log_structured_array, which is the main function that all the others end up calling, you can see it doesn’t do anything except just pass the log data on to the writer. So if you want to control logging levels from within the app, you need to do it from the log writer function itself. One approach would be to write your own custom writer function that filters out log messages you don’t want to see and pass the rest to one of the standard writers.
If you look at the API docs for g_log_writer_default (the default writer), you’ll see it drops info and debug messages unless G_MESSAGES_DEBUG is set. Likewise as the API docs for g_log_writer_standard_streams and g_log_writer_journald state, they log all messages. So yes, that’s both the documented and expected behaviour.
Looking at the source for the default writer is useful here, too. You can see that calls g_log_writer_is_journald(), which checks to see if stderr is connected to the journal. If so, g_log_writer_journald is used. So if you are using the default handler, the program will need to be launched via systemd to log to the journal.