From 1b2b6649155543b87bca6cca9b7fcafc5900dc43 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Thu, 1 Aug 2019 18:43:31 -0400 Subject: [PATCH] cli: apply log levels (`--log-level` option) to leftovers It is currently not possible to apply --log-level after a leftover. This patch proposes a way to allow it and to deal with the ambiguity that it poses. In the simple case, we have: babeltrace2 my-traces --log-level=TRACE All source components auto-discovered from the `my-traces` leftover will have the TRACE log level. If we have more than one leftover, but _no_ cross-leftover grouping, then it is also intuitive: babeltrace2 my-traces-1 --log-level=TRACE my-traces-2 --log-level=DEBUG ... all source components discovered from `my-traces-1` will have log level TRACE and all source components discovered from `my-traces-2` will have log level DEBUG. It becomes less obvious when components are given inputs coming from multiple leftovers (because of the auto-discovery grouping feature): which log level do they receive? For example, if the following line: babeltrace2 my-traces-1 --log-level=TRACE my-traces-2 --log-level=DEBUG leads to these components getting instantiated, with these inputs: * Source component X with inputs `my-traces-1/x` and `my-traces-2/x`. * Source component Y with input `my-traces-1/y` In this case, each component receives (on the `run` command line) the log level options of all leftovers that contributed to its inputs, in the same order as they are provided on the command line. The resulting `run` command line for the example above could therefore look like: ... --component x:src.my.comp --log-level=TRACE --log-level=DEBUG \ --component y:src.my.comp --log-level=TRACE resulting in these effective log levels: * Source component X: log level DEBUG * Source component Y: log level TRACE Change-Id: I5e1bf9e1b4dd139ff7900d81b302a1eda72fb37f Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/1810 Tested-by: jenkins Reviewed-by: Philippe Proulx --- src/cli/babeltrace2-cfg-cli-args.c | 83 ++++++++++++++--- .../test_auto_source_discovery_log_level | 92 +++++++++++++++++++ .../convert/test_auto_source_discovery_params | 12 ++- tests/cli/convert/test_convert_args | 3 +- .../bt_plugin_test.py | 25 ++++- .../dir-a/aaa | 0 .../dir-ab/aaa | 0 .../dir-ab/bbb | 0 .../dir-b/bbb | 0 9 files changed, 189 insertions(+), 26 deletions(-) create mode 100755 tests/cli/convert/test_auto_source_discovery_log_level rename tests/data/cli/convert/{auto-source-discovery-params => auto-source-discovery-params-log-level}/bt_plugin_test.py (69%) rename tests/data/cli/convert/{auto-source-discovery-params => auto-source-discovery-params-log-level}/dir-a/aaa (100%) rename tests/data/cli/convert/{auto-source-discovery-params => auto-source-discovery-params-log-level}/dir-ab/aaa (100%) rename tests/data/cli/convert/{auto-source-discovery-params => auto-source-discovery-params-log-level}/dir-ab/bbb (100%) rename tests/data/cli/convert/{auto-source-discovery-params => auto-source-discovery-params-log-level}/dir-b/bbb (100%) diff --git a/src/cli/babeltrace2-cfg-cli-args.c b/src/cli/babeltrace2-cfg-cli-args.c index a332bf72..72ac4f14 100644 --- a/src/cli/babeltrace2-cfg-cli-args.c +++ b/src/cli/babeltrace2-cfg-cli-args.c @@ -3194,6 +3194,7 @@ static int create_implicit_component_args_from_auto_discovered_sources( const struct auto_source_discovery *auto_disc, const bt_value *leftover_params, + const bt_value *leftover_loglevels, GPtrArray *component_args) { gchar *cc_name = NULL; @@ -3221,8 +3222,8 @@ int create_implicit_component_args_from_auto_discovered_sources( } /* - * Append parameters of all the leftovers that contributed to - * this component instance coming into existence. + * Append parameters and log levels of all the leftovers that + * contributed to this component instance coming into existence. */ orig_indices_count = bt_value_array_get_size(res->original_input_indices); for (orig_indices_i = 0; orig_indices_i < orig_indices_count; orig_indices_i++) { @@ -3234,6 +3235,7 @@ int create_implicit_component_args_from_auto_discovered_sources( bt_value_array_borrow_element_by_index_const( leftover_params, orig_idx); uint64_t params_i, params_count; + const bt_value *loglevel_value; params_count = bt_value_array_get_size(params_array); for (params_i = 0; params_i < params_count; params_i++) { @@ -3257,6 +3259,27 @@ int create_implicit_component_args_from_auto_discovered_sources( goto error; } } + + loglevel_value = bt_value_array_borrow_element_by_index_const( + leftover_loglevels, orig_idx); + if (bt_value_get_type(loglevel_value) == BT_VALUE_TYPE_STRING) { + const char *loglevel = bt_value_string_get(loglevel_value); + bt_value_array_append_element_status append_status; + + append_status = bt_value_array_append_string_element( + comp->extra_params, "--log-level"); + if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { + BT_CLI_LOGE_APPEND_CAUSE("Failed to append array element."); + goto error; + } + + append_status = bt_value_array_append_string_element( + comp->extra_params, loglevel); + if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { + BT_CLI_LOGE_APPEND_CAUSE("Failed to append array element."); + goto error; + } + } } status = append_parameter_to_args(comp->extra_params, "inputs", res->inputs); @@ -3331,6 +3354,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], GList *sink_names = NULL; bt_value *leftovers = NULL; bt_value *leftover_params = NULL; + bt_value *leftover_loglevels = NULL; struct implicit_component_args implicit_ctf_output_args = { 0 }; struct implicit_component_args implicit_lttng_live_args = { 0 }; struct implicit_component_args implicit_dummy_args = { 0 }; @@ -3445,6 +3469,12 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } + leftover_loglevels = bt_value_array_create(); + if (!leftover_loglevels) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto error; + } + if (auto_source_discovery_init(&auto_disc) != 0) { goto error; } @@ -3628,20 +3658,36 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } break; case OPT_LOG_LEVEL: - if (current_item_type != CONVERT_CURRENT_ITEM_TYPE_COMPONENT) { - BT_CLI_LOGE_APPEND_CAUSE( - "No current component (--component option) to assign a log level to:\n %s", - arg); - goto error; - } + if (current_item_type == CONVERT_CURRENT_ITEM_TYPE_COMPONENT) { + if (bt_value_array_append_string_element(run_args, "--log-level")) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto error; + } - if (bt_value_array_append_string_element(run_args, "--log-level")) { - BT_CLI_LOGE_APPEND_CAUSE_OOM(); - goto error; - } + if (bt_value_array_append_string_element(run_args, arg)) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto error; + } + } else if (current_item_type == CONVERT_CURRENT_ITEM_TYPE_LEFTOVER) { + uint64_t idx = bt_value_array_get_size(leftover_loglevels) - 1; + bt_value *log_level_str_value; - if (bt_value_array_append_string_element(run_args, arg)) { - BT_CLI_LOGE_APPEND_CAUSE_OOM(); + log_level_str_value = bt_value_string_create_init(arg); + if (!log_level_str_value) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto error; + } + + if (bt_value_array_set_element_by_index(leftover_loglevels, idx, + log_level_str_value)) { + bt_value_put_ref(log_level_str_value); + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto error; + } + } else { + BT_CLI_LOGE_APPEND_CAUSE( + "No current component (--component option) or non-option argument to assign a log level to:\n %s", + arg); goto error; } @@ -3746,6 +3792,12 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], BT_CLI_LOGE_APPEND_CAUSE_OOM(); goto error; } + + append_status = bt_value_array_append_element(leftover_loglevels, bt_value_null); + if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto error; + } } else { abort(); } @@ -4221,7 +4273,8 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } status = create_implicit_component_args_from_auto_discovered_sources( - &auto_disc, leftover_params, discovered_source_args); + &auto_disc, leftover_params, leftover_loglevels, + discovered_source_args); if (status != 0) { goto error; } diff --git a/tests/cli/convert/test_auto_source_discovery_log_level b/tests/cli/convert/test_auto_source_discovery_log_level new file mode 100755 index 00000000..ee918895 --- /dev/null +++ b/tests/cli/convert/test_auto_source_discovery_log_level @@ -0,0 +1,92 @@ +#!/bin/bash +# +# Copyright (C) 2019 Simon Marchi +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Test log level options are applied to sources auto-discovered by the convert +# command. + +if [ "x${BT_TESTS_SRCDIR:-}" != "x" ]; then + UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh" +else + UTILSSH="$(dirname "$0")/../../utils/utils.sh" +fi + +# shellcheck source=../../utils/utils.sh +SH_TAP=1 source "$UTILSSH" + +NUM_TESTS=4 + +plan_tests $NUM_TESTS + +data_dir="${BT_TESTS_DATADIR}/cli/convert/auto-source-discovery-params-log-level" +plugin_dir="${data_dir}" +dir_a="${data_dir}/dir-a" +dir_b="${data_dir}/dir-b" +dir_ab="${data_dir}/dir-ab" + +expected_file=$(mktemp -t expected.XXXXXX) +stderr_expected=/dev/null + +print_log_level="--params print=\"log-level\"" + +debug=2 +trace=1 + +# Apply log level to two components from one leftover. +cat > "$expected_file" < "$expected_file" < "$expected_file" < "$expected_file" < "$expected_file" <