Fix: add missing JUL loglevel handling
authorDavid Goulet <dgoulet@efficios.com>
Fri, 24 Jan 2014 17:36:44 +0000 (12:36 -0500)
committerDavid Goulet <dgoulet@efficios.com>
Tue, 28 Jan 2014 23:06:37 +0000 (18:06 -0500)
JUL loglevels are directly mapped to the Level class from the JUL
interface. A complete listing has been added to the enable-event help
command and to the lttng.h ABI as lttng_loglevel_jul.

Signed-off-by: David Goulet <dgoulet@efficios.com>
include/lttng/lttng.h
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/event.c
src/bin/lttng-sessiond/event.h
src/bin/lttng-sessiond/jul.c
src/bin/lttng-sessiond/jul.h
src/bin/lttng/commands/enable_events.c
src/common/sessiond-comm/jul.h
tests/regression/ust/java-jul/test_java_jul
tests/utils/utils.sh

index 85fdfaa257605f36ebbd7d99030e8f3ca32e97b9..18dec2a8acfbf4da2eb07a63bb3174107f4a5509 100644 (file)
@@ -95,6 +95,22 @@ enum lttng_loglevel {
        LTTNG_LOGLEVEL_DEBUG                  = 14,
 };
 
+/*
+ * Available loglevels for the JUL domain. Those are an exact map from the
+ * class java.util.logging.Level.
+ */
+enum lttng_loglevel_jul {
+       LTTNG_LOGLEVEL_JUL_OFF                = INT32_MAX,
+       LTTNG_LOGLEVEL_JUL_SEVERE             = 1000,
+       LTTNG_LOGLEVEL_JUL_WARNING            = 900,
+       LTTNG_LOGLEVEL_JUL_INFO               = 800,
+       LTTNG_LOGLEVEL_JUL_CONFIG             = 700,
+       LTTNG_LOGLEVEL_JUL_FINE               = 500,
+       LTTNG_LOGLEVEL_JUL_FINER              = 400,
+       LTTNG_LOGLEVEL_JUL_FINEST             = 300,
+       LTTNG_LOGLEVEL_JUL_ALL                = INT32_MIN,
+};
+
 /*
  * LTTng consumer mode
  */
