wslog: Add support for inverted debug matches

The --log-debug and --log-noisy now accepts a '!' to invert the
match and disable the debug (noisy respectively) log level for
the listed domains.

Note this is different from --log-domains, that option
enables/disables the entire log domain itself, regardless of log
level.
This commit is contained in:
João Valverde 2021-06-16 20:32:07 +01:00
parent 051a74378d
commit a6738d72a0
4 changed files with 60 additions and 30 deletions

View File

@ -1097,7 +1097,7 @@ sync_pipe_run_command(char* const argv[], gchar **data, gchar **primary_msg,
int logging_enabled;
/* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
logging_enabled = ws_log_level_is_active(LOG_LEVEL_INFO);
logging_enabled = ws_log_message_is_active(WS_LOG_DOMAIN, LOG_LEVEL_INFO);
if (logging_enabled) {
start_time = g_get_monotonic_time();
ws_info("sync_pipe_run_command() starts");

View File

@ -232,8 +232,8 @@ libwsutil.so.0 libwsutil0 #MINVER#
ws_log_get_level@Base 3.5.0
ws_log_init@Base 3.5.0
ws_log_init_with_data@Base 3.5.0
ws_log_level_is_active@Base 3.5.0
ws_log_level_to_string@Base 3.5.0
ws_log_message_is_active@Base 3.5.0
ws_log_parse_args@Base 3.5.0
ws_log_print_usage@Base 3.5.0
ws_log_set_debug_filter@Base 3.5.0

View File

@ -64,10 +64,18 @@ static GPtrArray *debug_filter = NULL;
/* List of domains to output noisy level unconditionally. */
static GPtrArray *noisy_filter = NULL;
/* True if active domains should match, false if actice domains should not
/* True if active domains should match, false if active domains should not
* match. */
static gboolean domain_filter_positive = TRUE;
/* True if debug filter enables debug log level, false if debug filter
* disables debug log level. */
static gboolean debug_filter_positive = TRUE;
/* True if noisy filter enables noisy log level, false if noisy filter
* disables noisy log level. */
static gboolean noisy_filter_positive = TRUE;
static ws_log_writer_cb *registered_log_writer = NULL;
static void *registered_log_writer_data = NULL;
@ -131,7 +139,7 @@ static enum ws_log_level string_to_log_level(const char *str_level)
}
gboolean ws_log_level_is_active(enum ws_log_level level)
static inline gboolean log_level_is_active(enum ws_log_level level)
{
/*
* Lower numerical levels have higher priority. Critical and above
@ -158,7 +166,7 @@ static inline gboolean filter_contains(GPtrArray *filter, const char *domain)
}
gboolean ws_log_domain_is_active(const char *domain)
static inline gboolean log_domain_is_active(const char *domain)
{
/*
* We don't filter the undefined domain, pretty much every permanent
@ -173,19 +181,45 @@ gboolean ws_log_domain_is_active(const char *domain)
return !domain_filter_positive;
}
#define ACTIVE 1
#define SILENT 0
#define CONTINUE -1
static gboolean log_drop_message(const char *domain, enum ws_log_level level)
static inline int level_filter_matches(GPtrArray *ptr, const char *domain,
enum ws_log_level level,
enum ws_log_level max_level,
gboolean positive)
{
if (noisy_filter != NULL && filter_contains(noisy_filter, domain)) {
return FALSE;
}
if (filter_contains(ptr, domain) == FALSE)
return CONTINUE;
if (debug_filter != NULL && level <= LOG_LEVEL_DEBUG &&
filter_contains(debug_filter, domain)) {
return FALSE;
}
if (positive)
return level <= max_level ? ACTIVE : SILENT;
return !ws_log_level_is_active(level) || !ws_log_domain_is_active(domain);
/* negative match */
return level >= max_level ? SILENT : CONTINUE;
}
#define DEBUG_FILTER_MATCHES(domain, level) \
level_filter_matches(debug_filter, domain, level, \
LOG_LEVEL_DEBUG, debug_filter_positive)
#define NOISY_FILTER_MATCHES(domain, level) \
level_filter_matches(noisy_filter, domain, level, \
LOG_LEVEL_NOISY, noisy_filter_positive)
gboolean ws_log_message_is_active(const char *domain, enum ws_log_level level)
{
int action;
if ((action = NOISY_FILTER_MATCHES(domain, level)) != CONTINUE)
return action;
if ((action = DEBUG_FILTER_MATCHES(domain, level)) != CONTINUE)
return action;
return log_level_is_active(level) && log_domain_is_active(domain);
}
@ -357,7 +391,7 @@ static GPtrArray *tokenize_filter_str(const char *str_filter,
const char *sep = ",;";
char *list, *str;
GPtrArray *domains;
gboolean positive;
gboolean negated = FALSE;
ws_assert(str_filter);
@ -366,12 +400,9 @@ static GPtrArray *tokenize_filter_str(const char *str_filter,
list = str = g_strdup(str_filter);
if (str[0] == '!') {
positive = FALSE;
negated = TRUE;
str += 1;
}
else {
positive = TRUE;
}
for (tok = strtok(str, sep); tok != NULL; tok = strtok(NULL, sep)) {
g_ptr_array_add(domains, g_strdup(tok));
@ -380,7 +411,7 @@ static GPtrArray *tokenize_filter_str(const char *str_filter,
g_free(list);
if (ret_positive)
*ret_positive = positive;
*ret_positive = !negated;
return domains;
}
@ -399,7 +430,7 @@ void ws_log_set_debug_filter(const char *str_filter)
if (debug_filter != NULL)
g_ptr_array_free(debug_filter, TRUE);
debug_filter = tokenize_filter_str(str_filter, NULL);
debug_filter = tokenize_filter_str(str_filter, &debug_filter_positive);
}
@ -408,7 +439,7 @@ void ws_log_set_noisy_filter(const char *str_filter)
if (noisy_filter != NULL)
g_ptr_array_free(noisy_filter, TRUE);
noisy_filter = tokenize_filter_str(str_filter, NULL);
noisy_filter = tokenize_filter_str(str_filter, &noisy_filter_positive);
}
@ -583,7 +614,7 @@ void ws_logv(const char *domain, enum ws_log_level level,
const char *format, va_list ap)
{
if (log_drop_message(domain, level))
if (ws_log_message_is_active(domain, level) == FALSE)
return;
log_write_dispatch(domain, level, NULL, -1, NULL, format, ap);
@ -594,7 +625,7 @@ void ws_logv_full(const char *domain, enum ws_log_level level,
const char *file, int line, const char *func,
const char *format, va_list ap)
{
if (log_drop_message(domain, level))
if (ws_log_message_is_active(domain, level) == FALSE)
return;
log_write_dispatch(domain, level, file, line, func, format, ap);
@ -606,7 +637,7 @@ void ws_log(const char *domain, enum ws_log_level level,
{
va_list ap;
if (log_drop_message(domain, level))
if (ws_log_message_is_active(domain, level) == FALSE)
return;
va_start(ap, format);
@ -621,7 +652,7 @@ void ws_log_full(const char *domain, enum ws_log_level level,
{
va_list ap;
if (log_drop_message(domain, level))
if (ws_log_message_is_active(domain, level) == FALSE)
return;
va_start(ap, format);

View File

@ -50,13 +50,12 @@ WS_DLL_PUBLIC
const char *ws_log_level_to_string(enum ws_log_level level);
/** Checks if the active log level would discard a message for the given
* log domain.
/** Checks if a domain and level combination generate output.
*
* Returns TRUE if a message will be discarded for the domain/log_level combo.
* Returns TRUE if a message will be printed for the domain/log_level combo.
*/
WS_DLL_PUBLIC
gboolean ws_log_level_is_active(enum ws_log_level level);
gboolean ws_log_message_is_active(const char *domain, enum ws_log_level level);
/** Return the currently active log level. */