2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
4 * SPDX-License-Identifier: GPL-2.0-only
16 #include <common/mi-lttng.h>
17 #include <common/time.h>
18 #include <lttng/constant.h>
19 #include <lttng/tracker.h>
21 #include "../command.h"
23 static int opt_userspace
;
24 static int opt_kernel
;
27 static int opt_python
;
28 static char *opt_channel
;
29 static int opt_domain
;
30 static int opt_fields
;
31 static int opt_syscall
;
33 const char *indent4
= " ";
34 const char *indent6
= " ";
35 const char *indent8
= " ";
37 #ifdef LTTNG_EMBED_HELP
38 static const char help_msg
[] =
39 #include <lttng-list.1.h>
49 static struct lttng_handle
*handle
;
50 static struct mi_writer
*writer
;
52 /* Only set when listing a single session. */
53 static struct lttng_session listed_session
;
55 static struct poptOption long_options
[] = {
56 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
57 {"help", 'h', POPT_ARG_NONE
, 0, OPT_HELP
, 0, 0},
58 {"kernel", 'k', POPT_ARG_VAL
, &opt_kernel
, 1, 0, 0},
59 {"jul", 'j', POPT_ARG_VAL
, &opt_jul
, 1, 0, 0},
60 {"log4j", 'l', POPT_ARG_VAL
, &opt_log4j
, 1, 0, 0},
61 {"python", 'p', POPT_ARG_VAL
, &opt_python
, 1, 0, 0},
62 {"userspace", 'u', POPT_ARG_NONE
, 0, OPT_USERSPACE
, 0, 0},
63 {"channel", 'c', POPT_ARG_STRING
, &opt_channel
, 0, 0, 0},
64 {"domain", 'd', POPT_ARG_VAL
, &opt_domain
, 1, 0, 0},
65 {"fields", 'f', POPT_ARG_VAL
, &opt_fields
, 1, 0, 0},
66 {"syscall", 'S', POPT_ARG_VAL
, &opt_syscall
, 1, 0, 0},
67 {"list-options", 0, POPT_ARG_NONE
, NULL
, OPT_LIST_OPTIONS
, NULL
, NULL
},
72 * Get command line from /proc for a specific pid.
74 * On success, return an allocated string pointer to the proc cmdline.
75 * On error, return NULL.
77 static char *get_cmdline_by_pid(pid_t pid
)
82 /* Can't go bigger than /proc/LTTNG_MAX_PID/cmdline */
83 char path
[sizeof("/proc//cmdline") + sizeof(LTTNG_MAX_PID_STR
) - 1];
85 snprintf(path
, sizeof(path
), "/proc/%d/cmdline", pid
);
86 fp
= fopen(path
, "r");
91 /* Caller must free() *cmdline */
92 cmdline
= zmalloc(PATH_MAX
);
94 PERROR("malloc cmdline");
97 ret
= fread(cmdline
, 1, PATH_MAX
, fp
);
99 PERROR("fread proc list");
110 const char *active_string(int value
)
113 case 0: return "inactive";
114 case 1: return "active";
116 default: return NULL
;
120 static const char *snapshot_string(int value
)
131 const char *enabled_string(int value
)
134 case 0: return " [disabled]";
135 case 1: return " [enabled]";
137 default: return NULL
;
142 const char *safe_string(const char *str
)
144 return str
? str
: "";
147 static const char *logleveltype_string(enum lttng_loglevel_type value
)
150 case LTTNG_EVENT_LOGLEVEL_ALL
:
152 case LTTNG_EVENT_LOGLEVEL_RANGE
:
154 case LTTNG_EVENT_LOGLEVEL_SINGLE
:
157 return " <<TYPE UNKN>>";
161 static const char *bitness_event(enum lttng_event_flag flags
)
163 if (flags
& LTTNG_EVENT_FLAG_SYSCALL_32
) {
164 if (flags
& LTTNG_EVENT_FLAG_SYSCALL_64
) {
165 return " [32/64-bit]";
169 } else if (flags
& LTTNG_EVENT_FLAG_SYSCALL_64
) {
177 * Get exclusion names message for a single event.
179 * Returned pointer must be freed by caller. Returns NULL on error.
181 static char *get_exclusion_names_msg(struct lttng_event
*event
)
185 char *exclusion_msg
= NULL
;
188 const char * const exclusion_fmt
= " [exclusions: ";
189 const size_t exclusion_fmt_len
= strlen(exclusion_fmt
);
191 exclusion_count
= lttng_event_get_exclusion_name_count(event
);
192 if (exclusion_count
< 0) {
194 } else if (exclusion_count
== 0) {
196 * No exclusions: return copy of empty string so that
197 * it can be freed by caller.
199 exclusion_msg
= strdup("");
204 * exclusion_msg's size is bounded by the exclusion_fmt string,
205 * a comma per entry, the entry count (fixed-size), a closing
206 * bracket, and a trailing \0.
208 exclusion_msg
= malloc(exclusion_count
+
209 exclusion_count
* LTTNG_SYMBOL_NAME_LEN
+
210 exclusion_fmt_len
+ 1);
211 if (!exclusion_msg
) {
215 at
= strcpy(exclusion_msg
, exclusion_fmt
) + exclusion_fmt_len
;
216 for (i
= 0; i
< exclusion_count
; ++i
) {
219 /* Append comma between exclusion names */
225 ret
= lttng_event_get_exclusion_name(event
, i
, &name
);
227 /* Prints '?' on local error; should never happen */
233 /* Append exclusion name */
234 at
+= sprintf(at
, "%s", name
);
237 /* This also puts a final '\0' at the end of exclusion_msg */
241 return exclusion_msg
;
244 static void print_userspace_probe_location(struct lttng_event
*event
)
246 const struct lttng_userspace_probe_location
*location
;
247 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
248 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
250 location
= lttng_event_get_userspace_probe_location(event
);
252 MSG("Event has no userspace probe location");
256 lookup_method
= lttng_userspace_probe_location_get_lookup_method(location
);
257 if (!lookup_method
) {
258 MSG("Event has no userspace probe location lookup method");
262 MSG("%s%s (type: userspace-probe)%s", indent6
, event
->name
, enabled_string(event
->enabled
));
264 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(lookup_method
);
266 switch (lttng_userspace_probe_location_get_type(location
)) {
267 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
:
268 MSG("%sType: Unknown", indent8
);
270 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
272 const char *function_name
;
273 const char *binary_path
;
275 MSG("%sType: Function", indent8
);
276 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
277 binary_path
= realpath(lttng_userspace_probe_location_function_get_binary_path(location
), NULL
);
279 MSG("%sBinary path: %s", indent8
, binary_path
? binary_path
: "NULL");
280 MSG("%sFunction: %s()", indent8
, function_name
? function_name
: "NULL");
281 switch (lookup_type
) {
282 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
283 MSG("%sLookup method: ELF", indent8
);
285 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
286 MSG("%sLookup method: default", indent8
);
289 MSG("%sLookup method: INVALID LOOKUP TYPE ENCOUNTERED", indent8
);
294 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
296 const char *probe_name
, *provider_name
;
297 const char *binary_path
;
299 MSG("%sType: Tracepoint", indent8
);
300 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
301 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
302 binary_path
= realpath(lttng_userspace_probe_location_tracepoint_get_binary_path(location
), NULL
);
303 MSG("%sBinary path: %s", indent8
, binary_path
? binary_path
: "NULL");
304 MSG("%sTracepoint: %s:%s", indent8
, provider_name
? provider_name
: "NULL", probe_name
? probe_name
: "NULL");
305 switch (lookup_type
) {
306 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
307 MSG("%sLookup method: SDT", indent8
);
310 MSG("%sLookup method: INVALID LOOKUP TYPE ENCOUNTERED", indent8
);
316 ERR("Invalid probe type encountered");
321 * Pretty print single event.
323 static void print_events(struct lttng_event
*event
)
326 const char *filter_str
;
327 char *filter_msg
= NULL
;
328 char *exclusion_msg
= NULL
;
330 ret
= lttng_event_get_filter_expression(event
, &filter_str
);
333 filter_msg
= strdup(" [failed to retrieve filter]");
334 } else if (filter_str
) {
335 const char * const filter_fmt
= " [filter: '%s']";
337 filter_msg
= malloc(strlen(filter_str
) +
338 strlen(filter_fmt
) + 1);
340 sprintf(filter_msg
, filter_fmt
,
345 exclusion_msg
= get_exclusion_names_msg(event
);
346 if (!exclusion_msg
) {
347 exclusion_msg
= strdup(" [failed to retrieve exclusions]");
350 switch (event
->type
) {
351 case LTTNG_EVENT_TRACEPOINT
:
353 if (event
->loglevel
!= -1) {
354 MSG("%s%s (loglevel%s %s (%d)) (type: tracepoint)%s%s%s",
357 logleveltype_string(event
->loglevel_type
),
358 mi_lttng_loglevel_string(event
->loglevel
, handle
->domain
.type
),
360 enabled_string(event
->enabled
),
361 safe_string(exclusion_msg
),
362 safe_string(filter_msg
));
364 MSG("%s%s (type: tracepoint)%s%s%s",
367 enabled_string(event
->enabled
),
368 safe_string(exclusion_msg
),
369 safe_string(filter_msg
));
373 case LTTNG_EVENT_FUNCTION
:
374 MSG("%s%s (type: function)%s%s", indent6
,
375 event
->name
, enabled_string(event
->enabled
),
376 safe_string(filter_msg
));
377 if (event
->attr
.probe
.addr
!= 0) {
378 MSG("%saddr: 0x%" PRIx64
, indent8
, event
->attr
.probe
.addr
);
380 MSG("%soffset: 0x%" PRIx64
, indent8
, event
->attr
.probe
.offset
);
381 MSG("%ssymbol: %s", indent8
, event
->attr
.probe
.symbol_name
);
384 case LTTNG_EVENT_PROBE
:
385 MSG("%s%s (type: probe)%s%s", indent6
,
386 event
->name
, enabled_string(event
->enabled
),
387 safe_string(filter_msg
));
388 if (event
->attr
.probe
.addr
!= 0) {
389 MSG("%saddr: 0x%" PRIx64
, indent8
, event
->attr
.probe
.addr
);
391 MSG("%soffset: 0x%" PRIx64
, indent8
, event
->attr
.probe
.offset
);
392 MSG("%ssymbol: %s", indent8
, event
->attr
.probe
.symbol_name
);
395 case LTTNG_EVENT_USERSPACE_PROBE
:
396 print_userspace_probe_location(event
);
398 case LTTNG_EVENT_FUNCTION_ENTRY
:
399 MSG("%s%s (type: function)%s%s", indent6
,
400 event
->name
, enabled_string(event
->enabled
),
401 safe_string(filter_msg
));
402 MSG("%ssymbol: \"%s\"", indent8
, event
->attr
.ftrace
.symbol_name
);
404 case LTTNG_EVENT_SYSCALL
:
405 MSG("%s%s%s%s%s%s", indent6
, event
->name
,
406 (opt_syscall
? "" : " (type:syscall)"),
407 enabled_string(event
->enabled
),
408 bitness_event(event
->flags
),
409 safe_string(filter_msg
));
411 case LTTNG_EVENT_NOOP
:
412 MSG("%s (type: noop)%s%s", indent6
,
413 enabled_string(event
->enabled
),
414 safe_string(filter_msg
));
416 case LTTNG_EVENT_ALL
:
419 /* We should never have "all" events in list. */
428 static const char *field_type(struct lttng_event_field
*field
)
430 switch(field
->type
) {
431 case LTTNG_EVENT_FIELD_INTEGER
:
433 case LTTNG_EVENT_FIELD_ENUM
:
435 case LTTNG_EVENT_FIELD_FLOAT
:
437 case LTTNG_EVENT_FIELD_STRING
:
439 case LTTNG_EVENT_FIELD_OTHER
:
440 default: /* fall-through */
446 * Pretty print single event fields.
448 static void print_event_field(struct lttng_event_field
*field
)
450 if (!field
->field_name
[0]) {
453 MSG("%sfield: %s (%s)%s", indent8
, field
->field_name
,
454 field_type(field
), field
->nowrite
? " [no write]" : "");
459 * Jul and ust event listing
461 static int mi_list_agent_ust_events(struct lttng_event
*events
, int count
,
462 struct lttng_domain
*domain
)
466 char *cmdline
= NULL
;
467 int pid_element_open
= 0;
469 /* Open domains element */
470 ret
= mi_lttng_domains_open(writer
);
476 ret
= mi_lttng_domain(writer
, domain
, 1);
481 /* Open pids element element */
482 ret
= mi_lttng_pids_open(writer
);
487 for (i
= 0; i
< count
; i
++) {
488 if (cur_pid
!= events
[i
].pid
) {
489 if (pid_element_open
) {
490 /* Close the previous events and pid element */
491 ret
= mi_lttng_close_multi_element(writer
, 2);
495 pid_element_open
= 0;
498 cur_pid
= events
[i
].pid
;
499 cmdline
= get_cmdline_by_pid(cur_pid
);
505 if (!pid_element_open
) {
506 /* Open and write a pid element */
507 ret
= mi_lttng_pid(writer
, cur_pid
, cmdline
, 1);
512 /* Open events element */
513 ret
= mi_lttng_events_open(writer
);
518 pid_element_open
= 1;
524 ret
= mi_lttng_event(writer
, &events
[i
], 0, handle
->domain
.type
);
531 ret
= mi_lttng_writer_close_element(writer
);
536 /* Close domain, domains */
537 ret
= mi_lttng_close_multi_element(writer
, 2);
545 static int list_agent_events(void)
547 int i
, size
, ret
= CMD_SUCCESS
;
548 struct lttng_domain domain
;
549 struct lttng_handle
*handle
= NULL
;
550 struct lttng_event
*event_list
= NULL
;
552 char *cmdline
= NULL
;
553 const char *agent_domain_str
;
555 memset(&domain
, 0, sizeof(domain
));
557 domain
.type
= LTTNG_DOMAIN_JUL
;
558 } else if (opt_log4j
) {
559 domain
.type
= LTTNG_DOMAIN_LOG4J
;
560 } else if (opt_python
) {
561 domain
.type
= LTTNG_DOMAIN_PYTHON
;
563 ERR("Invalid agent domain selected.");
568 agent_domain_str
= get_domain_str(domain
.type
);
570 DBG("Getting %s tracing events", agent_domain_str
);
572 handle
= lttng_create_handle(NULL
, &domain
);
573 if (handle
== NULL
) {
578 size
= lttng_list_tracepoints(handle
, &event_list
);
580 ERR("Unable to list %s events: %s", agent_domain_str
,
581 lttng_strerror(size
));
588 ret
= mi_list_agent_ust_events(event_list
, size
, &domain
);
595 MSG("%s events (Logger name):\n-------------------------",
602 for (i
= 0; i
< size
; i
++) {
603 if (cur_pid
!= event_list
[i
].pid
) {
604 cur_pid
= event_list
[i
].pid
;
605 cmdline
= get_cmdline_by_pid(cur_pid
);
606 if (cmdline
== NULL
) {
610 MSG("\nPID: %d - Name: %s", cur_pid
, cmdline
);
613 MSG("%s- %s", indent6
, event_list
[i
].name
);
622 lttng_destroy_handle(handle
);
627 * Ask session daemon for all user space tracepoints available.
629 static int list_ust_events(void)
631 int i
, size
, ret
= CMD_SUCCESS
;
632 struct lttng_domain domain
;
633 struct lttng_handle
*handle
;
634 struct lttng_event
*event_list
= NULL
;
636 char *cmdline
= NULL
;
638 memset(&domain
, 0, sizeof(domain
));
640 DBG("Getting UST tracing events");
642 domain
.type
= LTTNG_DOMAIN_UST
;
644 handle
= lttng_create_handle(NULL
, &domain
);
645 if (handle
== NULL
) {
650 size
= lttng_list_tracepoints(handle
, &event_list
);
652 ERR("Unable to list UST events: %s", lttng_strerror(size
));
659 ret
= mi_list_agent_ust_events(event_list
, size
, &domain
);
662 MSG("UST events:\n-------------");
668 for (i
= 0; i
< size
; i
++) {
669 if (cur_pid
!= event_list
[i
].pid
) {
670 cur_pid
= event_list
[i
].pid
;
671 cmdline
= get_cmdline_by_pid(cur_pid
);
672 if (cmdline
== NULL
) {
676 MSG("\nPID: %d - Name: %s", cur_pid
, cmdline
);
679 print_events(&event_list
[i
]);
688 lttng_destroy_handle(handle
);
694 * List all ust event with their fields
696 static int mi_list_ust_event_fields(struct lttng_event_field
*fields
, int count
,
697 struct lttng_domain
*domain
)
701 char *cmdline
= NULL
;
702 int pid_element_open
= 0;
703 int event_element_open
= 0;
704 struct lttng_event cur_event
;
706 memset(&cur_event
, 0, sizeof(cur_event
));
708 /* Open domains element */
709 ret
= mi_lttng_domains_open(writer
);
715 ret
= mi_lttng_domain(writer
, domain
, 1);
720 /* Open pids element */
721 ret
= mi_lttng_pids_open(writer
);
726 for (i
= 0; i
< count
; i
++) {
727 if (cur_pid
!= fields
[i
].event
.pid
) {
728 if (pid_element_open
) {
729 if (event_element_open
) {
730 /* Close the previous field element and event. */
731 ret
= mi_lttng_close_multi_element(writer
, 2);
735 event_element_open
= 0;
737 /* Close the previous events, pid element */
738 ret
= mi_lttng_close_multi_element(writer
, 2);
742 pid_element_open
= 0;
745 cur_pid
= fields
[i
].event
.pid
;
746 cmdline
= get_cmdline_by_pid(cur_pid
);
747 if (!pid_element_open
) {
748 /* Open and write a pid element */
749 ret
= mi_lttng_pid(writer
, cur_pid
, cmdline
, 1);
754 /* Open events element */
755 ret
= mi_lttng_events_open(writer
);
759 pid_element_open
= 1;
762 /* Wipe current event since we are about to print a new PID. */
763 memset(&cur_event
, 0, sizeof(cur_event
));
766 if (strcmp(cur_event
.name
, fields
[i
].event
.name
) != 0) {
767 if (event_element_open
) {
768 /* Close the previous fields element and the previous event */
769 ret
= mi_lttng_close_multi_element(writer
, 2);
773 event_element_open
= 0;
776 memcpy(&cur_event
, &fields
[i
].event
,
779 if (!event_element_open
) {
780 /* Open and write the event */
781 ret
= mi_lttng_event(writer
, &cur_event
, 1,
782 handle
->domain
.type
);
787 /* Open a fields element */
788 ret
= mi_lttng_event_fields_open(writer
);
792 event_element_open
= 1;
796 /* Print the event_field */
797 ret
= mi_lttng_event_field(writer
, &fields
[i
]);
803 /* Close pids, domain, domains */
804 ret
= mi_lttng_close_multi_element(writer
, 3);
813 * Ask session daemon for all user space tracepoint fields available.
815 static int list_ust_event_fields(void)
817 int i
, size
, ret
= CMD_SUCCESS
;
818 struct lttng_domain domain
;
819 struct lttng_handle
*handle
;
820 struct lttng_event_field
*event_field_list
;
822 char *cmdline
= NULL
;
824 struct lttng_event cur_event
;
826 memset(&domain
, 0, sizeof(domain
));
827 memset(&cur_event
, 0, sizeof(cur_event
));
829 DBG("Getting UST tracing event fields");
831 domain
.type
= LTTNG_DOMAIN_UST
;
833 handle
= lttng_create_handle(NULL
, &domain
);
834 if (handle
== NULL
) {
839 size
= lttng_list_tracepoint_fields(handle
, &event_field_list
);
841 ERR("Unable to list UST event fields: %s", lttng_strerror(size
));
848 ret
= mi_list_ust_event_fields(event_field_list
, size
, &domain
);
855 MSG("UST events:\n-------------");
861 for (i
= 0; i
< size
; i
++) {
862 if (cur_pid
!= event_field_list
[i
].event
.pid
) {
863 cur_pid
= event_field_list
[i
].event
.pid
;
864 cmdline
= get_cmdline_by_pid(cur_pid
);
865 if (cmdline
== NULL
) {
869 MSG("\nPID: %d - Name: %s", cur_pid
, cmdline
);
871 /* Wipe current event since we are about to print a new PID. */
872 memset(&cur_event
, 0, sizeof(cur_event
));
874 if (strcmp(cur_event
.name
, event_field_list
[i
].event
.name
) != 0) {
875 print_events(&event_field_list
[i
].event
);
876 memcpy(&cur_event
, &event_field_list
[i
].event
,
879 print_event_field(&event_field_list
[i
]);
886 free(event_field_list
);
888 lttng_destroy_handle(handle
);
894 * Print a list of kernel events
896 static int mi_list_kernel_events(struct lttng_event
*events
, int count
,
897 struct lttng_domain
*domain
)
901 /* Open domains element */
902 ret
= mi_lttng_domains_open(writer
);
908 ret
= mi_lttng_domain(writer
, domain
, 1);
914 ret
= mi_lttng_events_open(writer
);
919 for (i
= 0; i
< count
; i
++) {
920 ret
= mi_lttng_event(writer
, &events
[i
], 0, handle
->domain
.type
);
926 /* close events, domain and domains */
927 ret
= mi_lttng_close_multi_element(writer
, 3);
937 * Ask for all trace events in the kernel
939 static int list_kernel_events(void)
941 int i
, size
, ret
= CMD_SUCCESS
;
942 struct lttng_domain domain
;
943 struct lttng_handle
*handle
;
944 struct lttng_event
*event_list
;
946 memset(&domain
, 0, sizeof(domain
));
948 DBG("Getting kernel tracing events");
950 domain
.type
= LTTNG_DOMAIN_KERNEL
;
952 handle
= lttng_create_handle(NULL
, &domain
);
953 if (handle
== NULL
) {
958 size
= lttng_list_tracepoints(handle
, &event_list
);
960 ERR("Unable to list kernel events: %s", lttng_strerror(size
));
961 lttng_destroy_handle(handle
);
967 ret
= mi_list_kernel_events(event_list
, size
, &domain
);
973 MSG("Kernel events:\n-------------");
975 for (i
= 0; i
< size
; i
++) {
976 print_events(&event_list
[i
]);
985 lttng_destroy_handle(handle
);
989 lttng_destroy_handle(handle
);
995 * Print a list of system calls.
997 static int mi_list_syscalls(struct lttng_event
*events
, int count
)
1002 ret
= mi_lttng_events_open(writer
);
1007 for (i
= 0; i
< count
; i
++) {
1008 ret
= mi_lttng_event(writer
, &events
[i
], 0, handle
->domain
.type
);
1015 ret
= mi_lttng_writer_close_element(writer
);
1025 * Ask for kernel system calls.
1027 static int list_syscalls(void)
1029 int i
, size
, ret
= CMD_SUCCESS
;
1030 struct lttng_event
*event_list
;
1032 DBG("Getting kernel system call events");
1034 size
= lttng_list_syscalls(&event_list
);
1036 ERR("Unable to list system calls: %s", lttng_strerror(size
));
1043 ret
= mi_list_syscalls(event_list
, size
);
1049 MSG("System calls:\n-------------");
1051 for (i
= 0; i
< size
; i
++) {
1052 print_events(&event_list
[i
]);
1068 * Print a list of agent events
1070 static int mi_list_session_agent_events(struct lttng_event
*events
, int count
)
1074 /* Open events element */
1075 ret
= mi_lttng_events_open(writer
);
1080 for (i
= 0; i
< count
; i
++) {
1081 ret
= mi_lttng_event(writer
, &events
[i
], 0, handle
->domain
.type
);
1087 /* Close events element */
1088 ret
= mi_lttng_writer_close_element(writer
);
1095 * List agent events for a specific session using the handle.
1097 * Return CMD_SUCCESS on success else a negative value.
1099 static int list_session_agent_events(void)
1101 int ret
= CMD_SUCCESS
, count
, i
;
1102 struct lttng_event
*events
= NULL
;
1104 count
= lttng_list_events(handle
, "", &events
);
1107 ERR("%s", lttng_strerror(count
));
1113 ret
= mi_list_session_agent_events(events
, count
);
1120 MSG("Events (Logger name):\n---------------------");
1122 MSG("%sNone\n", indent6
);
1126 for (i
= 0; i
< count
; i
++) {
1127 const char *filter_str
;
1128 char *filter_msg
= NULL
;
1129 struct lttng_event
*event
= &events
[i
];
1131 ret
= lttng_event_get_filter_expression(event
,
1134 filter_msg
= strdup(" [failed to retrieve filter]");
1135 } else if (filter_str
) {
1136 const char * const filter_fmt
=
1139 filter_msg
= malloc(strlen(filter_str
) +
1140 strlen(filter_fmt
) + 1);
1142 sprintf(filter_msg
, filter_fmt
,
1147 if (event
->loglevel_type
!=
1148 LTTNG_EVENT_LOGLEVEL_ALL
) {
1149 MSG("%s- %s%s (loglevel%s %s)%s", indent4
,
1151 enabled_string(event
->enabled
),
1152 logleveltype_string(
1153 event
->loglevel_type
),
1154 mi_lttng_loglevel_string(
1156 handle
->domain
.type
),
1157 safe_string(filter_msg
));
1159 MSG("%s- %s%s%s", indent4
, event
->name
,
1160 enabled_string(event
->enabled
),
1161 safe_string(filter_msg
));
1177 * print a list of event
1179 static int mi_list_events(struct lttng_event
*events
, int count
)
1183 /* Open events element */
1184 ret
= mi_lttng_events_open(writer
);
1189 for (i
= 0; i
< count
; i
++) {
1190 ret
= mi_lttng_event(writer
, &events
[i
], 0, handle
->domain
.type
);
1196 /* Close events element */
1197 ret
= mi_lttng_writer_close_element(writer
);
1204 * List events of channel of session and domain.
1206 static int list_events(const char *channel_name
)
1208 int ret
= CMD_SUCCESS
, count
, i
;
1209 struct lttng_event
*events
= NULL
;
1211 count
= lttng_list_events(handle
, channel_name
, &events
);
1214 ERR("%s", lttng_strerror(count
));
1220 ret
= mi_list_events(events
, count
);
1227 MSG("\n%sEvent rules:", indent4
);
1229 MSG("%sNone\n", indent6
);
1233 for (i
= 0; i
< count
; i
++) {
1234 print_events(&events
[i
]);
1246 void print_timer(const char *timer_name
, uint32_t space_count
, int64_t value
)
1250 _MSG("%s%s:", indent6
, timer_name
);
1251 for (i
= 0; i
< space_count
; i
++) {
1256 MSG("%" PRId64
" %s", value
, USEC_UNIT
);
1263 * Pretty print channel
1265 static void print_channel(struct lttng_channel
*channel
)
1268 uint64_t discarded_events
, lost_packets
, monitor_timer_interval
;
1269 int64_t blocking_timeout
;
1271 ret
= lttng_channel_get_discarded_event_count(channel
,
1274 ERR("Failed to retrieve discarded event count of channel");
1278 ret
= lttng_channel_get_lost_packet_count(channel
,
1281 ERR("Failed to retrieve lost packet count of channel");
1285 ret
= lttng_channel_get_monitor_timer_interval(channel
,
1286 &monitor_timer_interval
);
1288 ERR("Failed to retrieve monitor interval of channel");
1292 ret
= lttng_channel_get_blocking_timeout(channel
,
1295 ERR("Failed to retrieve blocking timeout of channel");
1299 MSG("- %s:%s\n", channel
->name
, enabled_string(channel
->enabled
));
1300 MSG("%sAttributes:", indent4
);
1301 MSG("%sEvent-loss mode: %s", indent6
, channel
->attr
.overwrite
? "overwrite" : "discard");
1302 MSG("%sSub-buffer size: %" PRIu64
" bytes", indent6
, channel
->attr
.subbuf_size
);
1303 MSG("%sSub-buffer count: %" PRIu64
, indent6
, channel
->attr
.num_subbuf
);
1305 print_timer("Switch timer", 5, channel
->attr
.switch_timer_interval
);
1306 print_timer("Read timer", 7, channel
->attr
.read_timer_interval
);
1307 print_timer("Monitor timer", 4, monitor_timer_interval
);
1309 if (!channel
->attr
.overwrite
) {
1310 if (blocking_timeout
== -1) {
1311 MSG("%sBlocking timeout: infinite", indent6
);
1313 MSG("%sBlocking timeout: %" PRId64
" %s", indent6
,
1314 blocking_timeout
, USEC_UNIT
);
1318 MSG("%sTrace file count: %" PRIu64
" per stream", indent6
,
1319 channel
->attr
.tracefile_count
== 0 ?
1320 1 : channel
->attr
.tracefile_count
);
1321 if (channel
->attr
.tracefile_size
!= 0 ) {
1322 MSG("%sTrace file size: %" PRIu64
" bytes", indent6
,
1323 channel
->attr
.tracefile_size
);
1325 MSG("%sTrace file size: %s", indent6
, "unlimited");
1327 switch (channel
->attr
.output
) {
1328 case LTTNG_EVENT_SPLICE
:
1329 MSG("%sOutput mode: splice", indent6
);
1331 case LTTNG_EVENT_MMAP
:
1332 MSG("%sOutput mode: mmap", indent6
);
1336 MSG("\n%sStatistics:", indent4
);
1337 if (listed_session
.snapshot_mode
) {
1339 * The lost packet count is omitted for sessions in snapshot
1340 * mode as it is misleading: it would indicate the number of
1341 * packets that the consumer could not extract during the
1342 * course of recording the snapshot. It does not have the
1343 * same meaning as the "regular" lost packet count that
1344 * would result from the consumer not keeping up with
1345 * event production in an overwrite-mode channel.
1347 * A more interesting statistic would be the number of
1348 * packets lost between the first and last extracted
1349 * packets of a given snapshot (which prevents most analyses).
1351 MSG("%sNone", indent6
);
1352 goto skip_stats_printing
;
1355 if (!channel
->attr
.overwrite
) {
1356 MSG("%sDiscarded events: %" PRIu64
, indent6
, discarded_events
);
1358 MSG("%sLost packets: %" PRIu64
, indent6
, lost_packets
);
1360 skip_stats_printing
:
1366 * Print a list of channel
1369 static int mi_list_channels(struct lttng_channel
*channels
, int count
,
1370 const char *channel_name
)
1373 unsigned int chan_found
= 0;
1375 /* Open channels element */
1376 ret
= mi_lttng_channels_open(writer
);
1381 for (i
= 0; i
< count
; i
++) {
1382 if (channel_name
!= NULL
) {
1383 if (strncmp(channels
[i
].name
, channel_name
, NAME_MAX
) == 0) {
1390 /* Write channel element and leave it open */
1391 ret
= mi_lttng_channel(writer
, &channels
[i
], 1);
1396 /* Listing events per channel */
1397 ret
= list_events(channels
[i
].name
);
1402 /* Closing the channel element we opened earlier */
1403 ret
= mi_lttng_writer_close_element(writer
);
1413 /* Close channels element */
1414 ret
= mi_lttng_writer_close_element(writer
);
1424 * List channel(s) of session and domain.
1426 * If channel_name is NULL, all channels are listed.
1428 static int list_channels(const char *channel_name
)
1430 int count
, i
, ret
= CMD_SUCCESS
;
1431 unsigned int chan_found
= 0;
1432 struct lttng_channel
*channels
= NULL
;
1434 DBG("Listing channel(s) (%s)", channel_name
? : "<all>");
1436 count
= lttng_list_channels(handle
, &channels
);
1439 case LTTNG_ERR_KERN_CHAN_NOT_FOUND
:
1441 /* When printing mi this is not an error
1442 * but an empty channels element */
1446 WARN("No kernel channel");
1447 goto error_channels
;
1451 /* We had a real error */
1453 ERR("%s", lttng_strerror(count
));
1454 goto error_channels
;
1461 ret
= mi_list_channels(channels
, count
, channel_name
);
1469 MSG("Channels:\n-------------");
1472 for (i
= 0; i
< count
; i
++) {
1473 if (channel_name
!= NULL
) {
1474 if (strncmp(channels
[i
].name
, channel_name
, NAME_MAX
) == 0) {
1480 print_channel(&channels
[i
]);
1482 /* Listing events per channel */
1483 ret
= list_events(channels
[i
].name
);
1493 if (!chan_found
&& channel_name
!= NULL
) {
1495 ERR("Channel %s not found", channel_name
);
1506 static const char *get_tracker_str(enum lttng_tracker_type tracker_type
)
1508 switch (tracker_type
) {
1509 case LTTNG_TRACKER_PID
:
1511 case LTTNG_TRACKER_VPID
:
1513 case LTTNG_TRACKER_UID
:
1515 case LTTNG_TRACKER_VUID
:
1517 case LTTNG_TRACKER_GID
:
1519 case LTTNG_TRACKER_VGID
:
1526 * List tracker ID(s) of session and domain.
1528 static int list_tracker_ids(enum lttng_tracker_type tracker_type
)
1532 struct lttng_tracker_ids
*ids
= NULL
;
1533 unsigned int nr_ids
, i
;
1534 const struct lttng_tracker_id
*id
;
1535 enum lttng_tracker_id_status status
;
1537 ret
= lttng_list_tracker_ids(handle
, tracker_type
, &ids
);
1542 status
= lttng_tracker_ids_get_count(ids
, &nr_ids
);
1543 if (status
!= LTTNG_TRACKER_ID_STATUS_OK
) {
1549 id
= lttng_tracker_ids_get_at_index(ids
, 0);
1550 if (id
&& lttng_tracker_id_get_type(id
) == LTTNG_ID_ALL
) {
1556 _MSG("%s tracker: [", get_tracker_str(tracker_type
));
1558 /* Mi tracker_id element */
1560 /* Open tracker_id and targets elements */
1561 ret
= mi_lttng_id_tracker_open(writer
, tracker_type
);
1567 for (i
= 0; i
< nr_ids
; i
++) {
1568 enum lttng_tracker_id_status status
=
1569 LTTNG_TRACKER_ID_STATUS_OK
;
1571 const char *value_string
;
1573 id
= lttng_tracker_ids_get_at_index(ids
, i
);
1579 switch (lttng_tracker_id_get_type(id
)) {
1582 case LTTNG_ID_VALUE
:
1583 status
= lttng_tracker_id_get_value(id
, &value
);
1585 case LTTNG_ID_STRING
:
1586 status
= lttng_tracker_id_get_string(
1589 case LTTNG_ID_UNKNOWN
:
1594 if (status
!= LTTNG_TRACKER_ID_STATUS_OK
) {
1595 ERR("Invalid state for tracker id");
1603 switch (lttng_tracker_id_get_type(id
)) {
1607 case LTTNG_ID_VALUE
:
1610 case LTTNG_ID_STRING
:
1611 _MSG(" %s", value_string
);
1613 case LTTNG_ID_UNKNOWN
:
1614 ERR("Invalid state for tracker id");
1621 ret
= mi_lttng_id_target(
1622 writer
, tracker_type
, id
, 0);
1630 /* Mi close tracker_id and targets */
1632 ret
= mi_lttng_close_multi_element(writer
, 2);
1639 lttng_tracker_ids_destroy(ids
);
1644 * List all trackers of a domain
1646 static int list_trackers(const struct lttng_domain
*domain
)
1650 /* Trackers listing */
1652 ret
= mi_lttng_trackers_open(writer
);
1658 switch (domain
->type
) {
1659 case LTTNG_DOMAIN_KERNEL
:
1661 ret
= list_tracker_ids(LTTNG_TRACKER_PID
);
1666 ret
= list_tracker_ids(LTTNG_TRACKER_VPID
);
1671 ret
= list_tracker_ids(LTTNG_TRACKER_UID
);
1676 ret
= list_tracker_ids(LTTNG_TRACKER_VUID
);
1681 ret
= list_tracker_ids(LTTNG_TRACKER_GID
);
1686 ret
= list_tracker_ids(LTTNG_TRACKER_VGID
);
1691 case LTTNG_DOMAIN_UST
:
1693 ret
= list_tracker_ids(LTTNG_TRACKER_VPID
);
1698 ret
= list_tracker_ids(LTTNG_TRACKER_VUID
);
1703 ret
= list_tracker_ids(LTTNG_TRACKER_VGID
);
1712 /* Close trackers element */
1713 ret
= mi_lttng_writer_close_element(writer
);
1723 static enum cmd_error_code
print_periodic_rotation_schedule(
1724 const struct lttng_rotation_schedule
*schedule
)
1726 enum cmd_error_code ret
;
1727 enum lttng_rotation_status status
;
1730 status
= lttng_rotation_schedule_periodic_get_period(schedule
,
1732 if (status
!= LTTNG_ROTATION_STATUS_OK
) {
1733 ERR("Failed to retrieve period parameter from periodic rotation schedule.");
1738 MSG(" timer period: %" PRIu64
" %s", value
, USEC_UNIT
);
1744 static enum cmd_error_code
print_size_threshold_rotation_schedule(
1745 const struct lttng_rotation_schedule
*schedule
)
1747 enum cmd_error_code ret
;
1748 enum lttng_rotation_status status
;
1751 status
= lttng_rotation_schedule_size_threshold_get_threshold(schedule
,
1753 if (status
!= LTTNG_ROTATION_STATUS_OK
) {
1754 ERR("Failed to retrieve size parameter from size-based rotation schedule.");
1759 MSG(" size threshold: %" PRIu64
" bytes", value
);
1765 static enum cmd_error_code
print_rotation_schedule(
1766 const struct lttng_rotation_schedule
*schedule
)
1768 enum cmd_error_code ret
;
1770 switch (lttng_rotation_schedule_get_type(schedule
)) {
1771 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD
:
1772 ret
= print_size_threshold_rotation_schedule(schedule
);
1774 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC
:
1775 ret
= print_periodic_rotation_schedule(schedule
);
1784 * List the automatic rotation settings.
1786 static enum cmd_error_code
list_rotate_settings(const char *session_name
)
1789 enum cmd_error_code cmd_ret
= CMD_SUCCESS
;
1790 unsigned int count
, i
;
1791 struct lttng_rotation_schedules
*schedules
= NULL
;
1792 enum lttng_rotation_status status
;
1794 ret
= lttng_session_list_rotation_schedules(session_name
, &schedules
);
1795 if (ret
!= LTTNG_OK
) {
1796 ERR("Failed to list session rotation schedules: %s", lttng_strerror(ret
));
1797 cmd_ret
= CMD_ERROR
;
1801 status
= lttng_rotation_schedules_get_count(schedules
, &count
);
1802 if (status
!= LTTNG_ROTATION_STATUS_OK
) {
1803 ERR("Failed to retrieve the number of session rotation schedules.");
1804 cmd_ret
= CMD_ERROR
;
1809 cmd_ret
= CMD_SUCCESS
;
1813 MSG("Automatic rotation schedules:");
1815 ret
= mi_lttng_writer_open_element(writer
,
1816 mi_lttng_element_rotation_schedules
);
1818 cmd_ret
= CMD_ERROR
;
1823 for (i
= 0; i
< count
; i
++) {
1824 enum cmd_error_code tmp_ret
= CMD_SUCCESS
;
1825 const struct lttng_rotation_schedule
*schedule
;
1827 schedule
= lttng_rotation_schedules_get_at_index(schedules
, i
);
1829 ERR("Failed to retrieve session rotation schedule.");
1830 cmd_ret
= CMD_ERROR
;
1835 ret
= mi_lttng_rotation_schedule(writer
, schedule
);
1837 tmp_ret
= CMD_ERROR
;
1840 tmp_ret
= print_rotation_schedule(schedule
);
1844 * Report an error if the serialization of any of the
1845 * descriptors failed.
1847 cmd_ret
= cmd_ret
? cmd_ret
: tmp_ret
;
1852 /* Close the rotation_schedules element. */
1853 ret
= mi_lttng_writer_close_element(writer
);
1855 cmd_ret
= CMD_ERROR
;
1860 lttng_rotation_schedules_destroy(schedules
);
1866 * Find the session with session_name as name
1867 * and print his informations.
1869 static int mi_list_session(const char *session_name
,
1870 struct lttng_session
*sessions
, int count
)
1873 unsigned int session_found
= 0;
1875 if (session_name
== NULL
) {
1876 ret
= -LTTNG_ERR_SESS_NOT_FOUND
;
1880 for (i
= 0; i
< count
; i
++) {
1881 if (strncmp(sessions
[i
].name
, session_name
, NAME_MAX
) == 0) {
1882 /* We need to leave it open to append other informations
1883 * like domain, channel, events etc.*/
1885 ret
= mi_lttng_session(writer
, &sessions
[i
], 1);
1893 if (!session_found
) {
1894 ERR("Session '%s' not found", session_name
);
1895 ret
= -LTTNG_ERR_SESS_NOT_FOUND
;
1905 * List all availables session
1907 static int mi_list_sessions(struct lttng_session
*sessions
, int count
)
1911 /* Opening sessions element */
1912 ret
= mi_lttng_sessions_open(writer
);
1917 /* Listing sessions */
1918 for (i
= 0; i
< count
; i
++) {
1919 ret
= mi_lttng_session(writer
, &sessions
[i
], 0);
1925 /* Closing sessions element */
1926 ret
= mi_lttng_writer_close_element(writer
);
1936 * List available tracing session. List only basic information.
1938 * If session_name is NULL, all sessions are listed.
1940 static int list_sessions(const char *session_name
)
1942 int ret
= CMD_SUCCESS
;
1944 unsigned int session_found
= 0;
1945 struct lttng_session
*sessions
= NULL
;
1947 count
= lttng_list_sessions(&sessions
);
1948 DBG("Session count %d", count
);
1951 ERR("%s", lttng_strerror(count
));
1957 if (session_name
== NULL
) {
1958 /* List all sessions */
1959 ret
= mi_list_sessions(sessions
, count
);
1961 /* Note : this return an open session element */
1962 ret
= mi_list_session(session_name
, sessions
, count
);
1971 MSG("Currently no available tracing session");
1975 if (session_name
== NULL
) {
1976 MSG("Available tracing sessions:");
1979 for (i
= 0; i
< count
; i
++) {
1980 if (session_name
!= NULL
) {
1981 if (strncmp(sessions
[i
].name
, session_name
, NAME_MAX
) == 0) {
1983 MSG("Tracing session %s: [%s%s]", session_name
,
1984 active_string(sessions
[i
].enabled
),
1985 snapshot_string(sessions
[i
].snapshot_mode
));
1986 if (*sessions
[i
].path
) {
1987 MSG("%sTrace output: %s\n", indent4
, sessions
[i
].path
);
1989 memcpy(&listed_session
, &sessions
[i
],
1990 sizeof(listed_session
));
1994 MSG(" %d) %s [%s%s]", i
+ 1,
1996 active_string(sessions
[i
].enabled
),
1997 snapshot_string(sessions
[i
].snapshot_mode
));
1998 if (*sessions
[i
].path
) {
1999 MSG("%sTrace output: %s", indent4
, sessions
[i
].path
);
2001 if (sessions
[i
].live_timer_interval
!= 0) {
2002 MSG("%sLive timer interval: %u %s", indent4
,
2003 sessions
[i
].live_timer_interval
,
2010 if (!session_found
&& session_name
!= NULL
) {
2011 ERR("Session '%s' not found", session_name
);
2016 if (session_name
== NULL
) {
2017 MSG("\nUse lttng list <session_name> for more details");
2029 * list available domain(s) for a session.
2031 static int mi_list_domains(struct lttng_domain
*domains
, int count
)
2034 /* Open domains element */
2035 ret
= mi_lttng_domains_open(writer
);
2040 for (i
= 0; i
< count
; i
++) {
2041 ret
= mi_lttng_domain(writer
, &domains
[i
] , 0);
2047 /* Closing domains element */
2048 ret
= mi_lttng_writer_close_element(writer
);
2057 * List available domain(s) for a session.
2059 static int list_domains(const char *session_name
)
2061 int i
, count
, ret
= CMD_SUCCESS
;
2062 struct lttng_domain
*domains
= NULL
;
2065 count
= lttng_list_domains(session_name
, &domains
);
2068 ERR("%s", lttng_strerror(count
));
2074 ret
= mi_list_domains(domains
, count
);
2081 MSG("Domains:\n-------------");
2087 for (i
= 0; i
< count
; i
++) {
2088 switch (domains
[i
].type
) {
2089 case LTTNG_DOMAIN_KERNEL
:
2092 case LTTNG_DOMAIN_UST
:
2093 MSG(" - UST global");
2095 case LTTNG_DOMAIN_JUL
:
2096 MSG(" - JUL (Java Util Logging)");
2098 case LTTNG_DOMAIN_LOG4J
:
2099 MSG(" - LOG4j (Logging for Java)");
2101 case LTTNG_DOMAIN_PYTHON
:
2102 MSG(" - Python (logging)");
2118 * The 'list <options>' first level command
2120 int cmd_list(int argc
, const char **argv
)
2122 int opt
, ret
= CMD_SUCCESS
;
2123 const char *session_name
, *leftover
= NULL
;
2124 static poptContext pc
;
2125 struct lttng_domain domain
;
2126 struct lttng_domain
*domains
= NULL
;
2128 memset(&domain
, 0, sizeof(domain
));
2135 pc
= poptGetContext(NULL
, argc
, argv
, long_options
, 0);
2136 poptReadDefaultConfig(pc
, 0);
2138 while ((opt
= poptGetNextOpt(pc
)) != -1) {
2146 case OPT_LIST_OPTIONS
:
2147 list_cmd_options(stdout
, long_options
);
2150 ret
= CMD_UNDEFINED
;
2157 writer
= mi_lttng_writer_create(fileno(stdout
), lttng_opt_mi
);
2163 /* Open command element */
2164 ret
= mi_lttng_writer_command_open(writer
,
2165 mi_lttng_element_command_list
);
2171 /* Open output element */
2172 ret
= mi_lttng_writer_open_element(writer
,
2173 mi_lttng_element_command_output
);
2180 /* Get session name (trailing argument) */
2181 session_name
= poptGetArg(pc
);
2182 DBG2("Session name: %s", session_name
);
2184 leftover
= poptGetArg(pc
);
2186 ERR("Unknown argument: %s", leftover
);
2192 domain
.type
= LTTNG_DOMAIN_KERNEL
;
2193 } else if (opt_userspace
) {
2194 DBG2("Listing userspace global domain");
2195 domain
.type
= LTTNG_DOMAIN_UST
;
2196 } else if (opt_jul
) {
2197 DBG2("Listing JUL domain");
2198 domain
.type
= LTTNG_DOMAIN_JUL
;
2199 } else if (opt_log4j
) {
2200 domain
.type
= LTTNG_DOMAIN_LOG4J
;
2201 } else if (opt_python
) {
2202 domain
.type
= LTTNG_DOMAIN_PYTHON
;
2205 if (!opt_kernel
&& opt_syscall
) {
2206 WARN("--syscall will only work with the Kernel domain (-k)");
2211 if (opt_kernel
|| opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
) {
2212 handle
= lttng_create_handle(session_name
, &domain
);
2213 if (handle
== NULL
) {
2219 if (session_name
== NULL
) {
2220 if (!opt_kernel
&& !opt_userspace
&& !opt_jul
&& !opt_log4j
2222 ret
= list_sessions(NULL
);
2229 ret
= list_syscalls();
2234 ret
= list_kernel_events();
2240 if (opt_userspace
) {
2242 ret
= list_ust_event_fields();
2244 ret
= list_ust_events();
2250 if (opt_jul
|| opt_log4j
|| opt_python
) {
2251 ret
= list_agent_events();
2257 /* List session attributes */
2259 /* Open element sessions
2260 * Present for xml consistency */
2261 ret
= mi_lttng_sessions_open(writer
);
2266 /* MI: the ouptut of list_sessions is an unclosed session element */
2267 ret
= list_sessions(session_name
);
2272 ret
= list_rotate_settings(session_name
);
2277 /* Domain listing */
2279 ret
= list_domains(session_name
);
2283 /* Channel listing */
2284 if (opt_kernel
|| opt_userspace
) {
2286 /* Add of domains and domain element for xml
2287 * consistency and validation
2289 ret
= mi_lttng_domains_open(writer
);
2294 /* Open domain and leave it open for
2295 * nested channels printing */
2296 ret
= mi_lttng_domain(writer
, &domain
, 1);
2305 ret
= list_trackers(&domain
);
2311 ret
= list_channels(opt_channel
);
2317 /* Close domain and domain element */
2318 ret
= mi_lttng_close_multi_element(writer
, 2);
2328 /* We want all domain(s) */
2329 nb_domain
= lttng_list_domains(session_name
, &domains
);
2330 if (nb_domain
< 0) {
2332 ERR("%s", lttng_strerror(nb_domain
));
2337 ret
= mi_lttng_domains_open(writer
);
2344 for (i
= 0; i
< nb_domain
; i
++) {
2345 switch (domains
[i
].type
) {
2346 case LTTNG_DOMAIN_KERNEL
:
2347 MSG("=== Domain: Kernel ===\n");
2349 case LTTNG_DOMAIN_UST
:
2350 MSG("=== Domain: UST global ===\n");
2351 MSG("Buffering scheme: %s\n",
2352 domains
[i
].buf_type
==
2353 LTTNG_BUFFER_PER_PID
? "per-process" : "per-user");
2355 case LTTNG_DOMAIN_JUL
:
2356 MSG("=== Domain: JUL (Java Util Logging) ===\n");
2358 case LTTNG_DOMAIN_LOG4J
:
2359 MSG("=== Domain: LOG4j (Logging for Java) ===\n");
2361 case LTTNG_DOMAIN_PYTHON
:
2362 MSG("=== Domain: Python (logging) ===\n");
2365 MSG("=== Domain: Unimplemented ===\n");
2370 ret
= mi_lttng_domain(writer
, &domains
[i
], 1);
2377 /* Clean handle before creating a new one */
2379 lttng_destroy_handle(handle
);
2382 handle
= lttng_create_handle(session_name
, &domains
[i
]);
2383 if (handle
== NULL
) {
2388 if (domains
[i
].type
== LTTNG_DOMAIN_JUL
||
2389 domains
[i
].type
== LTTNG_DOMAIN_LOG4J
||
2390 domains
[i
].type
== LTTNG_DOMAIN_PYTHON
) {
2391 ret
= list_session_agent_events();
2399 switch (domains
[i
].type
) {
2400 case LTTNG_DOMAIN_KERNEL
:
2401 case LTTNG_DOMAIN_UST
:
2402 ret
= list_trackers(&domains
[i
]);
2411 ret
= list_channels(opt_channel
);
2418 /* Close domain element */
2419 ret
= mi_lttng_writer_close_element(writer
);
2428 /* Close the domains, session and sessions element */
2429 ret
= mi_lttng_close_multi_element(writer
, 3);
2440 /* Close output element */
2441 ret
= mi_lttng_writer_close_element(writer
);
2447 /* Command element close */
2448 ret
= mi_lttng_writer_command_close(writer
);
2456 if (writer
&& mi_lttng_writer_destroy(writer
)) {
2457 /* Preserve original error code */
2458 ret
= ret
? ret
: -LTTNG_ERR_MI_IO_FAIL
;
2463 lttng_destroy_handle(handle
);
2466 poptFreeContext(pc
);