2 * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: MIT
8 #include <common/macros.hpp>
10 #include <lttng/lttng.h>
21 static int print_capture(const struct lttng_condition
*condition
,
22 const struct lttng_event_field_value
*capture
,
23 unsigned int indent_level
);
24 static int print_array(const struct lttng_condition
*condition
,
25 const struct lttng_event_field_value
*array
,
26 unsigned int indent_level
);
28 static void indent(unsigned int indentation_level
)
31 for (i
= 0; i
< indentation_level
; i
++) {
36 static void print_one_event_expr(const struct lttng_event_expr
*event_expr
)
38 enum lttng_event_expr_type type
;
40 type
= lttng_event_expr_get_type(event_expr
);
43 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
47 name
= lttng_event_expr_event_payload_field_get_name(event_expr
);
53 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
57 name
= lttng_event_expr_channel_context_field_get_name(event_expr
);
58 printf("$ctx.%s", name
);
63 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
65 const char *provider_name
;
66 const char *type_name
;
69 lttng_event_expr_app_specific_context_field_get_provider_name(event_expr
);
70 type_name
= lttng_event_expr_app_specific_context_field_get_type_name(event_expr
);
72 printf("$app.%s:%s", provider_name
, type_name
);
77 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
80 const struct lttng_event_expr
*parent_expr
;
81 enum lttng_event_expr_status status
;
83 parent_expr
= lttng_event_expr_array_field_element_get_parent_expr(event_expr
);
84 LTTNG_ASSERT(parent_expr
!= nullptr);
86 print_one_event_expr(parent_expr
);
88 status
= lttng_event_expr_array_field_element_get_index(event_expr
, &index
);
89 LTTNG_ASSERT(status
== LTTNG_EVENT_EXPR_STATUS_OK
);
91 printf("[%u]", index
);
101 static bool action_group_contains_notify(const struct lttng_action
*action_group
)
103 unsigned int i
, count
;
104 enum lttng_action_status status
= lttng_action_list_get_count(action_group
, &count
);
106 if (status
!= LTTNG_ACTION_STATUS_OK
) {
107 printf("Failed to get action count from action group\n");
111 for (i
= 0; i
< count
; i
++) {
112 const struct lttng_action
*action
= lttng_action_list_get_at_index(action_group
, i
);
113 const enum lttng_action_type action_type
= lttng_action_get_type(action
);
115 if (action_type
== LTTNG_ACTION_TYPE_NOTIFY
) {
122 static int print_capture(const struct lttng_condition
*condition
,
123 const struct lttng_event_field_value
*capture
,
124 unsigned int indent_level
)
127 enum lttng_event_field_value_status event_field_status
;
131 const char *string_val
= nullptr;
133 switch (lttng_event_field_value_get_type(capture
)) {
134 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
:
137 lttng_event_field_value_unsigned_int_get_value(capture
, &u_val
);
138 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
143 printf("[Unsigned int] %" PRIu64
, u_val
);
146 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
:
148 event_field_status
= lttng_event_field_value_signed_int_get_value(capture
, &s_val
);
149 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
154 printf("[Signed int] %" PRId64
, s_val
);
157 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
160 lttng_event_field_value_unsigned_int_get_value(capture
, &u_val
);
161 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
166 printf("[Unsigned enum] %" PRIu64
, u_val
);
169 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
171 event_field_status
= lttng_event_field_value_signed_int_get_value(capture
, &s_val
);
172 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
177 printf("[Signed enum] %" PRId64
, s_val
);
180 case LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
:
182 event_field_status
= lttng_event_field_value_real_get_value(capture
, &d_val
);
183 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
188 printf("[Real] %lf", d_val
);
191 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
:
193 event_field_status
= lttng_event_field_value_string_get_value(capture
, &string_val
);
194 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
199 printf("[String] %s", string_val
);
202 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
:
203 printf("[Array] [\n");
204 print_array(condition
, capture
, indent_level
);
205 indent(indent_level
);
208 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNKNOWN
:
209 case LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID
:
219 static void print_unavailabe()
221 printf("Capture unavailable");
224 static int print_array(const struct lttng_condition
*condition
,
225 const struct lttng_event_field_value
*array
,
226 unsigned int indent_level
)
229 enum lttng_event_field_value_status event_field_status
;
230 unsigned int captured_field_count
;
232 event_field_status
= lttng_event_field_value_array_get_length(array
, &captured_field_count
);
233 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
238 for (unsigned int i
= 0; i
< captured_field_count
; i
++) {
239 const struct lttng_event_field_value
*captured_field
= nullptr;
240 const struct lttng_event_expr
*expr
=
241 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
245 indent(indent_level
+ 1);
248 print_one_event_expr(expr
);
251 event_field_status
= lttng_event_field_value_array_get_element_at_index(
252 array
, i
, &captured_field
);
253 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
254 if (event_field_status
== LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE
) {
261 print_capture(condition
, captured_field
, indent_level
+ 1);
264 if (i
+ 1 < captured_field_count
) {
276 static int print_captures(struct lttng_notification
*notification
)
279 const struct lttng_evaluation
*evaluation
= lttng_notification_get_evaluation(notification
);
280 const struct lttng_condition
*condition
= lttng_notification_get_condition(notification
);
283 enum lttng_condition_status condition_status
;
284 enum lttng_evaluation_event_rule_matches_status evaluation_status
;
286 const struct lttng_event_field_value
*captured_field_array
= nullptr;
287 unsigned int expected_capture_field_count
;
289 LTTNG_ASSERT(lttng_evaluation_get_type(evaluation
) ==
290 LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
);
292 condition_status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
293 condition
, &expected_capture_field_count
);
294 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
299 if (expected_capture_field_count
== 0) {
304 evaluation_status
= lttng_evaluation_event_rule_matches_get_captured_values(
305 evaluation
, &captured_field_array
);
306 if (evaluation_status
!= LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_OK
) {
311 printf("Captured field values:\n");
312 print_array(condition
, captured_field_array
, 1);
317 static int print_notification(struct lttng_notification
*notification
)
320 const struct lttng_evaluation
*evaluation
= lttng_notification_get_evaluation(notification
);
321 const enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
324 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
325 printf("Received consumed size notification\n");
327 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
328 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
329 printf("Received buffer usage notification\n");
331 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
332 printf("Received session rotation ongoing notification\n");
334 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
335 printf("Received session rotation completed notification\n");
337 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
339 const char *trigger_name
;
340 enum lttng_trigger_status trigger_status
;
344 const struct lttng_trigger
*trigger
= nullptr;
346 gettimeofday(&tv
, nullptr);
347 the_time
= tv
.tv_sec
;
349 strftime(time_str
, sizeof(time_str
), "[%m-%d-%Y] %T", localtime(&the_time
));
350 printf("%s.%ld - ", time_str
, tv
.tv_usec
);
352 trigger
= lttng_notification_get_trigger(notification
);
354 fprintf(stderr
, "Failed to retrieve notification's trigger");
358 trigger_status
= lttng_trigger_get_name(trigger
, &trigger_name
);
359 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
360 fprintf(stderr
, "Failed to retrieve trigger's name");
364 printf("Received notification of event rule matches trigger \"%s\"\n",
366 ret
= print_captures(notification
);
370 fprintf(stderr
, "Unknown notification type (%d)\n", type
);
377 int main(int argc
, char **argv
)
380 struct lttng_triggers
*triggers
= nullptr;
381 unsigned int count
, i
, j
, subcription_count
= 0, trigger_count
;
382 enum lttng_trigger_status trigger_status
;
383 struct lttng_notification_channel
*notification_channel
= nullptr;
386 fprintf(stderr
, "Missing trigger name(s)\n");
387 fprintf(stderr
, "Usage: notification-client TRIGGER_NAME ...");
392 trigger_count
= argc
- 1;
394 notification_channel
=
395 lttng_notification_channel_create(lttng_session_daemon_notification_endpoint
);
396 if (!notification_channel
) {
397 fprintf(stderr
, "Failed to create notification channel\n");
402 ret
= lttng_list_triggers(&triggers
);
403 if (ret
!= LTTNG_OK
) {
404 fprintf(stderr
, "Failed to list triggers\n");
408 trigger_status
= lttng_triggers_get_count(triggers
, &count
);
409 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
410 fprintf(stderr
, "Failed to get trigger count\n");
415 for (i
= 0; i
< count
; i
++) {
416 const struct lttng_trigger
*trigger
= lttng_triggers_get_at_index(triggers
, i
);
417 const struct lttng_condition
*condition
=
418 lttng_trigger_get_const_condition(trigger
);
419 const struct lttng_action
*action
= lttng_trigger_get_const_action(trigger
);
420 const enum lttng_action_type action_type
= lttng_action_get_type(action
);
421 enum lttng_notification_channel_status channel_status
;
422 const char *trigger_name
= nullptr;
423 bool subscribe
= false;
425 lttng_trigger_get_name(trigger
, &trigger_name
);
426 for (j
= 0; j
< trigger_count
; j
++) {
427 if (!strcmp(trigger_name
, argv
[j
+ 1])) {
437 if (!((action_type
== LTTNG_ACTION_TYPE_LIST
&&
438 action_group_contains_notify(action
)) ||
439 action_type
== LTTNG_ACTION_TYPE_NOTIFY
)) {
440 printf("The action of trigger \"%s\" is not \"notify\", skipping.\n",
446 lttng_notification_channel_subscribe(notification_channel
, condition
);
447 if (channel_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_ALREADY_SUBSCRIBED
) {
450 if (channel_status
) {
452 "Failed to subscribe to notifications of trigger \"%s\"\n",
458 printf("Subscribed to notifications of trigger \"%s\"\n", trigger_name
);
462 if (subcription_count
== 0) {
463 printf("No matching trigger with a notify action found.\n");
469 struct lttng_notification
*notification
;
470 enum lttng_notification_channel_status channel_status
;
472 channel_status
= lttng_notification_channel_get_next_notification(
473 notification_channel
, ¬ification
);
474 switch (channel_status
) {
475 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED
:
476 printf("Dropped notification\n");
478 case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
:
481 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
:
482 ret
= print_notification(notification
);
483 lttng_notification_destroy(notification
);
488 case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED
:
489 printf("Notification channel was closed by peer.\n");
493 "A communication error occurred on the notification channel.\n");
499 lttng_triggers_destroy(triggers
);
500 lttng_notification_channel_destroy(notification_channel
);