cli: add global --log-level option
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 14 Jun 2017 05:17:23 +0000 (01:17 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 14 Jun 2017 19:17:45 +0000 (15:17 -0400)
This new global option (applies before the command name) sets the
default log level of all the known (project's) loggers. This default
log level can still be overridden by a specific environment variable,
for example:

    BABELTRACE_PLUGIN_CTF_METADATA_LOG_LEVEL=D babeltrace --log-level=I ...

In this example, all the log levels are set to INFO, but
BABELTRACE_PLUGIN_CTF_METADATA_LOG_LEVEL overrides the `ctf` plugin's
metadata module's log level to DEBUG.

When you don't specify --log-level, it defaults to W (WARN), the current
behaviour.

--verbose is now the equivalent of --log-level=I, and --debug is the
equivalent of --log-level=V. --verbose and --debug do the same thing,
for the `convert` command, whether they are global or specific to the
command. --verbose and --debug can still be specified together, and
whatever the order, the lowest log level always wins: VERBOSE.
The --log-level option can override previous --verbose, --debug, or
--log-level options because it didn't exist in Babeltrace 1 anyway so
there's no way to break backward compatibility:

    babeltrace --log-level=W --verbose --log-level=E ...

In this case, the final log level is ERROR.

Other example with implicit `convert` command:

    babeltrace --log-level=E /path/to/trace -v

In this case, the command's --verbose option sets the log level to
INFO because it's lower than ERROR (set by --log-level=E).

One of the main use cases of the new --log-level option is to completely
disable logging:

    babeltrace --log-level=N ...

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
cli/babeltrace-cfg-cli-args.c
cli/babeltrace-cfg.h
cli/babeltrace.c

index e2608748b6e6381e8210acf132553dad25906566..394e9e65e318d216acb5611e6ff8ba5cec4c7d5e 100644 (file)
@@ -1775,7 +1775,7 @@ void print_help_usage(FILE *fp)
        fprintf(fp, "      --omit-system-plugin-path     Omit system plugins from plugin search path\n");
        fprintf(fp, "      --plugin-path=PATH[:PATH]...  Add PATH to the list of paths from which\n");
        fprintf(fp, "                                    dynamic plugins can be loaded\n");
-       fprintf(fp, "  -h  --help                        Show this help and quit\n");
+       fprintf(fp, "  -h, --help                        Show this help and quit\n");
        fprintf(fp, "\n");
        fprintf(fp, "See `babeltrace --help` for the list of general options.\n");
        fprintf(fp, "\n");
@@ -1964,7 +1964,7 @@ void print_query_usage(FILE *fp)
        fprintf(fp, "                                    (see the expected format of PARAMS below)\n");
        fprintf(fp, "      --plugin-path=PATH[:PATH]...  Add PATH to the list of paths from which\n");
        fprintf(fp, "                                    dynamic plugins can be loaded\n");
-       fprintf(fp, "  -h  --help                        Show this help and quit\n");
+       fprintf(fp, "  -h, --help                        Show this help and quit\n");
        fprintf(fp, "\n\n");
        print_expected_params_format(fp);
 }
@@ -2160,7 +2160,7 @@ void print_list_plugins_usage(FILE *fp)
        fprintf(fp, "      --omit-system-plugin-path     Omit system plugins from plugin search path\n");
        fprintf(fp, "      --plugin-path=PATH[:PATH]...  Add PATH to the list of paths from which\n");
        fprintf(fp, "                                    dynamic plugins can be loaded\n");
-       fprintf(fp, "  -h  --help                        Show this help and quit\n");
+       fprintf(fp, "  -h, --help                        Show this help and quit\n");
        fprintf(fp, "\n");
        fprintf(fp, "See `babeltrace --help` for the list of general options.\n");
        fprintf(fp, "\n");
@@ -2326,7 +2326,7 @@ void print_run_usage(FILE *fp)
        fprintf(fp, "                                    the current component with a name given by\n");
        fprintf(fp, "                                    the last argument of the --key option and a\n");
        fprintf(fp, "                                    value set to VAL\n");
-       fprintf(fp, "  -h  --help                        Show this help and quit\n");
+       fprintf(fp, "  -h, --help                        Show this help and quit\n");
        fprintf(fp, "\n");
        fprintf(fp, "See `babeltrace --help` for the list of general options.\n");
        fprintf(fp, "\n\n");
@@ -2793,7 +2793,7 @@ void print_convert_usage(FILE *fp)
        fprintf(fp, "                                    formatted for `xargs -0`, and quit\n");
        fprintf(fp, "  -u, --url=URL                     Set the `url` string parameter of the\n");
        fprintf(fp, "                                    current component to URL\n");
-       fprintf(fp, "  -h  --help                        Show this help and quit\n");
+       fprintf(fp, "  -h, --help                        Show this help and quit\n");
        fprintf(fp, "\n");
        fprintf(fp, "Implicit `source.ctf.fs` component options:\n");
        fprintf(fp, "\n");
@@ -3584,7 +3584,7 @@ static
 struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                int *retcode, bool force_omit_system_plugin_path,
                bool force_omit_home_plugin_path, bool force_no_debug_info,
-               struct bt_value *initial_plugin_paths)
+               struct bt_value *initial_plugin_paths, char *log_level)
 {
        poptContext pc = NULL;
        char *arg = NULL;
@@ -3592,8 +3592,6 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                        BT_CONFIG_COMPONENT_DEST_UNKNOWN;
        int opt, ret = 0;
        struct bt_config *cfg = NULL;
-       bool got_verbose_opt = false;
-       bool got_debug_opt = false;
        bool got_input_format_opt = false;
        bool got_output_format_opt = false;
        bool trimmer_has_begin = false;
@@ -4273,18 +4271,12 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                        base_implicit_ctf_input_args.exists = true;
                        break;
                case OPT_VERBOSE:
-                       if (got_verbose_opt) {
-                               printf_err("Duplicate -v/--verbose option\n");
-                               goto error;
+                       if (*log_level != 'V' && *log_level != 'D') {
+                               *log_level = 'I';
                        }
-
-                       append_implicit_component_param(&implicit_text_args,
-                               "verbose", "yes");
-                       implicit_text_args.exists = true;
-                       got_verbose_opt = true;
                        break;
                case OPT_DEBUG:
-                       got_debug_opt = true;
+                       *log_level = 'V';
                        break;
                }
 
@@ -4299,6 +4291,16 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                goto error;
        }
 
