forked from osmocom/wireshark
wslog: Add option to make a list of domains fatal
Add a command line option --log-fatal-domains= and environment variable WIRESHARK_LOG_FATAL_DOMAINS that aborts the programs if a domain in the list is logged to. Negative matches for fatal log domains not implemented for now, pending a relevant use-case.
This commit is contained in:
parent
ad66a854a0
commit
b7d15d0767
|
@ -10,12 +10,15 @@ For example, "warning" aborts on any "warning", "critical", or "error" messages.
|
|||
|
||||
// XXX List available domains if no list is provided?
|
||||
--log-domains <list>:: Only print messages for the specified log domains, e.g. "GUI,Epan,sshdump".
|
||||
List of domains must be comma-separated.
|
||||
List of domains must be comma-separated. Can be negated with "!" as the first character (inverts the match).
|
||||
|
||||
--log-debug <list>:: Force the specified domains to log at the "debug" level.
|
||||
List of domains must be comma-separated.
|
||||
List of domains must be comma-separated. Can be negated with "!" as the first character (inverts the match).
|
||||
|
||||
--log-noisy <list>:: Force the specified domains to log at the "noisy" level.
|
||||
List of domains must be comma-separated. Can be negated with "!" as the first character (inverts the match).
|
||||
|
||||
--log-fatal-domains <list>:: Abort the program if any messages are logged for the specified log domains.
|
||||
List of domains must be comma-separated.
|
||||
|
||||
--log-file <path>:: Write log messages and stderr output to the specified file.
|
||||
|
|
|
@ -412,8 +412,9 @@ libwsutil.so.0 libwsutil0 #MINVER#
|
|||
ws_log_set_debug_filter@Base 3.5.0
|
||||
ws_log_set_domain_filter@Base 3.5.0
|
||||
ws_log_set_noisy_filter@Base 3.5.0
|
||||
ws_log_set_fatal@Base 3.5.0
|
||||
ws_log_set_fatal_str@Base 3.5.0
|
||||
ws_log_set_fatal_domain_filter@Base 4.1.0
|
||||
ws_log_set_fatal_level@Base 4.1.0
|
||||
ws_log_set_fatal_level_str@Base 4.1.0
|
||||
ws_log_set_level@Base 3.5.0
|
||||
ws_log_set_level_str@Base 3.5.0
|
||||
ws_log_set_writer@Base 3.7.0
|
||||
|
|
|
@ -50,6 +50,12 @@
|
|||
* or "warning". */
|
||||
#define ENV_VAR_FATAL "WIRESHARK_LOG_FATAL"
|
||||
|
||||
/* Log domains that are fatal. */
|
||||
#define ENV_VAR_FATAL_DOMAIN "WIRESHARK_LOG_FATAL_DOMAIN"
|
||||
|
||||
/* Alias "domain" and "domains". */
|
||||
#define ENV_VAR_FATAL_DOMAIN_S "WIRESHARK_LOG_FATAL_DOMAINS"
|
||||
|
||||
/* Domains that will produce debug output, regardless of log level or
|
||||
* domain filter. */
|
||||
#define ENV_VAR_DEBUG "WIRESHARK_LOG_DEBUG"
|
||||
|
@ -99,6 +105,9 @@ static log_filter_t *debug_filter = NULL;
|
|||
/* List of domains to output noisy level unconditionally. */
|
||||
static log_filter_t *noisy_filter = NULL;
|
||||
|
||||
/* List of domains that are fatal. */
|
||||
static log_filter_t *fatal_filter = NULL;
|
||||
|
||||
static ws_log_writer_cb *registered_log_writer = NULL;
|
||||
|
||||
static void *registered_log_writer_data = NULL;
|
||||
|
@ -309,10 +318,14 @@ enum ws_log_level ws_log_set_level_str(const char *str_level)
|
|||
|
||||
|
||||
static const char *opt_level = "--log-level";
|
||||
/* Alias "domain" and "domains". */
|
||||
static const char *opt_domain = "--log-domain";
|
||||
/* Alias "domain" and "domains". */
|
||||
static const char *opt_domain_s = "--log-domains";
|
||||
static const char *opt_file = "--log-file";
|
||||
static const char *opt_fatal = "--log-fatal";
|
||||
static const char *opt_fatal_domain = "--log-fatal-domain";
|
||||
/* Alias "domain" and "domains". */
|
||||
static const char *opt_fatal_domain_s = "--log-fatal-domains";
|
||||
static const char *opt_debug = "--log-debug";
|
||||
static const char *opt_noisy = "--log-noisy";
|
||||
|
||||
|
@ -415,6 +428,25 @@ parse_console_compat_option(char *argv[],
|
|||
ws_log_set_level(level);
|
||||
}
|
||||
|
||||
/* Match "arg_name=value" or "arg_name value" to opt_name. */
|
||||
static bool optequal(const char *arg, const char *opt)
|
||||
{
|
||||
ws_assert(arg);
|
||||
ws_assert(opt);
|
||||
#define ARGEND(arg) (*(arg) == '\0' || *(arg) == ' ' || *(arg) == '=')
|
||||
|
||||
while (!ARGEND(arg) && *opt != '\0') {
|
||||
if (*arg != *opt) {
|
||||
return false;
|
||||
}
|
||||
arg += 1;
|
||||
opt += 1;
|
||||
}
|
||||
if (ARGEND(arg) && *opt == '\0') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ws_log_parse_args(int *argc_ptr, char *argv[],
|
||||
void (*vcmdarg_err)(const char *, va_list ap),
|
||||
|
@ -433,31 +465,39 @@ int ws_log_parse_args(int *argc_ptr, char *argv[],
|
|||
/* Configure from command line. */
|
||||
|
||||
while (*ptr != NULL) {
|
||||
if (g_str_has_prefix(*ptr, opt_level)) {
|
||||
if (optequal(*ptr, opt_level)) {
|
||||
option = opt_level;
|
||||
optlen = strlen(opt_level);
|
||||
}
|
||||
else if (g_str_has_prefix(*ptr, opt_domain)) {
|
||||
else if (optequal(*ptr, opt_domain)) {
|
||||
option = opt_domain;
|
||||
optlen = strlen(opt_domain);
|
||||
/* Alias "domain" and "domains". Last form wins. */
|
||||
if (*(*ptr + optlen) == 's') {
|
||||
optlen += 1;
|
||||
}
|
||||
}
|
||||
else if (g_str_has_prefix(*ptr, opt_file)) {
|
||||
else if (optequal(*ptr, opt_domain_s)) {
|
||||
option = opt_domain; /* Alias */
|
||||
optlen = strlen(opt_domain_s);
|
||||
}
|
||||
else if (optequal(*ptr, opt_fatal_domain)) {
|
||||
option = opt_fatal_domain;
|
||||
optlen = strlen(opt_fatal_domain);
|
||||
}
|
||||
else if (optequal(*ptr, opt_fatal_domain_s)) {
|
||||
option = opt_fatal_domain; /* Alias */
|
||||
optlen = strlen(opt_fatal_domain_s);
|
||||
}
|
||||
else if (optequal(*ptr, opt_file)) {
|
||||
option = opt_file;
|
||||
optlen = strlen(opt_file);
|
||||
}
|
||||
else if (g_str_has_prefix(*ptr, opt_fatal)) {
|
||||
else if (optequal(*ptr, opt_fatal)) {
|
||||
option = opt_fatal;
|
||||
optlen = strlen(opt_fatal);
|
||||
}
|
||||
else if (g_str_has_prefix(*ptr, opt_debug)) {
|
||||
else if (optequal(*ptr, opt_debug)) {
|
||||
option = opt_debug;
|
||||
optlen = strlen(opt_debug);
|
||||
}
|
||||
else if (g_str_has_prefix(*ptr, opt_noisy)) {
|
||||
else if (optequal(*ptr, opt_noisy)) {
|
||||
option = opt_noisy;
|
||||
optlen = strlen(opt_noisy);
|
||||
}
|
||||
|
@ -517,6 +557,9 @@ int ws_log_parse_args(int *argc_ptr, char *argv[],
|
|||
else if (option == opt_domain) {
|
||||
ws_log_set_domain_filter(value);
|
||||
}
|
||||
else if (option == opt_fatal_domain) {
|
||||
ws_log_set_fatal_domain_filter(value);
|
||||
}
|
||||
else if (value && option == opt_file) {
|
||||
FILE *fp = ws_fopen(value, "w");
|
||||
if (fp == NULL) {
|
||||
|
@ -530,7 +573,7 @@ int ws_log_parse_args(int *argc_ptr, char *argv[],
|
|||
}
|
||||
}
|
||||
else if (option == opt_fatal) {
|
||||
if (ws_log_set_fatal_str(value) == LOG_LEVEL_NONE) {
|
||||
if (ws_log_set_fatal_level_str(value) == LOG_LEVEL_NONE) {
|
||||
print_err(vcmdarg_err, exit_failure,
|
||||
"Fatal log level must be \"critical\" or "
|
||||
"\"warning\", not \"%s\".\n", value);
|
||||
|
@ -626,6 +669,13 @@ void ws_log_set_domain_filter(const char *str_filter)
|
|||
}
|
||||
|
||||
|
||||
void ws_log_set_fatal_domain_filter(const char *str_filter)
|
||||
{
|
||||
free_log_filter(&fatal_filter);
|
||||
tokenize_filter_str(&fatal_filter, str_filter, LOG_LEVEL_NONE);
|
||||
}
|
||||
|
||||
|
||||
void ws_log_set_debug_filter(const char *str_filter)
|
||||
{
|
||||
free_log_filter(&debug_filter);
|
||||
|
@ -640,7 +690,7 @@ void ws_log_set_noisy_filter(const char *str_filter)
|
|||
}
|
||||
|
||||
|
||||
enum ws_log_level ws_log_set_fatal(enum ws_log_level level)
|
||||
enum ws_log_level ws_log_set_fatal_level(enum ws_log_level level)
|
||||
{
|
||||
if (level <= LOG_LEVEL_NONE || level >= _LOG_LEVEL_LAST)
|
||||
return LOG_LEVEL_NONE;
|
||||
|
@ -654,12 +704,12 @@ enum ws_log_level ws_log_set_fatal(enum ws_log_level level)
|
|||
}
|
||||
|
||||
|
||||
enum ws_log_level ws_log_set_fatal_str(const char *str_level)
|
||||
enum ws_log_level ws_log_set_fatal_level_str(const char *str_level)
|
||||
{
|
||||
enum ws_log_level level;
|
||||
|
||||
level = string_to_log_level(str_level);
|
||||
return ws_log_set_fatal(level);
|
||||
return ws_log_set_fatal_level(level);
|
||||
}
|
||||
|
||||
|
||||
|
@ -760,7 +810,7 @@ void ws_log_init(const char *progname,
|
|||
|
||||
env = g_getenv(ENV_VAR_FATAL);
|
||||
if (env != NULL) {
|
||||
if (ws_log_set_fatal_str(env) == LOG_LEVEL_NONE) {
|
||||
if (ws_log_set_fatal_level_str(env) == LOG_LEVEL_NONE) {
|
||||
print_err(vcmdarg_err, LOG_ARGS_NOEXIT,
|
||||
"Ignoring invalid environment value %s=\"%s\"",
|
||||
ENV_VAR_FATAL, env);
|
||||
|
@ -773,6 +823,12 @@ void ws_log_init(const char *progname,
|
|||
else if ((env = g_getenv(ENV_VAR_DOMAIN)) != NULL)
|
||||
ws_log_set_domain_filter(env);
|
||||
|
||||
/* Alias "domain" and "domains". The plural form wins. */
|
||||
if ((env = g_getenv(ENV_VAR_FATAL_DOMAIN_S)) != NULL)
|
||||
ws_log_set_fatal_domain_filter(env);
|
||||
else if ((env = g_getenv(ENV_VAR_FATAL_DOMAIN)) != NULL)
|
||||
ws_log_set_fatal_domain_filter(env);
|
||||
|
||||
env = g_getenv(ENV_VAR_DEBUG);
|
||||
if (env != NULL)
|
||||
ws_log_set_debug_filter(env);
|
||||
|
@ -975,6 +1031,12 @@ static void log_write_dispatch(const char *domain, enum ws_log_level level,
|
|||
if (level >= fatal_log_level && level != LOG_LEVEL_ECHO) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (fatal_filter != NULL) {
|
||||
if (filter_contains(fatal_filter, domain) && fatal_filter->positive) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -128,6 +128,14 @@ enum ws_log_level ws_log_set_level_str(const char *str_level);
|
|||
WS_DLL_PUBLIC
|
||||
void ws_log_set_domain_filter(const char *domain_filter);
|
||||
|
||||
/** Set a fatal domain filter from a string.
|
||||
*
|
||||
* Domain filter is a case insensitive list separated by ',' or ';'. Domains
|
||||
* in the filter will cause the program to abort.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
void ws_log_set_fatal_domain_filter(const char *domain_filter);
|
||||
|
||||
|
||||
/** Set a debug filter from a string.
|
||||
*
|
||||
|
@ -155,7 +163,7 @@ void ws_log_set_noisy_filter(const char *str_filter);
|
|||
* Level LOG_LEVEL_ERROR is always fatal.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
enum ws_log_level ws_log_set_fatal(enum ws_log_level level);
|
||||
enum ws_log_level ws_log_set_fatal_level(enum ws_log_level level);
|
||||
|
||||
|
||||
/** Set the fatal log level from a string.
|
||||
|
@ -164,7 +172,7 @@ enum ws_log_level ws_log_set_fatal(enum ws_log_level level);
|
|||
* "warning" instead as arguments.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
enum ws_log_level ws_log_set_fatal_str(const char *str_level);
|
||||
enum ws_log_level ws_log_set_fatal_level_str(const char *str_level);
|
||||
|
||||
|
||||
/** Set the active log writer.
|
||||
|
|
Loading…
Reference in New Issue