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