+       /*
+        * Legacy behaviour: --verbose used to make the `text` output
+        * format print more information. --verbose is now equivalent to
+        * the INFO log level, which is why we compare to 'I' here.
+        */
+       if (*log_level == 'I') {
+               append_implicit_component_param(&implicit_text_args,
+                       "verbose", "yes");
+       }
+
        /*
         * Append home and system plugin paths now that we possibly got
         * --plugin-path.
@@ -4345,8 +4347,6 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                        goto error;
                }
 
-               cfg->debug = got_debug_opt;
-               cfg->verbose = got_verbose_opt;
                gs_leftover = leftovers->data;
                g_string_assign(cfg->cmd_data.print_ctf_metadata.path,
                        gs_leftover->str);
@@ -4435,8 +4435,6 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                                        goto error;
                                }
 
-                               cfg->debug = got_debug_opt;
-                               cfg->verbose = got_verbose_opt;
                                g_string_assign(cfg->cmd_data.print_lttng_live_sessions.url,
                                        gs_leftover->str);
                                goto end;
@@ -4706,8 +4704,6 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                goto error;
        }
 
-       cfg->debug = got_debug_opt;
-       cfg->verbose = got_verbose_opt;
        goto end;
 
 error:
@@ -4763,10 +4759,12 @@ void print_gen_usage(FILE *fp)
        fprintf(fp, "\n");
        fprintf(fp, "General options:\n");
        fprintf(fp, "\n");
-       fprintf(fp, "  -d, --debug        Turn on debug mode\n");
-       fprintf(fp, "  -h  --help         Show this help and quit\n");
-       fprintf(fp, "  -v, --verbose      Turn on verbose mode\n");
-       fprintf(fp, "  -V, --version      Show version and quit\n");
+       fprintf(fp, "  -d, --debug          Enable debug mode (same as --log-level=V)\n");
+       fprintf(fp, "  -h, --help           Show this help and quit\n");
+       fprintf(fp, "      --log-level=LVL  Set all log levels to LVL (`N`, `V`, `D`,\n");
+       fprintf(fp, "                       `I`, `W` (default), `E`, or `F`)\n");
+       fprintf(fp, "  -v, --verbose        Enable verbose mode (same as --log-level=I)\n");
+       fprintf(fp, "  -V, --version        Show version and quit\n");
        fprintf(fp, "\n");
        fprintf(fp, "Available commands:\n");
        fprintf(fp, "\n");
@@ -4779,18 +4777,49 @@ void print_gen_usage(FILE *fp)
        fprintf(fp, "Use `babeltrace COMMAND --help` to show the help of COMMAND.\n");
 }
 
+static
+char log_level_from_arg(const char *arg)
+{
+       char level = 'U';
+
+       if (strcmp(arg, "VERBOSE") == 0 ||
+                       strcmp(arg, "V") == 0) {
+               level = 'V';
+       } else if (strcmp(arg, "DEBUG") == 0 ||
+                       strcmp(arg, "D") == 0) {
+               level = 'D';
+       } else if (strcmp(arg, "INFO") == 0 ||
+                       strcmp(arg, "I") == 0) {
+               level = 'I';
+       } else if (strcmp(arg, "WARN") == 0 ||
+                       strcmp(arg, "WARNING") == 0 ||
+                       strcmp(arg, "W") == 0) {
+               level = 'W';
+       } else if (strcmp(arg, "ERROR") == 0 ||
+                       strcmp(arg, "E") == 0) {
+               level = 'E';
+       } else if (strcmp(arg, "FATAL") == 0 ||
+                       strcmp(arg, "F") == 0) {
+               level = 'F';
+       } else if (strcmp(arg, "NONE") == 0 ||
+                       strcmp(arg, "N") == 0) {
+               level = 'N';
+       }
+
+       return level;
+}
+
 struct bt_config *bt_config_cli_args_create(int argc, const char *argv[],
                int *retcode, bool force_omit_system_plugin_path,
                bool force_omit_home_plugin_path, bool force_no_debug_info,
                struct bt_value *initial_plugin_paths)
 {
        struct bt_config *config = NULL;
-       bool verbose = false;
-       bool debug = false;
        int i;
        const char **command_argv = NULL;
        int command_argc = -1;
        const char *command_name = NULL;
+       char log_level = 'U';
 
        enum command_type {
                COMMAND_TYPE_NONE = -1,
@@ -4820,13 +4849,49 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[],
 
        for (i = 1; i < argc; i++) {
                const char *cur_arg = argv[i];
+               const char *next_arg = i == (argc - 1) ? NULL : argv[i + 1];
 
                if (strcmp(cur_arg, "-d") == 0 ||
                                strcmp(cur_arg, "--debug") == 0) {
-                       debug = true;
+                       log_level = 'V';
                } else if (strcmp(cur_arg, "-v") == 0 ||
                                strcmp(cur_arg, "--verbose") == 0) {
-                       verbose = true;
+                       if (log_level != 'V' && log_level != 'D') {
+                               /*
+                                * Legacy: do not override a previous
+                                * --debug because --verbose and --debug
+                                * can be specified together (in this
+                                * case we want the lowest log level to
+                                * apply, VERBOSE).
+                                */
+                               log_level = 'I';
+                       }
+               } else if (strcmp(cur_arg, "--log-level") == 0) {
+                       if (!next_arg) {
+                               printf_err("Missing log level value for --log-level option\n");
+                               *retcode = 1;
+                               goto end;
+                       }
+
+                       log_level = log_level_from_arg(next_arg);
+                       if (log_level == 'U') {
+                               printf_err("Invalid argument for --log-level option:\n    %s\n",
+                                       next_arg);
+                               *retcode = 1;
+                               goto end;
+                       }
+
+                       i++;
+               } else if (strncmp(cur_arg, "--log-level=", 12) == 0) {
+                       const char *arg = &cur_arg[12];
+
+                       log_level = log_level_from_arg(arg);
+                       if (log_level == 'U') {
+                               printf_err("Invalid argument for --log-level option:\n    %s\n",
+                                       arg);
+                               *retcode = 1;
+                               goto end;
+                       }
                } else if (strcmp(cur_arg, "-V") == 0 ||
                                strcmp(cur_arg, "--version") == 0) {
                        print_version();
@@ -4836,12 +4901,13 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[],
                        print_gen_usage(stdout);
                        goto end;
                } else {
-                       bool has_command = true;
-
                        /*
                         * First unknown argument: is it a known command
                         * name?
                         */
+                       command_argv = &argv[i];
+                       command_argc = argc - i;
+
                        if (strcmp(cur_arg, "convert") == 0) {
                                command_type = COMMAND_TYPE_CONVERT;
                        } else if (strcmp(cur_arg, "list-plugins") == 0) {
@@ -4855,20 +4921,13 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[],
                        } else {
                                /*
                                 * Unknown argument, but not a known
-                                * command name: assume the whole
-                                * arguments are for the default convert
-                                * command.
+                                * command name: assume the default
+                                * `convert` command.
                                 */
                                command_type = COMMAND_TYPE_CONVERT;
-                               command_argv = argv;
-                               command_argc = argc;
-                               has_command = false;
-                       }
-
-                       if (has_command) {
-                               command_argv = &argv[i];
-                               command_argc = argc - i;
-                               command_name = cur_arg;
+                               command_name = "convert";
+                               command_argv = &argv[i - 1];
+                               command_argc = argc - i + 1;
                        }
                        break;
                }
