} while (0)
static bool is_first_error = true;
+static const int cli_default_log_level = BT_LOG_WARN;
/* INI-style parsing FSM states */
enum ini_parsing_fsm_state {
static
struct bt_config_component *bt_config_component_create(
bt_component_class_type type,
- const char *plugin_name, const char *comp_cls_name)
+ const char *plugin_name, const char *comp_cls_name,
+ int init_log_level)
{
struct bt_config_component *cfg_component = NULL;
goto error;
}
+ cfg_component->log_level = init_log_level;
+
/* Start with empty parameters */
cfg_component->params = bt_value_map_create();
if (!cfg_component->params) {
* option's argument.
*/
static
-struct bt_config_component *bt_config_component_from_arg(const char *arg)
+struct bt_config_component *bt_config_component_from_arg(const char *arg,
+ int init_log_level)
{
struct bt_config_component *cfg_comp = NULL;
char *name = NULL;
goto error;
}
- cfg_comp = bt_config_component_create(type, plugin_name, comp_cls_name);
+ cfg_comp = bt_config_component_create(type, plugin_name, comp_cls_name,
+ init_log_level);
if (!cfg_comp) {
goto error;
}
OPT_HELP,
OPT_INPUT_FORMAT,
OPT_LIST,
+ OPT_LOG_LEVEL,
OPT_NAME,
OPT_NAMES,
OPT_NO_DELTA,
if (bt_common_is_setuid_setgid()) {
BT_LOGI_STR("Skipping non-system plugin paths for setuid/setgid binary.");
} else {
- char *home_plugin_dir =
- bt_common_get_home_plugin_path();
+ char *home_plugin_dir = bt_common_get_home_plugin_path(
+ BT_LOG_OUTPUT_LEVEL);
if (home_plugin_dir) {
ret = bt_config_append_plugin_paths(
static
struct bt_config *bt_config_help_create(
- const bt_value *initial_plugin_paths)
+ const bt_value *initial_plugin_paths,
+ int default_log_level)
{
struct bt_config *cfg;
}
cfg->cmd_data.help.cfg_component =
- bt_config_component_create(-1, NULL, NULL);
+ bt_config_component_create(-1, NULL, NULL, default_log_level);
if (!cfg->cmd_data.help.cfg_component) {
goto error;
}
struct bt_config *bt_config_help_from_args(int argc, const char *argv[],
int *retcode, bool force_omit_system_plugin_path,
bool force_omit_home_plugin_path,
- const bt_value *initial_plugin_paths)
+ const bt_value *initial_plugin_paths, int default_log_level)
{
poptContext pc = NULL;
char *arg = NULL;
char *plugin_name = NULL, *comp_cls_name = NULL;
*retcode = 0;
- cfg = bt_config_help_create(initial_plugin_paths);
+ cfg = bt_config_help_create(initial_plugin_paths, default_log_level);
if (!cfg) {
goto error;
}
struct bt_config *bt_config_query_from_args(int argc, const char *argv[],
int *retcode, bool force_omit_system_plugin_path,
bool force_omit_home_plugin_path,
- const bt_value *initial_plugin_paths)
+ const bt_value *initial_plugin_paths,
+ int default_log_level)
{
poptContext pc = NULL;
char *arg = NULL;
leftover = poptGetArg(pc);
if (leftover) {
cfg->cmd_data.query.cfg_component =
- bt_config_component_from_arg(leftover);
+ bt_config_component_from_arg(leftover,
+ default_log_level);
if (!cfg->cmd_data.query.cfg_component) {
printf_err("Invalid format for component class specification:\n %s\n",
leftover);
fprintf(fp, " specify the name with --name)\n");
fprintf(fp, " -x, --connect=CONNECTION Connect two created components (see the\n");
fprintf(fp, " expected format of CONNECTION below)\n");
+ fprintf(fp, " -l, --log-level=LVL Set the log level of the current component to LVL\n");
+ fprintf(fp, " (`N`, `V`, `D`, `I`, `W`, `E`, or `F`)\n");
fprintf(fp, " -n, --name=NAME Set the name of the current component\n");
fprintf(fp, " to NAME (must be unique amongst all the\n");
fprintf(fp, " names of the created components)\n");
struct bt_config *bt_config_run_from_args(int argc, const char *argv[],
int *retcode, bool force_omit_system_plugin_path,
bool force_omit_home_plugin_path,
- const bt_value *initial_plugin_paths)
+ const bt_value *initial_plugin_paths, int default_log_level)
{
poptContext pc = NULL;
char *arg = NULL;
{ "component", 'c', POPT_ARG_STRING, NULL, OPT_COMPONENT, NULL, NULL },
{ "connect", 'x', POPT_ARG_STRING, NULL, OPT_CONNECT, NULL, NULL },
{ "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL },
+ { "log-level", 'l', POPT_ARG_STRING, NULL, OPT_LOG_LEVEL, NULL, NULL },
{ "name", 'n', POPT_ARG_STRING, NULL, OPT_NAME, NULL, NULL },
{ "omit-home-plugin-path", '\0', POPT_ARG_NONE, NULL, OPT_OMIT_HOME_PLUGIN_PATH, NULL, NULL },
{ "omit-system-plugin-path", '\0', POPT_ARG_NONE, NULL, OPT_OMIT_SYSTEM_PLUGIN_PATH, NULL, NULL },
}
}
- cur_cfg_comp = bt_config_component_from_arg(arg);
+ cur_cfg_comp = bt_config_component_from_arg(arg,
+ default_log_level);
if (!cur_cfg_comp) {
printf_err("Invalid format for --component option's argument:\n %s\n",
arg);
g_string_assign(cur_cfg_comp->instance_name, arg);
break;
+ case OPT_LOG_LEVEL:
+ if (!cur_cfg_comp) {
+ printf_err("Cannot set the log level of unavailable component:\n %s\n",
+ arg);
+ goto error;
+ }
+
+ cur_cfg_comp->log_level =
+ bt_log_get_level_from_string(arg);
+ if (cur_cfg_comp->log_level < 0) {
+ printf_err("Invalid argument for --log-level option:\n %s\n",
+ arg);
+ goto error;
+ }
+ break;
case OPT_BASE_PARAMS:
{
bt_value *params =
struct bt_config *bt_config_run_from_args_array(const bt_value *run_args,
int *retcode, bool force_omit_system_plugin_path,
bool force_omit_home_plugin_path,
- const bt_value *initial_plugin_paths)
+ const bt_value *initial_plugin_paths, int default_log_level)
{
struct bt_config *cfg = NULL;
const char **argv;
cfg = bt_config_run_from_args(argc, argv, retcode,
force_omit_system_plugin_path, force_omit_home_plugin_path,
- initial_plugin_paths);
+ initial_plugin_paths, default_log_level);
end:
free(argv);
fprintf(fp, " conversion graph, and optionally name it\n");
fprintf(fp, " NAME (you can also specify the name with\n");
fprintf(fp, " --name)\n");
+ fprintf(fp, " -l, --log-level=LVL Set the log level of the current component to LVL\n");
+ fprintf(fp, " (`N`, `V`, `D`, `I`, `W`, `E`, or `F`)\n");
fprintf(fp, " --name=NAME Set the name of the current component\n");
fprintf(fp, " to NAME (must be unique amongst all the\n");
fprintf(fp, " names of the created components)\n");
{ "fields", 'f', POPT_ARG_STRING, NULL, OPT_FIELDS, NULL, NULL },
{ "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL },
{ "input-format", 'i', POPT_ARG_STRING, NULL, OPT_INPUT_FORMAT, NULL, NULL },
+ { "log-level", 'l', POPT_ARG_STRING, NULL, OPT_LOG_LEVEL, NULL, NULL },
{ "name", '\0', POPT_ARG_STRING, NULL, OPT_NAME, NULL, NULL },
{ "names", 'n', POPT_ARG_STRING, NULL, OPT_NAMES, NULL, NULL },
{ "debug-info", '\0', POPT_ARG_NONE, NULL, OPT_DEBUG_INFO, NULL, NULL },
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,
- const bt_value *initial_plugin_paths, char *log_level)
+ const bt_value *initial_plugin_paths, int *default_log_level)
{
poptContext pc = NULL;
char *arg = NULL;
}
g_string_assign(cur_name, arg);
+ break;
+ case OPT_LOG_LEVEL:
+ if (cur_name_prefix->len == 0) {
+ printf_err("No current component to assign a log level to:\n %s\n",
+ arg);
+ goto error;
+ }
+
+ if (bt_value_array_append_string_element(run_args, "--log-level")) {
+ print_err_oom();
+ goto error;
+ }
+
+ if (bt_value_array_append_string_element(run_args, arg)) {
+ print_err_oom();
+ goto error;
+ }
+
break;
case OPT_OMIT_HOME_PLUGIN_PATH:
force_omit_home_plugin_path = true;
stream_intersection_mode = true;
break;
case OPT_VERBOSE:
- if (*log_level != 'V' && *log_level != 'D') {
- *log_level = 'I';
+ if (*default_log_level != BT_LOG_TRACE &&
+ *default_log_level != BT_LOG_DEBUG) {
+ *default_log_level = BT_LOG_INFO;
}
break;
case OPT_DEBUG:
- *log_level = 'V';
+ *default_log_level = BT_LOG_TRACE;
+ break;
+ default:
break;
}
/*
* 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.
+ * the INFO log level, which is why we compare to `BT_LOG_INFO`
+ * here.
*/
- if (*log_level == 'I') {
+ if (*default_log_level == BT_LOG_INFO) {
append_implicit_component_param(&implicit_text_args,
"verbose", "yes");
}
goto end;
}
+ /*
+ * If the log level is still unset at this point, set it to
+ * the program's default.
+ */
+ if (*default_log_level < 0) {
+ *default_log_level = cli_default_log_level;
+ }
+
cfg = bt_config_run_from_args_array(run_args, retcode,
- force_omit_system_plugin_path,
- force_omit_home_plugin_path,
- initial_plugin_paths);
+ force_omit_system_plugin_path,
+ force_omit_home_plugin_path,
+ initial_plugin_paths, *default_log_level);
if (!cfg) {
goto error;
}
fprintf(fp, "\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, " -l, --log-level=LVL Set all log levels to LVL (`N`, `V`, `D`,\n");
+ fprintf(fp, " -l, --log-level=LVL Set the default log level 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, "Use `babeltrace2 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,
const char **command_argv = NULL;
int command_argc = -1;
const char *command_name = NULL;
- char log_level = 'U';
+ int default_log_level = -1;
enum command_type {
COMMAND_TYPE_NONE = -1,
if (strcmp(cur_arg, "-d") == 0 ||
strcmp(cur_arg, "--debug") == 0) {
- log_level = 'V';
+ default_log_level = BT_LOG_TRACE;
} else if (strcmp(cur_arg, "-v") == 0 ||
strcmp(cur_arg, "--verbose") == 0) {
- if (log_level != 'V' && log_level != 'D') {
+ if (default_log_level != BT_LOG_TRACE &&
+ default_log_level != BT_LOG_DEBUG) {
/*
* 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).
+ * apply, TRACE).
*/
- log_level = 'I';
+ default_log_level = BT_LOG_INFO;
}
} else if (strcmp(cur_arg, "--log-level") == 0 ||
strcmp(cur_arg, "-l") == 0) {
goto end;
}
- log_level = log_level_from_arg(next_arg);
- if (log_level == 'U') {
+ default_log_level =
+ bt_log_get_level_from_string(next_arg);
+ if (default_log_level < 0) {
printf_err("Invalid argument for --log-level option:\n %s\n",
next_arg);
*retcode = 1;
} 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') {
+ default_log_level = bt_log_get_level_from_string(arg);
+ if (default_log_level < 0) {
printf_err("Invalid argument for --log-level option:\n %s\n",
arg);
*retcode = 1;
} else if (strncmp(cur_arg, "-l", 2) == 0) {
const char *arg = &cur_arg[2];
- log_level = log_level_from_arg(arg);
- if (log_level == 'U') {
+ default_log_level = bt_log_get_level_from_string(arg);
+ if (default_log_level < 0) {
printf_err("Invalid argument for --log-level option:\n %s\n",
arg);
*retcode = 1;
BT_ASSERT(command_argv);
BT_ASSERT(command_argc >= 0);
+ /*
+ * The convert command can set its own default log level for
+ * backward compatibility reasons. It only does so if there's no
+ * log level yet, so do not force one for this command.
+ */
+ if (command_type != COMMAND_TYPE_CONVERT && default_log_level < 0) {
+ /* Default log level */
+ default_log_level = cli_default_log_level;
+ }
+
switch (command_type) {
case COMMAND_TYPE_RUN:
config = bt_config_run_from_args(command_argc, command_argv,
retcode, force_omit_system_plugin_path,
- force_omit_home_plugin_path, initial_plugin_paths);
+ force_omit_home_plugin_path, initial_plugin_paths,
+ default_log_level);
break;
case COMMAND_TYPE_CONVERT:
config = bt_config_convert_from_args(command_argc, command_argv,
retcode, force_omit_system_plugin_path,
force_omit_home_plugin_path,
- initial_plugin_paths, &log_level);
+ initial_plugin_paths, &default_log_level);
break;
case COMMAND_TYPE_LIST_PLUGINS:
config = bt_config_list_plugins_from_args(command_argc,
case COMMAND_TYPE_HELP:
config = bt_config_help_from_args(command_argc,
command_argv, retcode, force_omit_system_plugin_path,
- force_omit_home_plugin_path, initial_plugin_paths);
+ force_omit_home_plugin_path, initial_plugin_paths,
+ default_log_level);
break;
case COMMAND_TYPE_QUERY:
config = bt_config_query_from_args(command_argc,
command_argv, retcode, force_omit_system_plugin_path,
- force_omit_home_plugin_path, initial_plugin_paths);
+ force_omit_home_plugin_path, initial_plugin_paths,
+ default_log_level);
break;
default:
abort();
}
if (config) {
- if (log_level == 'U') {
- log_level = 'W';
- }
-
- config->log_level = log_level;
+ BT_ASSERT(default_log_level >= BT_LOG_TRACE);
+ config->log_level = default_log_level;
config->command_name = command_name;
}