index 73ba7740fd131863172c53ae9e1cb558fe09f323..dc465173e3521984f48b91f23e1782b83ba22b09 100644 (file)
@@ -1461,7 +1461,7 @@ int cmd_enable_event(struct ltt_session *session, struct lttng_domain *domain,
 
                /* The wild card * means that everything should be enabled. */
                if (strncmp(event->name, "*", 1) == 0 && strlen(event->name) == 1) {
-                       ret = event_jul_enable_all(usess);
+                       ret = event_jul_enable_all(usess, event);
                } else {
                        ret = event_jul_enable(usess, event);
                }
@@ -1645,7 +1645,7 @@ int cmd_enable_event_all(struct ltt_session *session,
        }
        case LTTNG_DOMAIN_JUL:
        {
-               struct lttng_event uevent;
+               struct lttng_event uevent, event;
                struct lttng_domain tmp_dom;
                struct ltt_ust_session *usess = session->ust_session;
 
@@ -1671,7 +1671,12 @@ int cmd_enable_event_all(struct ltt_session *session,
                        goto error;
                }
 
-               ret = event_jul_enable_all(usess);
+               event.loglevel = LTTNG_LOGLEVEL_JUL_ALL;
+               event.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
+               strncpy(event.name, "*", sizeof(event.name));
+               event.name[sizeof(event.name) - 1] = '\0';
+
+               ret = event_jul_enable_all(usess, &event);
                if (ret != LTTNG_OK) {
                        goto error;
                }
index db62151f57512c4dca6fb1affe32806c44415190..499a2490e65cd6b32a591e839bbe6baef05f36a5 100644 (file)
@@ -615,24 +615,19 @@ error:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR* code.
  */
-int event_jul_enable_all(struct ltt_ust_session *usess)
+int event_jul_enable_all(struct ltt_ust_session *usess,
+               struct lttng_event *event)
 {
        int ret;
        struct jul_event *jevent;
-       struct lttng_event event;
        struct lttng_ht_iter iter;
 
        assert(usess);
 
        DBG("Event JUL enabling ALL events for session %" PRIu64, usess->id);
 
-       /* Create the * wildcard event name for the Java agent. */
-       memset(event.name, 0, sizeof(event.name));
-       strncpy(event.name, "*", sizeof(event.name));
-       event.name[sizeof(event.name) - 1] = '\0';
-
        /* Enable event on JUL application through TCP socket. */
-       ret = event_jul_enable(usess, &event);
+       ret = event_jul_enable(usess, event);
        if (ret != LTTNG_OK) {
                goto error;
        }
@@ -664,7 +659,9 @@ int event_jul_enable(struct ltt_ust_session *usess, struct lttng_event *event)
        assert(usess);
        assert(event);
 
-       DBG("Event JUL enabling %s for session %" PRIu64, event->name, usess->id);
+       DBG("Event JUL enabling %s for session %" PRIu64 " with loglevel type %d "
+                       "and loglevel %d", event->name, usess->id, event->loglevel_type,
+                       event->loglevel);
 
        jevent = jul_find_by_name(event->name, &usess->domain_jul);
        if (!jevent) {
@@ -673,6 +670,8 @@ int event_jul_enable(struct ltt_ust_session *usess, struct lttng_event *event)
                        ret = LTTNG_ERR_NOMEM;
                        goto error;
                }
+               jevent->loglevel = event->loglevel;
+               jevent->loglevel_type = event->loglevel_type;
                created = 1;
        }
 
index dba226654e37c0eafaa69d426dec3408d5a3fa94..e73814fd4ed8ba6dcaeca332fd87f1eed3506e3c 100644 (file)
@@ -47,7 +47,8 @@ int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess,
                struct ltt_ust_channel *uchan);
 
 int event_jul_enable(struct ltt_ust_session *usess, struct lttng_event *event);
-int event_jul_enable_all(struct ltt_ust_session *usess);
+int event_jul_enable_all(struct ltt_ust_session *usess,
+               struct lttng_event *event);
 
 int event_jul_disable(struct ltt_ust_session *usess, char *event_name);
 int event_jul_disable_all(struct ltt_ust_session *usess);
index 59be57f6efe086d5edf195c5c6aca21023b1d481..7b603cf25137031effccd15a7a53f19efa39c713 100644 (file)
@@ -248,6 +248,8 @@ static int enable_event(struct jul_app *app, struct jul_event *event)
                goto error_io;
        }
 
