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
This commit is contained in:
Matthias Clasen 2011-11-03 01:48:54 -04:00
parent 7456b43c3e
commit d2d62ecfcd
3 changed files with 92 additions and 2 deletions

View File

@ -54,7 +54,39 @@ variables like <envar>LANG</envar>, <envar>PATH</envar> or <envar>HOME</envar>.
<para> <para>
A list of log levels for which messages should be prefixed by the 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 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> </para>
</formalpara> </formalpara>

View File

@ -65,6 +65,7 @@
#include "gbacktrace.h" #include "gbacktrace.h"
#include "gcharset.h" #include "gcharset.h"
#include "gconvert.h" #include "gconvert.h"
#include "genviron.h"
#include "gmem.h" #include "gmem.h"
#include "gprintfint.h" #include "gprintfint.h"
#include "gtestutils.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) #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 static int
mklevel_prefix (gchar level_prefix[STRING_BUFFER_SIZE], mklevel_prefix (gchar level_prefix[STRING_BUFFER_SIZE],
GLogLevelFlags log_level) GLogLevelFlags log_level)
@ -1143,6 +1149,26 @@ escape_string (GString *string)
* domain and log level combination. It outputs the message to stderr * domain and log level combination. It outputs the message to stderr
* or stdout and if the log level is fatal it calls abort(). * 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, * 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 * %G_LOG_LEVEL_WARNING and %G_LOG_LEVEL_MESSAGE. stdout is used for
* the rest. * the rest.
@ -1156,7 +1182,18 @@ g_log_default_handler (const gchar *log_domain,
gchar level_prefix[STRING_BUFFER_SIZE], *string; gchar level_prefix[STRING_BUFFER_SIZE], *string;
GString *gstring; GString *gstring;
int fd; 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 */ /* we can be called externally with recursion for whatever reason */
if (log_level & G_LOG_FLAG_RECURSION) if (log_level & G_LOG_FLAG_RECURSION)
{ {

View File

@ -100,16 +100,37 @@ test_default_handler (void)
exit (0); exit (0);
} }
g_test_trap_assert_passed (); 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*"); g_test_trap_assert_stdout ("*INFO*message5*");
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT)) if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
{ {
g_debug ("message6"); g_log ("baz", G_LOG_LEVEL_DEBUG, "message6");
exit (0); exit (0);
} }
g_test_trap_assert_passed (); g_test_trap_assert_passed ();
g_test_trap_assert_stdout ("*DEBUG*message6*"); 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)) if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
{ {
g_log (G_LOG_DOMAIN, 1<<10, "message7"); g_log (G_LOG_DOMAIN, 1<<10, "message7");