From: Jonathan Rajotte Date: Thu, 15 Apr 2021 21:35:20 +0000 (-0400) Subject: add-trigger: rename --fire-* to --rate-policy=*:value X-Git-Tag: v2.13.0-rc1~79 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=bbadb5e0b423348492c56ef7d8430087d9d9349d add-trigger: rename --fire-* to --rate-policy=*:value With the move to firing policy to the action and the renaming to rate policy, a rename of the CLI options is necessary. We introduce the following format: --rate-policy=: Where type is either: once-after or every. Value is an unsigned long long value. Signed-off-by: Jonathan Rajotte Signed-off-by: Jérémie Galarneau Change-Id: I6df264c536293e686033d0baa8fe870c75c28b8d --- diff --git a/doc/man/lttng-add-trigger.1.txt b/doc/man/lttng-add-trigger.1.txt index 5e2e90e43..211b707bc 100644 --- a/doc/man/lttng-add-trigger.1.txt +++ b/doc/man/lttng-add-trigger.1.txt @@ -13,7 +13,6 @@ SYNOPSIS [verse] *lttng* ['linkgenoptions:(GENERAL OPTIONS)'] *add-trigger* [--id ID] - [--fire-every N] [--fire-once-after N] --condition CONDITION-NAME CONDITION-ARGS --action ACTION-NAME ACTION-ARGS [--action ACTION-NAME ACTION-ARGS]... @@ -29,10 +28,6 @@ actions associated to that trigger are executed. The tracing does not have to be active for the conditions to be met, and triggers are independent from tracing sessions. -By default, a trigger fires every time its condition is met. The -'--fire-every' and '--fire-once-after' options can be used to change -this mode. - The syntax by which conditions and actions are specified is described below. diff --git a/src/bin/lttng/commands/add_trigger.c b/src/bin/lttng/commands/add_trigger.c index 27a666c5d..d460c0ffb 100644 --- a/src/bin/lttng/commands/add_trigger.c +++ b/src/bin/lttng/commands/add_trigger.c @@ -40,9 +40,8 @@ enum { OPT_CONDITION, OPT_ACTION, OPT_ID, - OPT_FIRE_ONCE_AFTER, - OPT_FIRE_EVERY, OPT_USER_ID, + OPT_RATE_POLICY, OPT_ALL, OPT_FILTER, @@ -1335,13 +1334,84 @@ error: end: return cond; } + +static struct lttng_rate_policy *parse_rate_policy(const char *policy_str) +{ + int num_token; + char **tokens = NULL; + struct lttng_rate_policy *policy = NULL; + enum lttng_rate_policy_type policy_type; + unsigned long long value; + char *policy_type_str; + char *policy_value_str; + + assert(policy_str); + + /* + * rate policy fields are separated by ':'. + */ + tokens = strutils_split(policy_str, ':', 1); + num_token = strutils_array_of_strings_len(tokens); + + /* + * Early sanity check that the number of parameter is exactly 2. + * i.e : type:value + */ + if (num_token != 2) { + ERR("Rate policy format is invalid."); + goto end; + } + + policy_type_str = tokens[0]; + policy_value_str = tokens[1]; + + /* Parse the type. */ + if (strcmp(policy_type_str, "once-after") == 0) { + policy_type = LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N; + } else if (strcmp(policy_type_str, "every") == 0) { + policy_type = LTTNG_RATE_POLICY_TYPE_EVERY_N; + } else { + ERR("Rate policy type `%s` unknown.", policy_type_str); + goto end; + } + + /* Parse the value. */ + if (utils_parse_unsigned_long_long(policy_value_str, &value) != 0) { + ERR("Failed to parse rate policy value `%s` as an integer.", + policy_value_str); + goto end; + } + + if (value == 0) { + ERR("Rate policy value `%s` must be > 0.", policy_value_str); + goto end; + } + + switch (policy_type) { + case LTTNG_RATE_POLICY_TYPE_EVERY_N: + policy = lttng_rate_policy_every_n_create(value); + break; + case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N: + policy = lttng_rate_policy_once_after_n_create(value); + break; + default: + abort(); + } + + if (policy == NULL) { + ERR("Failed to create rate policy `%s`.", policy_str); + } + +end: + strutils_free_null_terminated_array_of_strings(tokens); + return policy; +} + static const struct argpar_opt_descr notify_action_opt_descrs[] = { - { OPT_FIRE_ONCE_AFTER, '\0', "fire-once-after", true }, - { OPT_FIRE_EVERY, '\0', "fire-every", true }, + { OPT_RATE_POLICY, '\0', "rate-policy", true }, ARGPAR_OPT_DESCR_SENTINEL }; - static struct lttng_action *handle_action_notify(int *argc, const char ***argv) { @@ -1349,8 +1419,6 @@ struct lttng_action *handle_action_notify(int *argc, const char ***argv) struct argpar_state *state = NULL; struct argpar_item *item = NULL; char *error = NULL; - char *fire_once_after_str = NULL; - char *fire_every_str = NULL; struct lttng_rate_policy *policy = NULL; state = argpar_state_create(*argc, *argv, notify_action_opt_descrs); @@ -1381,27 +1449,14 @@ struct lttng_action *handle_action_notify(int *argc, const char ***argv) (const struct argpar_item_opt *) item; switch (item_opt->descr->id) { - case OPT_FIRE_ONCE_AFTER: - { - if (!assign_string(&fire_once_after_str, - item_opt->arg, - "--fire-once-after")) { - goto error; - } - - break; - } - case OPT_FIRE_EVERY: + case OPT_RATE_POLICY: { - if (!assign_string(&fire_every_str, - item_opt->arg, - "--fire-every")) { + policy = parse_rate_policy(item_opt->arg); + if (!policy) { goto error; } - break; } - default: abort(); } @@ -1424,55 +1479,6 @@ struct lttng_action *handle_action_notify(int *argc, const char ***argv) *argc -= argpar_state_get_ingested_orig_args(state); *argv += argpar_state_get_ingested_orig_args(state); - if (fire_once_after_str && fire_every_str) { - ERR("--fire-once and --fire-every are mutually exclusive."); - goto error; - } - - if (fire_once_after_str) { - unsigned long long threshold; - - if (utils_parse_unsigned_long_long( - fire_once_after_str, &threshold) != 0) { - ERR("Failed to parse `%s` as an integer.", - fire_once_after_str); - goto error; - } - - if (threshold == 0) { - ERR("Once after N policy threshold cannot be `0`."); - goto error; - } - - policy = lttng_rate_policy_once_after_n_create(threshold); - if (!policy) { - ERR("Failed to create policy once after `%s`.", - fire_once_after_str); - goto error; - } - } - - if (fire_every_str) { - unsigned long long interval; - if (utils_parse_unsigned_long_long(fire_every_str, &interval) != - 0) { - ERR("Failed to parse `%s` as an integer.", - fire_every_str); - goto error; - } - if (interval == 0) { - ERR("Every N policy interval cannot be `0`."); - goto error; - } - - policy = lttng_rate_policy_every_n_create(interval); - if (!policy) { - ERR("Failed to create policy every `%s`.", - fire_every_str); - goto error; - } - } - action = lttng_action_notify_create(); if (!action) { ERR("Failed to create notify action"); @@ -1495,8 +1501,6 @@ error: action = NULL; free(error); end: - free(fire_once_after_str); - free(fire_every_str); lttng_rate_policy_destroy(policy); argpar_state_destroy(state); argpar_item_destroy(item); @@ -1522,8 +1526,6 @@ static struct lttng_action *handle_action_simple_session_with_policy(int *argc, struct argpar_state *state = NULL; struct argpar_item *item = NULL; const char *session_name_arg = NULL; - char *fire_once_after_str = NULL; - char *fire_every_str = NULL; char *error = NULL; enum lttng_action_status action_status; struct lttng_rate_policy *policy = NULL; @@ -1532,8 +1534,7 @@ static struct lttng_action *handle_action_simple_session_with_policy(int *argc, assert(set_rate_policy_cb); const struct argpar_opt_descr rate_policy_opt_descrs[] = { - { OPT_FIRE_ONCE_AFTER, '\0', "fire-once-after", true }, - { OPT_FIRE_EVERY, '\0', "fire-every", true }, + { OPT_RATE_POLICY, '\0', "rate-policy", true }, ARGPAR_OPT_DESCR_SENTINEL }; @@ -1565,27 +1566,14 @@ static struct lttng_action *handle_action_simple_session_with_policy(int *argc, (const struct argpar_item_opt *) item; switch (item_opt->descr->id) { - case OPT_FIRE_ONCE_AFTER: - { - if (!assign_string(&fire_once_after_str, - item_opt->arg, - "--fire-once-after")) { - goto error; - } - - break; - } - case OPT_FIRE_EVERY: + case OPT_RATE_POLICY: { - if (!assign_string(&fire_every_str, - item_opt->arg, - "--fire-every")) { + policy = parse_rate_policy(item_opt->arg); + if (!policy) { goto error; } - break; } - default: abort(); } @@ -1613,55 +1601,6 @@ static struct lttng_action *handle_action_simple_session_with_policy(int *argc, goto error; } - if (fire_once_after_str && fire_every_str) { - ERR("--fire-once and --fire-every are mutually exclusive."); - goto error; - } - - if (fire_once_after_str) { - unsigned long long threshold; - - if (utils_parse_unsigned_long_long( - fire_once_after_str, &threshold) != 0) { - ERR("Failed to parse `%s` as an integer.", - fire_once_after_str); - goto error; - } - - if (threshold == 0) { - ERR("Once after N policy threshold cannot be `0`."); - goto error; - } - - policy = lttng_rate_policy_once_after_n_create(threshold); - if (!policy) { - ERR("Failed to create policy once after `%s`.", - fire_once_after_str); - goto error; - } - } - - if (fire_every_str) { - unsigned long long interval; - if (utils_parse_unsigned_long_long(fire_every_str, &interval) != - 0) { - ERR("Failed to parse `%s` as an integer.", - fire_every_str); - goto error; - } - if (interval == 0) { - ERR("Every N policy interval cannot be `0`."); - goto error; - } - - policy = lttng_rate_policy_every_n_create(interval); - if (!policy) { - ERR("Failed to create policy every `%s`.", - fire_every_str); - goto error; - } - } - action = create_action_cb(); if (!action) { ERR("Failed to allocate %s session action.", action_name); @@ -1734,8 +1673,7 @@ static const struct argpar_opt_descr snapshot_action_opt_descrs[] = { { OPT_DATA_URL, '\0', "data-url", true }, { OPT_URL, '\0', "url", true }, { OPT_PATH, '\0', "path", true }, - { OPT_FIRE_ONCE_AFTER, '\0', "fire-once-after", true }, - { OPT_FIRE_EVERY, '\0', "fire-every", true }, + { OPT_RATE_POLICY, '\0', "rate-policy", true }, ARGPAR_OPT_DESCR_SENTINEL }; @@ -1754,8 +1692,6 @@ struct lttng_action *handle_action_snapshot_session(int *argc, char *url_arg = NULL; char *path_arg = NULL; char *error = NULL; - char *fire_once_after_str = NULL; - char *fire_every_str = NULL; enum lttng_action_status action_status; struct lttng_snapshot_output *snapshot_output = NULL; struct lttng_rate_policy *policy = NULL; @@ -1826,27 +1762,14 @@ struct lttng_action *handle_action_snapshot_session(int *argc, } break; - case OPT_FIRE_ONCE_AFTER: - { - if (!assign_string(&fire_once_after_str, - item_opt->arg, - "--fire-once-after")) { - goto error; - } - - break; - } - case OPT_FIRE_EVERY: + case OPT_RATE_POLICY: { - if (!assign_string(&fire_every_str, - item_opt->arg, - "--fire-every")) { + policy = parse_rate_policy(item_opt->arg); + if (!policy) { goto error; } - break; } - default: abort(); } @@ -1910,56 +1833,6 @@ struct lttng_action *handle_action_snapshot_session(int *argc, } } - /* Any rate policy ? */ - if (fire_once_after_str && fire_every_str) { - ERR("--fire-once and --fire-every are mutually exclusive."); - goto error; - } - - if (fire_once_after_str) { - unsigned long long threshold; - - if (utils_parse_unsigned_long_long( - fire_once_after_str, &threshold) != 0) { - ERR("Failed to parse `%s` as an integer.", - fire_once_after_str); - goto error; - } - - if (threshold == 0) { - ERR("Once after N policy threshold cannot be `0`."); - goto error; - } - - policy = lttng_rate_policy_once_after_n_create(threshold); - if (!policy) { - ERR("Failed to create policy once after `%s`.", - fire_once_after_str); - goto error; - } - } - - if (fire_every_str) { - unsigned long long interval; - if (utils_parse_unsigned_long_long(fire_every_str, &interval) != - 0) { - ERR("Failed to parse `%s` as an integer.", - fire_every_str); - goto error; - } - if (interval == 0) { - ERR("Every N policy interval cannot be `0`."); - goto error; - } - - policy = lttng_rate_policy_every_n_create(interval); - if (!policy) { - ERR("Failed to create policy every `%s`.", - fire_every_str); - goto error; - } - } - action = lttng_action_snapshot_session_create(); if (!action) { ERR("Failed to allocate snapshot session action."); diff --git a/tests/regression/tools/trigger/rate-policy/test_ust_rate_policy b/tests/regression/tools/trigger/rate-policy/test_ust_rate_policy index 27d813048..63993aa51 100755 --- a/tests/regression/tools/trigger/rate-policy/test_ust_rate_policy +++ b/tests/regression/tools/trigger/rate-policy/test_ust_rate_policy @@ -38,7 +38,7 @@ function test_rate_policy_every_n() $TRIGGER_NAME \ --condition on-event -u "tp:tptest" \ --action notify \ - --fire-every 5 + --rate-policy=every:5 # Add a trigger with a notify action for the tp:end event of the test # application. This allow us to "delimit" the reception loop for the @@ -124,7 +124,7 @@ function test_rate_policy_once_after_n() $TRIGGER_NAME \ --condition on-event -u "tp:tptest" \ --action notify \ - --fire-once-after 5 + --rate-policy=once-after:5 # Add a trigger with a notify action for the tp:end event of the test # application. This allow us to "delimit" the reception loop for the diff --git a/tests/regression/tools/trigger/test_add_trigger_cli b/tests/regression/tools/trigger/test_add_trigger_cli index 52c29120d..974938068 100755 --- a/tests/regression/tools/trigger/test_add_trigger_cli +++ b/tests/regression/tools/trigger/test_add_trigger_cli @@ -23,7 +23,7 @@ TESTDIR="$CURDIR/../../.." # shellcheck source=../../../utils/utils.sh source "$TESTDIR/utils/utils.sh" -plan_tests 231 +plan_tests 234 FULL_LTTNG_BIN="${TESTDIR}/../src/bin/lttng/${LTTNG_BIN}" @@ -92,39 +92,39 @@ test_success "--condition on-event -a -u" \ --action notify test_success "notify action polices" \ - --condition on-event -u test-fire-once-after \ + --condition on-event -u test-rate-policy=once-after \ --action notify \ - --fire-every=55 \ + --rate-policy=every:55 \ --action notify \ - --fire-once-after=55 + --rate-policy=once-after:55 test_success "start session action polices" \ - --condition on-event -u test-fire-once-after \ + --condition on-event -u test-rate-policy=once-after \ --action start-session my_session \ - --fire-every=55 \ + --rate-policy=every:55 \ --action start-session my_session \ - --fire-once-after=55 + --rate-policy=once-after:55 test_success "stop session action polices" \ - --condition on-event -u test-fire-once-after \ + --condition on-event -u test-rate-policy=once-after \ --action stop-session my_session \ - --fire-every=55 \ + --rate-policy=every:55 \ --action stop-session my_session \ - --fire-once-after=55 + --rate-policy=once-after:55 test_success "snapshot session action polices" \ - --condition on-event -u test-fire-once-after \ + --condition on-event -u test-rate-policy=once-after \ --action snapshot-session my_session \ - --fire-every=55 \ + --rate-policy=every:55 \ --action snapshot-session my_session \ - --fire-once-after=55 + --rate-policy=once-after:55 test_success "rotate session action polices" \ - --condition on-event -u test-fire-once-after \ + --condition on-event -u test-rate-policy=once-after \ --action rotate-session my_session \ - --fire-every=55 \ + --rate-policy=every:55 \ --action rotate-session my_session \ - --fire-once-after=55 + --rate-policy=once-after:55 skip $ist_root "non-root user: skipping kprobe tests" 9 || { test_success "--condition on-event probe by symbol" \ @@ -266,23 +266,28 @@ test_failure "missing argument to --id" \ "Error: While parsing argument #1 (\`--id\`): Missing required argument for option \`--id\`" \ --id -for cmd in fire-once-after fire-every; do +for cmd in rate-policy=once-after rate-policy=every; do test_failure "missing argument to --${cmd}" \ - "Error: While parsing argument #1 (\`--${cmd}\`): Missing required argument for option \`--${cmd}\`" \ + "Error: Rate policy format is invalid." \ --condition on-event -u -a --action notify \ --${cmd} test_failure "invalid argument to --${cmd}: non-digit character" \ - "Error: Failed to parse \`123bob\` as an integer." \ + "Error: Failed to parse rate policy value \`123bob\` as an integer." \ --condition on-event -u -a --action notify \ - --${cmd} 123bob + --${cmd}:123bob test_failure "invalid argument to --${cmd}: empty string" \ - "Error: Failed to parse \`\` as an integer." \ + "Error: Failed to parse rate policy value \`\` as an integer." \ --condition on-event -u -a --action notify \ - --${cmd} "" + --${cmd}":" done +test_failure "invalid argument to --rate-policy: unknown policy type" \ + "Error: Rate policy type \`bob\` unknown." \ + --condition on-event -u -a --action notify \ + --rate-policy=bob:123 + # `--condition` failures test_failure "missing args after --condition" \ "Error: Missing condition name." \ diff --git a/tests/regression/tools/trigger/test_list_triggers_cli b/tests/regression/tools/trigger/test_list_triggers_cli index fa1af958d..169613375 100755 --- a/tests/regression/tools/trigger/test_list_triggers_cli +++ b/tests/regression/tools/trigger/test_list_triggers_cli @@ -296,8 +296,8 @@ test_snapshot_action () lttng_add_trigger_ok "T5" --condition on-event -u some-event --action snapshot-session ze-session --ctrl-url=tcp://1.2.3.4:1111 --data-url=tcp://1.2.3.4:1112 lttng_add_trigger_ok "T6" --condition on-event -u some-event --action snapshot-session ze-session --path /some/path --max-size=1234 lttng_add_trigger_ok "T7" --condition on-event -u some-event --action snapshot-session ze-session --path /some/path --name=meh - lttng_add_trigger_ok "T8" --condition on-event -u some-event --action snapshot-session ze-session --fire-every 10 - lttng_add_trigger_ok "T9" --condition on-event -u some-event --action snapshot-session ze-session --fire-once-after 10 + lttng_add_trigger_ok "T8" --condition on-event -u some-event --action snapshot-session ze-session --rate-policy=every:10 + lttng_add_trigger_ok "T9" --condition on-event -u some-event --action snapshot-session ze-session --rate-policy=once-after:10 cat > "${tmp_expected_stdout}" <<- EOF @@ -382,8 +382,8 @@ test_notify_action () { start_lttng_sessiond_notap - lttng_add_trigger_ok "T0" --condition on-event -u some-event --action notify --fire-once-after 5 - lttng_add_trigger_ok "T1" --condition on-event -u some-event --action notify --fire-every 10 + lttng_add_trigger_ok "T0" --condition on-event -u some-event --action notify --rate-policy=once-after:5 + lttng_add_trigger_ok "T1" --condition on-event -u some-event --action notify --rate-policy=every:10 cat > "${tmp_expected_stdout}" <<- EOF