2 * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: MIT
8 #include <lttng/condition/event-rule.h>
9 #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
++) {
37 void print_one_event_expr(const struct lttng_event_expr
*event_expr
)
39 enum lttng_event_expr_type type
;
41 type
= lttng_event_expr_get_type(event_expr
);
44 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
: {
56 name
= lttng_event_expr_channel_context_field_get_name(event_expr
);
57 printf("$ctx.%s", name
);
62 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
: {
63 const char *provider_name
;
64 const char *type_name
;
67 lttng_event_expr_app_specific_context_field_get_provider_name(
70 lttng_event_expr_app_specific_context_field_get_type_name(
73 printf("$app.%s:%s", provider_name
, type_name
);
78 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(
85 assert(parent_expr
!= NULL
);
87 print_one_event_expr(parent_expr
);
89 status
= lttng_event_expr_array_field_element_get_index(
91 assert(status
== LTTNG_EVENT_EXPR_STATUS_OK
);
93 printf("[%u]", index
);
103 static bool action_group_contains_notify(
104 const struct lttng_action
*action_group
)
106 unsigned int i
, count
;
107 enum lttng_action_status status
=
108 lttng_action_group_get_count(action_group
, &count
);
110 if (status
!= LTTNG_ACTION_STATUS_OK
) {
111 printf("Failed to get action count from action group\n");
115 for (i
= 0; i
< count
; i
++) {
116 const struct lttng_action
*action
=
117 lttng_action_group_get_at_index(
119 const enum lttng_action_type action_type
=
120 lttng_action_get_type(action
);
122 if (action_type
== LTTNG_ACTION_TYPE_NOTIFY
) {
129 static int print_capture(const struct lttng_condition
*condition
,
130 const struct lttng_event_field_value
*capture
,
131 unsigned int indent_level
)
134 enum lttng_event_field_value_status event_field_status
;
135 enum lttng_event_field_value_type type
;
139 const char *string_val
= NULL
;
141 switch (lttng_event_field_value_get_type(capture
)) {
142 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
:
145 lttng_event_field_value_unsigned_int_get_value(
147 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
152 printf("[Unsigned int] %" PRIu64
, u_val
);
155 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
:
158 lttng_event_field_value_signed_int_get_value(
160 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
165 printf("[Signed int] %" PRId64
, s_val
);
168 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
171 lttng_event_field_value_unsigned_int_get_value(
173 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
178 printf("[Unsigned enum] %" PRIu64
, u_val
);
181 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
184 lttng_event_field_value_signed_int_get_value(
186 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
191 printf("[Signed enum] %" PRId64
, s_val
);
194 case LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
:
196 event_field_status
= lttng_event_field_value_real_get_value(
198 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
203 printf("[Real] %lf", d_val
);
206 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
:
208 string_val
= lttng_event_field_value_string_get_value(capture
);
209 if (string_val
== NULL
) {
214 printf("[String] %s", string_val
);
217 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
:
218 printf("[Array] [\n");
219 print_array(condition
, capture
, indent_level
);
220 indent(indent_level
);
223 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNKNOWN
:
224 case LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID
:
234 static void print_unavailabe(void)
236 printf("Capture unavailable");
239 static int print_array(const struct lttng_condition
*condition
,
240 const struct lttng_event_field_value
*array
,
241 unsigned int indent_level
)
244 enum lttng_event_field_value_status event_field_status
;
245 unsigned int captured_field_count
;
247 event_field_status
= lttng_event_field_value_array_get_length(
248 array
, &captured_field_count
);
249 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
254 for (unsigned int i
= 0; i
< captured_field_count
; i
++) {
255 const struct lttng_event_field_value
*captured_field
= NULL
;
256 const struct lttng_event_expr
*expr
=
257 lttng_condition_event_rule_get_capture_descriptor_at_index(
261 indent(indent_level
+ 1);
264 print_one_event_expr(expr
);
268 lttng_event_field_value_array_get_element_at_index(
269 array
, i
, &captured_field
);
270 if (event_field_status
!= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
) {
271 if (event_field_status
==
272 LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE
) {
279 print_capture(condition
, captured_field
, indent_level
+ 1);
282 if (i
+ 1 < captured_field_count
) {
294 static int print_captures(struct lttng_notification
*notification
)
297 const struct lttng_evaluation
*evaluation
=
298 lttng_notification_get_evaluation(notification
);
299 const struct lttng_condition
*condition
=
300 lttng_notification_get_condition(notification
);
303 enum lttng_condition_status condition_status
;
304 enum lttng_evaluation_status evaluation_status
;
305 enum lttng_event_field_value_status event_field_status
;
307 const struct lttng_event_field_value
*captured_field_array
= NULL
;
308 unsigned int expected_capture_field_count
;
309 unsigned int captured_field_count
;
311 assert(lttng_evaluation_get_type(evaluation
) ==
312 LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
);
315 lttng_condition_event_rule_get_capture_descriptor_count(
317 &expected_capture_field_count
);
318 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
323 if (expected_capture_field_count
== 0) {
328 evaluation_status
= lttng_evaluation_get_captured_values(
329 evaluation
, &captured_field_array
);
330 if (evaluation_status
!= LTTNG_EVALUATION_STATUS_OK
) {
335 printf("Captured field values:\n");
336 print_array(condition
, captured_field_array
, 1);
341 static int print_notification(struct lttng_notification
*notification
)
344 const struct lttng_evaluation
*evaluation
=
345 lttng_notification_get_evaluation(notification
);
346 const enum lttng_condition_type type
=
347 lttng_evaluation_get_type(evaluation
);
350 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
351 printf("Received consumed size notification\n");
353 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
354 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
355 printf("Received buffer usage notification\n");
357 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
358 printf("Received session rotation ongoing notification\n");
360 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
361 printf("Received session rotation completed notification\n");
363 case LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
:
365 const char *trigger_name
;
366 enum lttng_evaluation_status evaluation_status
;
371 gettimeofday(&tv
, NULL
);
372 the_time
= tv
.tv_sec
;
374 strftime(time_str
, sizeof(time_str
), "[%m-%d-%Y] %T",
375 localtime(&the_time
));
376 printf("%s.%ld - ", time_str
, tv
.tv_usec
);
379 lttng_evaluation_event_rule_get_trigger_name(
380 evaluation
, &trigger_name
);
381 if (evaluation_status
!= LTTNG_EVALUATION_STATUS_OK
) {
382 fprintf(stderr
, "Failed to get trigger name of event rule notification\n");
387 printf("Received notification of event rule trigger \"%s\"\n",
389 ret
= print_captures(notification
);
393 fprintf(stderr
, "Unknown notification type (%d)\n", type
);
399 int main(int argc
, char **argv
)
402 struct lttng_triggers
*triggers
= NULL
;
403 unsigned int count
, i
, j
, subcription_count
= 0, trigger_count
;
404 enum lttng_trigger_status trigger_status
;
405 struct lttng_notification_channel
*notification_channel
= NULL
;
408 fprintf(stderr
, "Missing trigger name(s)\n");
409 fprintf(stderr
, "Usage: notification-client TRIGGER_NAME ...");
414 trigger_count
= argc
- 1;
416 notification_channel
= lttng_notification_channel_create(
417 lttng_session_daemon_notification_endpoint
);
418 if (!notification_channel
) {
419 fprintf(stderr
, "Failed to create notification channel\n");
424 ret
= lttng_list_triggers(&triggers
);
425 if (ret
!= LTTNG_OK
) {
426 fprintf(stderr
, "Failed to list triggers\n");
430 trigger_status
= lttng_triggers_get_count(triggers
, &count
);
431 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
432 fprintf(stderr
, "Failed to get trigger count\n");
437 for (i
= 0; i
< count
; i
++) {
438 const struct lttng_trigger
*trigger
=
439 lttng_triggers_get_at_index(triggers
, i
);
440 const struct lttng_condition
*condition
=
441 lttng_trigger_get_const_condition(trigger
);
442 const struct lttng_action
*action
=
443 lttng_trigger_get_const_action(trigger
);
444 const enum lttng_action_type action_type
=
445 lttng_action_get_type(action
);
446 enum lttng_notification_channel_status channel_status
;
447 const char *trigger_name
= NULL
;
448 bool subscribe
= false;
450 lttng_trigger_get_name(trigger
, &trigger_name
);
451 for (j
= 0; j
< trigger_count
; j
++) {
452 if (!strcmp(trigger_name
, argv
[j
+ 1])) {
462 if (!((action_type
== LTTNG_ACTION_TYPE_GROUP
&&
463 action_group_contains_notify(action
)) ||
464 action_type
== LTTNG_ACTION_TYPE_NOTIFY
)) {
465 printf("The action of trigger \"%s\" is not \"notify\", skipping.\n",
470 channel_status
= lttng_notification_channel_subscribe(
471 notification_channel
, condition
);
472 if (channel_status
==
473 LTTNG_NOTIFICATION_CHANNEL_STATUS_ALREADY_SUBSCRIBED
) {
476 if (channel_status
) {
477 fprintf(stderr
, "Failed to subscribe to notifications of trigger \"%s\"\n",
483 printf("Subscribed to notifications of trigger \"%s\"\n",
488 if (subcription_count
== 0) {
489 printf("No matching trigger with a notify action found.\n");
495 struct lttng_notification
*notification
;
496 enum lttng_notification_channel_status channel_status
;
499 lttng_notification_channel_get_next_notification(
500 notification_channel
,
502 switch (channel_status
) {
503 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED
:
504 printf("Dropped notification\n");
506 case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
:
509 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
:
511 case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED
:
512 printf("Notification channel was closed by peer.\n");
515 fprintf(stderr
, "A communication error occurred on the notification channel.\n");
520 ret
= print_notification(notification
);
521 lttng_notification_destroy(notification
);
527 lttng_triggers_destroy(triggers
);
528 lttng_notification_channel_destroy(notification_channel
);