[glib] Make the default log handler more useful



commit d2d62ecfcd09f91ed423b66b5b21be602dce2ecd
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Nov 3 01:48:54 2011 -0400

    Make the default log handler more useful
    
    We make the default log handler only print default and informational
    messages if the log domain is explicitly requested.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=661926

 docs/reference/glib/running.sgml |   34 +++++++++++++++++++++++++++++++++-
 glib/gmessages.c                 |   37 +++++++++++++++++++++++++++++++++++++
 glib/tests/logging.c             |   23 ++++++++++++++++++++++-
 3 files changed, 92 insertions(+), 2 deletions(-)
---
diff --git a/docs/reference/glib/running.sgml b/docs/reference/glib/running.sgml
index 41215dd..0591008 100644
--- a/docs/reference/glib/running.sgml
+++ b/docs/reference/glib/running.sgml
@@ -54,7 +54,39 @@ variables like <envar>LANG</envar>, <envar>PATH</envar> or <envar>HOME</envar>.
   <para>
     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 <literal>G_LOG_LEVEL_MESSAGE</literal> and <literal>G_LOG_LEVEL_INFO</literal>. 
+    everything except <literal>G_LOG_LEVEL_MESSAGE</literal> and
+    <literal>G_LOG_LEVEL_INFO</literal>.
+    The possible values are
+    <literal>error</literal>,
+    <literal>warning</literal>,
+    <literal>critical</literal>,
+    <literal>message</literal>,
+    <literal>info</literal> and
+    <literal>debug</literal>.
+    You can also use the special values
+    <literal>all</literal> and
+    <literal>help</literal>.
+  </para>
+  <para>
+    This environment variable only affects the GLib log handler,
+    g_log_default_handler().
+  </para>
+</formalpara>
+
+<formalpara id="G_MESSAGES_DEBUG">
+  <title><envar>G_MESSAGES_DEBUG</envar></title>
+
+  <para>
+    A space-separated list of log domains for which informational
+    and debug messages should be printed. By default, these
+    messages are not printed.
+  </para>
+  <para>
+    You can also use the special value <literal>all</literal>.
+  </para>
+  <para>
+    This environment variable only affects the GLib log handler,
+    g_log_default_handler().
   </para>
 </formalpara>
 
diff --git a/glib/gmessages.c b/glib/gmessages.c
index 3edb67c..ef62d23 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:
+ * <variablelist>
+ *   <varlistentry>
+ *     <term><envar>G_MESSAGES_PREFIXED</envar></term>
+ *     <listitem>
+ *       A :-separated list of log levels for which messages should
+ *       be prefixed by the program name and PID of the aplication.
+ *     </listitem>
+ *   </varlistentry>
+ *   <varlistentry>
+ *     <term><envar>G_MESSAGES_DEBUG</envar></term>
+ *     <listitem>
+ *       A space-separated list of log domains for which debug and
+ *       informational messages are printed. By default these
+ *       messages are not printed.
+ *     </listitem>
+ *   </varlistentry>
+ * </variablelist>
+ *
  * 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 56340b6..9d69e6a 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");



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]