Add Python agent support
authorDavid Goulet <dgoulet@efficios.com>
Tue, 14 Oct 2014 15:15:22 +0000 (11:15 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Wed, 22 Oct 2014 15:24:36 +0000 (11:24 -0400)
Support the new Python agent shipped in liblttng-ust.

This adds the -p, --python option to the list and enable/disable-event
command to control the domain exactly like JUL and LOG4J.

The agent support is for the Python "logging" module.

Signed-off-by: David Goulet <dgoulet@efficios.com>
26 files changed:
configure.ac
doc/man/lttng.1
include/lttng/domain.h
include/lttng/event.h
src/bin/lttng-sessiond/agent.c
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/event.c
src/bin/lttng-sessiond/main.c
src/bin/lttng-sessiond/save.c
src/bin/lttng/commands/disable_events.c
src/bin/lttng/commands/enable_events.c
src/bin/lttng/commands/list.c
src/bin/lttng/utils.c
src/common/config/config.c
src/common/config/session.xsd
src/common/defaults.h
src/common/mi-lttng.c
src/common/mi-lttng.h
src/common/mi_lttng.xsd
src/lib/lttng-ctl/lttng-ctl.c
tests/fast_regression
tests/regression/ust/Makefile.am
tests/regression/ust/python-logging/LTTngTest.py [new file with mode: 0644]
tests/regression/ust/python-logging/Makefile.am [new file with mode: 0644]
tests/regression/ust/python-logging/test_python_logging [new file with mode: 0755]
tests/utils/utils.sh

index 487a2b9783b1a12d4570d95ad2d5b7ea044bc90b..8d1ff86ade00157200bc8df65990f22c19be0734 100644 (file)
@@ -497,6 +497,7 @@ AC_CONFIG_FILES([
        tests/regression/ust/libc-wrapper/Makefile
        tests/regression/ust/java-jul/Makefile
        tests/regression/ust/java-log4j/Makefile
        tests/regression/ust/libc-wrapper/Makefile
        tests/regression/ust/java-jul/Makefile
        tests/regression/ust/java-log4j/Makefile
+       tests/regression/ust/python-logging/Makefile
        tests/stress/Makefile
        tests/unit/Makefile
        tests/unit/ini_config/Makefile
        tests/stress/Makefile
        tests/unit/Makefile
        tests/unit/ini_config/Makefile
index f6d21e7ad4b9663a8100110a984c41329d41799b..47f273144c797cc3970a2e1b42b54e1fff6d29e5 100644 (file)
@@ -27,10 +27,11 @@ kernel and/or instrumented applications (lttng-ust(3)). Aggregating and reading
 those traces is done using the babeltrace(1) text viewer.
 
 We introduce the notion of \fBtracing domains\fP which is essentially a type of
 those traces is done using the babeltrace(1) text viewer.
 
 We introduce the notion of \fBtracing domains\fP which is essentially a type of
-tracer (kernel, user space, JUL or LOG4J for now). In the future, we could see
-more tracer like for instance an hypervisor. For some commands, you'll need to
-specify on which domain the command operates (\-u, \-k or \-j). For instance,
-the kernel domain must be specified when enabling a kernel event.
+tracer (kernel, user space, JUL, LOG4J or Python for now). In the future, we
+could see more tracer like for instance an hypervisor. For some commands,
+you'll need to specify on which domain the command operates (\-u, \-k, \-l, \-j
+or \-p). For instance, the kernel domain must be specified when enabling a
+kernel event.
 
 In order to trace the kernel, the session daemon needs to be running as root.
 LTTng provides the use of a \fBtracing group\fP (default: tracing). Whomever is
 
 In order to trace the kernel, the session daemon needs to be running as root.
 LTTng provides the use of a \fBtracing group\fP (default: tracing). Whomever is
@@ -542,6 +543,9 @@ Apply for Java application using Java Util Logging interface (JUL)
 .BR "\-l, \-\-log4j"
 Apply for Java application using LOG4J
 .TP
 .BR "\-l, \-\-log4j"
 Apply for Java application using LOG4J
 .TP
+.BR "\-p, \-\-python"
+Apply for Python application using the logging module.
+.TP
 .BR "\-\-tracepoint"
 Tracepoint event (default). Userspace tracer supports wildcards at the end
 of string. Don't forget to quote to deal with bash expansion.
 .BR "\-\-tracepoint"
 Tracepoint event (default). Userspace tracer supports wildcards at the end
 of string. Don't forget to quote to deal with bash expansion.
@@ -557,6 +561,8 @@ For the JUL domain, the loglevel ranges are detailed with the \-\-help
 option thus starting from SEVERE to FINEST.
 For the LOG4J domain, loglevels range from FATAL to TRACE which are also
 detailed in the help.
 option thus starting from SEVERE to FINEST.
 For the LOG4J domain, loglevels range from FATAL to TRACE which are also
 detailed in the help.
+For the Python domain, loglevels range from CRITICAL to DEBUG which are
+detailed in the help as well.
 .TP
 .BR "\-\-loglevel-only NAME"
 Tracepoint loglevel (only this loglevel).
 .TP
 .BR "\-\-loglevel-only NAME"
 Tracepoint loglevel (only this loglevel).
@@ -708,6 +714,9 @@ Apply for Java application using Java Util Logging interface (JUL)
 .TP
 .BR "\-l, \-\-log4j"
 Apply for Java application using LOG4J
 .TP
 .BR "\-l, \-\-log4j"
 Apply for Java application using LOG4J
+.TP
+.BR "\-p, \-\-python"
+Apply for Python application using the logging module.
 .RE
 .PP
 
 .RE
 .PP
 
@@ -728,6 +737,8 @@ With \-j alone, the available JUL event from registered application will be
 list. The event corresponds to the Logger name in the Java JUL application.
 With \-l alone, the available LOG4J event from registered application will be
 list. The event corresponds to the Logger name in the Java LOG4J application.
 list. The event corresponds to the Logger name in the Java JUL application.
 With \-l alone, the available LOG4J event from registered application will be
 list. The event corresponds to the Logger name in the Java LOG4J application.
+With \-p alone, the available Python event from registered application will be
+list. The event corresponds to the Logger name in the Python application.
 With \-u alone, it will list all available user-space events from registered
 applications. Here is an example of 'lttng list \-u':
 
 With \-u alone, it will list all available user-space events from registered
 applications. Here is an example of 'lttng list \-u':
 
@@ -758,9 +769,12 @@ Select user-space domain.
 .BR "\-j, \-\-jul"
 Apply for Java application using JUL
 .TP
 .BR "\-j, \-\-jul"
 Apply for Java application using JUL
 .TP
-.TP
 .BR "\-l, \-\-log4j"
 Apply for Java application using LOG4J
 .BR "\-l, \-\-log4j"
 Apply for Java application using LOG4J
+.TP
+.BR "\-p, \-\-python"
+Apply for Python application using the logging module.
+.TP
 .BR "\-f, \-\-fields"
 List event fields
 
 .BR "\-f, \-\-fields"
 List event fields
 
index becebe2dd96b59537678c75c2b362269416b9553..3ee04191c45411b11cab7c782b44795280ac88ff 100644 (file)
@@ -32,6 +32,7 @@ enum lttng_domain_type {
        LTTNG_DOMAIN_UST                      = 2,      /* Global Userspace tracer. */
        LTTNG_DOMAIN_JUL                      = 3,      /* Java Util Logging. */
        LTTNG_DOMAIN_LOG4J                    = 4,      /* Java Log4j Framework. */
        LTTNG_DOMAIN_UST                      = 2,      /* Global Userspace tracer. */
        LTTNG_DOMAIN_JUL                      = 3,      /* Java Util Logging. */
        LTTNG_DOMAIN_LOG4J                    = 4,      /* Java Log4j Framework. */
+       LTTNG_DOMAIN_PYTHON                   = 5,      /* Python logging Framework. */
 };
 
 /* Buffer type for a specific domain. */
 };
 
 /* Buffer type for a specific domain. */
index f1d8e6581252d3c03165e469ada60c1b47b21125..3e8fbe3e83f5f6b92269771fa5f8391a6811a6d4 100644 (file)
@@ -98,6 +98,19 @@ enum lttng_loglevel_log4j {
        LTTNG_LOGLEVEL_LOG4J_ALL              = INT32_MIN,
 };
 
        LTTNG_LOGLEVEL_LOG4J_ALL              = INT32_MIN,
 };
 
+/*
+ * Available loglevels for the Python domain. Those are an exact map from the
+ * Level class.
+ */
+enum lttng_loglevel_python {
+       LTTNG_LOGLEVEL_PYTHON_CRITICAL        = 50,
+       LTTNG_LOGLEVEL_PYTHON_ERROR           = 40,
+       LTTNG_LOGLEVEL_PYTHON_WARNING         = 30,
+       LTTNG_LOGLEVEL_PYTHON_INFO            = 20,
+       LTTNG_LOGLEVEL_PYTHON_DEBUG           = 10,
+       LTTNG_LOGLEVEL_PYTHON_NOTSET          = 0,
+};
+
 /*
  * LTTng consumer mode
  */
 /*
  * LTTng consumer mode
  */
