diff --git a/docs/reference/glib/running.sgml b/docs/reference/glib/running.sgml index 41215dd43..0591008e1 100644 --- a/docs/reference/glib/running.sgml +++ b/docs/reference/glib/running.sgml @@ -54,7 +54,39 @@ variables like LANG, PATH or HOME. A list of log levels for which messages should be prefixed by the program name and PID of the application. The default is to prefix - everything except G_LOG_LEVEL_MESSAGE and G_LOG_LEVEL_INFO. + everything except G_LOG_LEVEL_MESSAGE and + G_LOG_LEVEL_INFO. + The possible values are + error, + warning, + critical, + message, + info and + debug. + You can also use the special values + all and + help. + + + This environment variable only affects the GLib log handler, + g_log_default_handler(). + + + + + <envar>G_MESSAGES_DEBUG</envar> + + + A space-separated list of log domains for which informational + and debug messages should be printed. By default, these + messages are not printed. + + + You can also use the special value all. + + + This environment variable only affects the GLib log handler, + g_log_default_handler(). diff --git a/glib/gmessages.c b/glib/gmessages.c index 3edb67c8a..ef62d23e3 100644 --- a/glib/gmessages.c +++ b/glib/gmessages.c @@ -65,6 +65,7 @@ #include "gbacktrace.h" #include "gcharset.h" #include "gconvert.h" +#include "genviron.h" #include "gmem.h" #include "gprintfint.h" #include "gtestutils.h" @@ -969,6 +970,11 @@ format_unsigned (gchar *buf, #define ALERT_LEVELS (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING) +/* these are emitted by the default log handler */ +#define DEFAULT_LEVELS (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE) +/* these are filtered by G_MESSAGES_DEBUG by the default log handler */ +#define INFO_LEVELS (G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG) + static int mklevel_prefix (gchar level_prefix[STRING_BUFFER_SIZE], GLogLevelFlags log_level) @@ -1143,6 +1149,26 @@ escape_string (GString *string) * domain and log level combination. It outputs the message to stderr * or stdout and if the log level is fatal it calls abort(). * + * The behavior of this log handler can be influenced by a number of + * environment variables: + * + * + * G_MESSAGES_PREFIXED + * + * A :-separated list of log levels for which messages should + * be prefixed by the program name and PID of the aplication. + * + * + * + * G_MESSAGES_DEBUG + * + * A space-separated list of log domains for which debug and + * informational messages are printed. By default these + * messages are not printed. + * + * + * + * * stderr is used for levels %G_LOG_LEVEL_ERROR, %G_LOG_LEVEL_CRITICAL, * %G_LOG_LEVEL_WARNING and %G_LOG_LEVEL_MESSAGE. stdout is used for * the rest. @@ -1156,7 +1182,18 @@ g_log_default_handler (const gchar *log_domain, gchar level_prefix[STRING_BUFFER_SIZE], *string; GString *gstring; int fd; + const gchar *domains; + if ((log_level & DEFAULT_LEVELS) || (log_level >> G_LOG_LEVEL_USER_SHIFT)) + goto emit; + + domains = g_getenv ("G_MESSAGES_DEBUG"); + if (((log_level & INFO_LEVELS) == 0) || + domains == NULL || + (strcmp (domains, "all") != 0 && !strstr (domains, log_domain))) + return; + + emit: /* we can be called externally with recursion for whatever reason */ if (log_level & G_LOG_FLAG_RECURSION) { diff --git a/glib/tests/logging.c b/glib/tests/logging.c index 56340b667..9d69e6a04 100644 --- a/glib/tests/logging.c +++ b/glib/tests/logging.c @@ -100,16 +100,37 @@ test_default_handler (void) exit (0); } g_test_trap_assert_passed (); + g_test_trap_assert_stdout_unmatched ("*INFO*message5*"); + + g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE); + if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT)) + { + g_log ("bar", G_LOG_LEVEL_INFO, "message5"); + exit (0); + } + g_test_trap_assert_passed (); g_test_trap_assert_stdout ("*INFO*message5*"); if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT)) { - g_debug ("message6"); + g_log ("baz", G_LOG_LEVEL_DEBUG, "message6"); exit (0); } g_test_trap_assert_passed (); g_test_trap_assert_stdout ("*DEBUG*message6*"); + g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); + if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT)) + { + g_log ("foo", G_LOG_LEVEL_DEBUG, "6"); + g_log ("bar", G_LOG_LEVEL_DEBUG, "6"); + g_log ("baz", G_LOG_LEVEL_DEBUG, "6"); + exit (0); + } + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*DEBUG*6*6*6*"); + + g_unsetenv ("G_MESSAGES_DEBUG"); if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT)) { g_log (G_LOG_DOMAIN, 1<<10, "message7");