Add agent domains to lttng enable-event usage()
[lttng-tools.git] / src / bin / lttng / commands / enable_events.c
index 8b1215b111cfae31c2721c4a61f22211efd79d8e..07f5f1a9876c49c3d8214e026ed4fb1132a31d89 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #define _GNU_SOURCE
+#define _LGPL_SOURCE
 #include <assert.h>
 #include <popt.h>
 #include <stdio.h>
@@ -47,25 +48,19 @@ static char *opt_session_name;
 static int opt_userspace;
 static int opt_jul;
 static int opt_log4j;
+static int opt_python;
 static int opt_enable_all;
 static char *opt_probe;
 static char *opt_function;
-static char *opt_function_entry_symbol;
 static char *opt_channel_name;
 static char *opt_filter;
 static char *opt_exclude;
-#if 0
-/* Not implemented yet */
-static char *opt_cmd_name;
-static pid_t opt_pid;
-#endif
 
 enum {
        OPT_HELP = 1,
        OPT_TRACEPOINT,
        OPT_PROBE,
        OPT_FUNCTION,
-       OPT_FUNCTION_ENTRY,
        OPT_SYSCALL,
        OPT_USERSPACE,
        OPT_LOGLEVEL,
@@ -88,16 +83,10 @@ static struct poptOption long_options[] = {
        {"userspace",      'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
        {"jul",            'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0},
        {"log4j",          'l', POPT_ARG_VAL, &opt_log4j, 1, 0, 0},
+       {"python",         'p', POPT_ARG_VAL, &opt_python, 1, 0, 0},
        {"tracepoint",     0,   POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0},
        {"probe",          0,   POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0},
        {"function",       0,   POPT_ARG_STRING, &opt_function, OPT_FUNCTION, 0, 0},
-#if 0
-       /*
-        * Currently removed from lttng kernel tracer. Removed from
-        * lttng UI to discourage its use.
-        */
-       {"function:entry", 0,   POPT_ARG_STRING, &opt_function_entry_symbol, OPT_FUNCTION_ENTRY, 0, 0},
-#endif
        {"syscall",        0,   POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0},
        {"loglevel",       0,     POPT_ARG_STRING, 0, OPT_LOGLEVEL, 0, 0},
        {"loglevel-only",  0,     POPT_ARG_STRING, 0, OPT_LOGLEVEL_ONLY, 0, 0},
@@ -112,7 +101,7 @@ static struct poptOption long_options[] = {
  */
 static void usage(FILE *ofp)
 {
-       fprintf(ofp, "usage: lttng enable-event NAME[,NAME2,...] [-k|-u] [OPTIONS] \n");
+       fprintf(ofp, "usage: lttng enable-event NAME[,NAME2,...] (-k | -u | -j | -l | -p) [OPTIONS] \n");
        fprintf(ofp, "\n");
        fprintf(ofp, "Options:\n");
        fprintf(ofp, "  -h, --help               Show this help\n");
@@ -124,6 +113,7 @@ static void usage(FILE *ofp)
        fprintf(ofp, "  -u, --userspace          Apply to the user-space tracer\n");
        fprintf(ofp, "  -j, --jul                Apply for Java application using JUL\n");
        fprintf(ofp, "  -l, --log4j              Apply for Java application using LOG4j\n");
+       fprintf(ofp, "  -p, --python             Apply for Python application\n");
        fprintf(ofp, "\n");
        fprintf(ofp, "Event options:\n");
        fprintf(ofp, "    --tracepoint           Tracepoint event (default)\n");
@@ -140,10 +130,6 @@ static void usage(FILE *ofp)
        fprintf(ofp, "                           Dynamic function entry/return probe.\n");
        fprintf(ofp, "                           Addr and offset can be octal (0NNN...),\n");
        fprintf(ofp, "                           decimal (NNN...) or hexadecimal (0xNNN...)\n");
-#if 0
-       fprintf(ofp, "    --function:entry symbol\n");
-       fprintf(ofp, "                           Function tracer event\n");
-#endif
        fprintf(ofp, "    --syscall              System call event\n");
        fprintf(ofp, "\n");
        fprintf(ofp, "    --loglevel name\n");
@@ -197,6 +183,15 @@ static void usage(FILE *ofp)
        fprintf(ofp, "                               LOG4J_ALL            = INT32_MIN\n");
        fprintf(ofp, "                               (shortcuts such as \"severe\" are allowed)\n");
        fprintf(ofp, "\n");
+       fprintf(ofp, "                           Available Python domain loglevels:\n");
+       fprintf(ofp, "                               PYTHON_CRITICAL      = %d\n", LTTNG_LOGLEVEL_PYTHON_CRITICAL);
+       fprintf(ofp, "                               PYTHON_ERROR         = %d\n", LTTNG_LOGLEVEL_PYTHON_ERROR);
+       fprintf(ofp, "                               PYTHON_WARNING       = %d\n", LTTNG_LOGLEVEL_PYTHON_WARNING);
+       fprintf(ofp, "                               PYTHON_INFO          = %d\n", LTTNG_LOGLEVEL_PYTHON_INFO);
+       fprintf(ofp, "                               PYTHON_DEBUG         = %d\n", LTTNG_LOGLEVEL_PYTHON_DEBUG);
+       fprintf(ofp, "                               PYTHON_NOTSET        = %d\n", LTTNG_LOGLEVEL_PYTHON_NOTSET);
+       fprintf(ofp, "                               (shortcuts such as \"critical\" are allowed)\n");
+       fprintf(ofp, "\n");
        fprintf(ofp, "  -f, --filter \'expression\'\n");
        fprintf(ofp, "                           Filter expression on event fields and context.\n");
        fprintf(ofp, "                           Event recording depends on evaluation.\n");
@@ -321,6 +316,10 @@ static int loglevel_log4j_str_to_value(const char *inputstr)
        int i = 0;
        char str[LTTNG_SYMBOL_NAME_LEN];
 
+       if (!inputstr || strlen(inputstr) == 0) {
+               return -1;
+       }
+
        /*
         * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
         * added at the end of the loop so a the upper bound we avoid the overflow.
@@ -360,6 +359,10 @@ static int loglevel_jul_str_to_value(const char *inputstr)
        int i = 0;
        char str[LTTNG_SYMBOL_NAME_LEN];
 
+       if (!inputstr || strlen(inputstr) == 0) {
+               return -1;
+       }
+
        /*
         * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
         * added at the end of the loop so a the upper bound we avoid the overflow.
@@ -393,6 +396,45 @@ static int loglevel_jul_str_to_value(const char *inputstr)
        }
 }
 
+/*
+ * Maps Python loglevel from string to value
+ */
+static int loglevel_python_str_to_value(const char *inputstr)
+{
+       int i = 0;
+       char str[LTTNG_SYMBOL_NAME_LEN];
+
+       if (!inputstr || strlen(inputstr) == 0) {
+               return -1;
+       }
+
+       /*
+        * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
+        * added at the end of the loop so a the upper bound we avoid the overflow.
+        */
+       while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
+               str[i] = toupper(inputstr[i]);
+               i++;
+       }
+       str[i] = '\0';
+
+       if (!strcmp(str, "PYTHON_CRITICAL") || !strcmp(str, "CRITICAL")) {
+               return LTTNG_LOGLEVEL_PYTHON_CRITICAL;
+       } else if (!strcmp(str, "PYTHON_ERROR") || !strcmp(str, "ERROR")) {
+               return LTTNG_LOGLEVEL_PYTHON_ERROR;
+       } else if (!strcmp(str, "PYTHON_WARNING") || !strcmp(str, "WARNING")) {
+               return LTTNG_LOGLEVEL_PYTHON_WARNING;
+       } else if (!strcmp(str, "PYTHON_INFO") || !strcmp(str, "INFO")) {
+               return LTTNG_LOGLEVEL_PYTHON_INFO;
+       } else if (!strcmp(str, "PYTNON_DEBUG") || !strcmp(str, "DEBUG")) {
+               return LTTNG_LOGLEVEL_PYTHON_DEBUG;
+       } else if (!strcmp(str, "PYTHON_NOTSET") || !strcmp(str, "NOTSET")) {
+               return LTTNG_LOGLEVEL_PYTHON_NOTSET;
+       } else {
+               return -1;
+       }
+}
+
 /*
  * Maps loglevel from string to value
  */
@@ -402,6 +444,10 @@ int loglevel_str_to_value(const char *inputstr)
        int i = 0;
        char str[LTTNG_SYMBOL_NAME_LEN];
 
+       if (!inputstr || strlen(inputstr) == 0) {
+               return -1;
+       }
+
        /*
         * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
         * added at the end of the loop so a the upper bound we avoid the overflow.
@@ -514,7 +560,10 @@ char *print_exclusions(int count, char **names)
 
        /* add length of preamble + one for NUL - one for last (missing) comma */
        length += strlen(preamble);
-       ret = malloc(length);
+       ret = zmalloc(length);
+       if (!ret) {
+               return NULL;
+       }
        strncpy(ret, preamble, length);
        for (i = 0; i < count; i++) {
                strcat(ret, names[i]);
@@ -573,11 +622,25 @@ int check_exclusion_subsets(const char *event_name,
                                goto error;
                        }
                        if (e == '*') {
+                               char *string;
+                               char **new_exclusion_list;
+
                                /* Excluder is a proper subset of event */
+                               string = strndup(next_excluder, excluder_length);
+                               if (!string) {
+                                       PERROR("strndup error");
+                                       goto error;
+                               }
+                               new_exclusion_list = realloc(exclusion_list,
+                                       sizeof(char *) * (exclusion_count + 1));
+                               if (!new_exclusion_list) {
+                                       PERROR("realloc");
+                                       free(string);
+                                       goto error;
+                               }
+                               exclusion_list = new_exclusion_list;
                                exclusion_count++;
-                               exclusion_list = realloc(exclusion_list, sizeof(char **) * exclusion_count);
-                               exclusion_list[exclusion_count - 1] = strndup(next_excluder, excluder_length);
-
+                               exclusion_list[exclusion_count - 1] = string;
                                break;
                        }
                        if (x != e) {
@@ -632,11 +695,6 @@ static int enable_events(char *session_name)
        memset(&dom, 0, sizeof(dom));
 
        if (opt_kernel) {
-               if (opt_filter) {
-                       ERR("Filter not implement for kernel tracing yet");
-                       ret = CMD_ERROR;
-                       goto error;
-               }
                if (opt_loglevel) {
                        WARN("Kernel loglevels are not supported.");
                }
@@ -658,6 +716,10 @@ static int enable_events(char *session_name)
                dom.type = LTTNG_DOMAIN_LOG4J;
                /* Default. */
                dom.buf_type = LTTNG_BUFFER_PER_UID;
+       } else if (opt_python) {
+               dom.type = LTTNG_DOMAIN_PYTHON;
+               /* Default. */
+               dom.buf_type = LTTNG_BUFFER_PER_UID;
        } else {
                print_missing_domain();
                ret = CMD_ERROR;
@@ -692,7 +754,7 @@ static int enable_events(char *session_name)
                /* Default setup for enable all */
                if (opt_kernel) {
                        ev.type = opt_event_type;
-                       ev.name[0] = '\0';
+                       strcpy(ev.name, "*");
                        /* kernel loglevels not implemented */
                        ev.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
                } else {
@@ -700,13 +762,15 @@ static int enable_events(char *session_name)
                        strcpy(ev.name, "*");
                        ev.loglevel_type = opt_loglevel_type;
                        if (opt_loglevel) {
-                               assert(opt_userspace || opt_jul || opt_log4j);
+                               assert(opt_userspace || opt_jul || opt_log4j || opt_python);
                                if (opt_userspace) {
                                        ev.loglevel = loglevel_str_to_value(opt_loglevel);
                                } else if (opt_jul) {
                                        ev.loglevel = loglevel_jul_str_to_value(opt_loglevel);
                                } else if (opt_log4j) {
                                        ev.loglevel = loglevel_log4j_str_to_value(opt_loglevel);
+                               } else if (opt_python) {
+                                       ev.loglevel = loglevel_python_str_to_value(opt_loglevel);
                                }
                                if (ev.loglevel == -1) {
                                        ERR("Unknown loglevel %s", opt_loglevel);
@@ -714,11 +778,13 @@ static int enable_events(char *session_name)
                                        goto error;
                                }
                        } else {
-                               assert(opt_userspace || opt_jul || opt_log4j);
+                               assert(opt_userspace || opt_jul || opt_log4j || opt_python);
                                if (opt_userspace) {
                                        ev.loglevel = -1;
                                } else if (opt_jul || opt_log4j) {
                                        ev.loglevel = LTTNG_LOGLEVEL_JUL_ALL;
+                               } else if (opt_python) {
+                                       ev.loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
                                }
                        }
                }
@@ -743,6 +809,16 @@ static int enable_events(char *session_name)
                                                        print_channel_name(channel_name), session_name);
                                        warn = 1;
                                        break;
+                               case LTTNG_ERR_TRACE_ALREADY_STARTED:
+                               {
+                                       const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
+                                       ERR("Events: %s (channel %s, session %s)",
+                                                       msg,
+                                                       print_channel_name(channel_name),
+                                                       session_name);
+                                       error = 1;
+                                       break;
+                               }
                                default:
                                        ERR("Events: %s (channel %s, session %s)",
                                                        lttng_strerror(ret),
@@ -760,6 +836,12 @@ static int enable_events(char *session_name)
                        case LTTNG_EVENT_TRACEPOINT:
                                if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
                                        char *exclusion_string = print_exclusions(exclusion_count, exclusion_list);
+
+                                       if (!exclusion_string) {
+                                               PERROR("Cannot allocate exclusion_string");
+                                               error = 1;
+                                               goto end;
+                                       }
                                        MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
                                                        get_domain_str(dom.type),
                                                        exclusion_string,
@@ -768,6 +850,12 @@ static int enable_events(char *session_name)
                                        free(exclusion_string);
                                } else {
                                        char *exclusion_string = print_exclusions(exclusion_count, exclusion_list);
+
+                                       if (!exclusion_string) {
+                                               PERROR("Cannot allocate exclusion_string");
+                                               error = 1;
+                                               goto end;
+                                       }
                                        MSG("All %s tracepoints%s are enabled in channel %s",
                                                        get_domain_str(dom.type),
                                                        exclusion_string,
@@ -785,6 +873,12 @@ static int enable_events(char *session_name)
                        case LTTNG_EVENT_ALL:
                                if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
                                        char *exclusion_string = print_exclusions(exclusion_count, exclusion_list);
+
+                                       if (!exclusion_string) {
+                                               PERROR("Cannot allocate exclusion_string");
+                                               error = 1;
+                                               goto end;
+                                       }
                                        MSG("All %s events%s are enabled in channel %s for loglevel %s",
                                                        get_domain_str(dom.type),
                                                        exclusion_string,
@@ -793,6 +887,12 @@ static int enable_events(char *session_name)
                                        free(exclusion_string);
                                } else {
                                        char *exclusion_string = print_exclusions(exclusion_count, exclusion_list);
+
+                                       if (!exclusion_string) {
+                                               PERROR("Cannot allocate exclusion_string");
+                                               error = 1;
+                                               goto end;
+                                       }
                                        MSG("All %s events%s are enabled in channel %s",
                                                        get_domain_str(dom.type),
                                                        exclusion_string,
@@ -820,6 +920,16 @@ static int enable_events(char *session_name)
                                                print_channel_name(channel_name), session_name);
                                        warn = 1;
                                        break;
+                               case LTTNG_ERR_TRACE_ALREADY_STARTED:
+                               {
+                                       const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
+                                       ERR("All events: %s (channel %s, session %s, filter \'%s\')",
+                                                       msg,
+                                                       print_channel_name(channel_name),
+                                                       session_name, opt_filter);
+                                       error = 1;
+                                       break;
+                               }
                                default:
                                        ERR("All events: %s (channel %s, session %s, filter \'%s\')",
                                                        lttng_strerror(command_ret),
@@ -901,9 +1011,12 @@ static int enable_events(char *session_name)
                                        print_channel_name(channel_name));
 
                        switch (opt_event_type) {
-                       case LTTNG_EVENT_ALL:   /* Default behavior is tracepoint */
-                               ev.type = LTTNG_EVENT_TRACEPOINT;
-                               /* Fall-through */
+                       case LTTNG_EVENT_ALL:   /* Enable tracepoints and syscalls */
+                               /* If event name differs from *, select tracepoint. */
+                               if (strcmp(ev.name, "*")) {
+                                       ev.type = LTTNG_EVENT_TRACEPOINT;
+                               }
+                               break;
                        case LTTNG_EVENT_TRACEPOINT:
                                break;
                        case LTTNG_EVENT_PROBE:
@@ -922,11 +1035,6 @@ static int enable_events(char *session_name)
                                        goto error;
                                }
                                break;
-                       case LTTNG_EVENT_FUNCTION_ENTRY:
-                               strncpy(ev.attr.ftrace.symbol_name, opt_function_entry_symbol,
-                                               LTTNG_SYMBOL_NAME_LEN);
-                               ev.attr.ftrace.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
-                               break;
                        case LTTNG_EVENT_SYSCALL:
                                ev.type = LTTNG_EVENT_SYSCALL;
                                break;
@@ -938,14 +1046,6 @@ static int enable_events(char *session_name)
                        /* kernel loglevels not implemented */
                        ev.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
                } else if (opt_userspace) {             /* User-space tracer action */
-#if 0
-                       if (opt_cmd_name != NULL || opt_pid) {
-                               MSG("Only supporting tracing all UST processes (-u) for now.");
-                               ret = CMD_UNDEFINED;
-                               goto error;
-                       }
-#endif
-
                        DBG("Enabling UST event %s for channel %s, loglevel %s", event_name,
                                        print_channel_name(channel_name), opt_loglevel ? : "<all>");
 
@@ -960,7 +1060,6 @@ static int enable_events(char *session_name)
                                break;
                        case LTTNG_EVENT_PROBE:
                        case LTTNG_EVENT_FUNCTION:
-                       case LTTNG_EVENT_FUNCTION_ENTRY:
                        case LTTNG_EVENT_SYSCALL:
                        default:
                                ERR("Event type not available for user-space tracing");
@@ -1002,7 +1101,7 @@ static int enable_events(char *session_name)
                        } else {
                                ev.loglevel = -1;
                        }
-               } else if (opt_jul || opt_log4j) {
+               } else if (opt_jul || opt_log4j || opt_python) {
                        if (opt_event_type != LTTNG_EVENT_ALL &&
                                        opt_event_type != LTTNG_EVENT_TRACEPOINT) {
                                ERR("Event type not supported for domain.");
@@ -1016,6 +1115,8 @@ static int enable_events(char *session_name)
                                        ev.loglevel = loglevel_jul_str_to_value(opt_loglevel);
                                } else if (opt_log4j) {
                                        ev.loglevel = loglevel_log4j_str_to_value(opt_loglevel);
+                               } else if (opt_python) {
+                                       ev.loglevel = loglevel_python_str_to_value(opt_loglevel);
                                }
                                if (ev.loglevel == -1) {
                                        ERR("Unknown loglevel %s", opt_loglevel);
@@ -1027,6 +1128,8 @@ static int enable_events(char *session_name)
                                        ev.loglevel = LTTNG_LOGLEVEL_JUL_ALL;
                                } else if (opt_log4j) {
                                        ev.loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
+                               } else if (opt_python) {
+                                       ev.loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
                                }
                        }
                        ev.type = LTTNG_EVENT_TRACEPOINT;
@@ -1045,6 +1148,11 @@ static int enable_events(char *session_name)
                                        &ev, channel_name,
                                        NULL, exclusion_count, exclusion_list);
                        exclusion_string = print_exclusions(exclusion_count, exclusion_list);
+                       if (!exclusion_string) {
+                               PERROR("Cannot allocate exclusion_string");
+                               error = 1;
+                               goto end;
+                       }
                        if (command_ret < 0) {
                                /* Turn ret to positive value to handle the positive error code */
                                switch (-command_ret) {
@@ -1055,6 +1163,17 @@ static int enable_events(char *session_name)
                                                        print_channel_name(channel_name), session_name);
                                        warn = 1;
                                        break;
+                               case LTTNG_ERR_TRACE_ALREADY_STARTED:
+                               {
+                                       const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
+                                       ERR("Event %s%s: %s (channel %s, session %s)", event_name,
+                                                       exclusion_string,
+                                                       msg,
+                                                       print_channel_name(channel_name),
+                                                       session_name);
+                                       error = 1;
+                                       break;
+                               }
                                default:
                                        ERR("Event %s%s: %s (channel %s, session %s)", event_name,
                                                        exclusion_string,
@@ -1093,7 +1212,11 @@ static int enable_events(char *session_name)
                        command_ret = lttng_enable_event_with_exclusions(handle, &ev, channel_name,
                                        opt_filter, exclusion_count, exclusion_list);
                        exclusion_string = print_exclusions(exclusion_count, exclusion_list);
-
+                       if (!exclusion_string) {
+                               PERROR("Cannot allocate exclusion_string");
+                               error = 1;
+                               goto end;
+                       }
                        if (command_ret < 0) {
                                switch (-command_ret) {
                                case LTTNG_ERR_FILTER_EXIST:
@@ -1104,6 +1227,17 @@ static int enable_events(char *session_name)
                                                print_channel_name(channel_name), session_name);
                                        warn = 1;
                                        break;
+                               case LTTNG_ERR_TRACE_ALREADY_STARTED:
+                               {
+                                       const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
+                                       ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev.name,
+                                                       exclusion_string,
+                                                       msg,
+                                                       print_channel_name(channel_name),
+                                                       session_name, opt_filter);
+                                       error = 1;
+                                       break;
+                               }
                                default:
                                        ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev.name,
                                                        exclusion_string,
@@ -1232,9 +1366,6 @@ int cmd_enable_events(int argc, const char **argv)
                case OPT_FUNCTION:
                        opt_event_type = LTTNG_EVENT_FUNCTION;
                        break;
-               case OPT_FUNCTION_ENTRY:
-                       opt_event_type = LTTNG_EVENT_FUNCTION_ENTRY;
-                       break;
                case OPT_SYSCALL:
                        opt_event_type = LTTNG_EVENT_SYSCALL;
                        break;
This page took 0.029931 seconds and 4 git commands to generate.