index 1c1c6ab18ad4fc341f805288de1092f667bedb85..5cb8336c361d4377973b365608ec603597564afe 100644 (file)
@@ -539,6 +539,8 @@ int agent_list_events(struct lttng_event **events,
 
        assert(events);
 
 
        assert(events);
 
+       DBG2("Agent listing events for domain %d", domain);
+
        nbmem = UST_APP_EVENT_LIST_SIZE;
        tmp_events = zmalloc(nbmem * sizeof(*tmp_events));
        if (!tmp_events) {
        nbmem = UST_APP_EVENT_LIST_SIZE;
        tmp_events = zmalloc(nbmem * sizeof(*tmp_events));
        if (!tmp_events) {
index 2a1bfb5f4670110e24ffab931f085dac4ed57f0c..d882b074d54cd4f0348365ab4adb218ce263c48b 100644 (file)
@@ -1138,6 +1138,7 @@ int cmd_disable_event(struct ltt_session *session, int domain,
        }
        case LTTNG_DOMAIN_LOG4J:
        case LTTNG_DOMAIN_JUL:
        }
        case LTTNG_DOMAIN_LOG4J:
        case LTTNG_DOMAIN_JUL:
+       case LTTNG_DOMAIN_PYTHON:
        {
                struct agent *agt;
                struct ltt_ust_session *usess = session->ust_session;
        {
                struct agent *agt;
                struct ltt_ust_session *usess = session->ust_session;
@@ -1542,6 +1543,7 @@ int cmd_enable_event(struct ltt_session *session, struct lttng_domain *domain,
        }
        case LTTNG_DOMAIN_LOG4J:
        case LTTNG_DOMAIN_JUL:
        }
        case LTTNG_DOMAIN_LOG4J:
        case LTTNG_DOMAIN_JUL:
+       case LTTNG_DOMAIN_PYTHON:
        {
                const char *default_event_name, *default_chan_name;
                struct agent *agt;
        {
                const char *default_event_name, *default_chan_name;
                struct agent *agt;
@@ -1581,10 +1583,19 @@ int cmd_enable_event(struct ltt_session *session, struct lttng_domain *domain,
                memcpy(&tmp_dom, domain, sizeof(tmp_dom));
                tmp_dom.type = LTTNG_DOMAIN_UST;
 
                memcpy(&tmp_dom, domain, sizeof(tmp_dom));
                tmp_dom.type = LTTNG_DOMAIN_UST;
 
-               if (domain->type == LTTNG_DOMAIN_LOG4J) {
+               switch (domain->type) {
+               case LTTNG_DOMAIN_LOG4J:
                        default_chan_name = DEFAULT_LOG4J_CHANNEL_NAME;
                        default_chan_name = DEFAULT_LOG4J_CHANNEL_NAME;
-               } else {
+                       break;
+               case LTTNG_DOMAIN_JUL:
                        default_chan_name = DEFAULT_JUL_CHANNEL_NAME;
                        default_chan_name = DEFAULT_JUL_CHANNEL_NAME;
+                       break;
+               case LTTNG_DOMAIN_PYTHON:
+                       default_chan_name = DEFAULT_PYTHON_CHANNEL_NAME;
+                       break;
+               default:
+                       /* The switch/case we are in should avoid this else big problem */
+                       assert(0);
                }
 
                ret = cmd_enable_event(session, &tmp_dom, (char *) default_chan_name,
                }
 
                ret = cmd_enable_event(session, &tmp_dom, (char *) default_chan_name,
@@ -1756,6 +1767,7 @@ ssize_t cmd_list_tracepoints(int domain, struct lttng_event **events)
                break;
        case LTTNG_DOMAIN_LOG4J:
        case LTTNG_DOMAIN_JUL:
                break;
        case LTTNG_DOMAIN_LOG4J:
        case LTTNG_DOMAIN_JUL:
+       case LTTNG_DOMAIN_PYTHON:
                nb_events = agent_list_events(events, domain);
                if (nb_events < 0) {
                        ret = LTTNG_ERR_UST_LIST_FAIL;
                nb_events = agent_list_events(events, domain);
                if (nb_events < 0) {
                        ret = LTTNG_ERR_UST_LIST_FAIL;
@@ -2492,6 +2504,7 @@ ssize_t cmd_list_events(int domain, struct ltt_session *session,
        }
        case LTTNG_DOMAIN_LOG4J:
        case LTTNG_DOMAIN_JUL:
        }
        case LTTNG_DOMAIN_LOG4J:
        case LTTNG_DOMAIN_JUL:
+       case LTTNG_DOMAIN_PYTHON:
                if (session->ust_session) {
                        struct lttng_ht_iter iter;
                        struct agent *agt;
                if (session->ust_session) {
                        struct lttng_ht_iter iter;
                        struct agent *agt;
index 099cbd18db8ea42d767951f094df5dfd81856fbe..181926b415f3e2ed9b50fcb35f25d60d515e48e5 100644 (file)
@@ -715,26 +715,31 @@ const char *event_get_default_agent_ust_name(enum lttng_domain_type domain)
 {
        const char *default_event_name = NULL;
 
 {
        const char *default_event_name = NULL;
 
-       if (domain == LTTNG_DOMAIN_JUL) {
+       switch (domain) {
+       case LTTNG_DOMAIN_LOG4J:
                if (is_root) {
                if (is_root) {
-                       default_event_name = DEFAULT_SYS_JUL_EVENT_NAME;
+                       default_event_name = DEFAULT_SYS_LOG4J_EVENT_NAME;
                } else {
                } else {
-                       default_event_name = DEFAULT_USER_JUL_EVENT_NAME;
+                       default_event_name = DEFAULT_USER_LOG4J_EVENT_NAME;
                }
                }
-       } else if (domain == LTTNG_DOMAIN_LOG4J) {
+               break;
+       case LTTNG_DOMAIN_JUL:
                if (is_root) {
                if (is_root) {
-                       default_event_name = DEFAULT_SYS_LOG4J_EVENT_NAME;
+                       default_event_name = DEFAULT_SYS_JUL_EVENT_NAME;
                } else {
                } else {
-                       default_event_name = DEFAULT_USER_LOG4J_EVENT_NAME;
+                       default_event_name = DEFAULT_USER_JUL_EVENT_NAME;
                }
                }
-       } else {
+               break;
+       case LTTNG_DOMAIN_PYTHON:
+               default_event_name = DEFAULT_USER_PYTHON_EVENT_NAME;
+               break;
+       default:
                assert(0);
        }
 
        return default_event_name;
 }
 
                assert(0);
        }
 
        return default_event_name;
 }
 
-
 /*
  * Disable a single agent event for a given UST session.
  *
 /*
  * Disable a single agent event for a given UST session.
  *
@@ -770,6 +775,8 @@ int event_agent_disable(struct ltt_ust_session *usess, struct agent *agt,
                ust_channel_name = DEFAULT_JUL_CHANNEL_NAME;
        } else if (agt->domain == LTTNG_DOMAIN_LOG4J) {
                ust_channel_name = DEFAULT_LOG4J_CHANNEL_NAME;
                ust_channel_name = DEFAULT_JUL_CHANNEL_NAME;
        } else if (agt->domain == LTTNG_DOMAIN_LOG4J) {
                ust_channel_name = DEFAULT_LOG4J_CHANNEL_NAME;
+       } else if (agt->domain == LTTNG_DOMAIN_PYTHON) {
+               ust_channel_name = DEFAULT_PYTHON_CHANNEL_NAME;
        } else {
                ret = LTTNG_ERR_INVALID;
                goto error;
        } else {
                ret = LTTNG_ERR_INVALID;
                goto error;
index fa09758baa7083ed1a0b5c660fdf9f2e2b9ef03c..699d53323dd3b7eefe313d006f3b0e0605941336 100644 (file)
@@ -2603,6 +2603,7 @@ static int copy_session_consumer(int domain, struct ltt_session *session)
                break;
        case LTTNG_DOMAIN_JUL:
        case LTTNG_DOMAIN_LOG4J:
                break;
        case LTTNG_DOMAIN_JUL:
        case LTTNG_DOMAIN_LOG4J:
+       case LTTNG_DOMAIN_PYTHON:
        case LTTNG_DOMAIN_UST:
                DBG3("Copying tracing session consumer output in UST session");
                if (session->ust_session->consumer) {
        case LTTNG_DOMAIN_UST:
                DBG3("Copying tracing session consumer output in UST session");
                if (session->ust_session->consumer) {
@@ -2648,6 +2649,7 @@ static int create_ust_session(struct ltt_session *session,
        switch (domain->type) {
        case LTTNG_DOMAIN_JUL:
        case LTTNG_DOMAIN_LOG4J:
        switch (domain->type) {
        case LTTNG_DOMAIN_JUL:
        case LTTNG_DOMAIN_LOG4J:
+       case LTTNG_DOMAIN_PYTHON:
        case LTTNG_DOMAIN_UST:
                break;
        default:
        case LTTNG_DOMAIN_UST:
                break;
        default:
@@ -2895,6 +2897,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock,
                        break;
                case LTTNG_DOMAIN_JUL:
                case LTTNG_DOMAIN_LOG4J:
                        break;
                case LTTNG_DOMAIN_JUL:
                case LTTNG_DOMAIN_LOG4J:
+               case LTTNG_DOMAIN_PYTHON:
                case LTTNG_DOMAIN_UST:
                        if (!cmd_ctx->session->ust_session) {
                                ret = LTTNG_ERR_NO_CHANNEL;
                case LTTNG_DOMAIN_UST:
                        if (!cmd_ctx->session->ust_session) {
                                ret = LTTNG_ERR_NO_CHANNEL;
@@ -2977,6 +2980,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock,
                break;
        case LTTNG_DOMAIN_JUL:
        case LTTNG_DOMAIN_LOG4J:
                break;
        case LTTNG_DOMAIN_JUL:
        case LTTNG_DOMAIN_LOG4J:
+       case LTTNG_DOMAIN_PYTHON:
        case LTTNG_DOMAIN_UST:
        {
                if (!ust_app_supported()) {
        case LTTNG_DOMAIN_UST:
        {
                if (!ust_app_supported()) {
@@ -3071,6 +3075,7 @@ skip_domain:
                switch (cmd_ctx->lsm->domain.type) {
                case LTTNG_DOMAIN_JUL:
                case LTTNG_DOMAIN_LOG4J:
                switch (cmd_ctx->lsm->domain.type) {
                case LTTNG_DOMAIN_JUL:
                case LTTNG_DOMAIN_LOG4J:
+               case LTTNG_DOMAIN_PYTHON:
                case LTTNG_DOMAIN_UST:
                        if (uatomic_read(&ust_consumerd_state) != CONSUMER_STARTED) {
                                ret = LTTNG_ERR_NO_USTCONSUMERD;
                case LTTNG_DOMAIN_UST:
                        if (uatomic_read(&ust_consumerd_state) != CONSUMER_STARTED) {
                                ret = LTTNG_ERR_NO_USTCONSUMERD;
index 908e5f8fd2924d67223ffbdcbf8a04dfc158a502..aae56a8954a081d11508fa8a02f6dc081b7aafb5 100644 (file)
@@ -1161,7 +1161,8 @@ int save_ust_session(struct config_writer *writer,
 
                ust_chan = caa_container_of(node, struct ltt_ust_channel, node);
                agent_channel = !strcmp(DEFAULT_JUL_CHANNEL_NAME, ust_chan->name) ||
 
                ust_chan = caa_container_of(node, struct ltt_ust_channel, node);
                agent_channel = !strcmp(DEFAULT_JUL_CHANNEL_NAME, ust_chan->name) ||
-                       !strcmp(DEFAULT_LOG4J_CHANNEL_NAME, ust_chan->name);
+                       !strcmp(DEFAULT_LOG4J_CHANNEL_NAME, ust_chan->name) ||
+                       !strcmp(DEFAULT_PYTHON_CHANNEL_NAME, ust_chan->name);
                if (!(save_agent ^ agent_channel)) {
                        ret = save_ust_channel(writer, ust_chan, session->ust_session);
                        if (ret) {
                if (!(save_agent ^ agent_channel)) {
                        ret = save_ust_channel(writer, ust_chan, session->ust_session);
                        if (ret) {
index 1ce687aa422aebc2eb96e76e348b4552d3fdd565..e833fe9572141baf13c6a47ca7c922fb647d1155 100644 (file)
@@ -37,6 +37,7 @@ static int opt_userspace;
 static int opt_disable_all;
 static int opt_jul;
 static int opt_log4j;
 static int opt_disable_all;
 static int opt_jul;
 static int opt_log4j;
+static int opt_python;
 static int opt_event_type;
 #if 0
 /* Not implemented yet */
 static int opt_event_type;
 #if 0
 /* Not implemented yet */
@@ -62,6 +63,7 @@ static struct poptOption long_options[] = {
        {"channel",        'c', POPT_ARG_STRING, &opt_channel_name, 0, 0, 0},
        {"jul",            'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0},
        {"log4j",          'l', POPT_ARG_VAL, &opt_log4j, 1, 0, 0},
        {"channel",        'c', POPT_ARG_STRING, &opt_channel_name, 0, 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},
        {"kernel",         'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
        {"syscall",        0,   POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0},
 #if 0
        {"kernel",         'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
        {"syscall",        0,   POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0},
 #if 0
@@ -92,6 +94,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 to Java application using LOG4j\n");
        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 to Java application using LOG4j\n");
+       fprintf(ofp, "  -p, --python             Apply to Python application using logging\n");
        fprintf(ofp, "\n");
        fprintf(ofp, "Event options:\n");
        fprintf(ofp, "      --syscall            System call event\n");
        fprintf(ofp, "\n");
        fprintf(ofp, "Event options:\n");
        fprintf(ofp, "      --syscall            System call event\n");
@@ -178,6 +181,8 @@ static int disable_events(char *session_name)
                dom.type = LTTNG_DOMAIN_JUL;
        } else if (opt_log4j) {
                dom.type = LTTNG_DOMAIN_LOG4J;
                dom.type = LTTNG_DOMAIN_JUL;
        } else if (opt_log4j) {
                dom.type = LTTNG_DOMAIN_LOG4J;
+       } else if (opt_python) {
+               dom.type = LTTNG_DOMAIN_PYTHON;
        } else {
                print_missing_domain();
                ret = CMD_ERROR;
        } else {
                print_missing_domain();
                ret = CMD_ERROR;
index 8b1215b111cfae31c2721c4a61f22211efd79d8e..84bdb83c86466eb7489627bcc783d00e5323d713 100644 (file)
@@ -47,6 +47,7 @@ static char *opt_session_name;
 static int opt_userspace;
 static int opt_jul;
 static int opt_log4j;
 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 int opt_enable_all;
 static char *opt_probe;
 static char *opt_function;
@@ -88,6 +89,7 @@ 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},
        {"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},
        {"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},
@@ -124,6 +126,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, "  -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 Java application using LOG4j\n");
        fprintf(ofp, "\n");
        fprintf(ofp, "Event options:\n");
        fprintf(ofp, "    --tracepoint           Tracepoint event (default)\n");
        fprintf(ofp, "\n");
        fprintf(ofp, "Event options:\n");
        fprintf(ofp, "    --tracepoint           Tracepoint event (default)\n");
@@ -197,6 +200,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, "                               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");
        fprintf(ofp, "  -f, --filter \'expression\'\n");
        fprintf(ofp, "                           Filter expression on event fields and context.\n");
        fprintf(ofp, "                           Event recording depends on evaluation.\n");
@@ -393,6 +405,41 @@ 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];
+
+       /*
+        * 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
  */
 /*
  * Maps loglevel from string to value
  */
@@ -658,6 +705,10 @@ static int enable_events(char *session_name)
                dom.type = LTTNG_DOMAIN_LOG4J;
                /* Default. */
                dom.buf_type = LTTNG_BUFFER_PER_UID;
                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;
        } else {
                print_missing_domain();
                ret = CMD_ERROR;
@@ -700,13 +751,15 @@ static int enable_events(char *session_name)
                        strcpy(ev.name, "*");
                        ev.loglevel_type = opt_loglevel_type;
                        if (opt_loglevel) {
                        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);
                                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);
                                }
                                if (ev.loglevel == -1) {
                                        ERR("Unknown loglevel %s", opt_loglevel);
@@ -714,11 +767,13 @@ static int enable_events(char *session_name)
                                        goto error;
                                }
                        } else {
                                        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;
                                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;
                                }
                        }
                }
                                }
                        }
                }
@@ -1002,7 +1057,7 @@ static int enable_events(char *session_name)
                        } else {
                                ev.loglevel = -1;
                        }
                        } 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.");
                        if (opt_event_type != LTTNG_EVENT_ALL &&
                                        opt_event_type != LTTNG_EVENT_TRACEPOINT) {
                                ERR("Event type not supported for domain.");
@@ -1016,6 +1071,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);
                                        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);
                                }
                                if (ev.loglevel == -1) {
                                        ERR("Unknown loglevel %s", opt_loglevel);
@@ -1027,6 +1084,8 @@ static int enable_events(char *session_name)
                                        ev.loglevel = LTTNG_LOGLEVEL_JUL_ALL;
                                } else if (opt_log4j) {
                                        ev.loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
                                        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;
                                }
                        }
                        ev.type = LTTNG_EVENT_TRACEPOINT;
