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>
6 * SPDX-License-Identifier: MIT
9 #include "performance.h"
11 #include <lttng/tracepoint.h>
13 #include <lttng/condition/event-rule.h>
14 #include <lttng/lttng.h>
26 bool action_group_contains_notify(const struct lttng_action
*action_group
)
28 unsigned int i
, count
;
29 enum lttng_action_status status
=
30 lttng_action_group_get_count(action_group
, &count
);
32 if (status
!= LTTNG_ACTION_STATUS_OK
) {
33 printf("Failed to get action count from action group\n");
37 for (i
= 0; i
< count
; i
++) {
38 const struct lttng_action
*action
=
39 lttng_action_group_get_at_index(
41 const enum lttng_action_type action_type
=
42 lttng_action_get_type(action
);
44 if (action_type
== LTTNG_ACTION_TYPE_NOTIFY
) {
51 int main(int argc
, char **argv
)
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
;
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");
74 nb_reception
= atoi(argv
[2]);
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");
84 ret
= lttng_list_triggers(&triggers
);
85 if (ret
!= LTTNG_OK
) {
86 fprintf(stderr
, "Failed to list triggers\n");
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");
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
;
109 lttng_trigger_get_name(trigger
, &trigger_name
);
110 if (strcmp(trigger_name
, argv
[3])) {
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",
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",
131 printf("Subscribed to notifications of trigger \"%s\"\n",
136 if (subcription_count
== 0) {
137 printf("No matching trigger with a notify action found.\n");
142 for (int i
= 0; i
< nb_reception
; i
++) {
144 lttng_notification_channel_get_next_notification(
145 notification_channel
,
147 switch (channel_status
) {
148 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED
:
149 printf("Dropped notification\n");
153 case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
:
156 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
:
158 case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED
:
159 printf("Notification channel was closed by peer.\n");
162 fprintf(stderr
, "A communication error occurred on the notification channel.\n");
167 evaluation
= lttng_notification_get_evaluation(notification
);
168 type
= lttng_evaluation_get_type(evaluation
);
170 if (type
!= LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
) {
174 tracepoint(performance
, receive
, id
, i
);
175 lttng_notification_destroy(notification
);
182 lttng_triggers_destroy(triggers
);
183 lttng_notification_channel_destroy(notification_channel
);