+       msg.loglevel = event->loglevel;
+       msg.loglevel_type = event->loglevel_type;
        strncpy(msg.name, event->name, sizeof(msg.name));
        ret = send_payload(app->sock, &msg, sizeof(msg));
        if (ret < 0) {
index 92da2012e13f02d9d809e9593ff846730327ce88..1bcd5ef795edb190af64aa635ce7c0b12177cdc9 100644 (file)
@@ -67,6 +67,8 @@ struct jul_event {
         * the JUL API.
         */
        char name[LTTNG_SYMBOL_NAME_LEN];
+       enum lttng_loglevel_jul loglevel;
+       enum lttng_loglevel_type loglevel_type;
 
        /*
         * Tells if the event is enabled or not on the JUL Agent.
index c502a48757ebcd660d4fde0ef58446f1c9a981e9..556538daddd87444019e7013933803599c48c50c 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #define _GNU_SOURCE
+#include <assert.h>
 #include <popt.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -159,6 +160,19 @@ static void usage(FILE *ofp)
        fprintf(ofp, "                               TRACE_DEBUG_LINE     = 13\n");
        fprintf(ofp, "                               TRACE_DEBUG          = 14\n");
        fprintf(ofp, "                               (shortcuts such as \"system\" are allowed)\n");
+       fprintf(ofp, "\n");
+       fprintf(ofp, "                           Available JUL domain loglevels:\n");
+       fprintf(ofp, "                               JUL_OFF            = INT32_MAX\n");
+       fprintf(ofp, "                               JUL_SEVERE         = %d\n", LTTNG_LOGLEVEL_JUL_SEVERE);
+       fprintf(ofp, "                               JUL_WARNING        = %d\n", LTTNG_LOGLEVEL_JUL_WARNING);
+       fprintf(ofp, "                               JUL_INFO           = %d\n", LTTNG_LOGLEVEL_JUL_INFO);
+       fprintf(ofp, "                               JUL_CONFIG         = %d\n", LTTNG_LOGLEVEL_JUL_CONFIG);
+       fprintf(ofp, "                               JUL_FINE           = %d\n", LTTNG_LOGLEVEL_JUL_FINE);
+       fprintf(ofp, "                               JUL_FINER          = %d\n", LTTNG_LOGLEVEL_JUL_FINER);
+       fprintf(ofp, "                               JUL_FINEST         = %d\n", LTTNG_LOGLEVEL_JUL_FINEST);
+       fprintf(ofp, "                               JUL_ALL            = INT32_MIN\n");
+       fprintf(ofp, "                               (shortcuts such as \"severe\" 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");
@@ -271,6 +285,47 @@ end:
        return ret;
 }
 
+/*
+ * Maps JUL loglevel from string to value
+ */
+static int loglevel_jul_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, "JUL_OFF") || !strcmp(str, "OFF")) {
+               return LTTNG_LOGLEVEL_JUL_OFF;
+       } else if (!strcmp(str, "JUL_SEVERE") || !strcmp(str, "SEVERE")) {
+               return LTTNG_LOGLEVEL_JUL_SEVERE;
+       } else if (!strcmp(str, "JUL_WARNING") || !strcmp(str, "WARNING")) {
+               return LTTNG_LOGLEVEL_JUL_WARNING;
+       } else if (!strcmp(str, "JUL_INFO") || !strcmp(str, "INFO")) {
+               return LTTNG_LOGLEVEL_JUL_INFO;
+       } else if (!strcmp(str, "JUL_CONFIG") || !strcmp(str, "CONFIG")) {
+               return LTTNG_LOGLEVEL_JUL_CONFIG;
+       } else if (!strcmp(str, "JUL_FINE") || !strcmp(str, "FINE")) {
+               return LTTNG_LOGLEVEL_JUL_FINE;
+       } else if (!strcmp(str, "JUL_FINER") || !strcmp(str, "FINER")) {
+               return LTTNG_LOGLEVEL_JUL_FINER;
+       } else if (!strcmp(str, "JUL_FINEST") || !strcmp(str, "FINEST")) {
+               return LTTNG_LOGLEVEL_JUL_FINEST;
+       } else if (!strcmp(str, "JUL_ALL") || !strcmp(str, "ALL")) {
+               return LTTNG_LOGLEVEL_JUL_ALL;
+       } else {
+               return -1;
+       }
+}
+
 /*
  * Maps loglevel from string to value
  */
@@ -527,14 +582,24 @@ static int enable_events(char *session_name)
                        strcpy(ev.name, "*");
                        ev.loglevel_type = opt_loglevel_type;
                        if (opt_loglevel) {
-                               ev.loglevel = loglevel_str_to_value(opt_loglevel);
+                               assert(opt_userspace || opt_jul);
+                               if (opt_userspace) {
+                                       ev.loglevel = loglevel_str_to_value(opt_loglevel);
+                               } else if (opt_jul) {
+                                       ev.loglevel = loglevel_jul_str_to_value(opt_loglevel);
+                               }
                                if (ev.loglevel == -1) {
                                        ERR("Unknown loglevel %s", opt_loglevel);
                                        ret = -LTTNG_ERR_INVALID;
                                        goto error;
                                }
                        } else {
-                               ev.loglevel = -1;
+                               assert(opt_userspace || opt_jul);
+                               if (opt_userspace) {
+                                       ev.loglevel = -1;
+                               } else if (opt_jul) {
+                                       ev.loglevel = LTTNG_LOGLEVEL_JUL_ALL;
+                               }
                        }
                }
 
@@ -768,6 +833,18 @@ static int enable_events(char *session_name)
                                ret = CMD_UNSUPPORTED;
                                goto error;
                        }
+
+                       ev.loglevel_type = opt_loglevel_type;
+                       if (opt_loglevel) {
+                               ev.loglevel = loglevel_jul_str_to_value(opt_loglevel);
+                               if (ev.loglevel == -1) {
+                                       ERR("Unknown loglevel %s", opt_loglevel);
+                                       ret = -LTTNG_ERR_INVALID;
+                                       goto error;
+                               }
+                       } else {
+                               ev.loglevel = LTTNG_LOGLEVEL_JUL_ALL;
+                       }
                        ev.type = LTTNG_EVENT_TRACEPOINT;
                        strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN);
                        ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