index ea9427f4770f158458f6e8e79456f2f7d7b6c91b..7c3211a5927ffc2c34a0f3f5e72528be8c8c4575 100644 (file)
@@ -31,6 +31,7 @@ static int opt_userspace;
 static int opt_kernel;
 static int opt_jul;
 static int opt_log4j;
 static int opt_kernel;
 static int opt_jul;
 static int opt_log4j;
+static int opt_python;
 static char *opt_channel;
 static int opt_domain;
 static int opt_fields;
 static char *opt_channel;
 static int opt_domain;
 static int opt_fields;
@@ -60,6 +61,7 @@ static struct poptOption long_options[] = {
        {"kernel",    'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
        {"jul",       'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0},
        {"log4j",     'l', POPT_ARG_VAL, &opt_log4j, 1, 0, 0},
        {"kernel",    'k', POPT_ARG_VAL, &opt_kernel, 1, 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},
 #if 0
        /* Not implemented yet */
        {"userspace",      'u', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_cmd_name, OPT_USERSPACE, 0, 0},
 #if 0
        /* Not implemented yet */
        {"userspace",      'u', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_cmd_name, OPT_USERSPACE, 0, 0},
@@ -93,6 +95,7 @@ static void usage(FILE *ofp)
        fprintf(ofp, "  -u, --userspace         Select user-space domain.\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, "  -u, --userspace         Select user-space domain.\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 using logging\n");
        fprintf(ofp, "  -f, --fields            List event fields.\n");
        fprintf(ofp, "      --syscall           List available system calls.\n");
 #if 0
        fprintf(ofp, "  -f, --fields            List event fields.\n");
        fprintf(ofp, "      --syscall           List available system calls.\n");
 #if 0
@@ -427,6 +430,8 @@ static int list_agent_events(void)
                domain.type = LTTNG_DOMAIN_JUL;
        } else if (opt_log4j) {
                domain.type = LTTNG_DOMAIN_LOG4J;
                domain.type = LTTNG_DOMAIN_JUL;
        } else if (opt_log4j) {
                domain.type = LTTNG_DOMAIN_LOG4J;
+       } else if (opt_python) {
+               domain.type = LTTNG_DOMAIN_PYTHON;
        }
 
        agent_domain_str = get_domain_str(domain.type);
        }
 
        agent_domain_str = get_domain_str(domain.type);
@@ -1469,6 +1474,9 @@ static int list_domains(const char *session_name)
                        case LTTNG_DOMAIN_LOG4J:
                                MSG("  - LOG4j (Logging for Java)");
                                break;
                        case LTTNG_DOMAIN_LOG4J:
                                MSG("  - LOG4j (Logging for Java)");
                                break;
+                       case LTTNG_DOMAIN_PYTHON:
+                               MSG("  - Python (logging)");
+                               break;
                        default:
                                break;
                        }
                        default:
                                break;
                        }