@@ -4898,7 +4957,7 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[],
                config = bt_config_convert_from_args(command_argc, command_argv,
                        retcode, force_omit_system_plugin_path,
                        force_omit_home_plugin_path, force_no_debug_info,
-                       initial_plugin_paths);
+                       initial_plugin_paths, &log_level);
                break;
        case COMMAND_TYPE_LIST_PLUGINS:
                config = bt_config_list_plugins_from_args(command_argc,
@@ -4920,14 +4979,11 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[],
        }
 
        if (config) {
-               if (verbose) {
-                       config->verbose = true;
-               }
-
-               if (debug) {
-                       config->debug = true;
+               if (log_level == 'U') {
+                       log_level = 'W';
                }
 
+               config->log_level = log_level;
                config->command_name = command_name;
        }
 
index 8723129587918c155a95993930441773428ebf14..b9a4b5edd89736c274f1b002bbda241817347976 100644 (file)
@@ -70,6 +70,7 @@ struct bt_config {
        bool omit_home_plugin_path;
        bool command_needs_plugins;
        const char *command_name;
+       char log_level;
        enum bt_config_command command;
        union {
                /* BT_CONFIG_COMMAND_RUN */
index d7eeec614f8c6a93bba33b768946352cbb8cdf78..668491e7bdaecbb02afbd50a55f2cc6f32b3eee7 100644 (file)
@@ -1938,7 +1938,31 @@ void set_auto_log_levels(struct bt_config *cfg)
                         * Set library's default log level if not
                         * explicitly specified.
                         */
-                       bt_logging_set_global_level(BT_LOGGING_LEVEL_WARN);
+                       switch (cfg->log_level) {
+                       case 'N':
+                               bt_logging_set_global_level(BT_LOGGING_LEVEL_NONE);
+                               break;
+                       case 'V':
+                               bt_logging_set_global_level(BT_LOGGING_LEVEL_VERBOSE);
+                               break;
+                       case 'D':
+                               bt_logging_set_global_level(BT_LOGGING_LEVEL_DEBUG);
+                               break;
+                       case 'I':
+                               bt_logging_set_global_level(BT_LOGGING_LEVEL_INFO);
+                               break;
+                       case 'W':
+                               bt_logging_set_global_level(BT_LOGGING_LEVEL_WARN);
+                               break;
+                       case 'E':
+                               bt_logging_set_global_level(BT_LOGGING_LEVEL_ERROR);
+                               break;
+                       case 'F':
+                               bt_logging_set_global_level(BT_LOGGING_LEVEL_FATAL);
+                               break;
+                       default:
+                               abort();
+                       }
                }
        }
 
@@ -1952,7 +1976,31 @@ void set_auto_log_levels(struct bt_config *cfg)
                         * Set CLI's default log level if not explicitly
                         * specified.
                         */
-                       bt_cli_log_level = BT_LOG_WARN;
+                       switch (cfg->log_level) {
+                       case 'N':
+                               bt_cli_log_level = BT_LOG_NONE;
+                               break;
+                       case 'V':
+                               bt_cli_log_level = BT_LOG_VERBOSE;
+                               break;
+                       case 'D':
+                               bt_cli_log_level = BT_LOG_DEBUG;
+                               break;
+                       case 'I':
+                               bt_cli_log_level = BT_LOG_INFO;
+                               break;
+                       case 'W':
+                               bt_cli_log_level = BT_LOG_WARN;
+                               break;
+                       case 'E':
+                               bt_cli_log_level = BT_LOG_ERROR;
+                               break;
+                       case 'F':
+                               bt_cli_log_level = BT_LOG_FATAL;
+                               break;
+                       default:
+                               abort();
+                       }
                }
        }
 
@@ -1965,11 +2013,14 @@ void set_auto_log_levels(struct bt_config *cfg)
                        } else if (cfg->debug) {
                                setenv(*env_var_name, "V", 1);
                        } else {
+                               char val[2] = { 0 };
+
                                /*
                                 * Set module's default log level if not
                                 * explicitly specified.
                                 */
-                               setenv(*env_var_name, "W", 1);
+                               val[0] = cfg->log_level;
+                               setenv(*env_var_name, val, 1);
                        }
                }
 
This page took 0.032626 seconds and 4 git commands to generate.