libnm: support "stdout" flag for LIBNM_CLIENT_DEBUG for logging to stdout

Trace logging from libnm is verbose. So, by default we print trace
messages to stderr. However, that means that messages printed to stdout
are not in sync with the trace logging.

That means, if the libnm application prints messages to stdout, and
you'd like to correlate them with trace messages, it is difficult.

Add an option to allow printing trace messages to stdout.

  $ LIBNM_CLIENT_DEBUG=trace,stdout nmcli

Possibly redirecting stderr to stdout might also work around the
ordering issue. However, it's not entirely clear how buffering of
the file streams affects this.
This commit is contained in:
Thomas Haller 2020-07-15 11:29:43 +02:00
parent 39264bdb13
commit 16d5dff596
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 31 additions and 9 deletions

View file

@ -24,6 +24,7 @@ _nml_dbus_log_level_init (void)
{ "debug", _NML_DBUS_LOG_LEVEL_DEBUG },
{ "warning", _NML_DBUS_LOG_LEVEL_WARN },
{ "error", _NML_DBUS_LOG_LEVEL_ERROR },
{ "stdout", NML_DBUS_LOG_STDOUT },
};
int l;
@ -41,6 +42,7 @@ _nml_dbus_log_level_init (void)
void
_nml_dbus_log (NMLDBusLogLevel level,
gboolean use_stdout,
const char *fmt,
...) {
NMLDBusLogLevel configured_log_level;
@ -91,11 +93,19 @@ _nml_dbus_log (NMLDBusLogLevel level,
ts = nm_utils_clock_gettime_nsec (CLOCK_BOOTTIME);
g_printerr ("libnm-dbus: %s[%"G_GINT64_FORMAT".%05"G_GINT64_FORMAT"] %s\n",
prefix,
ts / NM_UTILS_NSEC_PER_SEC,
(ts / (NM_UTILS_NSEC_PER_SEC / 10000)) % 10000,
msg);
if (use_stdout) {
g_print ("libnm-dbus: %s[%"G_GINT64_FORMAT".%05"G_GINT64_FORMAT"] %s\n",
prefix,
ts / NM_UTILS_NSEC_PER_SEC,
(ts / (NM_UTILS_NSEC_PER_SEC / 10000)) % 10000,
msg);
} else {
g_printerr ("libnm-dbus: %s[%"G_GINT64_FORMAT".%05"G_GINT64_FORMAT"] %s\n",
prefix,
ts / NM_UTILS_NSEC_PER_SEC,
(ts / (NM_UTILS_NSEC_PER_SEC / 10000)) % 10000,
msg);
}
}
/*****************************************************************************/

View file

@ -55,6 +55,8 @@ typedef enum {
| NML_DBUS_LOG_LEVEL_DEBUG,
NML_DBUS_LOG_LEVEL_ERROR = _NML_DBUS_LOG_LEVEL_ERROR
| NML_DBUS_LOG_LEVEL_WARN,
NML_DBUS_LOG_STDOUT = 0x20,
} NMLDBusLogLevel;
#undef _LOGL_TRACE
@ -74,7 +76,7 @@ extern volatile int _nml_dbus_log_level;
int _nml_dbus_log_level_init (void);
static inline gboolean
nml_dbus_log_enabled (NMLDBusLogLevel level)
nml_dbus_log_enabled_full (NMLDBusLogLevel level, gboolean *out_use_stdout)
{
int l;
@ -90,25 +92,35 @@ nml_dbus_log_enabled (NMLDBusLogLevel level)
l = _nml_dbus_log_level_init ();
nm_assert (l & _NML_DBUS_LOG_LEVEL_INITIALIZED);
NM_SET_OUT (out_use_stdout, NM_FLAGS_HAS (l, NML_DBUS_LOG_STDOUT));
if (level == NML_DBUS_LOG_LEVEL_ANY)
return l != _NML_DBUS_LOG_LEVEL_INITIALIZED;
return !!(((NMLDBusLogLevel) l) & level);
}
static inline gboolean
nml_dbus_log_enabled (NMLDBusLogLevel level)
{
return nml_dbus_log_enabled_full (level, NULL);
}
void _nml_dbus_log (NMLDBusLogLevel level,
gboolean use_stdout,
const char *fmt,
...) _nm_printf (2, 3);
...) _nm_printf (3, 4);
#define NML_DBUS_LOG(level, ...) \
G_STMT_START { \
gboolean _use_stdout; \
\
G_STATIC_ASSERT ( (level) == _NML_DBUS_LOG_LEVEL_NONE \
|| (level) == NML_DBUS_LOG_LEVEL_TRACE \
|| (level) == NML_DBUS_LOG_LEVEL_DEBUG \
|| (level) == NML_DBUS_LOG_LEVEL_WARN \
|| (level) == NML_DBUS_LOG_LEVEL_ERROR); \
\
if (nml_dbus_log_enabled (level)) { \
_nml_dbus_log ((level), __VA_ARGS__); \
if (nml_dbus_log_enabled_full (level, &_use_stdout)) { \
_nml_dbus_log ((level), _use_stdout, __VA_ARGS__); \
} \
} G_STMT_END