SoW-2020-0002: Trace Hit Counters: trigger error reporting integration
[lttng-tools.git] / doc / examples / trigger-on-event / performance / consumer.c
1 /*
2 * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 * Copyright (C) 2020 Jonathan Rajotte-Julien
4 * <jonathan.rajotte-julein@efficios.com>
5 *
6 * SPDX-License-Identifier: MIT
7 *
8 */
9 #include "performance.h"
10
11 #include <lttng/tracepoint.h>
12
13 #include <lttng/condition/event-rule.h>
14 #include <lttng/lttng.h>
15
16 #include <assert.h>
17 #include <stdbool.h>
18 #include <stddef.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/time.h>
23 #include <time.h>
24 #include <unistd.h>
25
26 bool action_group_contains_notify(const struct lttng_action *action_group)
27 {
28 unsigned int i, count;
29 enum lttng_action_status status =
30 lttng_action_group_get_count(action_group, &count);
31
32 if (status != LTTNG_ACTION_STATUS_OK) {
33 printf("Failed to get action count from action group\n");
34 exit(1);
35 }
36
37 for (i = 0; i < count; i++) {
38 const struct lttng_action *action =
39 lttng_action_group_get_at_index(
40 action_group, i);
41 const enum lttng_action_type action_type =
42 lttng_action_get_type(action);
43
44 if (action_type == LTTNG_ACTION_TYPE_NOTIFY) {
45 return true;
46 }
47 }
48 return false;
49 }
50
51 int main(int argc, char **argv)
52 {
53 int ret;
54 int id, nb_reception;
55 struct lttng_triggers *triggers = NULL;
56 unsigned int count, i, subcription_count = 0;
57 enum lttng_trigger_status trigger_status;
58 struct lttng_notification_channel *notification_channel = NULL;
59 struct lttng_notification *notification;
60 enum lttng_notification_channel_status channel_status;
61 const struct lttng_evaluation *evaluation;
62 enum lttng_condition_type type;
63
64 if (argc != 4) {
65 fprintf(stderr, "Missing unique_id\n");
66 fprintf(stderr, "Missing nb_event\n");
67 fprintf(stderr, "Missing trigger name\n");
68 fprintf(stderr, "Usage: notification-client TRIGGER_NAME\n");
69 ret = 1;
70 goto end;
71 }
72
73 id = atoi(argv[1]);
74 nb_reception = atoi(argv[2]);
75
76 notification_channel = lttng_notification_channel_create(
77 lttng_session_daemon_notification_endpoint);
78 if (!notification_channel) {
79 fprintf(stderr, "Failed to create notification channel\n");
80 ret = -1;
81 goto end;
82 }
83
84 ret = lttng_list_triggers(&triggers);
85 if (ret != LTTNG_OK) {
86 fprintf(stderr, "Failed to list triggers\n");
87 goto end;
88 }
89
90 trigger_status = lttng_triggers_get_count(triggers, &count);
91 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
92 fprintf(stderr, "Failed to get trigger count\n");
93 ret = -1;
94 goto end;
95 }
96
97 for (i = 0; i < count; i++) {
98 const struct lttng_trigger *trigger =
99 lttng_triggers_get_at_index(triggers, i);
100 const struct lttng_condition *condition =
101 lttng_trigger_get_const_condition(trigger);
102 const struct lttng_action *action =
103 lttng_trigger_get_const_action(trigger);
104 const enum lttng_action_type action_type =
105 lttng_action_get_type(action);
106 enum lttng_notification_channel_status channel_status;
107 const char *trigger_name = NULL;
108
109 lttng_trigger_get_name(trigger, &trigger_name);
110 if (strcmp(trigger_name, argv[3])) {
111 continue;
112 }
113
114 if (!((action_type == LTTNG_ACTION_TYPE_GROUP &&
115 action_group_contains_notify(action)) ||
116 action_type == LTTNG_ACTION_TYPE_NOTIFY)) {
117 printf("The action of trigger \"%s\" is not \"notify\", skipping.\n",
118 trigger_name);
119 continue;
120 }
121
122 channel_status = lttng_notification_channel_subscribe(
123 notification_channel, condition);
124 if (channel_status) {
125 fprintf(stderr, "Failed to subscribe to notifications of trigger \"%s\"\n",
126 trigger_name);
127 ret = -1;
128 goto end;
129 }
130
131 printf("Subscribed to notifications of trigger \"%s\"\n",
132 trigger_name);
133 subcription_count++;
134 }
135
136 if (subcription_count == 0) {
137 printf("No matching trigger with a notify action found.\n");
138 ret = 0;
139 goto end;
140 }
141
142 for (int i = 0; i < nb_reception; i++) {
143 channel_status =
144 lttng_notification_channel_get_next_notification(
145 notification_channel,
146 &notification);
147 switch (channel_status) {
148 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED:
149 printf("Dropped notification\n");
150 sleep(1);
151 continue;
152 break;
153 case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED:
154 ret = 0;
155 goto end;
156 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK:
157 break;
158 case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED:
159 printf("Notification channel was closed by peer.\n");
160 break;
161 default:
162 fprintf(stderr, "A communication error occurred on the notification channel.\n");
163 ret = -1;
164 goto end;
165 }
166
167 evaluation = lttng_notification_get_evaluation(notification);
168 type = lttng_evaluation_get_type(evaluation);
169
170 if (type != LTTNG_CONDITION_TYPE_EVENT_RULE_HIT) {
171 assert(0);
172 }
173
174 tracepoint(performance, receive, id, i);
175 lttng_notification_destroy(notification);
176 if (ret) {
177 goto end;
178 }
179 }
180
181 end:
182 lttng_triggers_destroy(triggers);
183 lttng_notification_channel_destroy(notification_channel);
184 return !!ret;
185 }
This page took 0.040413 seconds and 5 git commands to generate.