2 * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 package org
.lttng
.ust
.jul
;
20 import java
.io
.IOException
;
21 import java
.io
.InputStream
;
22 import java
.io
.BufferedReader
;
23 import java
.io
.FileReader
;
24 import java
.util
.concurrent
.Semaphore
;
25 import java
.util
.concurrent
.TimeUnit
;
26 import java
.util
.logging
.FileHandler
;
27 import java
.util
.logging
.Handler
;
28 import java
.util
.logging
.Level
;
29 import java
.util
.logging
.Logger
;
30 import java
.util
.logging
.LogManager
;
31 import java
.util
.Enumeration
;
33 public class LTTngAgent
{
34 private static LogManager logManager
;
36 /* Possible that we have to threads handling two sessiond. */
37 private static LTTngLogHandler lttngHandlerRoot
;
38 private static LTTngLogHandler lttngHandlerUser
;
39 private static LTTngThread lttngThreadRoot
;
40 private static LTTngThread lttngThreadUser
;
41 private static Thread sessiondThRoot
;
42 private static Thread sessiondThUser
;
44 /* Singleton agent object. */
45 private static LTTngAgent curAgent
= null;
47 /* Indicate if this object has been initialized. */
48 private static boolean initialized
= false;
50 private static Semaphore registerSem
;
51 private final static int semTimeout
= 3; /* Seconds */
54 * Default value to connect to session daemon. Port number is dynamically
55 * fetched from the port file that is created by a running session daemon.
57 private static final String sessiondAddr
= "127.0.0.1";
60 * Constructor is private. This is a singleton and a reference should be
61 * acquired using getLTTngAgent().
63 private LTTngAgent() throws IOException
{
64 this.logManager
= LogManager
.getLogManager();
65 this.lttngHandlerUser
= new LTTngLogHandler(this.logManager
);
66 this.lttngHandlerRoot
= new LTTngLogHandler(this.logManager
);
67 this.lttngHandlerRoot
.is_root
= 1;
68 this.registerSem
= new Semaphore(0, true);
71 private void removeHandlers() throws SecurityException
, IOException
{
75 Enumeration list
= this.logManager
.getLoggerNames();
76 while (list
.hasMoreElements()) {
77 loggerName
= list
.nextElement().toString();
78 /* Somehow there is always an empty string at the end. */
79 if (loggerName
== "") {
83 logger
= this.logManager
.getLogger(loggerName
);
84 logger
.removeHandler(this.lttngHandlerUser
);
85 logger
.removeHandler(this.lttngHandlerRoot
);
89 private int getUID() throws IOException
{
91 byte b
[] = new byte[4];
92 String userName
= System
.getProperty("user.name");
93 String command
= "id -u " + userName
;
94 Process child
= Runtime
.getRuntime().exec(command
);
95 InputStream in
= child
.getInputStream();
98 uid
= Integer
.parseInt(new String(b
).trim(), 10);
105 * Public getter to acquire a reference to this singleton object.
107 public static synchronized LTTngAgent
getLTTngAgent() throws IOException
{
108 if (curAgent
== null) {
109 curAgent
= new LTTngAgent();
117 * Initialize LTTngAgent. This will attach the log handler to all Logger
118 * returned by the logManager.
120 private synchronized void init() throws SecurityException
, IOException
{
123 if (this.initialized
) {
127 /* Handle user session daemon if any. */
128 this.lttngThreadUser
= new LTTngThread(this.sessiondAddr
,
129 this.lttngHandlerUser
, this.registerSem
);
130 this.sessiondThUser
= new Thread(lttngThreadUser
);
131 this.sessiondThUser
.setDaemon(true);
132 this.sessiondThUser
.start();
133 /* Wait for registration done of per-user sessiond */
136 /* Handle root session daemon. */
137 this.lttngThreadRoot
= new LTTngThread(this.sessiondAddr
,
138 this.lttngHandlerRoot
, this.registerSem
);
139 this.sessiondThRoot
= new Thread(lttngThreadRoot
);
140 this.sessiondThRoot
.setDaemon(true);
141 this.sessiondThRoot
.start();
142 /* Wait for registration done of system-wide sessiond */
145 /* Wait for each registration to end. */
147 this.registerSem
.tryAcquire(nr_acquires
, semTimeout
,
149 } catch (InterruptedException e
) {
153 this.initialized
= true;
156 public void dispose() throws IOException
{
157 this.lttngThreadUser
.dispose();
158 if (this.lttngThreadRoot
!= null) {
159 this.lttngThreadRoot
.dispose();
162 /* Make sure there is no more LTTng handler attach to logger(s). */
163 this.removeHandlers();
166 this.sessiondThUser
.join();
167 if (this.sessiondThRoot
!= null) {
168 this.sessiondThRoot
.join();
170 } catch (InterruptedException e
) {