* SOFTWARE.
*/
+#define BT_LOG_TAG "CLI"
+#include "logging.h"
+
#include <babeltrace/babeltrace.h>
#include <babeltrace/plugin/plugin.h>
#include <babeltrace/common-internal.h>
#include <glib.h>
#include <inttypes.h>
#include <unistd.h>
+#include <signal.h>
#include "babeltrace-cfg.h"
#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_COMMON_LOG_LEVEL",
+ "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_PLUGIN_LTTNG_UTILS_DEBUG_INFO_FLT_LOG_LEVEL",
+ "BABELTRACE_PLUGIN_UTILS_TRIMMER_FLT_LOG_LEVEL",
+ "BABELTRACE_PYTHON_PLUGIN_PROVIDER_LOG_LEVEL",
+ NULL,
+};
+
+/* Application's processing graph (weak) */
+static struct bt_graph *the_graph;
+static bool canceled = false;
GPtrArray *loaded_plugins;
-BT_HIDDEN
-int bt_cli_log_level = BT_LOG_NONE;
+static
+void sigint_handler(int signum)
+{
+ if (signum != SIGINT) {
+ return;
+ }
+
+ if (the_graph) {
+ bt_graph_cancel(the_graph);
+ }
+
+ canceled = true;
+}
static
void init_static_data(void)
return "filter";
case BT_COMPONENT_CLASS_TYPE_UNKNOWN:
default:
- return "unknown";
+ return "(unknown)";
}
}
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(),
break;
}
default:
- assert(false);
+ abort();
}
}
print_cfg_print_lttng_live_sessions(cfg);
break;
default:
- assert(false);
+ abort();
}
}
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\"",
static
int cmd_query(struct bt_config *cfg)
{
- int ret;
+ int ret = 0;
struct bt_component_class *comp_cls = NULL;
struct bt_value *results = NULL;
- ret = load_all_plugins(cfg->plugin_paths);
- if (ret) {
- goto end;
- }
-
comp_cls = find_component_class(cfg->cmd_data.query.cfg_component->plugin_name->str,
cfg->cmd_data.query.cfg_component->comp_cls_name->str,
cfg->cmd_data.query.cfg_component->type);
static
int cmd_help(struct bt_config *cfg)
{
- int ret;
+ int ret = 0;
struct bt_plugin *plugin = NULL;
size_t i;
- ret = load_all_plugins(cfg->plugin_paths);
- if (ret) {
- goto end;
- }
-
plugin = find_plugin(cfg->cmd_data.help.cfg_component->plugin_name->str);
if (!plugin) {
BT_LOGE("Cannot find plugin: plugin-name=\"%s\"",
int ret = 0;
int plugins_count, component_classes_count = 0, i;
- ret = load_all_plugins(cfg->plugin_paths);
- if (ret) {
- goto end;
- }
-
printf("From the following plugin paths:\n\n");
print_value(stdout, cfg->plugin_paths, 2);
printf("\n");
static
int cmd_print_lttng_live_sessions(struct bt_config *cfg)
{
- printf("TODO\n");
- return -1;
+ int ret = 0;
+ struct bt_component_class *comp_cls = NULL;
+ struct bt_value *results = NULL;
+ struct bt_value *params = NULL;
+ struct bt_value *map = NULL;
+ struct bt_value *v = NULL;
+ static const char * const plugin_name = "ctf";
+ static const char * const comp_cls_name = "lttng-live";
+ static const enum bt_component_class_type comp_cls_type =
+ BT_COMPONENT_CLASS_TYPE_SOURCE;
+ int64_t array_size, i;
+
+ assert(cfg->cmd_data.print_lttng_live_sessions.url);
+ comp_cls = find_component_class(plugin_name, comp_cls_name,
+ comp_cls_type);
+ if (!comp_cls) {
+ BT_LOGE("Cannot find component class: plugin-name=\"%s\", "
+ "comp-cls-name=\"%s\", comp-cls-type=%d",
+ plugin_name, comp_cls_name,
+ BT_COMPONENT_CLASS_TYPE_SOURCE);
+ fprintf(stderr, "%s%sCannot find component class %s",
+ bt_common_color_bold(),
+ bt_common_color_fg_red(),
+ bt_common_color_reset());
+ print_plugin_comp_cls_opt(stderr, plugin_name,
+ comp_cls_name, comp_cls_type);
+ fprintf(stderr, "\n");
+ goto error;
+ }
+
+ params = bt_value_map_create();
+ if (!params) {
+ goto error;
+ }
+
+ ret = bt_value_map_insert_string(params, "url",
+ cfg->cmd_data.print_lttng_live_sessions.url->str);
+ if (ret) {
+ goto error;
+ }
+
+ results = bt_component_class_query(comp_cls, "sessions",
+ params);
+ if (!results) {
+ BT_LOGE_STR("Failed to query for sessions.");
+ fprintf(stderr, "%s%sFailed to request sessions%s\n",
+ bt_common_color_bold(),
+ bt_common_color_fg_red(),
+ bt_common_color_reset());
+ goto error;
+ }
+
+ if (!bt_value_is_array(results)) {
+ BT_LOGE_STR("Expecting an array for sessions query.");
+ fprintf(stderr, "%s%sUnexpected type returned by session query%s\n",
+ bt_common_color_bold(),
+ bt_common_color_fg_red(),
+ bt_common_color_reset());
+ goto error;
+ }
+
+ array_size = bt_value_array_size(results);
+ for (i = 0; i < array_size; i++) {
+ const char *url_text;
+ int64_t timer_us, streams, clients;
+
+ map = bt_value_array_get(results, i);
+ if (!map) {
+ BT_LOGE_STR("Unexpected empty array entry.");
+ goto error;
+ }
+ if (!bt_value_is_map(map)) {
+ BT_LOGE_STR("Unexpected entry type.");
+ goto error;
+ }
+
+ v = bt_value_map_get(map, "url");
+ if (!v) {
+ BT_LOGE_STR("Unexpected empty array \"url\" entry.");
+ goto error;
+ }
+ ret = bt_value_string_get(v, &url_text);
+ assert(ret == 0);
+ printf("%s", url_text);
+ BT_PUT(v);
+
+ v = bt_value_map_get(map, "timer-us");
+ if (!v) {
+ BT_LOGE_STR("Unexpected empty array \"timer-us\" entry.");
+ goto error;
+ }
+ ret = bt_value_integer_get(v, &timer_us);
+ assert(ret == 0);
+ printf(" (timer = %" PRIu64 ", ", timer_us);
+ BT_PUT(v);
+
+ v = bt_value_map_get(map, "stream-count");
+ if (!v) {
+ BT_LOGE_STR("Unexpected empty array \"stream-count\" entry.");
+ goto error;
+ }
+ ret = bt_value_integer_get(v, &streams);
+ assert(ret == 0);
+ printf("%" PRIu64 " stream(s), ", streams);
+ BT_PUT(v);
+
+ v = bt_value_map_get(map, "client-count");
+ if (!v) {
+ BT_LOGE_STR("Unexpected empty array \"client-count\" entry.");
+ goto error;
+ }
+ ret = bt_value_integer_get(v, &clients);
+ assert(ret == 0);
+ printf("%" PRIu64 " client(s) connected)\n", clients);
+ BT_PUT(v);
+
+ BT_PUT(map);
+ }
+end:
+ bt_put(v);
+ bt_put(map);
+ bt_put(results);
+ bt_put(params);
+ bt_put(comp_cls);
+ return 0;
+
+error:
+ ret = -1;
+ goto end;
}
static
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\", "
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,
*/
BT_LOGF("Invalid connection: downstream component is a source: "
"conn-arg=\"%s\"", cfg_conn->arg->str);
- assert(false);
+ abort();
}
downstream_port_count = port_count_fn(downstream_comp);
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\", "
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\"",
ret = -1;
end:
- bt_put(conn);
return ret;
}
struct bt_component *comp = NULL;
struct cmd_run_ctx *ctx = data;
- BT_LOGI("Port added to a graph's component: port-addr=%p, port-name=\"%s\"",
+ comp = bt_port_get_component(port);
+ BT_LOGI("Port added to a graph's component: comp-addr=%p, "
+ "comp-name=\"%s\", port-addr=%p, port-name=\"%s\"",
+ comp, comp ? bt_component_get_name(comp) : "",
port, bt_port_get_name(port));
- if (bt_port_is_connected(port)) {
- BT_LOGW_STR("Port is already connected.");
+ if (!ctx->connect_ports) {
goto end;
}
- comp = bt_port_get_component(port);
if (!comp) {
BT_LOGW_STR("Port has no component.");
goto end;
}
+ if (bt_port_is_connected(port)) {
+ BT_LOGW_STR("Port is already connected.");
+ goto end;
+ }
+
if (!bt_port_is_output(port)) {
BT_LOGI_STR("Skipping input port.");
goto end;
void graph_ports_connected_listener(struct bt_port *upstream_port,
struct bt_port *downstream_port, void *data)
{
+ struct bt_component *upstream_comp = bt_port_get_component(upstream_port);
+ struct bt_component *downstream_comp = bt_port_get_component(downstream_port);
+
+ assert(upstream_comp);
+ assert(downstream_comp);
BT_LOGI("Graph's component ports connected: "
+ "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\"",
+ upstream_comp, bt_component_get_name(upstream_comp),
upstream_port, bt_port_get_name(upstream_port),
+ downstream_comp, bt_component_get_name(downstream_comp),
downstream_port, bt_port_get_name(downstream_port));
+ bt_put(upstream_comp);
+ bt_put(downstream_comp);
}
static
}
BT_PUT(ctx->graph);
+ the_graph = NULL;
ctx->cfg = NULL;
}
goto error;
}
+ the_graph = ctx->graph;
ret = bt_graph_add_port_added_listener(ctx->graph,
graph_port_added_listener, ctx);
- if (ret) {
+ if (ret < 0) {
+ BT_LOGE_STR("Cannot add \"port added\" listener to graph.");
goto error;
}
ret = bt_graph_add_port_removed_listener(ctx->graph,
graph_port_removed_listener, ctx);
- if (ret) {
+ if (ret < 0) {
+ BT_LOGE_STR("Cannot add \"port removed\" listener to graph.");
goto error;
}
ret = bt_graph_add_ports_connected_listener(ctx->graph,
graph_ports_connected_listener, ctx);
- if (ret) {
+ if (ret < 0) {
+ BT_LOGE_STR("Cannot add \"ports connected\" listener to graph.");
goto error;
}
ret = bt_graph_add_ports_disconnected_listener(ctx->graph,
graph_ports_disconnected_listener, ctx);
- if (ret) {
+ if (ret < 0) {
+ BT_LOGE_STR("Cannot add \"ports disconnected\" listener to graph.");
goto error;
}
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-cls-name=\"%s\", comp-cls-type=%d, "
"comp-name=\"%s\"",
cfg_comp->plugin_name->str,
cfg_comp->comp_cls_name->str,
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);
}
return ret;
}
+static inline
+const char *bt_graph_status_str(enum bt_graph_status status)
+{
+ switch (status) {
+ case BT_GRAPH_STATUS_CANCELED:
+ return "BT_GRAPH_STATUS_CANCELED";
+ case BT_GRAPH_STATUS_AGAIN:
+ return "BT_GRAPH_STATUS_AGAIN";
+ case BT_GRAPH_STATUS_END:
+ return "BT_GRAPH_STATUS_END";
+ case BT_GRAPH_STATUS_OK:
+ return "BT_GRAPH_STATUS_OK";
+ case BT_GRAPH_STATUS_INVALID:
+ return "BT_GRAPH_STATUS_INVALID";
+ case BT_GRAPH_STATUS_NO_SINK:
+ return "BT_GRAPH_STATUS_NO_SINK";
+ case BT_GRAPH_STATUS_ERROR:
+ return "BT_GRAPH_STATUS_ERROR";
+ default:
+ return "(unknown)";
+ }
+}
+
static
int cmd_run(struct bt_config *cfg)
{
int ret = 0;
struct cmd_run_ctx ctx = { 0 };
- ret = load_all_plugins(cfg->plugin_paths);
- if (ret) {
- goto error;
- }
-
/* Initialize the command's context and the graph object */
if (cmd_run_ctx_init(&ctx, cfg)) {
BT_LOGE_STR("Cannot initialize the command's context.");
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.");
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.");
goto error;
}
+ if (canceled) {
+ BT_LOGI_STR("Canceled by user before running the graph.");
+ goto error;
+ }
+
BT_LOGI_STR("Running the graph.");
/* Run the graph */
while (true) {
enum bt_graph_status graph_status = bt_graph_run(ctx.graph);
+ /*
+ * Reset console in case something messed with console
+ * codes during the graph's execution.
+ */
+ printf("%s", bt_common_color_reset());
+ fflush(stdout);
+ fprintf(stderr, "%s", bt_common_color_reset());
+ BT_LOGV("bt_graph_run() returned: status=%s",
+ bt_graph_status_str(graph_status));
+
switch (graph_status) {
case BT_GRAPH_STATUS_OK:
break;
+ case BT_GRAPH_STATUS_CANCELED:
+ BT_LOGI_STR("Graph was canceled by user.");
+ goto error;
case BT_GRAPH_STATUS_AGAIN:
+ if (bt_graph_is_canceled(ctx.graph)) {
+ BT_LOGI_STR("Graph was canceled by user.");
+ goto error;
+ }
+
if (cfg->cmd_data.run.retry_duration_us > 0) {
BT_LOGV("Got BT_GRAPH_STATUS_AGAIN: sleeping: "
"time-us=%" PRIu64,
cfg->cmd_data.run.retry_duration_us);
if (usleep(cfg->cmd_data.run.retry_duration_us)) {
- // TODO: check EINTR and signal handler
+ if (bt_graph_is_canceled(ctx.graph)) {
+ BT_LOGI_STR("Graph was canceled by user.");
+ goto error;
+ }
}
}
break;
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;
+
+ /*
+ * Override the configuration's default log level if
+ * BABELTRACE_VERBOSE or BABELTRACE_DEBUG environment variables
+ * are found for backward compatibility with legacy Babetrace 1.
+ */
+ if (getenv("BABELTRACE_DEBUG") &&
+ strcmp(getenv("BABELTRACE_DEBUG"), "1") == 0) {
+ cfg->log_level = 'V';
+ } else if (getenv("BABELTRACE_VERBOSE") &&
+ strcmp(getenv("BABELTRACE_VERBOSE"), "1") == 0) {
+ cfg->log_level = 'I';
+ }
+
+ /*
+ * 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++;
+ }
+}
+
+static
+void set_sigint_handler(void)
+{
+ struct sigaction new_action, old_action;
+
+ new_action.sa_handler = sigint_handler;
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = 0;
+ sigaction(SIGINT, NULL, &old_action);
+
+ if (old_action.sa_handler != SIG_IGN) {
+ sigaction(SIGINT, &new_action, NULL);
+ }
}
int main(int argc, const char **argv)
struct bt_config *cfg;
init_log_level();
+ set_sigint_handler();
init_static_data();
cfg = bt_config_cli_args_create_with_default(argc, argv, &retcode);
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) {
ret = cmd_print_lttng_live_sessions(cfg);
break;
default:
- BT_LOGF("Invalid command: cmd=%d", cfg->command);
- assert(false);
+ BT_LOGF("Invalid/unknown command: cmd=%d", cfg->command);
+ abort();
}
+ BT_LOGI("Command completed: cmd=%d, command-name=\"%s\", ret=%d",
+ cfg->command, cfg->command_name, ret);
warn_command_name_and_directory_clash(cfg);
retcode = ret ? 1 : 0;