index fa14dbf8809b3c3a0c92cf6dccf1ed93376b8418..c9ab3d45a4ce7bce8d9e8318b80a07b9cc6d1fc2 100644 (file)
@@ -54,6 +54,8 @@ struct lttcomm_jul_hdr {
  * Enable event command payload.
  */
 struct lttcomm_jul_enable {
+       uint32_t loglevel;
+       uint32_t loglevel_type;
        char name[LTTNG_SYMBOL_NAME_LEN];
 } LTTNG_PACKED;
 
index ed963aa5722400509f0852fcdb55a937f89cc6ac..6ea0638598d48029d668fb86a22274bfed74bb84 100755 (executable)
@@ -30,7 +30,7 @@ JAVA_CP="$CURDIR:/usr/local/lib/lttng/java/liblttng-ust-jul.jar:/usr/lib/lttng/j
 
 TRACE_PATH=$(mktemp -d)
 
-NUM_TESTS=16
+NUM_TESTS=37
 
 source $TESTDIR/utils/utils.sh
 
@@ -64,6 +64,12 @@ function test_jul_before_start ()
 
        stop_lttng_tracing $SESSION_NAME
        destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting all events.
+       trace_matches $EVENT_NAME $(($NR_ITER - 1)) $TRACE_PATH
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
 }
 
 function test_jul_after_start ()
@@ -81,6 +87,73 @@ function test_jul_after_start ()
 
        stop_lttng_tracing $SESSION_NAME
        destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting all events.
+       trace_matches $EVENT_NAME $(($NR_ITER - 1)) $TRACE_PATH
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+}
+
+function test_jul_loglevel ()
+{
+       diag "Test JUL application with loglevel"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH
+       enable_jul_lttng_event_loglevel $SESSION_NAME $EVENT_NAME "JUL_INFO"
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay
+       run_app
+
+       wait_apps
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting all events.
+       trace_matches $EVENT_NAME $(($NR_ITER - 1)) $TRACE_PATH
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       diag "Test JUL applications with lower loglevel"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH
+       enable_jul_lttng_event_loglevel $SESSION_NAME $EVENT_NAME "JUL_SEVERE"
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay
+       run_app
+
+       wait_apps
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting 0 events.
+       trace_matches $EVENT_NAME 0 $TRACE_PATH
+       if [ $? -ne 0 ]; then
+               return $?
+       fi
+
+       diag "Test JUL applications with higher loglevel"
+
+       create_lttng_session $SESSION_NAME $TRACE_PATH
+       enable_jul_lttng_event_loglevel $SESSION_NAME $EVENT_NAME "JUL_FINER"
+       start_lttng_tracing $SESSION_NAME
+
+       # Run 5 times with a 1 second delay
+       run_app
+
+       wait_apps
+
+       stop_lttng_tracing $SESSION_NAME
+       destroy_lttng_session $SESSION_NAME
+
+       # Validate test. Expecting all events.
+       trace_matches $EVENT_NAME $(($NR_ITER - 1)) $TRACE_PATH
+       return $?
 }
 
 plan_tests $NUM_TESTS
@@ -98,6 +171,7 @@ skip $withapp "JUL support is needed. Skipping all tests." $NUM_TESTS ||
        start_lttng_sessiond
 
        tests=(
+               test_jul_loglevel
                test_jul_before_start
                test_jul_after_start
        )
@@ -105,15 +179,10 @@ skip $withapp "JUL support is needed. Skipping all tests." $NUM_TESTS ||
        for fct_test in ${tests[@]};
        do
                ${fct_test}
-
-               # Validate test
-               validate_trace $EVENT_NAME $TRACE_PATH
-               if [ $? -eq 0 ]; then
-                       # Only delete if successful
-                       rm -rf $TRACE_PATH
-               else
-                       break
+               if [ $? -ne 0 ]; then
+                       break;
                fi
+               rm -rf $TRACE_PATH
        done
 
        stop_lttng_sessiond
index 6421af1b5c5ed47dc02c67e3703b737d18aa250a..1595f1d16816f0fd3568b9bbfafc5b9e015376a1 100644 (file)
@@ -280,6 +280,24 @@ function enable_jul_lttng_event()
        ok $? "Enable JUL event $event_name for session $sess_name"
 }
 
+function enable_jul_lttng_event_loglevel()
+{
+       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 $loglevel "$event_name" $chan -s $sess_name -j >/dev/null 2>&1
+       ok $? "Enable JUL event $event_name for session $sess_name with loglevel $loglevel"
+}
+
 function enable_ust_lttng_event_filter()
 {
        sess_name="$1"
This page took 0.034358 seconds and 4 git commands to generate.