$(pkgpath)/client/SessiondCommandHeader.java \
$(pkgpath)/client/SessiondDisableEventCommand.java \
$(pkgpath)/client/SessiondEnableEventCommand.java \
- $(pkgpath)/client/SessiondListLoggersCommand.java
+ $(pkgpath)/client/SessiondListLoggersCommand.java \
+ $(pkgpath)/session/EventRule.java \
+ $(pkgpath)/session/LogLevelSelector.java
dist_noinst_DATA = $(jarfile_manifest)
jar_DATA = $(jarfile)
-classes = $(pkgpath)/*.class $(pkgpath)/client/*.class
+classes = $(pkgpath)/*.class $(pkgpath)/client/*.class $(pkgpath)/session/*.class
$(jarfile): classnoinst.stamp
$(JAR) cfm $(JARFLAGS) $@ $(jarfile_manifest) $(classes) && rm -f $(jarfile_symlink) && $(LN_S) $@ $(jarfile_symlink)
uninstall-hook:
cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink)
-CLEANFILES = $(jarfile) $(pkgpath)/*.class $(pkgpath)/client/*.class
+CLEANFILES = $(jarfile) $(pkgpath)/*.class $(pkgpath)/client/*.class $(pkgpath)/session/*.class
import org.lttng.ust.agent.client.ILttngTcpClientListener;
import org.lttng.ust.agent.client.LttngTcpSessiondClient;
+import org.lttng.ust.agent.session.EventRule;
/**
* Base implementation of a {@link ILttngAgent}.
* falls to 0, this means we can avoid sending log events through JNI
* because nobody wants them.
*
- * It uses a concurrent hash set", so that the {@link #isEventEnabled} and
+ * It uses a concurrent hash map, so that the {@link #isEventEnabled} and
* read methods do not need to take a synchronization lock.
*/
private final Map<String, Integer> enabledEvents = new ConcurrentHashMap<String, Integer>();
}
@Override
- public boolean eventEnabled(String eventName) {
+ public boolean eventEnabled(EventRule eventRule) {
+ String eventName = eventRule.getEventName();
+
if (eventName.equals(WILDCARD)) {
enabledWildcards.incrementAndGet();
return true;
}
-
if (eventName.endsWith(WILDCARD)) {
/* Strip the "*" from the name. */
String prefix = eventName.substring(0, eventName.length() - 1);
package org.lttng.ust.agent.client;
+import org.lttng.ust.agent.session.EventRule;
+
/**
* TCP client listener interface.
*
/**
* Callback for the TCP client to notify the listener agent that a request
- * for enabling an event was sent from the session daemon.
+ * for enabling an event rule was sent from the session daemon.
*
- * @param eventName
- * The name of the event that was requested to be enabled.
+ * @param eventRule
+ * The event rule that was requested to be enabled
* @return Since we do not track individual sessions, right now this command
* cannot fail. It will always return true.
*/
- boolean eventEnabled(String eventName);
+ boolean eventEnabled(EventRule eventRule);
/**
* Callback for the TCP client to notify the listener agent that a request
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import org.lttng.ust.agent.session.EventRule;
+import org.lttng.ust.agent.session.LogLevelSelector;
+
/**
* Session daemon command indicating to the Java agent that some events were
* enabled in the tracing session.
private static final int INT_SIZE = 4;
- /** Event name to enable in the tracing session */
+ /* Parameters of the event rule being enabled */
private final String eventName;
+ private final LogLevelSelector logLevelFilter;
+ private final String filterString;
public SessiondEnableEventCommand(byte[] data) {
if (data == null) {
ByteBuffer buf = ByteBuffer.wrap(data);
buf.order(ByteOrder.LITTLE_ENDIAN);
- buf.getInt(); // logLevel, currently unused
- buf.getInt(); // logLevelType, currently unused
+ int logLevel = buf.getInt();
+ int logLevelType = buf.getInt();
+ logLevelFilter = new LogLevelSelector(logLevel, logLevelType);
+
eventName = new String(data, dataOffset, data.length - dataOffset).trim();
+ filterString = null; /* Not yet sent by the sessiond */
}
@Override
public LttngAgentResponse execute(ILttngTcpClientListener agent) {
- boolean success = agent.eventEnabled(this.eventName);
+ EventRule rule = new EventRule(eventName, logLevelFilter, filterString);
+ boolean success = agent.eventEnabled(rule);
return (success ? LttngAgentResponse.SUCESS_RESPONSE : LttngAgentResponse.FAILURE_RESPONSE);
}
}
--- /dev/null
+/*
+ * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * 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.agent.session;
+
+/**
+ * Event filtering rule present in a tracing session.
+ *
+ * It typically comes from a "lttng enable-event" command, and contains a
+ * domain, event name, log level and filter string.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class EventRule {
+
+ private final String eventName;
+ private final LogLevelSelector logLevelSelector;
+ private final String filterString;
+
+ /**
+ * Constructor.
+ *
+ * @param eventName
+ * The name of the tracepoint
+ * @param logLevelSelector
+ * The log level of the event rule
+ * @param filterString
+ * The filtering string. May be null if there is no extra filter.
+ */
+ public EventRule(String eventName, LogLevelSelector logLevelSelector, String filterString) {
+ this.eventName = eventName;
+ this.logLevelSelector = logLevelSelector;
+ this.filterString = filterString;
+ }
+
+ /**
+ * Get the event name of this rule.
+ *
+ * @return The event name
+ */
+ public String getEventName() {
+ return eventName;
+ }
+
+ /**
+ * Get the log level filter configuration of the rule.
+ *
+ * @return The log level selector
+ */
+ public LogLevelSelector getLogLevelSelector() {
+ return logLevelSelector;
+ }
+
+ /**
+ * Get the filter string associated with this rule.
+ *
+ * @return The filter string, may be null for no filter string.
+ */
+ public String getFilterString() {
+ return filterString;
+ }
+
+ // ------------------------------------------------------------------------
+ // Methods from Object
+ // ------------------------------------------------------------------------
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((eventName == null) ? 0 : eventName.hashCode());
+ result = prime * result + ((filterString == null) ? 0 : filterString.hashCode());
+ result = prime * result + ((logLevelSelector == null) ? 0 : logLevelSelector.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ EventRule other = (EventRule) obj;
+
+ if (eventName == null) {
+ if (other.eventName != null) {
+ return false;
+ }
+ } else if (!eventName.equals(other.eventName)) {
+ return false;
+ }
+ /* else, continue */
+
+ if (filterString == null) {
+ if (other.filterString != null) {
+ return false;
+ }
+ } else if (!filterString.equals(other.filterString)) {
+ return false;
+ }
+ /* else, continue */
+
+ if (logLevelSelector == null) {
+ if (other.logLevelSelector != null) {
+ return false;
+ }
+ } else if (!logLevelSelector.equals(other.logLevelSelector)) {
+ return false;
+ }
+ /* else, continue */
+
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * 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.agent.session;
+
+/**
+ * Log level filtering element, which is part of an {@link EventRule}.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class LogLevelSelector {
+
+ /**
+ * The type of log level filter that is enabled.
+ *
+ * Defined from lttng-tools' include/lttng/event.h.
+ */
+ public enum LogLevelType {
+ /**
+ * All log levels are enabled. This overrides the value of
+ * {@link LogLevelSelector#getLogLevel}.
+ */
+ LTTNG_EVENT_LOGLEVEL_ALL(0),
+
+ /** This log level along with all log levels of higher severity are enabled. */
+ LTTNG_EVENT_LOGLEVEL_RANGE(1),
+
+ /** Only this exact log level is enabled. */
+ LTTNG_EVENT_LOGLEVEL_SINGLE(2);
+
+ private final int value;
+
+ private LogLevelType(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the numerical (int) value representing this log level type in the
+ * communication protocol.
+ *
+ * @return The int value
+ */
+ public int getValue() {
+ return value;
+ }
+
+ static LogLevelType fromValue(int val) {
+ switch (val) {
+ case 0:
+ return LTTNG_EVENT_LOGLEVEL_ALL;
+ case 1:
+ return LTTNG_EVENT_LOGLEVEL_RANGE;
+ case 2:
+ return LTTNG_EVENT_LOGLEVEL_SINGLE;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ private final int logLevel;
+ private final LogLevelType logLevelType;
+
+ /**
+ * Constructor using numerical values straight from the communication
+ * protocol.
+ *
+ * @param logLevel
+ * The numerical value of the log level. The exact value depends
+ * on the tracing domain, see include/lttng/event.h in the
+ * lttng-tools tree for the complete enumeration.
+ * @param logLevelType
+ * The numerical value of the log level type. It will be
+ * converted to a {@link LogLevelType} by this constructor.
+ * @throws IllegalArgumentException
+ * If the 'logLevelType' does not correspond to a valid value.
+ */
+ public LogLevelSelector(int logLevel, int logLevelType) {
+ this.logLevel = logLevel;
+ this.logLevelType = LogLevelType.fromValue(logLevelType);
+ }
+
+ /**
+ * "Manual" constructor, specifying the {@link LogLevelType} directly.
+ *
+ * @param logLevel
+ * The numerical value of the log level. The exact value depends
+ * on the tracing domain, see include/lttng/event.h in the
+ * lttng-tools tree for the complete enumeration.
+ * @param type
+ * The log level filter type.
+ */
+ public LogLevelSelector(int logLevel, LogLevelType type) {
+ this.logLevel = logLevel;
+ this.logLevelType = type;
+ }
+
+ /**
+ * Get the numerical value of the log level element. Does not apply if
+ * {@link #getLogLevelType} returns
+ * {@link LogLevelType#LTTNG_EVENT_LOGLEVEL_ALL}.
+ *
+ * @return The numerical value of the log level
+ */
+ public int getLogLevel() {
+ return logLevel;
+ }
+
+ /**
+ * Get the log level filter type.
+ *
+ * @return The log level filter type
+ */
+ public LogLevelType getLogLevelType() {
+ return logLevelType;
+ }
+
+ /**
+ * Helper method to determine if an event with the given log level should be
+ * traced when considering this filter.
+ *
+ * For example, if this filter object represents "higher severity than 5",
+ * and the log level passed in parameter is "8", it will return that it
+ * matches (higher value means higher severity).
+ *
+ * @param targetLogLevel
+ * The log level value of the event to check for
+ * @return Should this event be traced, or not
+ */
+ public boolean matches(int targetLogLevel) {
+ switch (logLevelType) {
+ case LTTNG_EVENT_LOGLEVEL_ALL:
+ return true;
+ case LTTNG_EVENT_LOGLEVEL_RANGE:
+ return (targetLogLevel >= logLevel);
+ case LTTNG_EVENT_LOGLEVEL_SINGLE:
+ return (targetLogLevel == logLevel);
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Methods from Object
+ // ------------------------------------------------------------------------
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + logLevel;
+ result = prime * result + ((logLevelType == null) ? 0 : logLevelType.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ LogLevelSelector other = (LogLevelSelector) obj;
+
+ if (logLevel != other.logLevel) {
+ return false;
+ }
+ if (logLevelType != other.logLevelType) {
+ return false;
+ }
+ return true;
+ }
+}