lttng list-triggers: handle all condition types
[lttng-tools.git] / src / bin / lttng / commands / list_triggers.c
CommitLineData
0de2479d
SM
1/*
2 * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8#include <stdio.h>
9
10#include "../command.h"
11
12#include "common/argpar/argpar.h"
13#include "common/dynamic-array.h"
14#include "common/mi-lttng.h"
15/* For lttng_condition_type_str(). */
16#include "lttng/condition/condition-internal.h"
90aa04a1
FD
17#include "lttng/condition/on-event.h"
18#include "lttng/condition/on-event-internal.h"
0de2479d
SM
19/* For lttng_domain_type_str(). */
20#include "lttng/domain-internal.h"
85b05318 21#include "../loglevel.h"
709fb83f 22#include <lttng/lttng.h>
0de2479d
SM
23
24#ifdef LTTNG_EMBED_HELP
25static const char help_msg[] =
279eb769 26#include <lttng-list-triggers.1.h>
0de2479d
SM
27;
28#endif
29
30enum {
31 OPT_HELP,
32 OPT_LIST_OPTIONS,
33};
34
35static const
36struct argpar_opt_descr list_trigger_options[] = {
37 { OPT_HELP, 'h', "help", false },
38 { OPT_LIST_OPTIONS, '\0', "list-options", false },
39 ARGPAR_OPT_DESCR_SENTINEL,
40};
41
19904669
SM
42static void print_condition_session_consumed_size(
43 const struct lttng_condition *condition)
44{
45 enum lttng_condition_status condition_status;
46 const char *session_name;
47 uint64_t threshold;
48
49 condition_status =
50 lttng_condition_session_consumed_size_get_session_name(
51 condition, &session_name);
52 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
53
54 lttng_condition_session_consumed_size_get_threshold(
55 condition, &threshold);
56 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
57
58 MSG(" session name: %s", session_name);
59 MSG(" threshold: %" PRIu64 " bytes", threshold);
60}
61
62static void print_condition_buffer_usage(
63 const struct lttng_condition *condition)
64{
65 enum lttng_condition_status condition_status;
66 const char *session_name, *channel_name;
67 enum lttng_domain_type domain_type;
68 uint64_t threshold;
69
70 condition_status = lttng_condition_buffer_usage_get_session_name(
71 condition, &session_name);
72 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
73
74 condition_status = lttng_condition_buffer_usage_get_channel_name(
75 condition, &channel_name);
76 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
77
78 condition_status = lttng_condition_buffer_usage_get_domain_type(
79 condition, &domain_type);
80 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
81
82 MSG(" session name: %s", session_name);
83 MSG(" channel name: %s", channel_name);
84 MSG(" domain: %s", lttng_domain_type_str(domain_type));
85
86 condition_status = lttng_condition_buffer_usage_get_threshold(
87 condition, &threshold);
88 if (condition_status == LTTNG_CONDITION_STATUS_OK) {
89 MSG(" threshold (bytes): %" PRIu64, threshold);
90 } else {
91 double threshold_ratio;
92
93 assert(condition_status == LTTNG_CONDITION_STATUS_UNSET);
94
95 condition_status =
96 lttng_condition_buffer_usage_get_threshold_ratio(
97 condition, &threshold_ratio);
98 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
99
100 MSG(" threshold (ratio): %.2f", threshold_ratio);
101 }
102}
103
104static void print_condition_session_rotation(
105 const struct lttng_condition *condition)
106{
107 enum lttng_condition_status condition_status;
108 const char *session_name;
109
110 condition_status = lttng_condition_session_rotation_get_session_name(
111 condition, &session_name);
112 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
113
114 MSG(" session name: %s", session_name);
115}
116
85b05318
JR
117/*
118 * Returns the human-readable log level name associated with a numerical value
119 * if there is one. The Log4j and JUL domains have discontinuous log level
120 * values (a value can fall between two labels). In those cases, NULL is
121 * returned.
122 */
123static const char *get_pretty_loglevel_name(
124 enum lttng_domain_type domain, int loglevel)
125{
126 const char *name = NULL;
127
128 switch (domain) {
129 case LTTNG_DOMAIN_UST:
130 name = loglevel_value_to_name(loglevel);
131 break;
132 case LTTNG_DOMAIN_LOG4J:
133 name = loglevel_log4j_value_to_name(loglevel);
134 break;
135 case LTTNG_DOMAIN_JUL:
136 name = loglevel_jul_value_to_name(loglevel);
137 break;
138 case LTTNG_DOMAIN_PYTHON:
139 name = loglevel_python_value_to_name(loglevel);
140 break;
141 default:
142 break;
143 }
144
145 return name;
146}
147
0de2479d
SM
148static
149void print_event_rule_tracepoint(const struct lttng_event_rule *event_rule)
150{
151 enum lttng_event_rule_status event_rule_status;
152 enum lttng_domain_type domain_type;
153 const char *pattern;
154 const char *filter;
155 int log_level;
85b05318 156 const struct lttng_log_level_rule *log_level_rule = NULL;
0de2479d
SM
157 unsigned int exclusions_count;
158 int i;
159
160 event_rule_status = lttng_event_rule_tracepoint_get_pattern(
161 event_rule, &pattern);
162 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
163
164 event_rule_status = lttng_event_rule_tracepoint_get_domain_type(
165 event_rule, &domain_type);
166 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
167
168 _MSG(" rule: %s (type: tracepoint, domain: %s", pattern,
169 lttng_domain_type_str(domain_type));
170
171 event_rule_status = lttng_event_rule_tracepoint_get_filter(
172 event_rule, &filter);
173 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
174 _MSG(", filter: %s", filter);
175 } else {
176 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
177 }
178
85b05318
JR
179 event_rule_status = lttng_event_rule_tracepoint_get_log_level_rule(
180 event_rule, &log_level_rule);
0de2479d 181 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
85b05318 182 enum lttng_log_level_rule_status llr_status;
0de2479d 183 const char *log_level_op;
85b05318
JR
184 const char *pretty_loglevel_name;
185
186 switch (lttng_log_level_rule_get_type(log_level_rule)) {
187 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
188 log_level_op = "is";
189 llr_status = lttng_log_level_rule_exactly_get_level(
190 log_level_rule, &log_level);
191 break;
192 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
193 log_level_op = "at least";
194 llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
195 log_level_rule, &log_level);
196 break;
197 default:
198 abort();
199 }
200
201 assert(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
202
203 pretty_loglevel_name = get_pretty_loglevel_name(
204 domain_type, log_level);
205 if (pretty_loglevel_name) {
206 _MSG(", log level %s %s", log_level_op,
207 pretty_loglevel_name);
208 } else {
209 _MSG(", log level %s %d", log_level_op, log_level);
210 }
0de2479d
SM
211 } else {
212 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
213 }
214
215 event_rule_status = lttng_event_rule_tracepoint_get_exclusions_count(
216 event_rule, &exclusions_count);
217 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
218 if (exclusions_count > 0) {
219 _MSG(", exclusions: ");
220 for (i = 0; i < exclusions_count; i++) {
221 const char *exclusion;
222
223 event_rule_status = lttng_event_rule_tracepoint_get_exclusion_at_index(
224 event_rule, i, &exclusion);
225 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
226
227 _MSG("%s%s", i > 0 ? "," : "", exclusion);
228 }
229 }
230
231 MSG(")");
232}
233
234static void print_kernel_probe_location(
235 const struct lttng_kernel_probe_location *location)
236{
237 enum lttng_kernel_probe_location_status status;
238 switch (lttng_kernel_probe_location_get_type(location)) {
239 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
240 {
241 uint64_t address;
242
243 status = lttng_kernel_probe_location_address_get_address(
244 location, &address);
245 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
246 ERR("Getting kernel probe location address failed.");
247 goto end;
248 }
249
250 _MSG("0x%" PRIx64, address);
251
252 break;
253 }
254 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
255 {
256 uint64_t offset;
257 const char *symbol_name;
258
259 symbol_name = lttng_kernel_probe_location_symbol_get_name(
260 location);
261 if (!symbol_name) {
262 ERR("Getting kernel probe location symbol name failed.");
263 goto end;
264 }
265
266 status = lttng_kernel_probe_location_symbol_get_offset(
267 location, &offset);
268 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
269 ERR("Getting kernel probe location address failed.");
270 goto end;
271 }
272
273 if (offset == 0) {
274 _MSG("%s", symbol_name);
275 } else {
276 _MSG("%s+0x%" PRIx64, symbol_name, offset);
277 }
278
279 break;
280 }
281 default:
282 abort();
283 };
284end:
285 return;
286}
287
288static
f2791161 289void print_event_rule_kernel_probe(const struct lttng_event_rule *event_rule)
0de2479d
SM
290{
291 enum lttng_event_rule_status event_rule_status;
292 const char *name;
293 const struct lttng_kernel_probe_location *location;
294
f2791161 295 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE);
0de2479d 296
d891bb52 297 event_rule_status = lttng_event_rule_kernel_probe_get_event_name(event_rule, &name);
0de2479d
SM
298 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
299 ERR("Failed to get kprobe event rule's name.");
300 goto end;
301 }
302
f2791161 303 event_rule_status = lttng_event_rule_kernel_probe_get_location(
0de2479d
SM
304 event_rule, &location);
305 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
306 ERR("Failed to get kprobe event rule's location.");
307 goto end;
308 }
309
310 _MSG(" rule: %s (type: probe, location: ", name);
311
312 print_kernel_probe_location(location);
313
314 MSG(")");
315
316end:
317 return;
318}
319
320static
1f1567a5 321void print_event_rule_userspace_probe(const struct lttng_event_rule *event_rule)
0de2479d
SM
322{
323 enum lttng_event_rule_status event_rule_status;
324 const char *name;
325 const struct lttng_userspace_probe_location *location;
326 enum lttng_userspace_probe_location_type userspace_probe_location_type;
327
1f1567a5 328 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE);
0de2479d 329
405f9e7d
JR
330 event_rule_status = lttng_event_rule_userspace_probe_get_event_name(
331 event_rule, &name);
0de2479d
SM
332 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
333 ERR("Failed to get uprobe event rule's name.");
334 goto end;
335 }
336
1f1567a5 337 event_rule_status = lttng_event_rule_userspace_probe_get_location(
0de2479d
SM
338 event_rule, &location);
339 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
340 ERR("Failed to get uprobe event rule's location.");
341 goto end;
342 }
343
8a917ae8 344 _MSG(" rule: %s (type: userspace probe, ", name);
0de2479d
SM
345
346 userspace_probe_location_type =
347 lttng_userspace_probe_location_get_type(location);
348
349 switch (userspace_probe_location_type) {
350 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
351 {
352 const char *binary_path, *function_name;
353
354 binary_path = lttng_userspace_probe_location_function_get_binary_path(
355 location);
356 function_name = lttng_userspace_probe_location_function_get_function_name(
357 location);
358
8a917ae8 359 _MSG("location type: ELF, location: %s:%s", binary_path, function_name);
0de2479d
SM
360 break;
361 }
362 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
8a917ae8
FD
363 {
364 const char *binary_path, *provider_name, *probe_name;
365
366 binary_path = lttng_userspace_probe_location_tracepoint_get_binary_path(
367 location);
368 provider_name = lttng_userspace_probe_location_tracepoint_get_provider_name(
369 location);
370 probe_name = lttng_userspace_probe_location_tracepoint_get_probe_name(
371 location);
372 _MSG("location type: SDT, location: %s:%s:%s", binary_path, provider_name, probe_name);
0de2479d 373 break;
8a917ae8 374 }
0de2479d
SM
375 default:
376 abort();
377 }
378
379 MSG(")");
380
381end:
382 return;
383}
384
385static
386void print_event_rule_syscall(const struct lttng_event_rule *event_rule)
387{
388 const char *pattern, *filter;
389 enum lttng_event_rule_status event_rule_status;
390
391 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_SYSCALL);
392
393 event_rule_status = lttng_event_rule_syscall_get_pattern(
394 event_rule, &pattern);
395 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
396
397 _MSG(" rule: %s (type: syscall", pattern);
398
399 event_rule_status = lttng_event_rule_syscall_get_filter(
400 event_rule, &filter);
401 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
402 _MSG(", filter: %s", filter);
403 } else {
404 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
405 }
406
407 MSG(")");
408}
409
410static
411void print_event_rule(const struct lttng_event_rule *event_rule)
412{
413 const enum lttng_event_rule_type event_rule_type =
414 lttng_event_rule_get_type(event_rule);
415
416 switch (event_rule_type) {
417 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
418 print_event_rule_tracepoint(event_rule);
419 break;
f2791161
JR
420 case LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE:
421 print_event_rule_kernel_probe(event_rule);
0de2479d 422 break;
1f1567a5
JR
423 case LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE:
424 print_event_rule_userspace_probe(event_rule);
0de2479d
SM
425 break;
426 case LTTNG_EVENT_RULE_TYPE_SYSCALL:
427 print_event_rule_syscall(event_rule);
428 break;
429 default:
430 abort();
431 }
432}
433
b203b4b0
SM
434static
435void print_one_event_expr(const struct lttng_event_expr *event_expr)
436{
437 enum lttng_event_expr_type type;
438
439 type = lttng_event_expr_get_type(event_expr);
440
441 switch (type) {
442 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
443 {
444 const char *name;
445
446 name = lttng_event_expr_event_payload_field_get_name(
447 event_expr);
448 _MSG("%s", name);
449
450 break;
451 }
452 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
453 {
454 const char *name;
455
456 name = lttng_event_expr_channel_context_field_get_name(
457 event_expr);
458 _MSG("$ctx.%s", name);
459
460 break;
461 }
462 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
463 {
464 const char *provider_name;
465 const char *type_name;
466
467 provider_name = lttng_event_expr_app_specific_context_field_get_provider_name(
468 event_expr);
469 type_name = lttng_event_expr_app_specific_context_field_get_type_name(
470 event_expr);
471
472 _MSG("$app.%s:%s", provider_name, type_name);
473
474 break;
475 }
476 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
477 {
478 unsigned int index;
479 const struct lttng_event_expr *parent_expr;
480 enum lttng_event_expr_status status;
481
482 parent_expr = lttng_event_expr_array_field_element_get_parent_expr(
483 event_expr);
484 assert(parent_expr != NULL);
485
486 print_one_event_expr(parent_expr);
487
488 status = lttng_event_expr_array_field_element_get_index(
489 event_expr, &index);
490 assert(status == LTTNG_EVENT_EXPR_STATUS_OK);
491
492 _MSG("[%u]", index);
493
494 break;
495 }
496 default:
497 abort();
498 }
499}
500
0de2479d 501static
d602bd6a 502void print_condition_on_event(const struct lttng_condition *condition)
0de2479d
SM
503{
504 const struct lttng_event_rule *event_rule;
505 enum lttng_condition_status condition_status;
b203b4b0 506 unsigned int cap_desc_count, i;
0de2479d
SM
507
508 condition_status =
d602bd6a 509 lttng_condition_on_event_get_rule(condition, &event_rule);
0de2479d
SM
510 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
511
512 print_event_rule(event_rule);
b203b4b0
SM
513
514 condition_status =
d602bd6a 515 lttng_condition_on_event_get_capture_descriptor_count(
b203b4b0
SM
516 condition, &cap_desc_count);
517 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
518
519 if (cap_desc_count > 0) {
520 MSG(" captures:");
521
522 for (i = 0; i < cap_desc_count; i++) {
523 const struct lttng_event_expr *cap_desc =
d602bd6a 524 lttng_condition_on_event_get_capture_descriptor_at_index(
b203b4b0
SM
525 condition, i);
526
527 _MSG(" - ");
528 print_one_event_expr(cap_desc);
529 MSG("");
530 }
531 }
0de2479d
SM
532}
533
534static
709fb83f
JG
535void print_action_errors(const struct lttng_trigger *trigger,
536 const struct lttng_action *action)
537{
538 unsigned int i, count, printed_errors_count = 0;
539 enum lttng_error_code error_query_ret;
540 enum lttng_error_query_results_status results_status;
541 struct lttng_error_query_results *results = NULL;
542 const char *trigger_name;
543 uid_t trigger_uid;
544 enum lttng_trigger_status trigger_status;
545 struct lttng_error_query *query =
546 lttng_error_query_action_create(trigger, action);
547
548 assert(query);
549
550 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
551 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
552
553 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
554 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
555
556 error_query_ret = lttng_error_query_execute(
557 query, lttng_session_daemon_command_endpoint, &results);
558 if (error_query_ret != LTTNG_OK) {
559 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
560 trigger_name, (int) trigger_uid,
561 lttng_strerror(-error_query_ret));
562 goto end;
563 }
564
565 results_status = lttng_error_query_results_get_count(results, &count);
566 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
567
568 _MSG(" errors:");
569
570 for (i = 0; i < count; i++) {
571 const struct lttng_error_query_result *result;
572 enum lttng_error_query_result_status result_status;
573 const char *result_name;
574 const char *result_description;
575 uint64_t result_value;
576
577 results_status = lttng_error_query_results_get_result(
578 results, &result, i);
579 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
580
581 result_status = lttng_error_query_result_get_name(
582 result, &result_name);
583 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
584 result_status = lttng_error_query_result_get_description(
585 result, &result_description);
586 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
587
588 if (lttng_error_query_result_get_type(result) ==
589 LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
590 result_status = lttng_error_query_result_counter_get_value(
591 result, &result_value);
592 assert(result_status ==
593 LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
594 if (result_value == 0) {
595 continue;
596 }
597
598 MSG("");
599 _MSG(" %s: %" PRIu64, result_name,
600 result_value);
601 printed_errors_count++;
602 } else {
603 _MSG(" Unknown error query result type for result '%s' (%s)",
604 result_name, result_description);
605 continue;
606 }
607 }
608
609 if (printed_errors_count == 0) {
610 _MSG(" none");
611 }
612
613end:
614 MSG("");
615 lttng_error_query_destroy(query);
616 lttng_error_query_results_destroy(results);
617}
618
619static
620void print_one_action(const struct lttng_trigger *trigger,
621 const struct lttng_action *action)
0de2479d
SM
622{
623 enum lttng_action_type action_type;
624 enum lttng_action_status action_status;
7f4d5b07 625 const struct lttng_rate_policy *policy = NULL;
0de2479d
SM
626 const char *value;
627
628 action_type = lttng_action_get_type(action);
629 assert(action_type != LTTNG_ACTION_TYPE_GROUP);
630
631 switch (action_type) {
632 case LTTNG_ACTION_TYPE_NOTIFY:
e45dd625
JR
633 _MSG("notify");
634
7f4d5b07 635 action_status = lttng_action_notify_get_rate_policy(
e45dd625
JR
636 action, &policy);
637 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 638 ERR("Failed to retrieve rate policy.");
e45dd625
JR
639 goto end;
640 }
0de2479d
SM
641 break;
642 case LTTNG_ACTION_TYPE_START_SESSION:
643 action_status = lttng_action_start_session_get_session_name(
644 action, &value);
645 assert(action_status == LTTNG_ACTION_STATUS_OK);
e45dd625
JR
646 _MSG("start session `%s`", value);
647
7f4d5b07 648 action_status = lttng_action_start_session_get_rate_policy(
e45dd625
JR
649 action, &policy);
650 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 651 ERR("Failed to retrieve rate policy.");
e45dd625
JR
652 goto end;
653 }
0de2479d
SM
654 break;
655 case LTTNG_ACTION_TYPE_STOP_SESSION:
656 action_status = lttng_action_stop_session_get_session_name(
657 action, &value);
658 assert(action_status == LTTNG_ACTION_STATUS_OK);
e45dd625
JR
659 _MSG("stop session `%s`", value);
660
7f4d5b07 661 action_status = lttng_action_stop_session_get_rate_policy(
e45dd625
JR
662 action, &policy);
663 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 664 ERR("Failed to retrieve rate policy.");
e45dd625
JR
665 goto end;
666 }
0de2479d
SM
667 break;
668 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
669 action_status = lttng_action_rotate_session_get_session_name(
670 action, &value);
671 assert(action_status == LTTNG_ACTION_STATUS_OK);
e45dd625
JR
672 _MSG("rotate session `%s`", value);
673
7f4d5b07 674 action_status = lttng_action_rotate_session_get_rate_policy(
e45dd625
JR
675 action, &policy);
676 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 677 ERR("Failed to retrieve rate policy.");
e45dd625
JR
678 goto end;
679 }
0de2479d
SM
680 break;
681 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
682 {
683 const struct lttng_snapshot_output *output;
684
685 action_status = lttng_action_snapshot_session_get_session_name(
686 action, &value);
687 assert(action_status == LTTNG_ACTION_STATUS_OK);
688 _MSG("snapshot session `%s`", value);
689
690 action_status = lttng_action_snapshot_session_get_output(
691 action, &output);
692 if (action_status == LTTNG_ACTION_STATUS_OK) {
693 const char *name;
694 uint64_t max_size;
695 const char *ctrl_url, *data_url;
696 bool starts_with_file, starts_with_net, starts_with_net6;
697
698 ctrl_url = lttng_snapshot_output_get_ctrl_url(output);
699 assert(ctrl_url && strlen(ctrl_url) > 0);
700
701 data_url = lttng_snapshot_output_get_data_url(output);
702 assert(data_url);
703
704 starts_with_file = strncmp(ctrl_url, "file://", strlen("file://")) == 0;
705 starts_with_net = strncmp(ctrl_url, "net://", strlen("net://")) == 0;
706 starts_with_net6 = strncmp(ctrl_url, "net6://", strlen("net6://")) == 0;
707
708 if (ctrl_url[0] == '/' || starts_with_file) {
709 if (starts_with_file) {
710 ctrl_url += strlen("file://");
711 }
712
713 _MSG(", path: %s", ctrl_url);
714 } else if (starts_with_net || starts_with_net6) {
715 _MSG(", url: %s", ctrl_url);
716 } else {
717 assert(strlen(data_url) > 0);
718
719 _MSG(", control url: %s, data url: %s", ctrl_url, data_url);
720 }
721
722 name = lttng_snapshot_output_get_name(output);
723 assert(name);
724 if (strlen(name) > 0) {
725 _MSG(", name: %s", name);
726 }
727
728 max_size = lttng_snapshot_output_get_maxsize(output);
729 if (max_size != -1ULL) {
730 _MSG(", max size: %" PRIu64, max_size);
731 }
732 }
733
7f4d5b07 734 action_status = lttng_action_snapshot_session_get_rate_policy(
e45dd625
JR
735 action, &policy);
736 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 737 ERR("Failed to retrieve rate policy.");
e45dd625
JR
738 goto end;
739 }
0de2479d
SM
740 break;
741 }
0de2479d
SM
742 default:
743 abort();
744 }
e45dd625
JR
745
746 if (policy) {
7f4d5b07
JR
747 enum lttng_rate_policy_type policy_type;
748 enum lttng_rate_policy_status policy_status;
e45dd625
JR
749 uint64_t policy_value = 0;
750
7f4d5b07 751 policy_type = lttng_rate_policy_get_type(policy);
e45dd625
JR
752
753 switch (policy_type) {
7f4d5b07
JR
754 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
755 policy_status = lttng_rate_policy_every_n_get_interval(
e45dd625 756 policy, &policy_value);
7f4d5b07
JR
757 if (policy_status != LTTNG_RATE_POLICY_STATUS_OK) {
758 ERR("Failed to get action rate policy interval");
e45dd625
JR
759 goto end;
760 }
761 if (policy_value > 1) {
762 /* The default is 1 so print only when it is a
763 * special case.
764 */
7f4d5b07 765 _MSG(", rate policy: after every %" PRIu64
e45dd625
JR
766 " occurrences",
767 policy_value);
768 }
769 break;
7f4d5b07
JR
770 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
771 policy_status = lttng_rate_policy_once_after_n_get_threshold(
e45dd625 772 policy, &policy_value);
7f4d5b07
JR
773 if (policy_status != LTTNG_RATE_POLICY_STATUS_OK) {
774 ERR("Failed to get action rate policy interval");
e45dd625
JR
775 goto end;
776 }
7f4d5b07 777 _MSG(", rate policy: once after %" PRIu64
e45dd625
JR
778 " occurrences",
779 policy_value);
780 break;
781 default:
782 abort();
783 }
784 }
785
786 MSG("");
709fb83f
JG
787 print_action_errors(trigger, action);
788
e45dd625
JR
789end:
790 return;
0de2479d
SM
791}
792
709fb83f
JG
793static
794void print_trigger_errors(const struct lttng_trigger *trigger)
795{
796 unsigned int i, count, printed_errors_count = 0;
797 enum lttng_error_code error_query_ret;
798 enum lttng_error_query_results_status results_status;
799 struct lttng_error_query_results *results = NULL;
800 enum lttng_trigger_status trigger_status;
801 const char *trigger_name;
802 uid_t trigger_uid;
803 struct lttng_error_query *query =
804 lttng_error_query_trigger_create(trigger);
805
806 assert(query);
807
808 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
809 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
810
811 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
812 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
813
814 error_query_ret = lttng_error_query_execute(
815 query, lttng_session_daemon_command_endpoint, &results);
816 if (error_query_ret != LTTNG_OK) {
817 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
818 trigger_name, (int) trigger_uid,
819 lttng_strerror(-error_query_ret));
820 goto end;
821 }
822
823 results_status = lttng_error_query_results_get_count(results, &count);
824 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
825
826 _MSG(" errors:");
827
828 for (i = 0; i < count; i++) {
829 const struct lttng_error_query_result *result;
830 enum lttng_error_query_result_status result_status;
831 const char *result_name;
832 const char *result_description;
833 uint64_t result_value;
834
835 results_status = lttng_error_query_results_get_result(
836 results, &result, i);
837 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
838
839 result_status = lttng_error_query_result_get_name(
840 result, &result_name);
841 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
842 result_status = lttng_error_query_result_get_description(
843 result, &result_description);
844 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
845
846 if (lttng_error_query_result_get_type(result) ==
847 LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
848 result_status = lttng_error_query_result_counter_get_value(
849 result, &result_value);
850 assert(result_status ==
851 LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
852 if (result_value == 0) {
853 continue;
854 }
855
856 MSG("");
857 _MSG(" %s: %" PRIu64, result_name,
858 result_value);
859 printed_errors_count++;
860 } else {
861 _MSG(" Unknown error query result type for result '%s' (%s)",
862 result_name, result_description);
863 continue;
864 }
865 }
866
867 if (printed_errors_count == 0) {
868 _MSG(" none");
869 }
870
871end:
872 MSG("");
873 lttng_error_query_destroy(query);
874 lttng_error_query_results_destroy(results);
875}
876
0de2479d
SM
877static
878void print_one_trigger(const struct lttng_trigger *trigger)
879{
880 const struct lttng_condition *condition;
881 enum lttng_condition_type condition_type;
882 const struct lttng_action *action;
883 enum lttng_action_type action_type;
884 enum lttng_trigger_status trigger_status;
885 const char *name;
0de2479d
SM
886 uid_t trigger_uid;
887
888 trigger_status = lttng_trigger_get_name(trigger, &name);
889 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
890
891 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
892 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
893
1d4b59f2 894 MSG("- name: %s", name);
481c5310 895 MSG(" owner uid: %d", trigger_uid);
0de2479d 896
0de2479d
SM
897 condition = lttng_trigger_get_const_condition(trigger);
898 condition_type = lttng_condition_get_type(condition);
899 MSG(" condition: %s", lttng_condition_type_str(condition_type));
900 switch (condition_type) {
19904669
SM
901 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
902 print_condition_session_consumed_size(condition);
903 break;
904 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
905 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
906 print_condition_buffer_usage(condition);
907 break;
908 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
909 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
910 print_condition_session_rotation(condition);
911 break;
d602bd6a
JR
912 case LTTNG_CONDITION_TYPE_ON_EVENT:
913 print_condition_on_event(condition);
0de2479d
SM
914 break;
915 default:
19904669 916 abort();
0de2479d
SM
917 }
918
919 action = lttng_trigger_get_const_action(trigger);
920 action_type = lttng_action_get_type(action);
921 if (action_type == LTTNG_ACTION_TYPE_GROUP) {
922 unsigned int count, i;
923 enum lttng_action_status action_status;
924
925 MSG(" actions:");
926
927 action_status = lttng_action_group_get_count(action, &count);
928 assert(action_status == LTTNG_ACTION_STATUS_OK);
929
930 for (i = 0; i < count; i++) {
931 const struct lttng_action *subaction =
932 lttng_action_group_get_at_index(
933 action, i);
934
935 _MSG(" ");
709fb83f 936 print_one_action(trigger, subaction);
0de2479d
SM
937 }
938 } else {
939 _MSG(" action:");
709fb83f 940 print_one_action(trigger, action);
0de2479d
SM
941 }
942
709fb83f 943 print_trigger_errors(trigger);
0de2479d
SM
944}
945
946static
947int compare_triggers_by_name(const void *a, const void *b)
948{
949 const struct lttng_trigger *trigger_a = *((const struct lttng_trigger **) a);
950 const struct lttng_trigger *trigger_b = *((const struct lttng_trigger **) b);
951 const char *name_a, *name_b;
952 enum lttng_trigger_status trigger_status;
953
954 trigger_status = lttng_trigger_get_name(trigger_a, &name_a);
955 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
956
957 trigger_status = lttng_trigger_get_name(trigger_b, &name_b);
958 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
959
960 return strcmp(name_a, name_b);
961}
962
963int cmd_list_triggers(int argc, const char **argv)
964{
965 int ret;
966 struct argpar_parse_ret argpar_parse_ret = {};
967 struct lttng_triggers *triggers = NULL;
968 int i;
969 struct lttng_dynamic_pointer_array sorted_triggers;
970 enum lttng_trigger_status trigger_status;
971 unsigned int num_triggers;
972
973 lttng_dynamic_pointer_array_init(&sorted_triggers, NULL);
974
975 argpar_parse_ret = argpar_parse(
976 argc - 1, argv + 1, list_trigger_options, true);
977 if (!argpar_parse_ret.items) {
978 ERR("%s", argpar_parse_ret.error);
979 goto error;
980 }
981
982 for (i = 0; i < argpar_parse_ret.items->n_items; i++) {
983 const struct argpar_item *item =
984 argpar_parse_ret.items->items[i];
985
986 if (item->type == ARGPAR_ITEM_TYPE_OPT) {
987 const struct argpar_item_opt *item_opt =
988 (const struct argpar_item_opt *) item;
989
990 switch (item_opt->descr->id) {
991 case OPT_HELP:
992 SHOW_HELP();
993 ret = 0;
994 goto end;
995
996 case OPT_LIST_OPTIONS:
997 list_cmd_options_argpar(stdout,
998 list_trigger_options);
999 ret = 0;
1000 goto end;
1001
1002 default:
1003 abort();
1004 }
1005
1006 } else {
1007 const struct argpar_item_non_opt *item_non_opt =
1008 (const struct argpar_item_non_opt *) item;
1009
1010 ERR("Unexpected argument: %s", item_non_opt->arg);
1011 }
1012 }
1013
1014 ret = lttng_list_triggers(&triggers);
1015 if (ret != LTTNG_OK) {
1016 ERR("Error listing triggers: %s.", lttng_strerror(-ret));
1017 goto error;
1018 }
1019
1020 trigger_status = lttng_triggers_get_count(triggers, &num_triggers);
1021 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
1022 ERR("Failed to get trigger count.");
1023 goto error;
1024 }
1025
1026 for (i = 0; i < num_triggers; i++) {
1027 const int add_ret = lttng_dynamic_pointer_array_add_pointer(
1028 &sorted_triggers,
1029 (void *) lttng_triggers_get_at_index(triggers, i));
1030
1031 if (add_ret) {
1032 ERR("Failed to allocate array of struct lttng_trigger *.");
1033 goto error;
1034 }
1035 }
1036
1037 qsort(sorted_triggers.array.buffer.data, num_triggers,
1038 sizeof(struct lttng_trigger *),
1039 compare_triggers_by_name);
1040
1041 for (i = 0; i < num_triggers; i++) {
1042 const struct lttng_trigger *trigger_to_print =
1043 (const struct lttng_trigger *)
1044 lttng_dynamic_pointer_array_get_pointer(
1045 &sorted_triggers, i);
1046
1047 print_one_trigger(trigger_to_print);
1048 }
1049
1050 ret = 0;
1051 goto end;
1052
1053error:
1054 ret = 1;
1055
1056end:
1057 argpar_parse_ret_fini(&argpar_parse_ret);
1058 lttng_triggers_destroy(triggers);
1059 lttng_dynamic_pointer_array_reset(&sorted_triggers);
1060
1061 return ret;
1062}
This page took 0.065969 seconds and 4 git commands to generate.