X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=doc%2Fexamples%2Ftrigger-on-event%2Fperformance%2Fconsumer.c;fp=doc%2Fexamples%2Ftrigger-on-event%2Fperformance%2Fconsumer.c;h=65d2b59d5e9bd8882e980ae4113bef85b9d5a531;hp=0000000000000000000000000000000000000000;hb=d3a684eebfe788a7527368d65d7f020bdd1e61d9;hpb=b2081a0f39bce45b3d1cf063308a9b77712f1a9f diff --git a/doc/examples/trigger-on-event/performance/consumer.c b/doc/examples/trigger-on-event/performance/consumer.c new file mode 100644 index 000000000..65d2b59d5 --- /dev/null +++ b/doc/examples/trigger-on-event/performance/consumer.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2020 Jérémie Galarneau + * Copyright (C) 2020 Jonathan Rajotte-Julien + * + * + * SPDX-License-Identifier: MIT + * + */ +#include "performance.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool action_group_contains_notify(const struct lttng_action *action_group) +{ + unsigned int i, count; + enum lttng_action_status status = + lttng_action_group_get_count(action_group, &count); + + if (status != LTTNG_ACTION_STATUS_OK) { + printf("Failed to get action count from action group\n"); + exit(1); + } + + for (i = 0; i < count; i++) { + const struct lttng_action *action = + lttng_action_group_get_at_index_const( + action_group, i); + const enum lttng_action_type action_type = + lttng_action_get_type(action); + + if (action_type == LTTNG_ACTION_TYPE_NOTIFY) { + return true; + } + } + return false; +} + +int main(int argc, char **argv) +{ + int ret; + int id, nb_reception; + struct lttng_triggers *triggers = NULL; + unsigned int count, i, subcription_count = 0; + enum lttng_trigger_status trigger_status; + struct lttng_notification_channel *notification_channel = NULL; + struct lttng_notification *notification; + enum lttng_notification_channel_status channel_status; + const struct lttng_evaluation *evaluation; + enum lttng_condition_type type; + + if (argc != 4) { + fprintf(stderr, "Missing unique_id\n"); + fprintf(stderr, "Missing nb_event\n"); + fprintf(stderr, "Missing trigger name\n"); + fprintf(stderr, "Usage: notification-client TRIGGER_NAME\n"); + ret = 1; + goto end; + } + + id = atoi(argv[1]); + nb_reception = atoi(argv[2]); + + notification_channel = lttng_notification_channel_create( + lttng_session_daemon_notification_endpoint); + if (!notification_channel) { + fprintf(stderr, "Failed to create notification channel\n"); + ret = -1; + goto end; + } + + ret = lttng_list_triggers(&triggers); + if (ret) { + fprintf(stderr, "Failed to list triggers\n"); + goto end; + } + + trigger_status = lttng_triggers_get_count(triggers, &count); + if (trigger_status != LTTNG_TRIGGER_STATUS_OK) { + fprintf(stderr, "Failed to get trigger count\n"); + ret = -1; + goto end; + } + + for (i = 0; i < count; i++) { + const struct lttng_trigger *trigger = + lttng_triggers_get_at_index(triggers, i); + const struct lttng_condition *condition = + lttng_trigger_get_const_condition(trigger); + const struct lttng_action *action = + lttng_trigger_get_const_action(trigger); + const enum lttng_action_type action_type = + lttng_action_get_type(action); + enum lttng_notification_channel_status channel_status; + const char *trigger_name = NULL; + + lttng_trigger_get_name(trigger, &trigger_name); + if (strcmp(trigger_name, argv[3])) { + continue; + } + + if (!((action_type == LTTNG_ACTION_TYPE_GROUP && + action_group_contains_notify(action)) || + action_type == LTTNG_ACTION_TYPE_NOTIFY)) { + printf("The action of trigger \"%s\" is not \"notify\", skipping.\n", + trigger_name); + continue; + } + + channel_status = lttng_notification_channel_subscribe( + notification_channel, condition); + if (channel_status) { + fprintf(stderr, "Failed to subscribe to notifications of trigger \"%s\"\n", + trigger_name); + ret = -1; + goto end; + } + + printf("Subscribed to notifications of trigger \"%s\"\n", + trigger_name); + subcription_count++; + } + + if (subcription_count == 0) { + printf("No matching trigger with a notify action found.\n"); + ret = 0; + goto end; + } + + for (int i = 0; i < nb_reception; i++) { + channel_status = + lttng_notification_channel_get_next_notification( + notification_channel, + ¬ification); + switch (channel_status) { + case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED: + printf("Dropped notification\n"); + sleep(1); + continue; + break; + case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED: + ret = 0; + goto end; + case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK: + break; + case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED: + printf("Notification channel was closed by peer.\n"); + break; + default: + fprintf(stderr, "A communication error occurred on the notification channel.\n"); + ret = -1; + goto end; + } + + evaluation = lttng_notification_get_evaluation(notification); + type = lttng_evaluation_get_type(evaluation); + + if (type != LTTNG_CONDITION_TYPE_EVENT_RULE_HIT) { + assert(0); + } + + tracepoint(performance, receive, id, i); + lttng_notification_destroy(notification); + if (ret) { + goto end; + } + } + +end: + lttng_triggers_destroy(triggers); + lttng_notification_channel_destroy(notification_channel); + return !!ret; +}