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