@@ -1561,6 +1569,8 @@ int cmd_list(int argc, const char **argv)
                domain.type = LTTNG_DOMAIN_JUL;
        } else if (opt_log4j) {
                domain.type = LTTNG_DOMAIN_LOG4J;
                domain.type = LTTNG_DOMAIN_JUL;
        } else if (opt_log4j) {
                domain.type = LTTNG_DOMAIN_LOG4J;
+       } else if (opt_python) {
+               domain.type = LTTNG_DOMAIN_PYTHON;
        }
 
        if (!opt_kernel && opt_syscall) {
        }
 
        if (!opt_kernel && opt_syscall) {
@@ -1569,7 +1579,7 @@ int cmd_list(int argc, const char **argv)
                goto end;
        }
 
                goto end;
        }
 
-       if (opt_kernel || opt_userspace || opt_jul || opt_log4j) {
+       if (opt_kernel || opt_userspace || opt_jul || opt_log4j || opt_python) {
                handle = lttng_create_handle(session_name, &domain);
                if (handle == NULL) {
                        ret = CMD_FATAL;
                handle = lttng_create_handle(session_name, &domain);
                if (handle == NULL) {
                        ret = CMD_FATAL;
@@ -1578,7 +1588,8 @@ int cmd_list(int argc, const char **argv)
        }
 
        if (session_name == NULL) {
        }
 
        if (session_name == NULL) {
-               if (!opt_kernel && !opt_userspace && !opt_jul && !opt_log4j) {
+               if (!opt_kernel && !opt_userspace && !opt_jul && !opt_log4j
+                               && !opt_python) {
                        ret = list_sessions(NULL);
                        if (ret) {
                                goto end;
                        ret = list_sessions(NULL);
                        if (ret) {
                                goto end;
@@ -1607,7 +1618,7 @@ int cmd_list(int argc, const char **argv)
                                goto end;
                        }
                }
                                goto end;
                        }
                }
-               if (opt_jul || opt_log4j) {
+               if (opt_jul || opt_log4j || opt_python) {
                        ret = list_agent_events();
                        if (ret) {
                                goto end;
                        ret = list_agent_events();
                        if (ret) {
                                goto end;
@@ -1705,6 +1716,9 @@ int cmd_list(int argc, const char **argv)
                                case LTTNG_DOMAIN_LOG4J:
                                        MSG("=== Domain: LOG4j (Logging for Java) ===\n");
                                        break;
                                case LTTNG_DOMAIN_LOG4J:
                                        MSG("=== Domain: LOG4j (Logging for Java) ===\n");
                                        break;
+                               case LTTNG_DOMAIN_PYTHON:
+                                       MSG("=== Domain: Python (logging) ===\n");
+                                       break;
                                default:
                                        MSG("=== Domain: Unimplemented ===\n");
                                        break;
                                default:
                                        MSG("=== Domain: Unimplemented ===\n");
                                        break;
@@ -1730,7 +1744,8 @@ int cmd_list(int argc, const char **argv)
                                }
 
                                if (domains[i].type == LTTNG_DOMAIN_JUL ||
                                }
 
                                if (domains[i].type == LTTNG_DOMAIN_JUL ||
-                                               domains[i].type == LTTNG_DOMAIN_LOG4J) {
+                                               domains[i].type == LTTNG_DOMAIN_LOG4J ||
+                                               domains[i].type == LTTNG_DOMAIN_PYTHON) {
                                        ret = list_session_agent_events();
                                        if (ret) {
                                                goto end;
                                        ret = list_session_agent_events();
                                        if (ret) {
                                                goto end;
index fc592ebdeee16f68df1a52ad9c0bf2b770ed8466..c518405cae2944c6fd3e6e997f024eed307ad0ff 100644 (file)
@@ -37,6 +37,7 @@ 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_ust = "UST";
 static const char *str_jul = "JUL";
 static const char *str_log4j = "LOG4J";
+static const char *str_python = "Python";
 
 /*
  *  get_session_name
 
 /*
  *  get_session_name
@@ -278,6 +279,9 @@ const char *get_domain_str(enum lttng_domain_type domain)
        case LTTNG_DOMAIN_LOG4J:
                str_dom = str_log4j;
                break;
        case LTTNG_DOMAIN_LOG4J:
                str_dom = str_log4j;
                break;
+       case LTTNG_DOMAIN_PYTHON:
+               str_dom = str_python;
+               break;
        default:
                /* Should not have an unknown domain or else define it. */
                assert(0);
        default:
                /* Should not have an unknown domain or else define it. */
                assert(0);
index e44710b5ae0872b7e3eded59460a6f70865b30f7..feb3334cffbaba06a39c7fd1f24b60835db33bd5 100644 (file)
@@ -118,6 +118,7 @@ const char * const config_domain_type_kernel = "KERNEL";
 const char * const config_domain_type_ust = "UST";
 const char * const config_domain_type_jul = "JUL";
 const char * const config_domain_type_log4j = "LOG4J";
 const char * const config_domain_type_ust = "UST";
 const char * const config_domain_type_jul = "JUL";
 const char * const config_domain_type_log4j = "LOG4J";
+const char * const config_domain_type_python = "PYTHON";
 
 const char * const config_buffer_type_per_pid = "PER_PID";
 const char * const config_buffer_type_per_uid = "PER_UID";
 
 const char * const config_buffer_type_per_pid = "PER_PID";
 const char * const config_buffer_type_per_uid = "PER_UID";
@@ -752,6 +753,8 @@ int get_domain_type(xmlChar *domain)
                ret = LTTNG_DOMAIN_JUL;
        } else if (!strcmp((char *) domain, config_domain_type_log4j)) {
                ret = LTTNG_DOMAIN_LOG4J;
                ret = LTTNG_DOMAIN_JUL;
        } else if (!strcmp((char *) domain, config_domain_type_log4j)) {
                ret = LTTNG_DOMAIN_LOG4J;
+       } else if (!strcmp((char *) domain, config_domain_type_python)) {
+               ret = LTTNG_DOMAIN_PYTHON;
        } else {
                goto error;
        }
        } else {
                goto error;
        }
@@ -2154,6 +2157,7 @@ int process_session_node(xmlNodePtr session_node, const char *session_name,
        struct lttng_domain *ust_domain = NULL;
        struct lttng_domain *jul_domain = NULL;
        struct lttng_domain *log4j_domain = NULL;
        struct lttng_domain *ust_domain = NULL;
        struct lttng_domain *jul_domain = NULL;
        struct lttng_domain *log4j_domain = NULL;
+       struct lttng_domain *python_domain = NULL;
 
        for (node = xmlFirstElementChild(session_node); node;
                node = xmlNextElementSibling(node)) {
 
        for (node = xmlFirstElementChild(session_node); node;
                node = xmlNextElementSibling(node)) {
@@ -2287,6 +2291,13 @@ int process_session_node(xmlNodePtr session_node, const char *session_name,
                        }
                        log4j_domain = domain;
                        break;
                        }
                        log4j_domain = domain;
                        break;
+               case LTTNG_DOMAIN_PYTHON:
+                       if (python_domain) {
+                               /* Same domain seen twice, invalid! */
+                               goto domain_init_error;
+                       }
+                       python_domain = domain;
+                       break;
                default:
                        WARN("Invalid domain type");
                        goto domain_init_error;
                default:
                        WARN("Invalid domain type");
                        goto domain_init_error;
index 3023216ea23e23eff437b9c52e96892e7a151d40..6d74e85f78744f6d30935c2a6d45dd0dc317cf43 100644 (file)
@@ -193,6 +193,7 @@ elementFormDefault="qualified" version="2.5">
                <xs:enumeration value="UST"/>
                <xs:enumeration value="JUL"/>
                <xs:enumeration value="LOG4J"/>
                <xs:enumeration value="UST"/>
                <xs:enumeration value="JUL"/>
                <xs:enumeration value="LOG4J"/>
+               <xs:enumeration value="PYTHON"/>
        </xs:restriction>
 </xs:simpleType>
 
        </xs:restriction>
 </xs:simpleType>
 
index 25d7b327b02799f2ce8dc39ed05a8ad64271bad4..c7e801d14d79bd8aadfa52bcd2bee01f69fce2a9 100644 (file)
 #define DEFAULT_SYS_LOG4J_EVENT_NAME      "lttng_log4j:sys*"
 #define DEFAULT_USER_LOG4J_EVENT_NAME     "lttng_log4j:user*"
 
 #define DEFAULT_SYS_LOG4J_EVENT_NAME      "lttng_log4j:sys*"
 #define DEFAULT_USER_LOG4J_EVENT_NAME     "lttng_log4j:user*"
 
-/* JUL default channel name. */
+/* Default Python domain channel name. */
+#define DEFAULT_PYTHON_CHANNEL_NAME       "lttng_python_channel"
+/* Default Python tracepoint name. This is a wildcard for the python domain. */
+#define DEFAULT_USER_PYTHON_EVENT_NAME    "lttng_python:user*"
+
 #define DEFAULT_CHANNEL_OVERWRITE       0
 #define DEFAULT_CHANNEL_TRACEFILE_SIZE  0
 #define DEFAULT_CHANNEL_TRACEFILE_COUNT 0
 #define DEFAULT_CHANNEL_OVERWRITE       0
 #define DEFAULT_CHANNEL_TRACEFILE_SIZE  0
 #define DEFAULT_CHANNEL_TRACEFILE_COUNT 0
index c21ed5a6311491cd875d246c6d4244fb8dda26f9..882afc1b6e5a3828cf029f1f4f19aa7133a14bd5 100644 (file)
@@ -135,6 +135,14 @@ const char * const mi_lttng_loglevel_str_log4j_debug = "LOG4J_DEBUG";
 const char * const mi_lttng_loglevel_str_log4j_trace = "LOG4J_TRACE";
 const char * const mi_lttng_loglevel_str_log4j_all = "LOG4J_ALL";
 
 const char * const mi_lttng_loglevel_str_log4j_trace = "LOG4J_TRACE";
 const char * const mi_lttng_loglevel_str_log4j_all = "LOG4J_ALL";
 
+/* String related to loglevel Python */
+const char * const mi_lttng_loglevel_str_python_critical = "PYTHON_CRITICAL";
+const char * const mi_lttng_loglevel_str_python_error = "PYTHON_ERROR";
+const char * const mi_lttng_loglevel_str_python_warning = "PYTHON_WARNING";
+const char * const mi_lttng_loglevel_str_python_info = "PYTHON_INFO";
+const char * const mi_lttng_loglevel_str_python_debug = "PYTHON_DEBUG";
+const char * const mi_lttng_loglevel_str_python_notset = "PYTHON_NOTSET";
+
 /* String related to loglevel type */
 const char * const mi_lttng_loglevel_type_all = "ALL";
 const char * const mi_lttng_loglevel_type_range = "RANGE";
 /* String related to loglevel type */
 const char * const mi_lttng_loglevel_type_all = "ALL";
 const char * const mi_lttng_loglevel_type_range = "RANGE";
@@ -250,6 +258,24 @@ const char *mi_lttng_loglevel_string(int value, enum lttng_domain_type domain)
                        return mi_lttng_loglevel_str_unknown;
                }
                break;
                        return mi_lttng_loglevel_str_unknown;
                }
                break;
+       case LTTNG_DOMAIN_PYTHON:
+               switch (value) {
+               case LTTNG_LOGLEVEL_PYTHON_CRITICAL:
+                       return mi_lttng_loglevel_str_python_critical;
+               case LTTNG_LOGLEVEL_PYTHON_ERROR:
+                       return mi_lttng_loglevel_str_python_error;
+               case LTTNG_LOGLEVEL_PYTHON_WARNING:
+                       return mi_lttng_loglevel_str_python_warning;
+               case LTTNG_LOGLEVEL_PYTHON_INFO:
+                       return mi_lttng_loglevel_str_python_info;
+               case LTTNG_LOGLEVEL_PYTHON_DEBUG:
+                       return mi_lttng_loglevel_str_python_debug;
+               case LTTNG_LOGLEVEL_PYTHON_NOTSET:
+                       return mi_lttng_loglevel_str_python_notset;
+               default:
+                       return mi_lttng_loglevel_str_unknown;
+               }
+               break;
        }
 
        /* Reaching this means the domain is unknown. */
        }
 
        /* Reaching this means the domain is unknown. */
index a181e0b1045cc9fd95c8d5880f3f985c51b1a80b..fd1ef936eb4167fb409c4c34a5cb5f55ac7b9d42 100644 (file)
@@ -159,6 +159,14 @@ const char * const mi_lttng_loglevel_str_log4j_debug;
 const char * const mi_lttng_loglevel_str_log4j_trace;
 const char * const mi_lttng_loglevel_str_log4j_all;
 
 const char * const mi_lttng_loglevel_str_log4j_trace;
 const char * const mi_lttng_loglevel_str_log4j_all;
 
+/* String related to loglevel Python */
+const char * const mi_lttng_loglevel_str_python_critical;
+const char * const mi_lttng_loglevel_str_python_error;
+const char * const mi_lttng_loglevel_str_python_warning;
+const char * const mi_lttng_loglevel_str_python_info;
+const char * const mi_lttng_loglevel_str_python_debug;
+const char * const mi_lttng_loglevel_str_python_notset;
+
 /* String related to loglevel type */
 const char * const mi_lttng_loglevel_type_all;
 const char * const mi_lttng_loglevel_type_range;
 /* String related to loglevel type */
 const char * const mi_lttng_loglevel_type_all;
 const char * const mi_lttng_loglevel_type_range;
index f5fc7293c044c9156aeb945b48ecf97b21578d72..3f0894e83960bd1a80f88cedbfc186a6d4288405 100644 (file)
@@ -140,6 +140,12 @@ THE SOFTWARE.
                        <xs:enumeration value="LOG4J_DEBUG" />
                        <xs:enumeration value="LOG4J_TRACE" />
                        <xs:enumeration value="LOG4J_ALL" />
                        <xs:enumeration value="LOG4J_DEBUG" />
                        <xs:enumeration value="LOG4J_TRACE" />
                        <xs:enumeration value="LOG4J_ALL" />
+                       <xs:enumeration value="PYTHON_CRITICAL" />
+                       <xs:enumeration value="PYTHON_ERROR" />
+                       <xs:enumeration value="PYTHON_WARNING" />
+                       <xs:enumeration value="PYTHON_INFO" />
+                       <xs:enumeration value="PYTHON_DEBUG" />
+                       <xs:enumeration value="PYTHON_NOTSET" />
                        <xs:enumeration value="UNKNOWN" />
                </xs:restriction>
        </xs:simpleType>
                        <xs:enumeration value="UNKNOWN" />
                </xs:restriction>
        </xs:simpleType>
@@ -228,6 +234,7 @@ THE SOFTWARE.
                        <xs:enumeration value="UST"/>
                        <xs:enumeration value="JUL"/>
                        <xs:enumeration value="LOG4J"/>
                        <xs:enumeration value="UST"/>
                        <xs:enumeration value="JUL"/>
                        <xs:enumeration value="LOG4J"/>
+                       <xs:enumeration value="PYTHON"/>
                </xs:restriction>
        </xs:simpleType>
 
                </xs:restriction>
        </xs:simpleType>
 
index ff57a0d1a7a70237e396274b8a4847f1194beb3d..aae0e4fa5708ed4fd6c6416d5074c867da4bc62f 100644 (file)
@@ -106,6 +106,7 @@ void lttng_ctl_copy_lttng_domain(struct lttng_domain *dst,
                case LTTNG_DOMAIN_UST:
                case LTTNG_DOMAIN_JUL:
                case LTTNG_DOMAIN_LOG4J:
                case LTTNG_DOMAIN_UST:
                case LTTNG_DOMAIN_JUL:
                case LTTNG_DOMAIN_LOG4J:
+               case LTTNG_DOMAIN_PYTHON:
                        memcpy(dst, src, sizeof(struct lttng_domain));
                        break;
                default:
                        memcpy(dst, src, sizeof(struct lttng_domain));
                        break;
                default:
@@ -690,25 +691,25 @@ int lttng_enable_event_with_filter(struct lttng_handle *handle,
 }
 
 /*
 }
 
 /*
- * Depending on the event, return a newly allocated JUL filter expression or
+ * Depending on the event, return a newly allocated agent filter expression or
  * NULL if not applicable.
  *
  * An event with NO loglevel and the name is * will return NULL.
  */
  * NULL if not applicable.
  *
  * An event with NO loglevel and the name is * will return NULL.
  */
-static char *set_jul_filter(const char *filter, struct lttng_event *ev)
+static char *set_agent_filter(const char *filter, struct lttng_event *ev)
 {
        int err;
 {
        int err;
-       char *jul_filter = NULL;
+       char *agent_filter = NULL;
 
        assert(ev);
 
        /* Don't add filter for the '*' event. */
        if (ev->name[0] != '*') {
                if (filter) {
 
        assert(ev);
 
        /* Don't add filter for the '*' event. */
        if (ev->name[0] != '*') {
                if (filter) {
-                       err = asprintf(&jul_filter, "(%s) && (logger_name == \"%s\")", filter,
+                       err = asprintf(&agent_filter, "(%s) && (logger_name == \"%s\")", filter,
                                        ev->name);
                } else {
                                        ev->name);
                } else {
-                       err = asprintf(&jul_filter, "logger_name == \"%s\"", ev->name);
+                       err = asprintf(&agent_filter, "logger_name == \"%s\"", ev->name);
                }
                if (err < 0) {
                        PERROR("asprintf");
                }
                if (err < 0) {
                        PERROR("asprintf");
@@ -726,18 +727,18 @@ static char *set_jul_filter(const char *filter, struct lttng_event *ev)
                        op = "==";
                }
 
                        op = "==";
                }
 
-               if (filter || jul_filter) {
+               if (filter || agent_filter) {
                        char *new_filter;
 
                        err = asprintf(&new_filter, "(%s) && (int_loglevel %s %d)",
                        char *new_filter;
 
                        err = asprintf(&new_filter, "(%s) && (int_loglevel %s %d)",
-                                       jul_filter ? jul_filter : filter, op,
+                                       agent_filter ? agent_filter : filter, op,
                                        ev->loglevel);
                                        ev->loglevel);
-                       if (jul_filter) {
-                               free(jul_filter);
+                       if (agent_filter) {
+                               free(agent_filter);
                        }
                        }
-                       jul_filter = new_filter;
+                       agent_filter = new_filter;
                } else {
                } else {
-                       err = asprintf(&jul_filter, "int_loglevel %s %d", op,
+                       err = asprintf(&agent_filter, "int_loglevel %s %d", op,
                                        ev->loglevel);
                }
                if (err < 0) {
                                        ev->loglevel);
                }
                if (err < 0) {
@@ -746,9 +747,9 @@ static char *set_jul_filter(const char *filter, struct lttng_event *ev)
                }
        }
 
                }
        }
 
-       return jul_filter;
+       return agent_filter;
 error:
 error:
-       free(jul_filter);
+       free(agent_filter);
        return NULL;
 }
 
        return NULL;
 }
 
@@ -941,7 +942,8 @@ int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
         */
        if (exclusion_count == 0 && filter_expression == NULL &&
                        (handle->domain.type != LTTNG_DOMAIN_JUL &&
         */
        if (exclusion_count == 0 && filter_expression == NULL &&
                        (handle->domain.type != LTTNG_DOMAIN_JUL &&
-                               handle->domain.type != LTTNG_DOMAIN_LOG4J)) {
+                               handle->domain.type != LTTNG_DOMAIN_LOG4J &&
+                               handle->domain.type != LTTNG_DOMAIN_PYTHON)) {
                goto ask_sessiond;
        }
 
                goto ask_sessiond;
        }
 
@@ -952,24 +954,26 @@ int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
 
        /* Parse filter expression */
        if (filter_expression != NULL || handle->domain.type == LTTNG_DOMAIN_JUL
 
        /* Parse filter expression */
        if (filter_expression != NULL || handle->domain.type == LTTNG_DOMAIN_JUL
-                       || handle->domain.type == LTTNG_DOMAIN_LOG4J) {
+                       || handle->domain.type == LTTNG_DOMAIN_LOG4J
+                       || handle->domain.type == LTTNG_DOMAIN_PYTHON) {
                if (handle->domain.type == LTTNG_DOMAIN_JUL ||
                if (handle->domain.type == LTTNG_DOMAIN_JUL ||
-                               handle->domain.type == LTTNG_DOMAIN_LOG4J) {
-                       char *jul_filter;
+                               handle->domain.type == LTTNG_DOMAIN_LOG4J ||
+                               handle->domain.type == LTTNG_DOMAIN_PYTHON) {
+                       char *agent_filter;
 
                        /* Setup JUL filter if needed. */
 
                        /* Setup JUL filter if needed. */
-                       jul_filter = set_jul_filter(filter_expression, ev);
-                       if (!jul_filter) {
+                       agent_filter = set_agent_filter(filter_expression, ev);
+                       if (!agent_filter) {
                                if (!filter_expression) {
                                        /* No JUL and no filter, just skip everything below. */
                                        goto ask_sessiond;
                                }
                        } else {
                                /*
                                if (!filter_expression) {
                                        /* No JUL and no filter, just skip everything below. */
                                        goto ask_sessiond;
                                }
                        } else {
                                /*
-                                * With a JUL filter, the original filter has been added to it
-                                * thus replace the filter expression.
+                                * With an agent filter, the original filter has been added to
+                                * it thus replace the filter expression.
                                 */
                                 */
-                               filter_expression = jul_filter;
+                               filter_expression = agent_filter;
                                free_filter_expression = 1;
                        }
                }
                                free_filter_expression = 1;
                        }
                }
@@ -1102,7 +1106,8 @@ int lttng_disable_event_ext(struct lttng_handle *handle,
         */
        if (filter_expression == NULL &&
                        (handle->domain.type != LTTNG_DOMAIN_JUL &&
         */
        if (filter_expression == NULL &&
                        (handle->domain.type != LTTNG_DOMAIN_JUL &&
-                               handle->domain.type != LTTNG_DOMAIN_LOG4J)) {
+                               handle->domain.type != LTTNG_DOMAIN_LOG4J &&
+                               handle->domain.type != LTTNG_DOMAIN_PYTHON)) {
                goto ask_sessiond;
        }
 
                goto ask_sessiond;
        }
 
@@ -1113,14 +1118,16 @@ int lttng_disable_event_ext(struct lttng_handle *handle,
 
        /* Parse filter expression */
        if (filter_expression != NULL || handle->domain.type == LTTNG_DOMAIN_JUL
 
        /* Parse filter expression */
        if (filter_expression != NULL || handle->domain.type == LTTNG_DOMAIN_JUL
-                       || handle->domain.type == LTTNG_DOMAIN_LOG4J) {
+                       || handle->domain.type == LTTNG_DOMAIN_LOG4J
+                       || handle->domain.type == LTTNG_DOMAIN_PYTHON) {
                if (handle->domain.type == LTTNG_DOMAIN_JUL ||
                if (handle->domain.type == LTTNG_DOMAIN_JUL ||
-                               handle->domain.type == LTTNG_DOMAIN_LOG4J) {
-                       char *jul_filter;
+                               handle->domain.type == LTTNG_DOMAIN_LOG4J ||
+                               handle->domain.type == LTTNG_DOMAIN_PYTHON) {
+                       char *agent_filter;
 
                        /* Setup JUL filter if needed. */
 
                        /* Setup JUL filter if needed. */
-                       jul_filter = set_jul_filter(filter_expression, ev);
-                       if (!jul_filter) {
+                       agent_filter = set_agent_filter(filter_expression, ev);
+                       if (!agent_filter) {
                                if (!filter_expression) {
                                        /* No JUL and no filter, just skip everything below. */
                                        goto ask_sessiond;
                                if (!filter_expression) {
                                        /* No JUL and no filter, just skip everything below. */
                                        goto ask_sessiond;
@@ -1130,7 +1137,7 @@ int lttng_disable_event_ext(struct lttng_handle *handle,
                                 * With a JUL filter, the original filter has been added to it
                                 * thus replace the filter expression.
                                 */
                                 * With a JUL filter, the original filter has been added to it
                                 * thus replace the filter expression.
                                 */
-                               filter_expression = jul_filter;
+                               filter_expression = agent_filter;
                                free_filter_expression = 1;
                        }
                }
                                free_filter_expression = 1;
                        }
                }
index af478abda65c199813513c7a04e08d87edaca654..c14f7f215b57eed3d01003b5c01655ab9951f9d1 100644 (file)
@@ -21,6 +21,7 @@ regression/ust/nprocesses/test_nprocesses
 regression/ust/overlap/test_overlap
 regression/ust/java-jul/test_java_jul
 regression/ust/java-log4j/test_java_log4j
 regression/ust/overlap/test_overlap
 regression/ust/java-jul/test_java_jul
 regression/ust/java-log4j/test_java_log4j
+regression/ust/python-logging/test_python_logging
 regression/ust/test_event_basic
 regression/ust/test_event_tracef
 regression/ust/test_event_wildcard
 regression/ust/test_event_basic
 regression/ust/test_event_tracef
 regression/ust/test_event_wildcard
index 273994a770ed05e380dbaebfa24f8ccad01230fa..0d11f90883da89d9fa1849fdc6d3fdb0e5eb4275 100644 (file)
@@ -1,7 +1,7 @@
 if HAVE_LIBLTTNG_UST_CTL
 SUBDIRS = nprocesses high-throughput low-throughput before-after multi-session \
                overlap buffers-pid linking daemon exit-fast fork libc-wrapper \
 if HAVE_LIBLTTNG_UST_CTL
 SUBDIRS = nprocesses high-throughput low-throughput before-after multi-session \
                overlap buffers-pid linking daemon exit-fast fork libc-wrapper \
-               periodical-metadata-flush java-jul java-log4j
+               periodical-metadata-flush java-jul java-log4j python-logging
 
 EXTRA_DIST = test_event_basic test_event_wildcard test_event_tracef test_event_perf
 
 
 EXTRA_DIST = test_event_basic test_event_wildcard test_event_tracef test_event_perf
 
diff --git a/tests/regression/ust/python-logging/LTTngTest.py b/tests/regression/ust/python-logging/LTTngTest.py
new file mode 100644 (file)
index 0000000..a3ed8f9
--- /dev/null
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2014 - David Goulet <dgoulet@efficios.com>
+#
+# This library is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; version 2.1 of the License.
+#
+# This library 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 Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+
+import sys
+import logging
+import errno
+
+from time import sleep
+
+def cleanup(code, agent = None):
+    """
+    Cleanup agent and exit with given code.
+    """
+    if agent is not None:
+        agent.destroy()
+
+    sys.exit(code)
+
+try:
+    import lttng_agent
+except ImportError as e:
+    print("LTTng Agent not found. Aborting")
+    cleanup(errno.ENOSYS)
+
+def run():
+    """
+    Main for this test program. Based on the Java testing program that behaves
+    exactly the same.
+    """
+
+    agent = lttng_agent.LTTngAgent()
+    ev1 = logging.getLogger("python-ev-test1");
+    ev2 = logging.getLogger("python-ev-test2");
+
+    try:
+        nr_iter = int(sys.argv[1])
+        wait_time = int(sys.argv[2])
+        fire_debug_ev = 0
+        fire_second_ev = 0
+    except IndexError as e:
+        print("Missing arguments. Aborting")
+        cleanup(errno.EINVAL, agent)
+    except ValueError as e:
+        print("Invalid arguments. Aborting")
+        cleanup(errno.EINVAL, agent)
+
+    if len(sys.argv) > 3:
+        fire_debug_ev = int(sys.argv[3])
+    if len(sys.argv) > 4:
+        fire_second_ev = int(sys.argv[4])
+
+    for i in range(0, nr_iter):
+        ev1.info("%s fired" % ev1.name)
+        if fire_debug_ev != 0:
+            ev1.debug("%s DEBUG fired" % ev1.name)
+        sleep(wait_time)
+
+    if fire_second_ev != 0:
+        ev2.info("%s fired" % ev2.name)
+
+if __name__ == "__main__":
+    run()
diff --git a/tests/regression/ust/python-logging/Makefile.am b/tests/regression/ust/python-logging/Makefile.am
new file mode 100644 (file)
index 0000000..34a8dee
--- /dev/null
@@ -0,0 +1,21 @@
+#if USE_PYTHON
+
+noinst_SCRIPTS = test_python_logging
+EXTRA_DIST = test_python_logging LTTngPython.py
+
+all-local:
+       @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
+               for script in $(EXTRA_DIST); do \
+                       cp -f $(srcdir)/$$script $(builddir); \
+               done; \
+       fi
+
+clean-local:
+       rm -f *.class
+       @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
+               for script in $(EXTRA_DIST); do \
+                       rm -f $(builddir)/$$script; \
+               done; \
+       fi
+
+#endif
diff --git a/tests/regression/ust/python-logging/test_python_logging b/tests/regression/ust/python-logging/test_python_logging
new file mode 100755 (executable)
index 0000000..b2fa6fb
--- /dev/null
@@ -0,0 +1,593 @@
+#!/bin/bash
+#
+# Copyright (C) - 2014 David Goulet <dgoulet@efficios.com>
+#
+# 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.
+#
+# 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.
+
+TEST_DESC="Java Python support"
+
+CURDIR=$(dirname $0)/
+TESTDIR=$CURDIR/../../..
+NR_ITER=5
+NR_SEC_WAIT=1
+TESTAPP_NAME="LTTngTest"
+TESTAPP_BIN="$TESTAPP_NAME.py"
+TESTAPP_PATH="$CURDIR"
+SESSION_NAME="python-test"
+EVENT_NAME="python-ev-test1"
+EVENT_NAME2="python-ev-test2"
+OUTPUT_DEST="/dev/null"
+
+NUM_TESTS=156
+
+source $TESTDIR/utils/utils.sh
+
+function run_app
+{
+       local debug_tp=$1
+       local fire_second_tp=$2
+
+       python $TESTAPP_PATH/$TESTAPP_BIN $NR_ITER $NR_SEC_WAIT $debug_tp $fire_second_tp
+}
+
+function run_app_background
+{
+       run_app $@ &
+}
+
+function enable_python_loglevel_only()
+{
+       sess_name=$1
+       event_name="$2"
+       loglevel=$3
+       channel_name=$4
+
+       if [ -z $channel_name ]; then
+               # default channel if none specified
+               chan=""
+       else
+               chan="-c $channel_name"
+       fi
+
+       $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event --loglevel-only $loglevel "$event_name" $chan -s $sess_name -p >$OUTPUT_DEST
+       ok $? "Enable Python event $event_name for session $sess_name with loglevel-only $loglevel"
+}
+
+function enable_python_filter()
+{
+       local sess_name="$1"
+       local event_name="$2"
+       local filter="$3"
+
+       $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event "$event_name" -s $sess_name -p --filter "$filter" >/dev/null 2>&1
+       ok $? "Enable event $event_name with filter $filter for session $sess_name"
+}
+
+function enable_python_filter_loglevel_only()
+{
+       local sess_name="$1"
+       local event_name="$2"
+       local filter="$3"
+       local loglevel="$4"
+
+       $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event --loglevel-only $loglevel "$event_name" -s $sess_name -p --filter "$filter" >$OUTPUT_DEST
+       ok $? "Enable event $event_name with filter \"$filter\" and loglevel-only $loglevel for session $sess_name"
+}
+
+# MUST set TESTDIR before calling those functions
+
+function test_python_before_start ()
+{
+       diag "Test Python application BEFORE tracing starts"
+       create_lttng_session $SESSION_NAME $TRACE_PATH
+       enable_python_lttng_event $SESSION_NAME $EVENT_NAME
+
+       # Run 5 times with a 1 second delay
+       run_app_background
+
+       start_lttng_tracing $SESSION_NAME
+
+       # Wait for the applications started in background
+       wait ${!}
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting all events.
+       trace_match_only $EVENT_NAME $NR_ITER $TRACE_PATH
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_after_start ()
+{
+       diag "Test Python application AFTER tracing starts"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH
+       enable_python_lttng_event $SESSION_NAME $EVENT_NAME
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay
+       run_app
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting all events.
+       trace_match_only $EVENT_NAME $NR_ITER $TRACE_PATH
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_loglevel ()
+{
+       diag "Test Python application with loglevel"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH
+       enable_python_lttng_event_loglevel $SESSION_NAME $EVENT_NAME "INFO"
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay
+       run_app
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting all events.
+       trace_match_only $EVENT_NAME $NR_ITER $TRACE_PATH
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       diag "Test Python applications with lower loglevel"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH
+       enable_python_lttng_event_loglevel $SESSION_NAME $EVENT_NAME "CRITICAL"
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay
+       run_app
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting 0 events.
+       trace_match_only $EVENT_NAME 0 $TRACE_PATH
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       diag "Test Python applications with higher loglevel"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH
+       enable_python_lttng_event_loglevel $SESSION_NAME $EVENT_NAME "DEBUG"
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay
+       run_app
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting all events.
+       trace_match_only $EVENT_NAME $NR_ITER $TRACE_PATH
+       return $?
+}
+
+function test_python_loglevel_multiple ()
+{
+       diag "Test Python application with multiple loglevel"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH
+       enable_python_lttng_event_loglevel $SESSION_NAME $EVENT_NAME "INFO"
+       enable_python_lttng_event_loglevel $SESSION_NAME $EVENT_NAME "DEBUG"
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay and fire two TP.
+       run_app 1
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting all events times two.
+       trace_match_only $EVENT_NAME $(($NR_ITER * 2)) $TRACE_PATH
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH
+       enable_python_lttng_event_loglevel $SESSION_NAME '*' "INFO"
+       enable_python_lttng_event_loglevel $SESSION_NAME '*' "DEBUG"
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay and fire two TP.
+       run_app 1
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting all events times two.
+       trace_match_only $EVENT_NAME $(($NR_ITER * 2)) $TRACE_PATH
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_multi_session_loglevel()
+{
+       diag "Test Python with multiple session"
+
+       create_lttng_session $SESSION_NAME-1 $TRACE_PATH/$SESSION_NAME-1
+       enable_python_loglevel_only $SESSION_NAME-1 '*' "INFO"
+       start_lttng_tracing $SESSION_NAME-1
+
+       create_lttng_session $SESSION_NAME-2 $TRACE_PATH/$SESSION_NAME-2
+       enable_python_loglevel_only $SESSION_NAME-2 '*' "DEBUG"
+       start_lttng_tracing $SESSION_NAME-2
+
+       # Run 5 times with a 1 second delay and fire second TP.
+       run_app 1 1
+
+       stop_lttng_tracing $SESSION_NAME-1
+       stop_lttng_tracing $SESSION_NAME-2
+       destroy_lttng_session $SESSION_NAME-1
+       destroy_lttng_session $SESSION_NAME-2
+
+       # Expecting NR_ITER events being the main event and the second tp one.
+       trace_matches $EVENT_NAME $NR_ITER $TRACE_PATH/$SESSION_NAME-1
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+       trace_matches $EVENT_NAME2 1 $TRACE_PATH/$SESSION_NAME-1
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       # Expectin NR_ITER events being the debug TP.
+       trace_match_only $EVENT_NAME $NR_ITER $TRACE_PATH/$SESSION_NAME-2
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_multi_session_disable()
+{
+       diag "Test Python with multiple session with disabled event"
+
+       create_lttng_session $SESSION_NAME-1 $TRACE_PATH/$SESSION_NAME-1
+       enable_python_lttng_event $SESSION_NAME-1 $EVENT_NAME
+       enable_python_lttng_event $SESSION_NAME-1 $EVENT_NAME2
+       disable_python_lttng_event $SESSION_NAME-1 $EVENT_NAME
+       start_lttng_tracing $SESSION_NAME-1
+
+       create_lttng_session $SESSION_NAME-2 $TRACE_PATH/$SESSION_NAME-2
+       enable_python_lttng_event $SESSION_NAME-2 $EVENT_NAME2
+       start_lttng_tracing $SESSION_NAME-2
+
+       # Run 5 times with a 1 second delay and fire second TP.
+       run_app 0 1
+
+       stop_lttng_tracing $SESSION_NAME-1
+       stop_lttng_tracing $SESSION_NAME-2
+       destroy_lttng_session $SESSION_NAME-1
+       destroy_lttng_session $SESSION_NAME-2
+
+       # Validate test. Expecting one event of the second TP.
+       trace_match_only $EVENT_NAME2 1 $TRACE_PATH/$SESSION_NAME-1
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       # Validate test. Expecting one event of the second TP.
+       trace_match_only $EVENT_NAME2 1 $TRACE_PATH/$SESSION_NAME-2
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_multi_session_disable_wildcard()
+{
+       diag "Test Python with multiple session with disabled wildcard event"
+
+       create_lttng_session $SESSION_NAME-1 $TRACE_PATH/$SESSION_NAME-1
+       enable_python_lttng_event $SESSION_NAME-1 '*'
+
+       create_lttng_session $SESSION_NAME-2 $TRACE_PATH/$SESSION_NAME-2
+       enable_python_lttng_event $SESSION_NAME-2 '*'
+
+       disable_python_lttng_event $SESSION_NAME-1 '*'
+
+       start_lttng_tracing $SESSION_NAME-1
+       start_lttng_tracing $SESSION_NAME-2
+
+       run_app
+
+       stop_lttng_tracing $SESSION_NAME-1
+       stop_lttng_tracing $SESSION_NAME-2
+       destroy_lttng_session $SESSION_NAME-1
+       destroy_lttng_session $SESSION_NAME-2
+
+       # Validate test. Expecting NO event of the first TP.
+       trace_match_only $EVENT_NAME 0 $TRACE_PATH/$SESSION_NAME-1
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       # Validate test. Expecting all events of the first TP.
+       trace_match_only $EVENT_NAME $NR_ITER $TRACE_PATH/$SESSION_NAME-2
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_disable_all()
+{
+       diag "Test Python with multiple session with disabled all event"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH/$SESSION_NAME
+       enable_python_lttng_event $SESSION_NAME '*'
+       enable_python_lttng_event $SESSION_NAME $EVENT_NAME
+       enable_python_lttng_event $SESSION_NAME $EVENT_NAME2
+
+       disable_python_lttng_event $SESSION_NAME '*'
+
+       start_lttng_tracing $SESSION_NAME
+
+       run_app 0 1
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting NO event of the first TP and second TP.
+       trace_match_only $EVENT_NAME 0 $TRACE_PATH/$SESSION_NAME
+       trace_match_only $EVENT_NAME2 0 $TRACE_PATH/$SESSION_NAME
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_multi_session()
+{
+       diag "Test Python with multiple session"
+
+       create_lttng_session $SESSION_NAME-1 $TRACE_PATH/$SESSION_NAME-1
+       enable_python_lttng_event $SESSION_NAME-1 $EVENT_NAME
+       start_lttng_tracing $SESSION_NAME-1
+
+       create_lttng_session $SESSION_NAME-2 $TRACE_PATH/$SESSION_NAME-2
+       enable_python_lttng_event $SESSION_NAME-2 $EVENT_NAME2
+       start_lttng_tracing $SESSION_NAME-2
+
+       # Run 5 times with a 1 second delay and fire second TP.
+       run_app 0 1
+
+       stop_lttng_tracing $SESSION_NAME-1
+       stop_lttng_tracing $SESSION_NAME-2
+       destroy_lttng_session $SESSION_NAME-1
+       destroy_lttng_session $SESSION_NAME-2
+
+       # Validate test. Expecting all events of first TP
+       trace_match_only $EVENT_NAME $NR_ITER $TRACE_PATH/$SESSION_NAME-1
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       # Validate test. Expecting one event of the second TP.
+       trace_match_only $EVENT_NAME2 1 $TRACE_PATH/$SESSION_NAME-2
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_destroy_session()
+{
+       diag "Test Python two session with destroy"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH/first-sess
+       enable_python_lttng_event $SESSION_NAME $EVENT_NAME
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay
+       run_app_background 0 1
+
+       sleep 1
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting at least one event num 1
+       validate_trace $EVENT_NAME $TRACE_PATH/first-sess
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH/second-sess
+       enable_python_lttng_event $SESSION_NAME $EVENT_NAME2
+       start_lttng_tracing $SESSION_NAME
+
+       # Wait for the applications started in background
+       wait ${!}
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting only one event num 2
+       trace_match_only $EVENT_NAME2 1 $TRACE_PATH/second-sess
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_filtering()
+{
+       diag "Test Python filtering"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH/$SESSION_NAME
+       # Enable all event with a filter.
+       enable_python_filter $SESSION_NAME '*' 'msg == "python-ev-test2 fired"'
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay and fire second TP.
+       run_app 0 1
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting one event of the second TP only.
+       trace_match_only $EVENT_NAME2 1 $TRACE_PATH/$SESSION_NAME
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH/$SESSION_NAME
+       # Enable first Logger but filter msg payload for the INFO one while
+       # triggering the debug and second TP.
+       enable_python_filter $SESSION_NAME $EVENT_NAME 'msg == "python-ev-test1 fired"'
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay, fire debug and second TP.
+       run_app 1 1
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting NR_ITER event of the main INFO tp.
+       trace_match_only $EVENT_NAME $NR_ITER $TRACE_PATH/$SESSION_NAME
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_disable()
+{
+       diag "Test Python disable event"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH/$SESSION_NAME
+       # Enable all event with a filter.
+       enable_python_lttng_event $SESSION_NAME $EVENT_NAME
+       enable_python_lttng_event $SESSION_NAME $EVENT_NAME2
+       disable_python_lttng_event $SESSION_NAME $EVENT_NAME
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay and fire second TP.
+       run_app 0 1
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting one event of the second TP only.
+       trace_match_only $EVENT_NAME2 1 $TRACE_PATH/$SESSION_NAME
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_disable_enable()
+{
+       diag "Test Python disable event followed by an enable"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH/$SESSION_NAME
+       # Enable all event with a filter.
+       enable_python_lttng_event $SESSION_NAME $EVENT_NAME
+       disable_python_lttng_event $SESSION_NAME $EVENT_NAME
+       enable_python_lttng_event $SESSION_NAME $EVENT_NAME
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay and fire second TP.
+       run_app 0 1
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting NR_ITER event of the main INFO tp.
+       trace_match_only $EVENT_NAME $NR_ITER $TRACE_PATH/$SESSION_NAME
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_python_filter_loglevel()
+{
+       local BOGUS_EVENT_NAME="not_a_real_event"
+       local FILTER="int_loglevel > 30 || int_loglevel < 30"
+       local ALL_EVENTS="."
+
+       diag "Test Python a filter with a loglevel"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH/$SESSION_NAME
+       # Enable an event with a filter and the loglevel-only option.
+       enable_python_filter_loglevel_only $SESSION_NAME $BOGUS_EVENT_NAME "$FILTER" "INFO"
+       disable_python_lttng_event $SESSION_NAME $BOGUS_EVENT_NAME
+       enable_python_filter_loglevel_only $SESSION_NAME $BOGUS_EVENT_NAME "$FILTER" "INFO"
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay and fire second TP.
+       run_app 0 1
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting no events.
+       trace_match_only $ALL_EVENTS 0 $TRACE_PATH/$SESSION_NAME
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+plan_tests $NUM_TESTS
+
+print_test_banner "$TEST_DESC"
+
+if [ ! -f "$TESTAPP_BIN" ]; then
+       withapp=0
+else
+       withapp=1
+fi
+
+skip $withapp "Python support is needed. Skipping all tests." $NUM_TESTS ||
+{
+       start_lttng_sessiond
+
+       tests=(
+               test_python_multi_session_disable_wildcard
+               test_python_multi_session_disable
+               test_python_disable
+               test_python_disable_enable
+               test_python_disable_all
+               test_python_filtering
+               test_python_multi_session_loglevel
+               test_python_destroy_session
+               test_python_loglevel
+               test_python_loglevel_multiple
+               test_python_before_start
+               test_python_after_start
+               test_python_multi_session
+               test_python_filter_loglevel
+       )
+
+       for fct_test in ${tests[@]};
+       do
+               TRACE_PATH=$(mktemp -d)
+
+               ${fct_test}
+               if [ $? -ne 0 ]; then
+                       break;
+               fi
+               rm -rf $TRACE_PATH
+       done
+
+       stop_lttng_sessiond
+}
index e2cd7f881630b3013cb7e40e3990f1f18f64ee24..fe75461fc8603aafce928db1b292ae2cd2a3ea85 100644 (file)
@@ -514,6 +514,41 @@ function enable_log4j_lttng_event_loglevel()
        ok $? "Enable LOG4J event $event_name for session $sess_name with loglevel $loglevel"
 }
 
        ok $? "Enable LOG4J event $event_name for session $sess_name with loglevel $loglevel"
 }
 
+function enable_python_lttng_event()
+{
+       sess_name=$1
+       event_name="$2"
+       channel_name=$3
+
+       if [ -z $channel_name ]; then
+               # default channel if none specified
+               chan=""
+       else
+               chan="-c $channel_name"
+       fi
+
+       $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event "$event_name" $chan -s $sess_name -p >$OUTPUT_DEST
+       ok $? "Enable Python event $event_name for session $sess_name"
+}
+
+function enable_python_lttng_event_loglevel()
+{
+       local sess_name=$1
+       local event_name="$2"
+       local loglevel=$3
+       local channel_name=$4
+
+       if [ -z $channel_name ]; then
+               # default channel if none specified
+               chan=""
+       else
+               chan="-c $channel_name"
+       fi
+
+       $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event --loglevel $loglevel "$event_name" $chan -s $sess_name -p >$OUTPUT_DEST
+       ok $? "Enable Python event $event_name for session $sess_name with loglevel $loglevel"
+}
+
 function enable_ust_lttng_event_filter()
 {
        local sess_name="$1"
 function enable_ust_lttng_event_filter()
 {
        local sess_name="$1"
@@ -579,6 +614,15 @@ function disable_log4j_lttng_event ()
        ok $? "Disable LOG4J event $event_name for session $sess_name"
 }
 
        ok $? "Disable LOG4J event $event_name for session $sess_name"
 }
 
+function disable_python_lttng_event ()
+{
+       local sess_name="$1"
+       local event_name="$2"
+
+       $TESTDIR/../src/bin/lttng/$LTTNG_BIN disable-event "$event_name" -s $sess_name -p >$OUTPUT_DEST
+       ok $? "Disable Python event $event_name for session $sess_name"
+}
+
 function start_lttng_tracing ()
 {
        local sess_name=$1
 function start_lttng_tracing ()
 {
        local sess_name=$1
This page took 0.061031 seconds and 5 git commands to generate.