X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng%2Futils.c;h=e836943991da04d16c9c0764230cd4e3ca6367e6;hp=fc592ebdeee16f68df1a52ad9c0bf2b770ed8466;hb=1004b7191b421c7c07acf964d0110d93bb022699;hpb=5cdb6027a2b78fd93aa7f61174625190b5fc3459 diff --git a/src/bin/lttng/utils.c b/src/bin/lttng/utils.c index fc592ebde..e83694399 100644 --- a/src/bin/lttng/utils.c +++ b/src/bin/lttng/utils.c @@ -1,21 +1,11 @@ /* - * Copyright (c) 2011 David Goulet + * Copyright (C) 2011 David Goulet * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2 only, - * as published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE +#define _LGPL_SOURCE #include #include #include @@ -25,28 +15,29 @@ #include #include #include +#include +#include #include #include +#include #include "conf.h" #include "utils.h" #include "command.h" -static const char *str_kernel = "Kernel"; -static const char *str_ust = "UST"; -static const char *str_jul = "JUL"; -static const char *str_log4j = "LOG4J"; +static const char *str_all = "ALL"; +static const char *str_tracepoint = "Tracepoint"; +static const char *str_syscall = "Syscall"; +static const char *str_probe = "Probe"; +static const char *str_userspace_probe = "Userspace Probe"; +static const char *str_function = "Function"; -/* - * get_session_name - * - * Return allocated string with the session name found in the config - * directory. - */ -char *get_session_name(void) +static +char *_get_session_name(int quiet) { - char *path, *session_name = NULL; + const char *path; + char *session_name = NULL; /* Get path to config file */ path = utils_get_home_dir(); @@ -55,7 +46,8 @@ char *get_session_name(void) } /* Get session name from config */ - session_name = config_read_session_name(path); + session_name = quiet ? config_read_session_name_quiet(path) : + config_read_session_name(path); if (session_name == NULL) { goto error; } @@ -68,6 +60,28 @@ error: return NULL; } +/* + * get_session_name + * + * Return allocated string with the session name found in the config + * directory. + */ +char *get_session_name(void) +{ + return _get_session_name(0); +} + +/* + * get_session_name_quiet (no warnings/errors emitted) + * + * Return allocated string with the session name found in the config + * directory. + */ +char *get_session_name_quiet(void) +{ + return _get_session_name(1); +} + /* * list_commands * @@ -109,6 +123,24 @@ void list_cmd_options(FILE *ofp, struct poptOption *options) } } +/* + * Same as list_cmd_options, but for options specified for argpar. + */ +void list_cmd_options_argpar(FILE *ofp, const struct argpar_opt_descr *options) +{ + int i; + + for (i = 0; options[i].long_name != NULL; i++) { + const struct argpar_opt_descr *option = &options[i]; + + fprintf(ofp, "--%s\n", option->long_name); + + if (isprint(option->short_name)) { + fprintf(ofp, "-%c\n", option->short_name); + } + } +} + /* * fls: returns the position of the most significant bit. * Returns 0 if no bit is set, else returns the position of the most @@ -130,7 +162,7 @@ unsigned int fls_u32(uint32_t x) #define HAS_FLS_U32 #endif -#if defined(__x86_64) +#if defined(__x86_64) && defined(__LP64__) static inline unsigned int fls_u64(uint64_t x) { @@ -261,29 +293,35 @@ int get_count_order_ulong(unsigned long x) return fls_ulong(x - 1); } -const char *get_domain_str(enum lttng_domain_type domain) +const char *get_event_type_str(enum lttng_event_type type) { - const char *str_dom; + const char *str_event_type; - switch (domain) { - case LTTNG_DOMAIN_KERNEL: - str_dom = str_kernel; + switch (type) { + case LTTNG_EVENT_ALL: + str_event_type = str_all; + break; + case LTTNG_EVENT_TRACEPOINT: + str_event_type = str_tracepoint; break; - case LTTNG_DOMAIN_UST: - str_dom = str_ust; + case LTTNG_EVENT_SYSCALL: + str_event_type = str_syscall; break; - case LTTNG_DOMAIN_JUL: - str_dom = str_jul; + case LTTNG_EVENT_PROBE: + str_event_type = str_probe; break; - case LTTNG_DOMAIN_LOG4J: - str_dom = str_log4j; + case LTTNG_EVENT_USERSPACE_PROBE: + str_event_type = str_userspace_probe; + break; + case LTTNG_EVENT_FUNCTION: + str_event_type = str_function; break; default: - /* Should not have an unknown domain or else define it. */ + /* Should not have an unknown event type or else define it. */ assert(0); } - return str_dom; + return str_event_type; } /* @@ -316,14 +354,14 @@ int spawn_relayd(const char *pathname, int port) if (errno == ENOENT) { ERR("No relayd found. Use --relayd-path."); } else { - perror("execlp"); + PERROR("execlp"); } kill(getppid(), SIGTERM); /* wake parent */ exit(EXIT_FAILURE); } else if (pid > 0) { goto end; } else { - perror("fork"); + PERROR("fork"); ret = -1; goto end; } @@ -344,7 +382,7 @@ int check_relayd(void) fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { - perror("socket check relayd"); + PERROR("socket check relayd"); ret = -1; goto error_socket; } @@ -353,7 +391,7 @@ int check_relayd(void) sin.sin_port = htons(DEFAULT_NETWORK_VIEWER_PORT); ret = inet_pton(sin.sin_family, "127.0.0.1", &sin.sin_addr); if (ret < 1) { - perror("inet_pton check relayd"); + PERROR("inet_pton check relayd"); ret = -1; goto error; } @@ -362,7 +400,7 @@ int check_relayd(void) * A successful connect means the relayd exists thus returning 0 else a * negative value means it does NOT exists. */ - ret = connect(fd, &sin, sizeof(sin)); + ret = connect(fd, (struct sockaddr *) &sin, sizeof(sin)); if (ret < 0) { /* Not found. */ ret = 0; @@ -373,8 +411,262 @@ int check_relayd(void) error: if (close(fd) < 0) { - perror("close relayd fd"); + PERROR("close relayd fd"); } error_socket: return ret; } + +int print_missing_or_multiple_domains(unsigned int domain_count, + bool include_agent_domains) +{ + int ret = 0; + + if (domain_count == 0) { + ERR("Please specify a domain (--kernel/--userspace%s).", + include_agent_domains ? + "/--jul/--log4j/--python" : + ""); + ret = -1; + } else if (domain_count > 1) { + ERR("Only one domain must be specified."); + ret = -1; + } + + return ret; +} + +/* + * Get the discarded events and lost packet counts. + */ +void print_session_stats(const char *session_name) +{ + char *str; + const int ret = get_session_stats_str(session_name, &str); + + if (ret >= 0 && str) { + MSG("%s", str); + free(str); + } +} + +int get_session_stats_str(const char *session_name, char **out_str) +{ + int count, nb_domains, domain_idx, channel_idx, session_idx, ret; + struct lttng_domain *domains; + struct lttng_channel *channels; + uint64_t discarded_events_total = 0, lost_packets_total = 0; + struct lttng_session *sessions = NULL; + const struct lttng_session *selected_session = NULL; + char *stats_str = NULL; + bool print_discarded_events = false, print_lost_packets = false; + + count = lttng_list_sessions(&sessions); + if (count < 1) { + ERR("Failed to retrieve session descriptions while printing session statistics."); + ret = -1; + goto end; + } + + /* Identify the currently-selected sessions. */ + for (session_idx = 0; session_idx < count; session_idx++) { + if (!strcmp(session_name, sessions[session_idx].name)) { + selected_session = &sessions[session_idx]; + break; + } + } + if (!selected_session) { + ERR("Failed to retrieve session \"%s\" description while printing session statistics.", session_name); + ret = -1; + goto end; + } + + nb_domains = lttng_list_domains(session_name, &domains); + if (nb_domains < 0) { + ret = -1; + goto end; + } + for (domain_idx = 0; domain_idx < nb_domains; domain_idx++) { + struct lttng_handle *handle = lttng_create_handle(session_name, + &domains[domain_idx]); + + if (!handle) { + ERR("Failed to create session handle while printing session statistics."); + ret = -1; + goto end; + } + + count = lttng_list_channels(handle, &channels); + for (channel_idx = 0; channel_idx < count; channel_idx++) { + uint64_t discarded_events = 0, lost_packets = 0; + struct lttng_channel *channel = &channels[channel_idx]; + + ret = lttng_channel_get_discarded_event_count(channel, + &discarded_events); + if (ret) { + ERR("Failed to retrieve discarded event count from channel %s", + channel->name); + } + + ret = lttng_channel_get_lost_packet_count(channel, + &lost_packets); + if (ret) { + ERR("Failed to retrieve lost packet count from channel %s", + channel->name); + } + + discarded_events_total += discarded_events; + lost_packets_total += lost_packets; + } + lttng_destroy_handle(handle); + } + + print_discarded_events = discarded_events_total > 0 && + !selected_session->snapshot_mode; + print_lost_packets = lost_packets_total > 0 && + !selected_session->snapshot_mode; + + if (print_discarded_events && print_lost_packets) { + ret = asprintf(&stats_str, + "Warning: %" PRIu64 + " events were discarded and %" PRIu64 + " packets were lost, please refer to " + "the documentation on channel configuration.", + discarded_events_total, lost_packets_total); + } else if (print_discarded_events) { + ret = asprintf(&stats_str, + "Warning: %" PRIu64 + " events were discarded, please refer to " + "the documentation on channel configuration.", + discarded_events_total); + } else if (print_lost_packets) { + ret = asprintf(&stats_str, + "Warning: %" PRIu64 + " packets were lost, please refer to " + "the documentation on channel configuration.", + lost_packets_total); + } else { + ret = 0; + } + + if (ret < 0) { + ERR("Failed to format lost packet and discarded events statistics"); + } else { + *out_str = stats_str; + ret = 0; + } +end: + free(sessions); + return ret; +} + +int show_cmd_help(const char *cmd_name, const char *help_msg) +{ + int ret; + char page_name[32]; + + ret = sprintf(page_name, "lttng-%s", cmd_name); + assert(ret > 0 && ret < 32); + ret = utils_show_help(1, page_name, help_msg); + if (ret && !help_msg) { + ERR("Cannot view man page `lttng-%s(1)`", cmd_name); + perror("exec"); + } + + return ret; +} + +int print_trace_archive_location( + const struct lttng_trace_archive_location *location, + const char *session_name) +{ + int ret = 0; + enum lttng_trace_archive_location_type location_type; + enum lttng_trace_archive_location_status status; + bool printed_location = false; + + location_type = lttng_trace_archive_location_get_type(location); + + _MSG("Trace chunk archive for session %s is now readable", + session_name); + switch (location_type) { + case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL: + { + const char *absolute_path; + + status = lttng_trace_archive_location_local_get_absolute_path( + location, &absolute_path); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + MSG(" at %s", absolute_path); + printed_location = true; + break; + } + case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY: + { + uint16_t control_port, data_port; + const char *host, *relative_path, *protocol_str; + enum lttng_trace_archive_location_relay_protocol_type protocol; + + /* Fetch all relay location parameters. */ + status = lttng_trace_archive_location_relay_get_protocol_type( + location, &protocol); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_host( + location, &host); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_control_port( + location, &control_port); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_data_port( + location, &data_port); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_relative_path( + location, &relative_path); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + switch (protocol) { + case LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP: + protocol_str = "tcp"; + break; + default: + protocol_str = "unknown"; + break; + } + + MSG(" on relay %s://%s/%s [control port %" PRIu16 ", data port %" + PRIu16 "]", protocol_str, host, + relative_path, control_port, data_port); + printed_location = true; + break; + } + default: + break; + } +end: + if (!printed_location) { + MSG(" at an unknown location"); + } + return ret; +}