From b2064f542c84041bf0b991d7d83f9e85db8adc19 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Fri, 24 Jan 2014 12:36:44 -0500 Subject: [PATCH] Fix: add missing JUL loglevel handling 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 --- include/lttng/lttng.h | 16 ++++ src/bin/lttng-sessiond/cmd.c | 11 ++- src/bin/lttng-sessiond/event.c | 17 ++-- src/bin/lttng-sessiond/event.h | 3 +- src/bin/lttng-sessiond/jul.c | 2 + src/bin/lttng-sessiond/jul.h | 2 + src/bin/lttng/commands/enable_events.c | 81 ++++++++++++++++++- src/common/sessiond-comm/jul.h | 2 + tests/regression/ust/java-jul/test_java_jul | 87 ++++++++++++++++++--- tests/utils/utils.sh | 18 +++++ 10 files changed, 215 insertions(+), 24 deletions(-) diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 85fdfaa25..18dec2a8a 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -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 */ diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 73ba7740f..dc465173e 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -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; } diff --git a/src/bin/lttng-sessiond/event.c b/src/bin/lttng-sessiond/event.c index db62151f5..499a2490e 100644 --- a/src/bin/lttng-sessiond/event.c +++ b/src/bin/lttng-sessiond/event.c @@ -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; } diff --git a/src/bin/lttng-sessiond/event.h b/src/bin/lttng-sessiond/event.h index dba226654..e73814fd4 100644 --- a/src/bin/lttng-sessiond/event.h +++ b/src/bin/lttng-sessiond/event.h @@ -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); diff --git a/src/bin/lttng-sessiond/jul.c b/src/bin/lttng-sessiond/jul.c index 59be57f6e..7b603cf25 100644 --- a/src/bin/lttng-sessiond/jul.c +++ b/src/bin/lttng-sessiond/jul.c @@ -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) { diff --git a/src/bin/lttng-sessiond/jul.h b/src/bin/lttng-sessiond/jul.h index 92da2012e..1bcd5ef79 100644 --- a/src/bin/lttng-sessiond/jul.h +++ b/src/bin/lttng-sessiond/jul.h @@ -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. diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c index c502a4875..556538dad 100644 --- a/src/bin/lttng/commands/enable_events.c +++ b/src/bin/lttng/commands/enable_events.c @@ -16,6 +16,7 @@ */ #define _GNU_SOURCE +#include #include #include #include @@ -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'; diff --git a/src/common/sessiond-comm/jul.h b/src/common/sessiond-comm/jul.h index fa14dbf88..c9ab3d45a 100644 --- a/src/common/sessiond-comm/jul.h +++ b/src/common/sessiond-comm/jul.h @@ -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; diff --git a/tests/regression/ust/java-jul/test_java_jul b/tests/regression/ust/java-jul/test_java_jul index ed963aa57..6ea063859 100755 --- a/tests/regression/ust/java-jul/test_java_jul +++ b/tests/regression/ust/java-jul/test_java_jul @@ -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 diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh index 6421af1b5..1595f1d16 100644 --- a/tests/utils/utils.sh +++ b/tests/utils/utils.sh @@ -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" -- 2.34.1