#define TRACEPOINT_CREATE_PROBES
#include "lttng_ust_jul.h"
-JNIEXPORT void JNICALL Java_org_lttng_ust_jul_LTTngUst_tracepoint(JNIEnv *env,
+/*
+ * System tracepoint meaning only root agent will fire this.
+ */
+JNIEXPORT void JNICALL Java_org_lttng_ust_jul_LTTngUst_tracepointS(JNIEnv *env,
jobject jobj,
jstring msg,
jstring logger_name,
const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
- tracepoint(lttng_jul, jul_event, msg_cstr, logger_name_cstr,
+ tracepoint(lttng_jul, sys_event, msg_cstr, logger_name_cstr,
+ class_name_cstr, method_name_cstr, millis, log_level, thread_id);
+
+ (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
+ (*env)->ReleaseStringUTFChars(env, logger_name, logger_name_cstr);
+ (*env)->ReleaseStringUTFChars(env, class_name, class_name_cstr);
+ (*env)->ReleaseStringUTFChars(env, method_name, method_name_cstr);
+}
+
+/*
+ * User tracepoint meaning only a non root agent will fire this.
+ */
+JNIEXPORT void JNICALL Java_org_lttng_ust_jul_LTTngUst_tracepointU(JNIEnv *env,
+ jobject jobj,
+ jstring msg,
+ jstring logger_name,
+ jstring class_name,
+ jstring method_name,
+ jlong millis,
+ jint log_level,
+ jint thread_id)
+{
+ jboolean iscopy;
+ const char *msg_cstr = (*env)->GetStringUTFChars(env, msg, &iscopy);
+ const char *logger_name_cstr = (*env)->GetStringUTFChars(env, logger_name, &iscopy);
+ const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
+ const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
+
+ tracepoint(lttng_jul, user_event, msg_cstr, logger_name_cstr,
class_name_cstr, method_name_cstr, millis, log_level, thread_id);
(*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
#include <lttng/tracepoint.h>
-TRACEPOINT_EVENT(lttng_jul, jul_event,
+/*
+ * Privileged tracepoint meaning that this is only enable and fired by the root
+ * session daemon.
+ */
+TRACEPOINT_EVENT(lttng_jul, sys_event,
+ TP_ARGS(
+ const char *, msg,
+ const char *, logger_name,
+ const char *, class_name,
+ const char *, method_name,
+ long, millis,
+ int, log_level,
+ int, thread_id),
+ TP_FIELDS(
+ ctf_string(msg, msg)
+ ctf_string(logger_name, logger_name)
+ ctf_string(class_name, class_name)
+ ctf_string(method_name, method_name)
+ ctf_integer(long, long_millis, millis)
+ ctf_integer(int, int_loglevel, log_level)
+ ctf_integer(int, int_threadid, thread_id)
+ )
+)
+
+/*
+ * User tracepoint meaning that this is only enable and fired by a non root
+ * session daemon.
+ */
+TRACEPOINT_EVENT(lttng_jul, user_event,
TP_ARGS(
const char *, msg,
const char *, logger_name,
import java.util.Enumeration;
public class LTTngAgent {
- private static LTTngLogHandler lttngHandler;
private static LogManager logManager;
- private static LTTngThread lttngThread;
- private static Thread sessiondTh;
+
+ /* Possible that we have to threads handling two sessiond. */
+ private static LTTngLogHandler lttngHandlerRoot;
+ private static LTTngLogHandler lttngHandlerUser;
+ private static LTTngThread lttngThreadRoot;
+ private static LTTngThread lttngThreadUser;
+ private static Thread sessiondThRoot;
+ private static Thread sessiondThUser;
/* Singleton agent object. */
private static LTTngAgent curAgent = null;
*/
private LTTngAgent() throws IOException {
this.logManager = LogManager.getLogManager();
- this.lttngHandler = new LTTngLogHandler(this.logManager);
+ this.lttngHandlerUser = new LTTngLogHandler(this.logManager);
+ this.lttngHandlerRoot = new LTTngLogHandler(this.logManager);
+ this.lttngHandlerRoot.is_root = 1;
this.registerSem = new Semaphore(0, true);
}
}
logger = this.logManager.getLogger(loggerName);
- logger.removeHandler(this.lttngHandler);
+ logger.removeHandler(this.lttngHandlerUser);
+ logger.removeHandler(this.lttngHandlerRoot);
}
}
return System.getProperty("user.home");
}
- private int getPortFromFile() throws IOException {
+ private int getPortFromFile(String path) throws IOException {
int port;
- int uid = getUID();
- String path;
BufferedReader br;
- /* Check if root or not, it tells where to get the port file. */
- if (uid == 0) {
- path = rootPortFile;
- } else {
- path = new String(getHomePath() + userPortFile);
- }
-
try {
br = new BufferedReader(new FileReader(path));
String line = br.readLine();
* returned by the logManager.
*/
private synchronized void init() throws SecurityException, IOException {
+ int user_port, root_port;
+ int nr_acquires = 0;
+
if (this.initialized) {
return;
}
- this.lttngThread = new LTTngThread(this.sessiondAddr,
- getPortFromFile(), this.lttngHandler, this.registerSem);
- this.sessiondTh = new Thread(lttngThread);
- this.sessiondTh.start();
+ root_port = getPortFromFile(rootPortFile);
+ if (getUID() == 0) {
+ user_port = root_port;
+ } else {
+ user_port = getPortFromFile(getHomePath() + userPortFile);
+ }
- this.initialized = true;
+ /* Handle user session daemon if any. */
+ this.lttngThreadUser = new LTTngThread(this.sessiondAddr, user_port,
+ this.lttngHandlerUser, this.registerSem);
+ this.sessiondThUser = new Thread(lttngThreadUser);
+ this.sessiondThUser.start();
+ /* Wait for registration done of per-user sessiond */
+ nr_acquires++;
+
+ /* Having two different ports, we have to try both. */
+ if (root_port != user_port) {
+ /* Handle root session daemon. */
+ this.lttngThreadRoot = new LTTngThread(this.sessiondAddr,
+ root_port, this.lttngHandlerRoot, this.registerSem);
+ this.sessiondThRoot = new Thread(lttngThreadRoot);
+ this.sessiondThRoot.start();
+ /* Wait for registration done of system-wide sessiond */
+ nr_acquires++;
+ }
- /* Wait for the registration to end. */
+ /* Wait for each registration to end. */
try {
- this.registerSem.acquire();
+ this.registerSem.acquire(nr_acquires);
} catch (InterruptedException e) {
e.printStackTrace();
}
+
+ this.initialized = true;
}
public void dispose() throws IOException {
- this.lttngThread.dispose();
+ this.lttngThreadUser.dispose();
+ if (this.lttngThreadRoot != null) {
+ this.lttngThreadRoot.dispose();
+ }
/* Make sure there is no more LTTng handler attach to logger(s). */
this.removeHandlers();
try {
- this.sessiondTh.join();
+ this.sessiondThUser.join();
+ if (this.sessiondThRoot != null) {
+ this.sessiondThRoot.join();
+ }
} catch (InterruptedException e) {
e.printStackTrace();
}
public int logLevelAll = 0;
public int logLevelTypeAll;
+ /* Am I a root Log Handler. */
+ public int is_root = 0;
+
public LogManager logManager;
/* Indexed by name and corresponding LTTngEvent. */
* 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());
+ }
}
}
* can proceed to continue tracing.
*/
this.registerSem.release();
- break;
+ /*
+ * We don't send any reply to the registration done command.
+ * This just marks the end of the initial session setup.
+ */
+ continue;
}
case CMD_LIST:
{
* @param thread_id
* Identifier for the thread where the message originated.
*/
- public static native void tracepoint(String msg, String logger_name, String class_name,
+
+ /* Use for a user session daemon. */
+ public static native void tracepointU(String msg, String logger_name, String class_name,
+ String method_name, long millis, int log_level, int thread_id);
+
+ /* Use for a root session daemon. */
+ public static native void tracepointS(String msg, String logger_name, String class_name,
String method_name, long millis, int log_level, int thread_id);
}