Fix: JUL agent connect to user and root sessiond
[lttng-ust.git] / liblttng-ust-jul / org / lttng / ust / jul / LTTngAgent.java
CommitLineData
43e5396b
DG
1/*
2 * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
3 *
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.
7 *
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
11 * for more details.
12 *
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
16 */
17
18package org.lttng.ust.jul;
19
20import java.io.IOException;
21import java.io.FileNotFoundException;
22import java.io.InputStream;
23import java.io.BufferedReader;
24import java.io.FileReader;
25import java.util.concurrent.Semaphore;
26import java.util.logging.FileHandler;
27import java.util.logging.Handler;
28import java.util.logging.Level;
29import java.util.logging.Logger;
30import java.util.logging.LogManager;
31import java.util.Enumeration;
32
33public class LTTngAgent {
43e5396b 34 private static LogManager logManager;
9aabed2d
DG
35
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;
43e5396b
DG
43
44 /* Singleton agent object. */
45 private static LTTngAgent curAgent = null;
46
47 /* Indicate if this object has been initialized. */
48 private static boolean initialized = false;
49
50 private static Semaphore registerSem;
51
52 private static final String sessiondAddr = "127.0.0.1";
53 private static final int sessiondPort = 5345;
54
55 private static final String rootPortFile = "/var/run/lttng/jul.port";
56 private static final String userPortFile = "/.lttng/jul.port";
57
58 /*
59 * Constructor is private. This is a singleton and a reference should be
60 * acquired using getLTTngAgent().
61 */
62 private LTTngAgent() throws IOException {
63 this.logManager = LogManager.getLogManager();
9aabed2d
DG
64 this.lttngHandlerUser = new LTTngLogHandler(this.logManager);
65 this.lttngHandlerRoot = new LTTngLogHandler(this.logManager);
66 this.lttngHandlerRoot.is_root = 1;
43e5396b
DG
67 this.registerSem = new Semaphore(0, true);
68 }
69
70 private void removeHandlers() throws SecurityException, IOException {
71 String loggerName;
72 Logger logger;
73
74 Enumeration list = this.logManager.getLoggerNames();
75 while (list.hasMoreElements()) {
76 loggerName = list.nextElement().toString();
77 /* Somehow there is always an empty string at the end. */
78 if (loggerName == "") {
79 continue;
80 }
81
82 logger = this.logManager.getLogger(loggerName);
9aabed2d
DG
83 logger.removeHandler(this.lttngHandlerUser);
84 logger.removeHandler(this.lttngHandlerRoot);
43e5396b
DG
85 }
86 }
87
88 private int getUID() throws IOException {
89 int uid;
90 byte b[] = new byte[4];
91 String userName = System.getProperty("user.name");
92 String command = "id -u " + userName;
93 Process child = Runtime.getRuntime().exec(command);
94 InputStream in = child.getInputStream();
95
96 in.read(b);
97 uid = Integer.parseInt(new String(b).trim(), 10);
98 in.close();
99
100 return uid;
101 }
102
103 private String getHomePath() {
104 return System.getProperty("user.home");
105 }
106
9aabed2d 107 private int getPortFromFile(String path) throws IOException {
43e5396b 108 int port;
43e5396b
DG
109 BufferedReader br;
110
43e5396b
DG
111 try {
112 br = new BufferedReader(new FileReader(path));
113 String line = br.readLine();
114 port = Integer.parseInt(line, 10);
115 if (port < 0 || port > 65535) {
116 port = sessiondPort;
117 }
118 br.close();
119 } catch (FileNotFoundException e) {
120 port = sessiondPort;
121 }
122
123 return port;
124 }
125
126 /*
127 * Public getter to acquire a reference to this singleton object.
128 */
129 public static synchronized LTTngAgent getLTTngAgent() throws IOException {
130 if (curAgent == null) {
131 curAgent = new LTTngAgent();
132 curAgent.init();
133 }
134
135 return curAgent;
136 }
137
138 /*
139 * Initialize LTTngAgent. This will attach the log handler to all Logger
140 * returned by the logManager.
141 */
142 private synchronized void init() throws SecurityException, IOException {
9aabed2d
DG
143 int user_port, root_port;
144 int nr_acquires = 0;
145
43e5396b
DG
146 if (this.initialized) {
147 return;
148 }
149
9aabed2d
DG
150 root_port = getPortFromFile(rootPortFile);
151 if (getUID() == 0) {
152 user_port = root_port;
153 } else {
154 user_port = getPortFromFile(getHomePath() + userPortFile);
155 }
43e5396b 156
9aabed2d
DG
157 /* Handle user session daemon if any. */
158 this.lttngThreadUser = new LTTngThread(this.sessiondAddr, user_port,
159 this.lttngHandlerUser, this.registerSem);
160 this.sessiondThUser = new Thread(lttngThreadUser);
161 this.sessiondThUser.start();
162 /* Wait for registration done of per-user sessiond */
163 nr_acquires++;
164
165 /* Having two different ports, we have to try both. */
166 if (root_port != user_port) {
167 /* Handle root session daemon. */
168 this.lttngThreadRoot = new LTTngThread(this.sessiondAddr,
169 root_port, this.lttngHandlerRoot, this.registerSem);
170 this.sessiondThRoot = new Thread(lttngThreadRoot);
171 this.sessiondThRoot.start();
172 /* Wait for registration done of system-wide sessiond */
173 nr_acquires++;
174 }
43e5396b 175
9aabed2d 176 /* Wait for each registration to end. */
43e5396b 177 try {
9aabed2d 178 this.registerSem.acquire(nr_acquires);
43e5396b
DG
179 } catch (InterruptedException e) {
180 e.printStackTrace();
181 }
9aabed2d
DG
182
183 this.initialized = true;
43e5396b
DG
184 }
185
186 public void dispose() throws IOException {
9aabed2d
DG
187 this.lttngThreadUser.dispose();
188 if (this.lttngThreadRoot != null) {
189 this.lttngThreadRoot.dispose();
190 }
43e5396b
DG
191
192 /* Make sure there is no more LTTng handler attach to logger(s). */
193 this.removeHandlers();
194
195 try {
9aabed2d
DG
196 this.sessiondThUser.join();
197 if (this.sessiondThRoot != null) {
198 this.sessiondThRoot.join();
199 }
43e5396b
DG
200 } catch (InterruptedException e) {
201 e.printStackTrace();
202 }
203 }
204}
This page took 0.030734 seconds and 4 git commands to generate.