X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=cli%2Fbabeltrace.c;h=668491e7bdaecbb02afbd50a55f2cc6f32b3eee7;hb=4adc5a41399d7a7099d40e55662282108dde13a7;hp=f63150a273632ff6d753592cd2ba854143339856;hpb=0d107cdd376ff07c7bc6da9dfd46d57463442df1;p=babeltrace.git diff --git a/cli/babeltrace.c b/cli/babeltrace.c index f63150a2..668491e7 100644 --- a/cli/babeltrace.c +++ b/cli/babeltrace.c @@ -26,6 +26,9 @@ * SOFTWARE. */ +#define BT_LOG_TAG "CLI" +#include "logging.h" + #include #include #include @@ -54,10 +57,22 @@ #include "babeltrace-cfg-cli-args.h" #include "babeltrace-cfg-cli-args-default.h" -#define BT_LOG_TAG "CLI" -#include "logging.h" - #define ENV_BABELTRACE_WARN_COMMAND_NAME_DIRECTORY_CLASH "BABELTRACE_CLI_WARN_COMMAND_NAME_DIRECTORY_CLASH" +#define ENV_BABELTRACE_CLI_LOG_LEVEL "BABELTRACE_CLI_LOG_LEVEL" + +/* + * Known environment variable names for the log levels of the project's + * modules. + */ +static const char* log_level_env_var_names[] = { + "BABELTRACE_PLUGIN_CTF_BTR_LOG_LEVEL", + "BABELTRACE_PLUGIN_CTF_FS_SRC_LOG_LEVEL", + "BABELTRACE_PLUGIN_CTF_LTTNG_LIVE_SRC_LOG_LEVEL", + "BABELTRACE_PLUGIN_CTF_METADATA_LOG_LEVEL", + "BABELTRACE_PLUGIN_CTF_NOTIF_ITER_LOG_LEVEL", + "BABELTRACE_PYTHON_PLUGIN_PROVIDER_LOG_LEVEL", + NULL, +}; /* Application's processing graph (weak) */ static struct bt_graph *the_graph; @@ -65,9 +80,6 @@ static bool canceled = false; GPtrArray *loaded_plugins; -BT_HIDDEN -int bt_cli_log_level = BT_LOG_NONE; - static void sigint_handler(int signum) { @@ -181,7 +193,7 @@ const char *component_type_str(enum bt_component_class_type type) return "filter"; case BT_COMPONENT_CLASS_TYPE_UNKNOWN: default: - return "unknown"; + return "(unknown)"; } } @@ -202,13 +214,11 @@ void print_plugin_comp_cls_opt(FILE *fh, const char *plugin_name, goto end; } - fprintf(fh, "%s%s--%s%s %s'%s%s%s%s.%s%s%s'", + fprintf(fh, "'%s%s%s%s.%s%s%s.%s%s%s'", bt_common_color_bold(), bt_common_color_fg_cyan(), component_type_str(type), - bt_common_color_reset(), bt_common_color_fg_default(), - bt_common_color_bold(), bt_common_color_fg_blue(), shell_plugin_name->str, bt_common_color_fg_default(), @@ -581,6 +591,19 @@ int load_dynamic_plugins(struct bt_value *plugin_paths) plugin_path_value = bt_value_array_get(plugin_paths, i); bt_value_string_get(plugin_path_value, &plugin_path); assert(plugin_path); + + /* + * Skip this if the directory does not exist because + * bt_plugin_create_all_from_dir() expects an existing + * directory. + */ + if (!g_file_test(plugin_path, G_FILE_TEST_IS_DIR)) { + BT_LOGV("Skipping nonexistent directory path: " + "path=\"%s\"", plugin_path); + BT_PUT(plugin_path_value); + continue; + } + plugin_set = bt_plugin_create_all_from_dir(plugin_path, false); if (!plugin_set) { BT_LOGD("Unable to load dynamic plugins: path=\"%s\"", @@ -1168,7 +1191,7 @@ int cmd_run_ctx_connect_upstream_port_to_downstream_component( uint64_t i; int64_t (*port_count_fn)(struct bt_component *); struct bt_port *(*port_by_index_fn)(struct bt_component *, uint64_t); - void *conn = NULL; + enum bt_graph_status status = BT_GRAPH_STATUS_ERROR; BT_LOGI("Connecting upstream port to the next available downstream port: " "upstream-port-addr=%p, upstream-port-name=\"%s\", " @@ -1180,7 +1203,7 @@ int cmd_run_ctx_connect_upstream_port_to_downstream_component( cfg_conn->downstream_comp_name->str); assert(downstreamp_comp_name_quark > 0); downstream_comp = g_hash_table_lookup(ctx->components, - (gpointer) (long) downstreamp_comp_name_quark); + GUINT_TO_POINTER(downstreamp_comp_name_quark)); if (!downstream_comp) { BT_LOGE("Cannot find downstream component: comp-name=\"%s\", " "conn-arg=\"%s\"", cfg_conn->downstream_comp_name->str, @@ -1233,10 +1256,35 @@ int cmd_run_ctx_connect_upstream_port_to_downstream_component( cfg_conn->downstream_port_glob->str, -1ULL, downstream_port_name, -1ULL)) { /* We have a winner! */ - conn = bt_graph_connect_ports(ctx->graph, - upstream_port, downstream_port); + status = bt_graph_connect_ports(ctx->graph, + upstream_port, downstream_port, NULL); bt_put(downstream_port); - if (!conn) { + switch (status) { + case BT_GRAPH_STATUS_OK: + break; + case BT_GRAPH_STATUS_CANCELED: + BT_LOGI_STR("Graph was canceled by user."); + status = BT_GRAPH_STATUS_OK; + break; + case BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION: + BT_LOGE("A component refused a connection to one of its ports: " + "upstream-comp-addr=%p, upstream-comp-name=\"%s\", " + "upstream-port-addr=%p, upstream-port-name=\"%s\", " + "downstream-comp-addr=%p, downstream-comp-name=\"%s\", " + "downstream-port-addr=%p, downstream-port-name=\"%s\", " + "conn-arg=\"%s\"", + upstream_comp, bt_component_get_name(upstream_comp), + upstream_port, bt_port_get_name(upstream_port), + downstream_comp, cfg_conn->downstream_comp_name->str, + downstream_port, downstream_port_name, + cfg_conn->arg->str); + fprintf(stderr, + "A component refused a connection to one of its ports (`%s` to `%s`): %s\n", + bt_port_get_name(upstream_port), + downstream_port_name, + cfg_conn->arg->str); + break; + default: BT_LOGE("Cannot create connection: graph refuses to connect ports: " "upstream-comp-addr=%p, upstream-comp-name=\"%s\", " "upstream-port-addr=%p, upstream-port-name=\"%s\", " @@ -1274,7 +1322,7 @@ int cmd_run_ctx_connect_upstream_port_to_downstream_component( bt_put(downstream_port); } - if (!conn) { + if (status != BT_GRAPH_STATUS_OK) { BT_LOGE("Cannot create connection: cannot find a matching downstream port for upstream port: " "upstream-port-addr=%p, upstream-port-name=\"%s\", " "downstream-comp-name=\"%s\", conn-arg=\"%s\"", @@ -1293,7 +1341,6 @@ error: ret = -1; end: - bt_put(conn); return ret; } @@ -1384,6 +1431,11 @@ void graph_port_added_listener(struct bt_port *port, void *data) "comp-name=\"%s\", port-addr=%p, port-name=\"%s\"", comp, comp ? bt_component_get_name(comp) : "", port, bt_port_get_name(port)); + + if (!ctx->connect_ports) { + goto end; + } + if (!comp) { BT_LOGW_STR("Port has no component."); goto end; @@ -1564,9 +1616,9 @@ int cmd_run_ctx_create_components_from_config_components( goto error; } - comp = bt_component_create(comp_cls, - cfg_comp->instance_name->str, cfg_comp->params); - if (!comp) { + ret = bt_graph_add_component(ctx->graph, comp_cls, + cfg_comp->instance_name->str, cfg_comp->params, &comp); + if (ret) { BT_LOGE("Cannot create component: plugin-name=\"%s\", " "comp-cls-name=\"%s\", comp-cls-type=%d, " "comp-name=\"%s\"", @@ -1586,7 +1638,7 @@ int cmd_run_ctx_create_components_from_config_components( quark = g_quark_from_string(cfg_comp->instance_name->str); assert(quark > 0); g_hash_table_insert(ctx->components, - (gpointer) (long) quark, comp); + GUINT_TO_POINTER(quark), comp); comp = NULL; BT_PUT(comp_cls); } @@ -1710,8 +1762,6 @@ const char *bt_graph_status_str(enum bt_graph_status status) return "BT_GRAPH_STATUS_END"; case BT_GRAPH_STATUS_OK: return "BT_GRAPH_STATUS_OK"; - case BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH: - return "BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH"; case BT_GRAPH_STATUS_INVALID: return "BT_GRAPH_STATUS_INVALID"; case BT_GRAPH_STATUS_NO_SINK: @@ -1736,6 +1786,13 @@ int cmd_run(struct bt_config *cfg) goto error; } + if (canceled) { + BT_LOGI_STR("Canceled by user before creating components."); + goto error; + } + + BT_LOGI_STR("Creating components."); + /* Create the requested component instances */ if (cmd_run_ctx_create_components(&ctx)) { BT_LOGE_STR("Cannot create components."); @@ -1743,6 +1800,13 @@ int cmd_run(struct bt_config *cfg) goto error; } + if (canceled) { + BT_LOGI_STR("Canceled by user before connecting components."); + goto error; + } + + BT_LOGI_STR("Connecting components."); + /* Connect the initially visible component ports */ if (cmd_run_ctx_connect_ports(&ctx)) { BT_LOGE_STR("Cannot connect initial component ports."); @@ -1751,7 +1815,8 @@ int cmd_run(struct bt_config *cfg) } if (canceled) { - goto end; + BT_LOGI_STR("Canceled by user before running the graph."); + goto error; } BT_LOGI_STR("Running the graph."); @@ -1845,33 +1910,128 @@ void warn_command_name_and_directory_clash(struct bt_config *cfg) static void init_log_level(void) { - enum bt_logging_level log_level = BT_LOG_NONE; - const char *log_level_env = getenv("BABELTRACE_CLI_LOG_LEVEL"); - - if (!log_level_env) { - goto set_level; - } - - if (strcmp(log_level_env, "VERBOSE") == 0) { - log_level = BT_LOGGING_LEVEL_VERBOSE; - } else if (strcmp(log_level_env, "DEBUG") == 0) { - log_level = BT_LOGGING_LEVEL_DEBUG; - } else if (strcmp(log_level_env, "INFO") == 0) { - log_level = BT_LOGGING_LEVEL_INFO; - } else if (strcmp(log_level_env, "WARN") == 0) { - log_level = BT_LOGGING_LEVEL_WARN; - } else if (strcmp(log_level_env, "ERROR") == 0) { - log_level = BT_LOGGING_LEVEL_ERROR; - } else if (strcmp(log_level_env, "FATAL") == 0) { - log_level = BT_LOGGING_LEVEL_FATAL; - } else if (strcmp(log_level_env, "NONE") == 0) { - log_level = BT_LOGGING_LEVEL_NONE; - } - -set_level: - bt_cli_log_level = log_level; + bt_cli_log_level = bt_log_get_level_from_env(ENV_BABELTRACE_CLI_LOG_LEVEL); +} + +static +void set_auto_log_levels(struct bt_config *cfg) +{ + const char **env_var_name; + + /* + * Set log levels according to --debug or --verbose. For + * backward compatibility, --debug is more verbose than + * --verbose. So: + * + * --verbose: INFO log level + * --debug: VERBOSE log level (includes DEBUG, which is + * is less verbose than VERBOSE in the internal + * logging framework) + */ + if (!getenv("BABELTRACE_LOGGING_GLOBAL_LEVEL")) { + if (cfg->verbose) { + bt_logging_set_global_level(BT_LOGGING_LEVEL_INFO); + } else if (cfg->debug) { + bt_logging_set_global_level(BT_LOGGING_LEVEL_VERBOSE); + } else { + /* + * Set library's default log level if not + * explicitly specified. + */ + 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(); + } + } + } + + if (!getenv(ENV_BABELTRACE_CLI_LOG_LEVEL)) { + if (cfg->verbose) { + bt_cli_log_level = BT_LOG_INFO; + } else if (cfg->debug) { + bt_cli_log_level = BT_LOG_VERBOSE; + } else { + /* + * Set CLI's default log level if not explicitly + * specified. + */ + 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(); + } + } + } + + env_var_name = log_level_env_var_names; + + while (*env_var_name) { + if (!getenv(*env_var_name)) { + if (cfg->verbose) { + setenv(*env_var_name, "I", 1); + } 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. + */ + val[0] = cfg->log_level; + setenv(*env_var_name, val, 1); + } + } + + env_var_name++; + } + + babeltrace_debug = cfg->debug; + babeltrace_verbose = cfg->verbose; } +static void set_sigint_handler(void) { struct sigaction new_action, old_action; @@ -1916,22 +2076,7 @@ int main(int argc, const char **argv) goto end; } - if (cfg->verbose) { - bt_cli_log_level = BT_LOGGING_LEVEL_VERBOSE; - bt_logging_set_global_level(BT_LOGGING_LEVEL_VERBOSE); - // TODO: for backward compat., set the log level - // environment variables of the known plugins - // to VERBOSE - } else if (cfg->debug) { - bt_cli_log_level = BT_LOGGING_LEVEL_DEBUG; - bt_logging_set_global_level(BT_LOGGING_LEVEL_DEBUG); - // TODO: for backward compat., set the log level - // environment variables of the known plugins - // to DEBUG - } - - babeltrace_debug = cfg->debug; - babeltrace_verbose = cfg->verbose; + set_auto_log_levels(cfg); print_cfg(cfg); if (cfg->command_needs_plugins) {