import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.LogManager;
+import java.util.logging.Level;
+import java.util.HashMap;
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;
+ }
+
+ public int getLevel() {
+ return this.level;
+ }
+
+ public int getType() {
+ return this.type;
+ }
+}
+
public class LTTngLogHandler extends Handler {
public LogManager logManager;
+ private HashMap<String, LTTngLogLevel> logLevels =
+ new HashMap<String, LTTngLogLevel>();
+
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);
+ }
+
@Override
public void close() throws SecurityException {}
@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;
+ }
+
+ if (fire_tp == 0) {
+ 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.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.lang.Object;
import java.util.logging.Logger;
import java.util.ArrayList;
import java.util.HashMap;
*/
final static int NAME_MAX = 255;
+ /*
+ * Size of a primitive type int in byte. Because you know, Java can't
+ * provide that since it does not makes sense...
+ */
+ final static int INT_SIZE = 4;
+
public interface SessiondResponse {
/**
* Gets a byte array of the command so that it may be streamed
public class sessiond_enable_handler implements SessiondResponse, SessiondCommand {
private final static int SIZE = 4;
public String name;
+ public int lttngLogLevel;
+ public int lttngLogLevelType;
/** Return status code to the session daemon. */
public lttng_jul_ret_code code;
@Override
public void populate(byte[] data) {
+ int data_offset = INT_SIZE * 2;
+
ByteBuffer buf = ByteBuffer.wrap(data);
buf.order(ByteOrder.LITTLE_ENDIAN);
- name = new String(data, 0, data.length);
+ lttngLogLevel = buf.getInt();
+ lttngLogLevelType = buf.getInt();
+ name = new String(data, data_offset, data.length - data_offset);
}
@Override
}
logger = handler.logManager.getLogger(loggerName);
+ handler.setLogLevel(loggerName, lttngLogLevel,
+ lttngLogLevelType);
logger.addHandler(handler);
enabledLoggers.put(loggerName, logger);
}
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);
return null;