import java.util.logging.LogRecord;
import java.util.logging.LogManager;
import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.Map;
import org.lttng.ust.jul.LTTngUst;
-/* Note: This is taken from the LTTng tools ABI. */
-class LTTngLogLevelABI {
- /* Loglevel type. */
- public static final int LOGLEVEL_TYPE_ALL = 0;
- public static final int LOGLEVEL_TYPE_RANGE = 1;
- 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;
+class LTTngLogger {
+ /*
+ * The log handler is attached to the logger when the reference count is
+ * nonzero. Each event referring to a logger holds a reference to that
+ * logger. If down to 0, this object is removed from the handler.
+ */
+ public int refcount;
+ public String name;
+ Logger logger;
+
+ public LTTngLogger(String name, Logger logger) {
+ this.name = name;
+ this.refcount = 0;
+ this.logger = logger;
}
- public int getLevel() {
- return this.level;
+ public void attach(LTTngLogHandler handler) {
+ this.logger.addHandler(handler);
}
- public int getType() {
- return this.type;
+ public void detach(LTTngLogHandler handler) {
+ this.logger.removeHandler(handler);
}
}
public class LTTngLogHandler extends Handler {
+ /* Am I a root Log Handler. */
+ public int is_root = 0;
+
public LogManager logManager;
- private HashMap<String, LTTngLogLevel> logLevels =
- new HashMap<String, LTTngLogLevel>();
+ /* Logger object attached to this handler that can trigger a tracepoint. */
+ private Map<String, LTTngLogger> loggerMap =
+ Collections.synchronizedMap(new HashMap<String, LTTngLogger>());
+ /* Constructor */
public LTTngLogHandler(LogManager logManager) {
super();
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);
+ /*
+ * Return true if the logger is enabled and attached. Else, if not found,
+ * return false.
+ */
+ public boolean exists(String name) {
+ if (loggerMap.get(name) != null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /*
+ * Attach an event to this handler. If no logger object exists, one is
+ * created else the refcount is incremented.
+ */
+ public void attachEvent(LTTngEvent event) {
+ Logger logger;
+ LTTngLogger lttngLogger;
+
+ /* Does the logger actually exist. */
+ logger = this.logManager.getLogger(event.name);
+ if (logger == null) {
+ /* Stop attach right now. */
+ return;
+ }
+
+ lttngLogger = loggerMap.get(event.name);
+ if (lttngLogger == null) {
+ lttngLogger = new LTTngLogger(event.name, logger);
+
+ /* Attach the handler to the logger and add is to the map. */
+ lttngLogger.attach(this);
+ lttngLogger.refcount = 1;
+ loggerMap.put(lttngLogger.name, lttngLogger);
+ } else {
+ lttngLogger.refcount += 1;
+ }
+ }
+
+ /*
+ * Dettach an event from this handler. If the refcount goes down to 0, the
+ * logger object is removed thus not attached anymore.
+ */
+ public void detachEvent(LTTngEvent event) {
+ LTTngLogger logger;
+
+ logger = loggerMap.get(event.name);
+ if (logger != null) {
+ logger.refcount -= 1;
+ if (logger.refcount == 0) {
+ /* Dettach from handler since no more event is associated. */
+ logger.detach(this);
+ loggerMap.remove(logger);
+ }
+ }
+ }
+
+ /*
+ * Cleanup this handler state meaning put it back to a vanilla state.
+ */
+ public void clear() {
+ this.loggerMap.clear();
}
@Override
@Override
public void publish(LogRecord record) {
- int fire_tp = 0, rec_log_level, ev_type, ev_log_level;
- LTTngLogLevel lttngLogLevel;
- String event_name = record.getLoggerName();
-
- lttngLogLevel = logLevels.get(event_name);
- if (lttngLogLevel != null) {
- rec_log_level = record.getLevel().intValue();
- ev_log_level = lttngLogLevel.getLevel();
- ev_type = lttngLogLevel.getType();
-
- switch (ev_type) {
- case LTTngLogLevelABI.LOGLEVEL_TYPE_RANGE:
- if (ev_log_level <= rec_log_level) {
- fire_tp = 1;
- }
- break;
- case LTTngLogLevelABI.LOGLEVEL_TYPE_SINGLE:
- if (ev_log_level == rec_log_level) {
- fire_tp = 1;
- }
- break;
- case LTTngLogLevelABI.LOGLEVEL_TYPE_ALL:
- fire_tp = 1;
- break;
- }
- } else {
- /* No loglevel attached thus fire tracepoint. */
- fire_tp = 1;
- }
+ LTTngLogger logger;
- if (fire_tp == 0) {
+ logger = loggerMap.get(record.getLoggerName());
+ if (logger == null) {
+ /* Ignore and don't fire TP. */
return;
}
* caller is used for the event name, the raw message is taken, the
* loglevel of the record and the thread ID.
*/
- LTTngUst.tracepoint(record.getMessage(), record.getLoggerName(),
- record.getSourceClassName(), record.getSourceMethodName(),
- record.getMillis(), record.getLevel().intValue(),
- record.getThreadID());
+ if (this.is_root == 1) {
+ LTTngUst.tracepointS(record.getMessage(),
+ record.getLoggerName(), record.getSourceClassName(),
+ record.getSourceMethodName(), record.getMillis(),
+ record.getLevel().intValue(), record.getThreadID());
+ } else {
+ LTTngUst.tracepointU(record.getMessage(),
+ record.getLoggerName(), record.getSourceClassName(),
+ record.getSourceMethodName(), record.getMillis(),
+ record.getLevel().intValue(), record.getThreadID());
+ }
}
}