add-trigger: rename --fire-* to --rate-policy=*:value
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Thu, 15 Apr 2021 21:35:20 +0000 (17:35 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 18 Apr 2021 23:28:57 +0000 (19:28 -0400)
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=<type>:<value>

Where type is either: once-after or every.
Value is an unsigned long long value.

Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I6df264c536293e686033d0baa8fe870c75c28b8d

doc/man/lttng-add-trigger.1.txt
src/bin/lttng/commands/add_trigger.c
tests/regression/tools/trigger/rate-policy/test_ust_rate_policy
tests/regression/tools/trigger/test_add_trigger_cli
tests/regression/tools/trigger/test_list_triggers_cli

index 5e2e90e4362535dfcf0b874c11f95047f282234c..211b707bc6851937de81cf353eee6444afbcb534 100644 (file)
@@ -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.
 
index 27a666c5da97dba8c8ab900d336ef7229f5f0184..d460c0ffbda494a31aedd1b1832f498587254c00 100644 (file)
@@ -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.");
index 27d813048769e95c60be6d5f90ac235f7f3d94a1..63993aa5150e0f007f04ebe6dec48646ef773839 100755 (executable)
@@ -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
index 52c29120dc2b328b3b3aaf367352d8ed43410595..974938068707c48243ddf2977de5b65ceef0782b 100755 (executable)
@@ -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." \
index fa1af958d7d98346ea78bb723e4a7b2106507745..169613375132bb6f3b60fa59b0db923bc6bbe69f 100755 (executable)
@@ -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
This page took 0.034405 seconds and 4 git commands to generate.