import org.lttng.ust.jul.LTTngUst;
-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 void attach(LTTngLogHandler handler) {
- this.logger.addHandler(handler);
- }
-
- 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 int refcount = 0;
public LogManager logManager;
/* Logger object attached to this handler that can trigger a tracepoint. */
- private Map<String, LTTngLogger> loggerMap =
- Collections.synchronizedMap(new HashMap<String, LTTngLogger>());
+ public Map<String, LTTngEvent> enabledEvents =
+ Collections.synchronizedMap(new HashMap<String, LTTngEvent>());
/* Constructor */
public LTTngLogHandler(LogManager logManager) {
LTTngUst.init();
}
- /*
- * 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();
+ this.enabledEvents.clear();
}
@Override
@Override
public void publish(LogRecord record) {
- LTTngLogger logger;
-
- logger = loggerMap.get(record.getLoggerName());
- if (logger == null) {
- /* Ignore and don't fire TP. */
- return;
- }
-
/*
* Specific tracepoing designed for JUL events. The source class of the
* caller is used for the event name, the raw message is taken, the
import java.lang.Object;
import java.util.logging.Logger;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
import java.util.List;
-import java.util.Set;
import java.util.Enumeration;
public interface LTTngSessiondCmd2_4 {
buf.order(ByteOrder.LITTLE_ENDIAN);
lttngLogLevel = buf.getInt();
lttngLogLevelType = buf.getInt();
- name = new String(data, data_offset, data.length - data_offset);
+ name = new String(data, data_offset, data.length - data_offset).trim();
}
@Override
* @return Event name as a string if the event is NOT found thus was
* not enabled.
*/
- public void execute(LTTngLogHandler handler,
- Map<String, ArrayList<LTTngEvent>> eventMap, Set wildCardSet) {
- ArrayList<LTTngEvent> bucket;
+ public void execute(LTTngLogHandler handler) {
LTTngEvent event;
- if (name == null) {
+ if (this.name == null) {
this.code = lttng_jul_ret_code.CODE_INVALID_CMD;
return;
}
- /* Wild card to enable ALL logger. */
- if (name.trim().equals("*")) {
- String loggerName;
- Enumeration loggers = handler.logManager.getLoggerNames();
-
- /* Add event to the wildcard set. */
- wildCardSet.add(new LTTngEvent(name.trim(), lttngLogLevel,
- lttngLogLevelType));
-
- /*
- * Create an event for each logger found and attach it to the
- * handler.
- */
- while (loggers.hasMoreElements()) {
- loggerName = loggers.nextElement().toString();
- /* Somehow there is always an empty string at the end. */
- if (loggerName == "") {
- continue;
- }
-
- event = new LTTngEvent(loggerName, lttngLogLevel,
- lttngLogLevelType);
- /* Attach event to Log handler to it can be traced. */
- handler.attachEvent(event);
-
- /*
- * The agent timer call this function with eventMap set to
- * null because it already has a reference to an existing
- * event so is should not try to add a new one here.
- */
- if (eventMap != null) {
- bucket = eventMap.get(loggerName);
- if (bucket == null) {
- bucket = new ArrayList<LTTngEvent>();
- eventMap.put(loggerName, bucket);
- }
- bucket.add(event);
- }
- }
- } else {
- event = new LTTngEvent(name.trim(), lttngLogLevel,
- lttngLogLevelType);
- /* Attach event to Log handler to it can be traced. */
- handler.attachEvent(event);
-
- /*
- * The agent timer call this function with eventMap set to
- * null because it already has a reference to an existing
- * event so is should not try to add a new one here.
- */
- if (eventMap != null) {
- bucket = eventMap.get(name.trim());
- if (bucket == null) {
- bucket = new ArrayList<LTTngEvent>();
- eventMap.put(name.trim(), bucket);
- }
- bucket.add(event);
- }
+ /* Add event to the enabled events hash map. */
+ event = handler.enabledEvents.put(this.name,
+ new LTTngEvent(this.name, 0, 0));
+ if (event != null) {
+ /* The event exists so skip updating the refcount. */
+ this.code = lttng_jul_ret_code.CODE_SUCCESS_CMD;
+ return;
+ }
+
+ /*
+ * Get the root logger and attach to it if it's the first enable
+ * seen by the handler.
+ */
+ Logger rootLogger = handler.logManager.getLogger("");
+
+ handler.refcount++;
+ if (handler.refcount == 1) {
+ /* Add handler only if it's the first enable. */
+ rootLogger.addHandler(handler);
}
this.code = lttng_jul_ret_code.CODE_SUCCESS_CMD;
@Override
public void populate(byte[] data) {
- int data_offset = INT_SIZE * 2;
-
ByteBuffer buf = ByteBuffer.wrap(data);
buf.order(ByteOrder.LITTLE_ENDIAN);
- lttngLogLevel = buf.getInt();
- lttngLogLevelType = buf.getInt();
- name = new String(data, data_offset, data.length - data_offset);
+ name = new String(data).trim();
}
@Override
* Execute disable handler action which is to disable the given handler
* to the received name.
*/
- public void execute(LTTngLogHandler handler,
- Map<String, ArrayList<LTTngEvent>> eventMap, Set wildCardSet) {
- ArrayList<LTTngEvent> bucket;
+ public void execute(LTTngLogHandler handler) {
LTTngEvent event;
- if (name == null) {
+ if (this.name == null) {
this.code = lttng_jul_ret_code.CODE_INVALID_CMD;
return;
}
- /* Wild card to disable ALL logger. */
- if (name.trim().equals("*")) {
- String loggerName;
- Enumeration loggers = handler.logManager.getLoggerNames();
-
- /* Remove event from the wildcard set. */
- wildCardSet.remove(new LTTngEvent(name.trim(), lttngLogLevel,
- lttngLogLevelType));
-
- while (loggers.hasMoreElements()) {
- loggerName = loggers.nextElement().toString();
- /* Somehow there is always an empty string at the end. */
- if (loggerName == "") {
- continue;
- }
-
- event = new LTTngEvent(loggerName, lttngLogLevel,
- lttngLogLevelType);
-
- bucket = eventMap.get(loggerName);
- if (bucket != null) {
- handler.detachEvent(event);
- bucket.remove(event);
- if (bucket.isEmpty() == true) {
- eventMap.remove(bucket);
- }
- }
- }
- this.code = lttng_jul_ret_code.CODE_SUCCESS_CMD;
- } else {
- event = new LTTngEvent(this.name, lttngLogLevel,
- lttngLogLevelType);
-
- bucket = eventMap.get(this.name);
- if (bucket != null) {
- handler.detachEvent(event);
- bucket.remove(event);
- if (bucket.isEmpty() == true) {
- eventMap.remove(bucket);
- }
- this.code = lttng_jul_ret_code.CODE_SUCCESS_CMD;
- } else {
- this.code = lttng_jul_ret_code.CODE_UNK_LOGGER_NAME;
- }
+ /*
+ * Try to remove the logger name from the events map and if we
+ * can't, just skip the refcount update since the event was never
+ * enabled.
+ */
+ event = handler.enabledEvents.remove(this.name);
+ if (event == null) {
+ /* The event didn't exists so skip updating the refcount. */
+ this.code = lttng_jul_ret_code.CODE_INVALID_CMD;
+ return;
}
+ Logger rootLogger = handler.logManager.getLogger("");
+
+ handler.refcount--;
+ if (handler.refcount == 0) {
+ rootLogger.removeHandler(handler);
+ }
+
+ this.code = lttng_jul_ret_code.CODE_SUCCESS_CMD;
return;
}
}
import java.io.FileNotFoundException;
import java.net.*;
import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Enumeration;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
import java.util.logging.Logger;
-import java.util.Collections;
class USTRegisterMsg {
public static int pid;
private Semaphore registerSem;
- private Timer eventTimer;
-
- /*
- * Indexed by event name but can contains duplicates since multiple
- * sessions can enable the same event with or without different loglevels.
- */
- private Map<String, ArrayList<LTTngEvent>> eventMap =
- Collections.synchronizedMap(
- new HashMap<String, ArrayList<LTTngEvent>>());
-
- private Set<LTTngEvent> wildCardSet =
- Collections.synchronizedSet(new HashSet<LTTngEvent>());
-
- /* Timer delay at each 5 seconds. */
- private final static long timerDelay = 5 * 1000;
- private static boolean timerInitialized;
-
private static final String rootPortFile = "/var/run/lttng/jul.port";
private static final String userPortFile = "/.lttng/jul.port";
public LTTngTCPSessiondClient(String host, Semaphore sem) {
this.sessiondHost = host;
this.registerSem = sem;
- this.eventTimer = new Timer();
- this.timerInitialized = false;
- }
-
- private void setupEventTimer() {
- if (this.timerInitialized) {
- return;
- }
-
- this.eventTimer.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() {
- LTTngSessiondCmd2_4.sessiond_enable_handler enableCmd = new
- LTTngSessiondCmd2_4.sessiond_enable_handler();
-
- synchronized (eventMap) {
- String loggerName;
- Enumeration loggers = handler.logManager.getLoggerNames();
-
- /*
- * Create an event for each logger found and attach it to the
- * handler.
- */
- while (loggers.hasMoreElements()) {
- ArrayList<LTTngEvent> bucket;
-
- loggerName = loggers.nextElement().toString();
-
- /* Logger is already enabled or end of list, skip it. */
- if (handler.exists(loggerName) == true ||
- loggerName.equals("")) {
- continue;
- }
-
- bucket = eventMap.get(loggerName);
- if (bucket == null) {
- /* No event(s) exist for this logger. */
- continue;
- }
-
- for (LTTngEvent event : bucket) {
- enableCmd.name = event.name;
- enableCmd.lttngLogLevel = event.logLevel.level;
- enableCmd.lttngLogLevelType = event.logLevel.type;
-
- /* Event exist so pass null here. */
- enableCmd.execute(handler, null, wildCardSet);
- }
- }
- }
-
- /* Handle wild cards. */
- synchronized (wildCardSet) {
- Map<String, ArrayList<LTTngEvent>> modifiedEvents =
- new HashMap<String, ArrayList<LTTngEvent>>();
- Set<LTTngEvent> tmpSet = new HashSet<LTTngEvent>();
- Iterator<LTTngEvent> it = wildCardSet.iterator();
-
- while (it.hasNext()) {
- LTTngEvent event = it.next();
-
- /* Only support * for now. */
- if (event.name.equals("*")) {
- enableCmd.name = event.name;
- enableCmd.lttngLogLevel = event.logLevel.level;
- enableCmd.lttngLogLevelType = event.logLevel.type;
-
- /* That might create a new event so pass the map. */
- enableCmd.execute(handler, modifiedEvents, tmpSet);
- }
- }
- eventMap.putAll(modifiedEvents);
- }
- }
- }, this.timerDelay, this.timerDelay);
-
- this.timerInitialized = true;
}
/*
* Cleanup Agent state.
*/
private void cleanupState() {
- eventMap.clear();
- wildCardSet.clear();
if (this.handler != null) {
this.handler.clear();
}
*/
registerToSessiond();
- setupEventTimer();
-
/*
* Block on socket receive and wait for command from the
* session daemon. This will return if and only if there is a
public void destroy() {
this.quit = true;
- this.eventTimer.cancel();
try {
if (this.sessiondSock != null) {
break;
}
enableCmd.populate(data);
- enableCmd.execute(this.handler, this.eventMap, this.wildCardSet);
+ enableCmd.execute(this.handler);
data = enableCmd.getBytes();
break;
}
break;
}
disableCmd.populate(data);
- disableCmd.execute(this.handler, this.eventMap, this.wildCardSet);
+ disableCmd.execute(this.handler);
data = disableCmd.getBytes();
break;
}