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().
+
+
+
+
+ G_MESSAGES_DEBUG
+
+
+ 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");