Refactor liblttng-ust-jul in liblttng-ust-agent
[lttng-ust.git] / liblttng-ust-java-agent / java / org / lttng / ust / agent / LTTngAgent.java
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
18 package org.lttng.ust.agent;
19
20 import org.lttng.ust.agent.jul.LTTngJUL;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.BufferedReader;
25 import java.io.FileReader;
26 import java.util.concurrent.Semaphore;
27 import java.util.concurrent.TimeUnit;
28 import java.util.Enumeration;
29 import java.lang.reflect.InvocationTargetException;
30
31 import java.util.logging.Logger;
32 import java.util.logging.FileHandler;;
33 import java.util.logging.SimpleFormatter;
34
35 public class LTTngAgent {
36 /* Domains */
37 static enum Domain {
38 JUL(3), LOG4J(4);
39 private int value;
40
41 private Domain(int value) {
42 this.value = value;
43 }
44
45 public int value() {
46 return value;
47 }
48 }
49
50 private static LogFramework julUser;
51 private static LogFramework julRoot;
52 private static LogFramework log4jUser;
53 private static LogFramework log4jRoot;
54
55 /* Sessiond clients */
56 private static LTTngTCPSessiondClient julUserClient;
57 private static LTTngTCPSessiondClient julRootClient;
58 private static LTTngTCPSessiondClient log4jUserClient;
59 private static LTTngTCPSessiondClient log4jRootClient;
60
61 private static Thread sessiondThreadJULUser;
62 private static Thread sessiondThreadJULRoot;
63 private static Thread sessiondThreadLog4jUser;
64 private static Thread sessiondThreadLog4jRoot;
65
66 private boolean useJUL = false;
67 private boolean useLog4j = false;
68
69 /* Singleton agent object */
70 private static LTTngAgent curAgent = null;
71
72 /* Indicate if this object has been initialized. */
73 private static boolean initialized = false;
74
75 private static Semaphore registerSem;
76 private final static int semTimeout = 3; /* Seconds */
77
78 /*
79 * Constructor is private. This is a singleton and a reference should be
80 * acquired using getLTTngAgent().
81 */
82 private LTTngAgent() throws IOException {
83 initAgentJULClasses();
84
85 /* Since Log4j is a 3rd party JAR, we need to check if we can load any of its classes */
86 Boolean log4jLoaded = loadLog4jClasses();
87 if (log4jLoaded) {
88 initAgentLog4jClasses();
89 }
90
91 this.registerSem = new Semaphore(0, true);
92 }
93
94 private Boolean loadLog4jClasses() {
95 Boolean loaded = false;
96 try {
97 ClassLoader loader = ClassLoader.getSystemClassLoader();
98 loader.loadClass("org.apache.log4j.Logger");
99 loaded = true;
100 } catch (ClassNotFoundException e) {
101 /* Log4j classes not found, no need to create the relevant objects */
102 loaded = false;
103 }
104
105 return loaded;
106 }
107
108 private void initAgentJULClasses() {
109 try {
110 ClassLoader loader = ClassLoader.getSystemClassLoader();
111 Class<?> lttngJUL = loader.loadClass("org.lttng.ust.agent.jul.LTTngJUL");
112 this.julUser = (LogFramework)lttngJUL.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(false);
113 this.julRoot = (LogFramework)lttngJUL.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(true);
114 this.useJUL = true;
115 } catch (ClassNotFoundException e) {
116 /* LTTng JUL classes not found, no need to create the relevant objects */
117 this.useJUL = false;
118 } catch (InstantiationException e) {
119 this.useJUL = false;
120 } catch (NoSuchMethodException e) {
121 this.useJUL = false;
122 } catch (IllegalAccessException e) {
123 this.useJUL = false;
124 } catch (InvocationTargetException e) {
125 this.useJUL = false;
126 }
127 }
128
129 private void initAgentLog4jClasses() {
130 try {
131 ClassLoader loader = ClassLoader.getSystemClassLoader();
132 Class<?> lttngLog4j = loader.loadClass("org.lttng.ust.agent.log4j.LTTngLog4j");
133 this.log4jUser = (LogFramework)lttngLog4j.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(false);
134 this.log4jRoot = (LogFramework)lttngLog4j.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(true);
135 this.useLog4j = true;
136 } catch (ClassNotFoundException e) {
137 /* LTTng Log4j classes not found, no need to create the relevant objects */
138 this.useLog4j = false;
139 } catch (InstantiationException e) {
140 this.useLog4j = false;
141 } catch (NoSuchMethodException e) {
142 this.useLog4j = false;
143 } catch (IllegalAccessException e) {
144 this.useLog4j = false;
145 } catch (InvocationTargetException e) {
146 this.useLog4j = false;
147 }
148 }
149
150 /*
151 * Public getter to acquire a reference to this singleton object.
152 */
153 public static synchronized LTTngAgent getLTTngAgent() throws IOException {
154 if (curAgent == null) {
155 curAgent = new LTTngAgent();
156 curAgent.init();
157 }
158
159 return curAgent;
160 }
161
162 private synchronized void init() throws SecurityException, IOException {
163 if (this.initialized) {
164 return;
165 }
166
167 Integer numJULThreads = 0;
168 Integer numLog4jThreads = 0;
169
170 if (this.useJUL) {
171 numJULThreads = initJULClientThreads();
172 }
173
174 if (this.useLog4j) {
175 numLog4jThreads = initLog4jClientThreads();
176 }
177
178 Integer numThreads = numJULThreads + numLog4jThreads;
179
180 /* Wait for each registration to end. */
181 try {
182 this.registerSem.tryAcquire(numThreads,
183 semTimeout,
184 TimeUnit.SECONDS);
185 } catch (InterruptedException e) {
186 e.printStackTrace();
187 }
188
189 this.initialized = true;
190 }
191
192 private synchronized Integer initJULClientThreads() {
193 Integer numThreads = 2;
194
195 /* Handle user session daemon if any. */
196 this.julUserClient = new LTTngTCPSessiondClient(Domain.JUL,
197 this.julUser,
198 this.registerSem);
199
200 String userThreadName = "LTTng UST agent JUL user thread";
201 this.sessiondThreadJULUser = new Thread(julUserClient, userThreadName);
202 this.sessiondThreadJULUser.setDaemon(true);
203 this.sessiondThreadJULUser.start();
204
205 /* Handle root session daemon. */
206 this.julRootClient = new LTTngTCPSessiondClient(Domain.JUL,
207 this.julRoot,
208 this.registerSem);
209
210 String rootThreadName = "LTTng UST agent JUL root thread";
211 this.sessiondThreadJULRoot = new Thread(julRootClient, rootThreadName);
212 this.sessiondThreadJULRoot.setDaemon(true);
213 this.sessiondThreadJULRoot.start();
214
215 return numThreads;
216 }
217
218 private synchronized Integer initLog4jClientThreads() {
219 Integer numThreads = 2;
220
221 this.log4jUserClient = new LTTngTCPSessiondClient(Domain.LOG4J,
222 this.log4jUser,
223 this.registerSem);
224
225 String userThreadName = "LTTng UST agent Log4j user thread";
226 this.sessiondThreadLog4jUser = new Thread(log4jUserClient, userThreadName);
227 this.sessiondThreadLog4jUser.setDaemon(true);
228 this.sessiondThreadLog4jUser.start();
229
230 this.log4jRootClient = new LTTngTCPSessiondClient(Domain.LOG4J,
231 this.log4jRoot,
232 this.registerSem);
233
234 String rootThreadName = "LTTng UST agent Log4j root thread";
235 this.sessiondThreadLog4jRoot = new Thread(log4jRootClient,rootThreadName);
236 this.sessiondThreadLog4jRoot.setDaemon(true);
237 this.sessiondThreadLog4jRoot.start();
238
239 return numThreads;
240 }
241
242
243 public void dispose() throws IOException {
244 if (this.useJUL) {
245 this.julUserClient.destroy();
246 this.julRootClient.destroy();
247 this.julUser.reset();
248 this.julRoot.reset();
249 }
250
251 if (this.useLog4j) {
252 this.log4jUserClient.destroy();
253 this.log4jRootClient.destroy();
254 this.log4jUser.reset();
255 this.log4jRoot.reset();
256 }
257
258 try {
259 if (this.useJUL) {
260 this.sessiondThreadJULUser.join();
261 this.sessiondThreadJULRoot.join();
262 }
263
264 if (this.useLog4j) {
265 this.sessiondThreadLog4jUser.join();
266 this.sessiondThreadLog4jRoot.join();
267 }
268
269 } catch (InterruptedException e) {
270 e.printStackTrace();
271 }
272 }
273 }
This page took 0.035498 seconds and 4 git commands to generate.