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