From: David Goulet Date: Fri, 7 Feb 2014 20:09:12 +0000 (-0500) Subject: Fix: add LTTngEvent class to fix delayed logger X-Git-Tag: v2.4.0-rc4~5 X-Git-Url: https://git.lttng.org/?p=lttng-ust.git;a=commitdiff_plain;h=5b5ffa03ce2a490ddf34d3715c21c7b633567b9a Fix: add LTTngEvent class to fix delayed logger This commit introduces a new object called LTTngEvent that represent a LTTng event containing some attributes, for now loglevel data. Instead of moving event string name around, this object is created once and kept in the log handler so once a record is publish we can match attributes such as loglevels. This has to be done in order to fix the issue where we have a Logger that appears later on during runtime (with the timer that poll every 5 seconds). With a created event object we can lookup back the event attributes and enabled it accordingly. Same goes with the * (all events) where we now keep the loglevel values process wide so we can force the new events to use it. Signed-off-by: David Goulet Signed-off-by: Mathieu Desnoyers --- diff --git a/liblttng-ust-jul/Makefile.am b/liblttng-ust-jul/Makefile.am index 89c90804..9b86caae 100644 --- a/liblttng-ust-jul/Makefile.am +++ b/liblttng-ust-jul/Makefile.am @@ -10,6 +10,7 @@ liblttng_ust_jul_jni_la_SOURCES = LTTngUst.c lttng_ust_jul.h nodist_liblttng_ust_jul_jni_la_SOURCES = org_lttng_ust_jul_LTTngUst.h dist_noinst_DATA = $(LTTNG_JUL_SRCDIR)/LTTngUst.java \ $(LTTNG_JUL_SRCDIR)/LTTngAgent.java \ + $(LTTNG_JUL_SRCDIR)/LTTngEvent.java \ $(LTTNG_JUL_SRCDIR)/LTTngLogHandler.java \ $(LTTNG_JUL_SRCDIR)/LTTngSessiondCmd2_4.java \ $(LTTNG_JUL_SRCDIR)/LTTngTCPSessiondClient.java \ @@ -41,6 +42,7 @@ LTTngUst.c: org_lttng_ust_jul_LTTngUst.h LTTNG_AGENT_FILES = $(LTTNG_JUL_SRCDIR)/LTTngAgent.java \ $(LTTNG_JUL_SRCDIR)/LTTngLogHandler.java \ + $(LTTNG_JUL_SRCDIR)/LTTngEvent.java \ $(LTTNG_JUL_SRCDIR)/LTTngSessiondCmd2_4.java \ $(LTTNG_JUL_SRCDIR)/LTTngTCPSessiondClient.java \ $(LTTNG_JUL_SRCDIR)/LTTngThread.java diff --git a/liblttng-ust-jul/org/lttng/ust/jul/LTTngEvent.java b/liblttng-ust-jul/org/lttng/ust/jul/LTTngEvent.java new file mode 100644 index 00000000..a519f449 --- /dev/null +++ b/liblttng-ust-jul/org/lttng/ust/jul/LTTngEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 - David Goulet + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License, version 2.1 only, + * as published by the Free Software Foundation. + * + * 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 + */ + +package org.lttng.ust.jul; + +import java.lang.String; + +import org.lttng.ust.jul.LTTngUst; + +class LTTngLogLevel { + /* This level is a JUL int level value. */ + public int level; + public int type; + + public LTTngLogLevel(String event_name, int level, int type) { + this.type = type; + this.level = level; + } +} + +public class LTTngEvent { + /* Name of the event. */ + public String name; + public LTTngLogLevel logLevel; + + public LTTngEvent(String name, int loglevel, int loglevel_type) { + this.name = name; + this.logLevel = new LTTngLogLevel(name, loglevel, loglevel_type); + } +} diff --git a/liblttng-ust-jul/org/lttng/ust/jul/LTTngLogHandler.java b/liblttng-ust-jul/org/lttng/ust/jul/LTTngLogHandler.java index d2d55874..f61677d0 100644 --- a/liblttng-ust-jul/org/lttng/ust/jul/LTTngLogHandler.java +++ b/liblttng-ust-jul/org/lttng/ust/jul/LTTngLogHandler.java @@ -34,37 +34,20 @@ class LTTngLogLevelABI { public static final int LOGLEVEL_TYPE_SINGLE = 2; } -class LTTngLogLevel { - /* Event name on which this loglevel is applied on. */ - private String event_name; - /* This level is a JUL int level value. */ - private int level; - private int type; - - public LTTngLogLevel(String event_name, int level, int type) { - this.event_name = event_name; - this.type = type; - this.level = level; - } - - public String getName() { - return this.event_name; - } - - public int getLevel() { - return this.level; - } - - public int getType() { - return this.type; - } -} - public class LTTngLogHandler extends Handler { + /* + * Indicate if the enable all event has been seen and if yes logger that we + * enabled should use the loglevel/type below. + */ + public int logLevelUseAll = 0; + public int logLevelAll = 0; + public int logLevelTypeAll; + public LogManager logManager; - private HashMap logLevels = - new HashMap(); + /* Indexed by name and corresponding LTTngEvent. */ + private HashMap eventMap = + new HashMap(); public LTTngLogHandler(LogManager logManager) { super(); @@ -75,10 +58,8 @@ public class LTTngLogHandler extends Handler { LTTngUst.init(); } - public void setLogLevel(String event_name, int level, int type) { - LTTngLogLevel lttngLogLevel = new LTTngLogLevel(event_name, level, - type); - logLevels.put(event_name, lttngLogLevel); + public void setEvent(LTTngEvent event) { + eventMap.put(event.name, event); } @Override @@ -90,14 +71,16 @@ public class LTTngLogHandler extends Handler { @Override public void publish(LogRecord record) { int fire_tp = 0, rec_log_level, ev_type, ev_log_level; + LTTngEvent event; LTTngLogLevel lttngLogLevel; - String event_name = record.getLoggerName(); + String logger_name = record.getLoggerName(); - lttngLogLevel = logLevels.get(event_name); - if (lttngLogLevel != null) { + /* Get back the event if any and check for loglevel. */ + event = eventMap.get(logger_name); + if (event != null) { rec_log_level = record.getLevel().intValue(); - ev_log_level = lttngLogLevel.getLevel(); - ev_type = lttngLogLevel.getType(); + ev_log_level = event.logLevel.level; + ev_type = event.logLevel.type; switch (ev_type) { case LTTngLogLevelABI.LOGLEVEL_TYPE_RANGE: diff --git a/liblttng-ust-jul/org/lttng/ust/jul/LTTngSessiondCmd2_4.java b/liblttng-ust-jul/org/lttng/ust/jul/LTTngSessiondCmd2_4.java index 6f3cef34..7f5f61d1 100644 --- a/liblttng-ust-jul/org/lttng/ust/jul/LTTngSessiondCmd2_4.java +++ b/liblttng-ust-jul/org/lttng/ust/jul/LTTngSessiondCmd2_4.java @@ -140,6 +140,29 @@ public interface LTTngSessiondCmd2_4 { return data; } + /* + * Enable a logger meaning add our handler to it using an exiting + * event. If successful, the logger is added to the given enabled + * Loggers hashmap. + * + * @return 0 if NO logger is found else 1 if added. + */ + public int enableLogger(LTTngLogHandler handler, LTTngEvent event, + HashMap enabledLoggers) { + Logger logger; + + logger = handler.logManager.getLogger(event.name); + if (logger == null) { + return 0; + } + + handler.setEvent(event); + logger.addHandler(handler); + enabledLoggers.put(event.name, logger); + + return 1; + } + /** * Execute enable handler action which is to enable the given handler * to the received name. @@ -147,8 +170,10 @@ public interface LTTngSessiondCmd2_4 { * @return Event name as a string if the event is NOT found thus was * not enabled. */ - public String execute(LTTngLogHandler handler, HashMap enabledLoggers) { + public LTTngEvent execute(LTTngLogHandler handler, HashMap enabledLoggers) { + int ret; Logger logger; + LTTngEvent event; if (name == null) { this.code = lttng_jul_ret_code.CODE_INVALID_CMD; @@ -159,6 +184,15 @@ public interface LTTngSessiondCmd2_4 { if (name.trim().equals("*")) { String loggerName; Enumeration loggers = handler.logManager.getLoggerNames(); + + /* + * Keep the loglevel value for all events in case an event + * appears later on. + */ + handler.logLevelUseAll = 1; + handler.logLevelAll = lttngLogLevel; + handler.logLevelTypeAll = lttngLogLevelType; + while (loggers.hasMoreElements()) { loggerName = loggers.nextElement().toString(); /* Somehow there is always an empty string at the end. */ @@ -170,32 +204,35 @@ public interface LTTngSessiondCmd2_4 { continue; } - logger = handler.logManager.getLogger(loggerName); - handler.setLogLevel(loggerName, lttngLogLevel, + /* + * Create new event object and set it in the log handler so + * we can process the record entry with the right + * attributes like the loglevels. + */ + event = new LTTngEvent(loggerName, lttngLogLevel, lttngLogLevelType); - logger.addHandler(handler); - enabledLoggers.put(loggerName, logger); + enableLogger(handler, event, enabledLoggers); } this.code = lttng_jul_ret_code.CODE_SUCCESS_CMD; - /* - * Return the name as a new string so we can add the * event - * name to the event list that we need to enable for new - * Logger. - */ - return new String(name); + + event = new LTTngEvent("*", lttngLogLevel, lttngLogLevelType); + return event; } this.code = lttng_jul_ret_code.CODE_SUCCESS_CMD; - logger = handler.logManager.getLogger(name.trim()); - if (logger != null) { - handler.setLogLevel(name.trim(), lttngLogLevel, - lttngLogLevelType); - logger.addHandler(handler); - enabledLoggers.put(name.trim(), logger); + + /* + * Create new event object and set it in the log handler so we can + * process the record entry with the right attributes like the + * loglevels. + */ + event = new LTTngEvent(name.trim(), lttngLogLevel, + lttngLogLevelType); + ret = enableLogger(handler, event, enabledLoggers); + if (ret == 1) { return null; - } else { - return new String(name); } + return event; } } diff --git a/liblttng-ust-jul/org/lttng/ust/jul/LTTngTCPSessiondClient.java b/liblttng-ust-jul/org/lttng/ust/jul/LTTngTCPSessiondClient.java index 0c2cb48f..25d1cb2e 100644 --- a/liblttng-ust-jul/org/lttng/ust/jul/LTTngTCPSessiondClient.java +++ b/liblttng-ust-jul/org/lttng/ust/jul/LTTngTCPSessiondClient.java @@ -57,7 +57,7 @@ public class LTTngTCPSessiondClient { private Semaphore registerSem; private Timer eventTimer; - private List enabledEventList = new ArrayList(); + private List enabledEventList = new ArrayList(); /* * Map of Logger objects that have been enabled. They are indexed by name. */ @@ -86,11 +86,14 @@ public class LTTngTCPSessiondClient { * We have to make a copy here since it is possible that the * enabled event list is changed during an iteration on it. */ - List tmpList = new ArrayList(enabledEventList); + List tmpList = new ArrayList(enabledEventList); LTTngSessiondCmd2_4.sessiond_enable_handler enableCmd = new LTTngSessiondCmd2_4.sessiond_enable_handler(); - for (String strEventName: tmpList) { + for (LTTngEvent event: tmpList) { + int ret; + Logger logger; + /* * Check if this Logger name has been enabled already. Note * that in the case of "*", it's never added in that hash @@ -101,13 +104,41 @@ public class LTTngTCPSessiondClient { * LogHandler can be added twice on a Logger object... * don't ask... */ - if (enabledLoggers.get(strEventName) != null) { + logger = enabledLoggers.get(event.name); + if (logger != null) { + continue; + } + + /* + * Set to one means that the enable all event has been seen + * thus event from that point on must use loglevel for all + * events. Else the object has its own loglevel. + */ + if (handler.logLevelUseAll == 1) { + event.logLevel.level = handler.logLevelAll; + event.logLevel.type = handler.logLevelTypeAll; + } + + /* + * The all event is a special case since we have to iterate + * over every Logger to see which one was not enabled. + */ + if (event.name.equals("*")) { + enableCmd.name = event.name; + enableCmd.lttngLogLevel = event.logLevel.level; + enableCmd.lttngLogLevelType = event.logLevel.type; + /* + * The return value is irrelevant since the * event is + * always kept in the list. + */ + enableCmd.execute(handler, enabledLoggers); continue; } - enableCmd.name = strEventName; - if (enableCmd.execute(handler, enabledLoggers) == null) { - enabledEventList.remove(strEventName); + ret = enableCmd.enableLogger(handler, event, enabledLoggers); + if (ret == 1) { + /* Enabled so remove the event from the list. */ + enabledEventList.remove(event); } } } @@ -232,7 +263,7 @@ public class LTTngTCPSessiondClient { } case CMD_ENABLE: { - String event_name; + LTTngEvent event; LTTngSessiondCmd2_4.sessiond_enable_handler enableCmd = new LTTngSessiondCmd2_4.sessiond_enable_handler(); if (data == null) { @@ -240,14 +271,14 @@ public class LTTngTCPSessiondClient { break; } enableCmd.populate(data); - event_name = enableCmd.execute(this.handler, this.enabledLoggers); - if (event_name != null) { + event = enableCmd.execute(this.handler, this.enabledLoggers); + if (event != null) { /* * Add the event to the list so it can be enabled if * the logger appears at some point in time. */ - if (enabledEventList.contains(event_name) == false) { - enabledEventList.add(event_name); + if (enabledEventList.contains(event) == false) { + enabledEventList.add(event); } } data = enableCmd.getBytes();