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