X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng%2Fcommands%2Flist.c;h=d25b5632bb85513e40d028b21ae9c6335c8e5c20;hp=696e80e7f2c9a8bfd3e54de5c4caba0024e68b84;hb=5e18ec73f48d06fd508fb74386d175d45606d7e2;hpb=45a32634662c4b3f411deaf7380c89bf3b6e4a59 diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c index 696e80e7f..d25b5632b 100644 --- a/src/bin/lttng/commands/list.c +++ b/src/bin/lttng/commands/list.c @@ -27,6 +27,7 @@ static int opt_userspace; static int opt_kernel; +static int opt_jul; static char *opt_channel; static int opt_domain; static int opt_fields; @@ -52,6 +53,7 @@ static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0}, + {"jul", 'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0}, #if 0 /* Not implemented yet */ {"userspace", 'u', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_cmd_name, OPT_USERSPACE, 0, 0}, @@ -71,7 +73,7 @@ static struct poptOption long_options[] = { */ static void usage(FILE *ofp) { - fprintf(ofp, "usage: lttng list [OPTIONS] [SESSION []]\n"); + fprintf(ofp, "usage: lttng list [OPTIONS] [SESSION [SESSION OPTIONS]]\n"); fprintf(ofp, "\n"); fprintf(ofp, "With no arguments, list available tracing session(s)\n"); fprintf(ofp, "\n"); @@ -82,6 +84,7 @@ static void usage(FILE *ofp) fprintf(ofp, " --list-options Simple listing of options\n"); fprintf(ofp, " -k, --kernel Select kernel domain\n"); fprintf(ofp, " -u, --userspace Select user-space domain.\n"); + fprintf(ofp, " -j, --jul Apply for Java application using JUL\n"); fprintf(ofp, " -f, --fields List event fields.\n"); #if 0 fprintf(ofp, " -p, --pid PID List user-space events by PID\n"); @@ -104,7 +107,7 @@ static char *get_cmdline_by_pid(pid_t pid) int ret; FILE *fp; char *cmdline = NULL; - char path[24]; /* Can't go bigger than /proc/65535/cmdline */ + char path[20]; /* Can't go bigger than /proc/65535/cmdline */ snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); fp = fopen(path, "r"); @@ -114,6 +117,10 @@ static char *get_cmdline_by_pid(pid_t pid) /* Caller must free() *cmdline */ cmdline = malloc(PATH_MAX); + if (!cmdline) { + perror("malloc cmdline"); + goto end; + } ret = fread(cmdline, 1, PATH_MAX, fp); if (ret < 0) { perror("fread proc list"); @@ -128,13 +135,23 @@ static const char *active_string(int value) { switch (value) { - case 0: return " [inactive]"; - case 1: return " [active]"; + case 0: return "inactive"; + case 1: return "active"; case -1: return ""; default: return NULL; } } +static const char *snapshot_string(int value) +{ + switch (value) { + case 1: + return " snapshot"; + default: + return ""; + } +} + static const char *enabled_string(int value) { @@ -155,6 +172,43 @@ const char *filter_string(int value) } } +static +const char *exclusion_string(int value) +{ + switch (value) { + case 1: return " [has exclusions]"; + default: return ""; + } +} + +static const char *loglevel_jul_string(int value) +{ + switch (value) { + case -1: + return ""; + case LTTNG_LOGLEVEL_JUL_OFF: + return "JUL_OFF"; + case LTTNG_LOGLEVEL_JUL_SEVERE: + return "JUL_SEVERE"; + case LTTNG_LOGLEVEL_JUL_WARNING: + return "JUL_WARNING"; + case LTTNG_LOGLEVEL_JUL_INFO: + return "JUL_INFO"; + case LTTNG_LOGLEVEL_JUL_CONFIG: + return "JUL_CONFIG"; + case LTTNG_LOGLEVEL_JUL_FINE: + return "JUL_FINE"; + case LTTNG_LOGLEVEL_JUL_FINER: + return "JUL_FINER"; + case LTTNG_LOGLEVEL_JUL_FINEST: + return "JUL_FINEST"; + case LTTNG_LOGLEVEL_JUL_ALL: + return "JUL_ALL"; + default: + return "<>"; + } +} + static const char *loglevel_string(int value) { switch (value) { @@ -195,6 +249,20 @@ static const char *loglevel_string(int value) } } +static const char *logleveltype_string(enum lttng_loglevel_type value) +{ + switch (value) { + case LTTNG_EVENT_LOGLEVEL_ALL: + return ":"; + case LTTNG_EVENT_LOGLEVEL_RANGE: + return " <="; + case LTTNG_EVENT_LOGLEVEL_SINGLE: + return " =="; + default: + return " <>"; + } +} + /* * Pretty print single event. */ @@ -204,22 +272,36 @@ static void print_events(struct lttng_event *event) case LTTNG_EVENT_TRACEPOINT: { if (event->loglevel != -1) { - MSG("%s%s (loglevel: %s (%d)) (type: tracepoint)%s%s", + MSG("%s%s (loglevel%s %s (%d)) (type: tracepoint)%s%s%s", indent6, event->name, + logleveltype_string(event->loglevel_type), loglevel_string(event->loglevel), event->loglevel, enabled_string(event->enabled), + exclusion_string(event->exclusion), filter_string(event->filter)); } else { - MSG("%s%s (type: tracepoint)%s%s", + MSG("%s%s (type: tracepoint)%s%s%s", indent6, event->name, enabled_string(event->enabled), + exclusion_string(event->exclusion), filter_string(event->filter)); } break; } + case LTTNG_EVENT_FUNCTION: + MSG("%s%s (type: function)%s%s", indent6, + event->name, enabled_string(event->enabled), + filter_string(event->filter)); + if (event->attr.probe.addr != 0) { + MSG("%saddr: 0x%" PRIx64, indent8, event->attr.probe.addr); + } else { + MSG("%soffset: 0x%" PRIx64, indent8, event->attr.probe.offset); + MSG("%ssymbol: %s", indent8, event->attr.probe.symbol_name); + } + break; case LTTNG_EVENT_PROBE: MSG("%s%s (type: probe)%s%s", indent6, event->name, enabled_string(event->enabled), @@ -231,7 +313,6 @@ static void print_events(struct lttng_event *event) MSG("%ssymbol: %s", indent8, event->attr.probe.symbol_name); } break; - case LTTNG_EVENT_FUNCTION: case LTTNG_EVENT_FUNCTION_ENTRY: MSG("%s%s (type: function)%s%s", indent6, event->name, enabled_string(event->enabled), @@ -284,6 +365,60 @@ static void print_event_field(struct lttng_event_field *field) field_type(field), field->nowrite ? " [no write]" : ""); } +static int list_jul_events(void) +{ + int i, size; + struct lttng_domain domain; + struct lttng_handle *handle; + struct lttng_event *event_list; + pid_t cur_pid = 0; + char *cmdline = NULL; + + DBG("Getting JUL tracing events"); + + memset(&domain, 0, sizeof(domain)); + domain.type = LTTNG_DOMAIN_JUL; + + handle = lttng_create_handle(NULL, &domain); + if (handle == NULL) { + goto error; + } + + size = lttng_list_tracepoints(handle, &event_list); + if (size < 0) { + ERR("Unable to list JUL events: %s", lttng_strerror(size)); + lttng_destroy_handle(handle); + return size; + } + + MSG("JUL events (Logger name):\n-------------------------"); + + if (size == 0) { + MSG("None"); + } + + for (i = 0; i < size; i++) { + if (cur_pid != event_list[i].pid) { + cur_pid = event_list[i].pid; + cmdline = get_cmdline_by_pid(cur_pid); + MSG("\nPID: %d - Name: %s", cur_pid, cmdline); + free(cmdline); + } + MSG("%s- %s", indent6, event_list[i].name); + } + + MSG(""); + + free(event_list); + lttng_destroy_handle(handle); + + return CMD_SUCCESS; + +error: + lttng_destroy_handle(handle); + return -1; +} + /* * Ask session daemon for all user space tracepoints available. */ @@ -294,6 +429,7 @@ static int list_ust_events(void) struct lttng_handle *handle; struct lttng_event *event_list; pid_t cur_pid = 0; + char *cmdline = NULL; memset(&domain, 0, sizeof(domain)); @@ -308,7 +444,7 @@ static int list_ust_events(void) size = lttng_list_tracepoints(handle, &event_list); if (size < 0) { - ERR("Unable to list UST events"); + ERR("Unable to list UST events: %s", lttng_strerror(size)); lttng_destroy_handle(handle); return size; } @@ -322,7 +458,9 @@ static int list_ust_events(void) for (i = 0; i < size; i++) { if (cur_pid != event_list[i].pid) { cur_pid = event_list[i].pid; - MSG("\nPID: %d - Name: %s", cur_pid, get_cmdline_by_pid(cur_pid)); + cmdline = get_cmdline_by_pid(cur_pid); + MSG("\nPID: %d - Name: %s", cur_pid, cmdline); + free(cmdline); } print_events(&event_list[i]); } @@ -349,6 +487,8 @@ static int list_ust_event_fields(void) struct lttng_handle *handle; struct lttng_event_field *event_field_list; pid_t cur_pid = 0; + char *cmdline = NULL; + struct lttng_event cur_event; memset(&domain, 0, sizeof(domain)); @@ -365,7 +505,7 @@ static int list_ust_event_fields(void) size = lttng_list_tracepoint_fields(handle, &event_field_list); if (size < 0) { - ERR("Unable to list UST event fields"); + ERR("Unable to list UST event fields: %s", lttng_strerror(size)); lttng_destroy_handle(handle); return size; } @@ -379,7 +519,11 @@ static int list_ust_event_fields(void) for (i = 0; i < size; i++) { if (cur_pid != event_field_list[i].event.pid) { cur_pid = event_field_list[i].event.pid; - MSG("\nPID: %d - Name: %s", cur_pid, get_cmdline_by_pid(cur_pid)); + cmdline = get_cmdline_by_pid(cur_pid); + MSG("\nPID: %d - Name: %s", cur_pid, cmdline); + free(cmdline); + /* Wipe current event since we are about to print a new PID. */ + memset(&cur_event, 0, sizeof(cur_event)); } if (strcmp(cur_event.name, event_field_list[i].event.name) != 0) { print_events(&event_field_list[i].event); @@ -424,7 +568,7 @@ static int list_kernel_events(void) size = lttng_list_tracepoints(handle, &event_list); if (size < 0) { - ERR("Unable to list kernel events"); + ERR("Unable to list kernel events: %s", lttng_strerror(size)); lttng_destroy_handle(handle); return size; } @@ -447,6 +591,46 @@ error: return -1; } +/* + * List JUL events for a specific session using the handle. + * + * Return CMD_SUCCESS on success else a negative value. + */ +static int list_session_jul_events(void) +{ + int ret, count, i; + struct lttng_event *events = NULL; + + count = lttng_list_events(handle, "", &events); + if (count < 0) { + ret = count; + ERR("%s", lttng_strerror(ret)); + goto error; + } + + MSG("Events (Logger name):\n---------------------"); + if (count == 0) { + MSG("%sNone\n", indent6); + goto end; + } + + for (i = 0; i < count; i++) { + MSG("%s- %s%s (loglevel%s %s)", indent4, events[i].name, + enabled_string(events[i].enabled), + logleveltype_string(events[i].loglevel_type), + loglevel_jul_string(events[i].loglevel)); + } + + MSG(""); + +end: + free(events); + ret = CMD_SUCCESS; + +error: + return ret; +} + /* * List events of channel of session and domain. */ @@ -458,6 +642,7 @@ static int list_events(const char *channel_name) count = lttng_list_events(handle, channel_name, &events); if (count < 0) { ret = count; + ERR("%s", lttng_strerror(ret)); goto error; } @@ -474,9 +659,7 @@ static int list_events(const char *channel_name) MSG(""); end: - if (events) { - free(events); - } + free(events); ret = CMD_SUCCESS; error: @@ -496,6 +679,8 @@ static void print_channel(struct lttng_channel *channel) MSG("%snumber of subbufers: %" PRIu64, indent6, channel->attr.num_subbuf); MSG("%sswitch timer interval: %u", indent6, channel->attr.switch_timer_interval); MSG("%sread timer interval: %u", indent6, channel->attr.read_timer_interval); + MSG("%strace file count: %" PRIu64, indent6, channel->attr.tracefile_count); + MSG("%strace file size (bytes): %" PRIu64, indent6, channel->attr.tracefile_size); switch (channel->attr.output) { case LTTNG_EVENT_SPLICE: MSG("%soutput: splice()", indent6); @@ -521,11 +706,18 @@ static int list_channels(const char *channel_name) count = lttng_list_channels(handle, &channels); if (count < 0) { - ret = count; + switch (-count) { + case LTTNG_ERR_KERN_CHAN_NOT_FOUND: + ret = CMD_SUCCESS; + WARN("No kernel channel"); + break; + default: + /* We had a real error */ + ret = count; + ERR("%s", lttng_strerror(ret)); + break; + } goto error_channels; - } else if (count == 0) { - ERR("Channel %s not found", channel_name); - goto error; } if (channel_name == NULL) { @@ -545,7 +737,7 @@ static int list_channels(const char *channel_name) /* Listing events per channel */ ret = list_events(channels[i].name); if (ret < 0) { - MSG("%s", lttng_strerror(ret)); + ERR("%s", lttng_strerror(ret)); } if (chan_found) { @@ -582,6 +774,7 @@ static int list_sessions(const char *session_name) DBG("Session count %d", count); if (count < 0) { ret = count; + ERR("%s", lttng_strerror(ret)); goto error; } else if (count == 0) { MSG("Currently no available tracing session"); @@ -596,18 +789,18 @@ static int list_sessions(const char *session_name) if (session_name != NULL) { if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) { session_found = 1; - MSG("Tracing session %s:%s", session_name, active_string(sessions[i].enabled)); - MSG("%sTrace path: %s\n", indent4, sessions[i].path); + MSG("Tracing session %s: [%s%s]", session_name, + active_string(sessions[i].enabled), + snapshot_string(sessions[i].snapshot_mode)); + MSG("%sTrace path: %s", indent4, sessions[i].path); + MSG("%sLive timer interval (usec): %u\n", indent4, + sessions[i].live_timer_interval); break; } - continue; - } - - MSG(" %d) %s (%s)%s", i + 1, sessions[i].name, sessions[i].path, - active_string(sessions[i].enabled)); - - if (session_found) { - break; + } else { + MSG(" %d) %s (%s) [%s%s]", i + 1, sessions[i].name, sessions[i].path, + active_string(sessions[i].enabled), + snapshot_string(sessions[i].snapshot_mode)); } } @@ -643,6 +836,7 @@ static int list_domains(const char *session_name) count = lttng_list_domains(session_name, &domains); if (count < 0) { ret = count; + ERR("%s", lttng_strerror(ret)); goto error; } else if (count == 0) { MSG(" None"); @@ -657,6 +851,9 @@ static int list_domains(const char *session_name) case LTTNG_DOMAIN_UST: MSG(" - UST global"); break; + case LTTNG_DOMAIN_JUL: + MSG(" - JUL (Java Util Logging)"); + break; default: break; } @@ -674,8 +871,7 @@ error: */ int cmd_list(int argc, const char **argv) { - int opt, i, ret = CMD_SUCCESS; - int nb_domain; + int opt, ret = CMD_SUCCESS; const char *session_name; static poptContext pc; struct lttng_domain domain; @@ -692,6 +888,13 @@ int cmd_list(int argc, const char **argv) pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); + /* TODO: mi support */ + if (lttng_opt_mi) { + ret = -LTTNG_ERR_MI_NOT_IMPLEMENTED; + ERR("mi option not supported"); + goto end; + } + while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: @@ -719,9 +922,12 @@ int cmd_list(int argc, const char **argv) } else if (opt_userspace) { DBG2("Listing userspace global domain"); domain.type = LTTNG_DOMAIN_UST; + } else if (opt_jul) { + DBG2("Listing JUL domain"); + domain.type = LTTNG_DOMAIN_JUL; } - if (opt_kernel || opt_userspace) { + if (opt_kernel || opt_userspace || opt_jul) { handle = lttng_create_handle(session_name, &domain); if (handle == NULL) { ret = CMD_FATAL; @@ -730,7 +936,7 @@ int cmd_list(int argc, const char **argv) } if (session_name == NULL) { - if (!opt_kernel && !opt_userspace) { + if (!opt_kernel && !opt_userspace && !opt_jul) { ret = list_sessions(NULL); if (ret != 0) { goto end; @@ -739,6 +945,7 @@ int cmd_list(int argc, const char **argv) if (opt_kernel) { ret = list_kernel_events(); if (ret < 0) { + ret = CMD_ERROR; goto end; } } @@ -749,6 +956,14 @@ int cmd_list(int argc, const char **argv) ret = list_ust_events(); } if (ret < 0) { + ret = CMD_ERROR; + goto end; + } + } + if (opt_jul) { + ret = list_jul_events(); + if (ret < 0) { + ret = CMD_ERROR; goto end; } } @@ -765,17 +980,20 @@ int cmd_list(int argc, const char **argv) goto end; } - if (opt_kernel) { + if (opt_kernel || opt_userspace) { /* Channel listing */ ret = list_channels(opt_channel); if (ret < 0) { goto end; } } else { + int i, nb_domain; + /* We want all domain(s) */ nb_domain = lttng_list_domains(session_name, &domains); if (nb_domain < 0) { ret = nb_domain; + ERR("%s", lttng_strerror(ret)); goto end; } @@ -786,6 +1004,12 @@ int cmd_list(int argc, const char **argv) break; case LTTNG_DOMAIN_UST: MSG("=== Domain: UST global ===\n"); + MSG("Buffer type: %s\n", + domains[i].buf_type == + LTTNG_BUFFER_PER_PID ? "per PID" : "per UID"); + break; + case LTTNG_DOMAIN_JUL: + MSG("=== Domain: JUL (Java Util Logging) ===\n"); break; default: MSG("=== Domain: Unimplemented ===\n"); @@ -803,6 +1027,14 @@ int cmd_list(int argc, const char **argv) goto end; } + if (domains[i].type == LTTNG_DOMAIN_JUL) { + ret = list_session_jul_events(); + if (ret < 0) { + goto end; + } + continue; + } + ret = list_channels(opt_channel); if (ret < 0) { goto end; @@ -812,9 +1044,7 @@ int cmd_list(int argc, const char **argv) } end: - if (domains) { - free(domains); - } + free(domains); if (handle) { lttng_destroy_handle(handle); }