Fix: Small fixes to the Java agent example files
[lttng-ust.git] / liblttng-ust-java-agent / java / lttng-ust-agent-common / org / lttng / ust / agent / LTTngAgent.java
CommitLineData
501f6777
CB
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.agent;
19
501f6777 20import java.io.IOException;
bc7de6d9 21import java.lang.reflect.InvocationTargetException;
501f6777
CB
22import java.util.concurrent.Semaphore;
23import java.util.concurrent.TimeUnit;
501f6777
CB
24
25public class LTTngAgent {
08284556 26
501f6777
CB
27 /* Domains */
28 static enum Domain {
29 JUL(3), LOG4J(4);
30 private int value;
31
32 private Domain(int value) {
33 this.value = value;
34 }
35
36 public int value() {
37 return value;
38 }
39 }
40
08284556
AM
41 private static final int SEM_TIMEOUT = 3; /* Seconds */
42
501f6777
CB
43 private static LogFramework julUser;
44 private static LogFramework julRoot;
45 private static LogFramework log4jUser;
46 private static LogFramework log4jRoot;
47
48 /* Sessiond clients */
49 private static LTTngTCPSessiondClient julUserClient;
50 private static LTTngTCPSessiondClient julRootClient;
51 private static LTTngTCPSessiondClient log4jUserClient;
52 private static LTTngTCPSessiondClient log4jRootClient;
53
54 private static Thread sessiondThreadJULUser;
55 private static Thread sessiondThreadJULRoot;
56 private static Thread sessiondThreadLog4jUser;
57 private static Thread sessiondThreadLog4jRoot;
58
59 private boolean useJUL = false;
60 private boolean useLog4j = false;
61
62 /* Singleton agent object */
63 private static LTTngAgent curAgent = null;
64
65 /* Indicate if this object has been initialized. */
66 private static boolean initialized = false;
67
68 private static Semaphore registerSem;
501f6777
CB
69
70 /*
71 * Constructor is private. This is a singleton and a reference should be
72 * acquired using getLTTngAgent().
73 */
bc7de6d9 74 private LTTngAgent() {
501f6777
CB
75 initAgentJULClasses();
76
77 /* Since Log4j is a 3rd party JAR, we need to check if we can load any of its classes */
78 Boolean log4jLoaded = loadLog4jClasses();
79 if (log4jLoaded) {
80 initAgentLog4jClasses();
81 }
82
bc7de6d9 83 registerSem = new Semaphore(0, true);
501f6777
CB
84 }
85
bc7de6d9 86 private static Boolean loadLog4jClasses() {
17be0b58
CB
87 Class<?> logging;
88
501f6777 89 try {
9a9a2d37 90 logging = loadClass("org.apache.log4j.spi.LoggingEvent");
501f6777
CB
91 } catch (ClassNotFoundException e) {
92 /* Log4j classes not found, no need to create the relevant objects */
17be0b58
CB
93 return false;
94 }
95
96 /*
97 * Detect capabilities of the log4j library. We only
98 * support log4j >= 1.2.15. The getTimeStamp() method
99 * was introduced in log4j 1.2.15, so verify that it
100 * is available.
101 *
102 * We can't rely on the getPackage().getImplementationVersion()
103 * call that would retrieves information from the manifest file
104 * found in the JAR since the manifest file shipped
105 * from upstream is known to be broken in several
106 * versions of the library.
107 *
108 * More info:
109 * https://issues.apache.org/bugzilla/show_bug.cgi?id=44370
110 */
111
112 try {
113 logging.getDeclaredMethod("getTimeStamp");
114 } catch (NoSuchMethodException e) {
0bc36e5d 115 System.err.println("Warning: The loaded log4j library is too old. Log4j tracing with LTTng will be disabled.");
17be0b58
CB
116 return false;
117 } catch (NullPointerException e) {
118 /* Should never happen */
119 return false;
120 } catch (SecurityException e) {
121 return false;
501f6777
CB
122 }
123
17be0b58 124 return true;
501f6777
CB
125 }
126
bc7de6d9 127 private static Class<?> loadClass(String className) throws ClassNotFoundException {
9a9a2d37
JG
128 ClassLoader loader;
129 Class<?> loadedClass;
130
131 try {
132 /* Try to load class using the current thread's context class loader */
133 loader = Thread.currentThread().getContextClassLoader();
134 loadedClass = loader.loadClass(className);
135 } catch (ClassNotFoundException e) {
136 /* Loading failed, try using the system class loader */
137 loader = ClassLoader.getSystemClassLoader();
138 loadedClass = loader.loadClass(className);
139 }
140
141 return loadedClass;
142 }
143
501f6777
CB
144 private void initAgentJULClasses() {
145 try {
9a9a2d37 146 Class<?> lttngJUL = loadClass("org.lttng.ust.agent.jul.LTTngJUL");
08284556
AM
147 julUser = (LogFramework) lttngJUL.getDeclaredConstructor(new Class[] { Boolean.class }).newInstance(false);
148 julRoot = (LogFramework) lttngJUL.getDeclaredConstructor(new Class[] { Boolean.class }).newInstance(true);
501f6777
CB
149 this.useJUL = true;
150 } catch (ClassNotFoundException e) {
151 /* LTTng JUL classes not found, no need to create the relevant objects */
152 this.useJUL = false;
153 } catch (InstantiationException e) {
154 this.useJUL = false;
155 } catch (NoSuchMethodException e) {
156 this.useJUL = false;
157 } catch (IllegalAccessException e) {
158 this.useJUL = false;
159 } catch (InvocationTargetException e) {
160 this.useJUL = false;
161 }
162 }
163
164 private void initAgentLog4jClasses() {
165 try {
9a9a2d37 166 Class<?> lttngLog4j = loadClass("org.lttng.ust.agent.log4j.LTTngLog4j");
bc7de6d9
AM
167 log4jUser = (LogFramework)lttngLog4j.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(false);
168 log4jRoot = (LogFramework)lttngLog4j.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(true);
501f6777
CB
169 this.useLog4j = true;
170 } catch (ClassNotFoundException e) {
171 /* LTTng Log4j classes not found, no need to create the relevant objects */
172 this.useLog4j = false;
173 } catch (InstantiationException e) {
174 this.useLog4j = false;
175 } catch (NoSuchMethodException e) {
176 this.useLog4j = false;
177 } catch (IllegalAccessException e) {
178 this.useLog4j = false;
179 } catch (InvocationTargetException e) {
180 this.useLog4j = false;
181 }
182 }
183
184 /*
185 * Public getter to acquire a reference to this singleton object.
186 */
187 public static synchronized LTTngAgent getLTTngAgent() throws IOException {
188 if (curAgent == null) {
189 curAgent = new LTTngAgent();
190 curAgent.init();
191 }
192
193 return curAgent;
194 }
195
bc7de6d9
AM
196 private synchronized void init() throws SecurityException {
197 if (initialized) {
501f6777
CB
198 return;
199 }
200
201 Integer numJULThreads = 0;
202 Integer numLog4jThreads = 0;
203
204 if (this.useJUL) {
205 numJULThreads = initJULClientThreads();
206 }
207
208 if (this.useLog4j) {
209 numLog4jThreads = initLog4jClientThreads();
210 }
211
212 Integer numThreads = numJULThreads + numLog4jThreads;
213
214 /* Wait for each registration to end. */
215 try {
bc7de6d9 216 registerSem.tryAcquire(numThreads,
08284556 217 SEM_TIMEOUT,
501f6777
CB
218 TimeUnit.SECONDS);
219 } catch (InterruptedException e) {
220 e.printStackTrace();
221 }
222
bc7de6d9 223 initialized = true;
501f6777
CB
224 }
225
bc7de6d9 226 private synchronized static Integer initJULClientThreads() {
501f6777
CB
227 Integer numThreads = 2;
228
229 /* Handle user session daemon if any. */
bc7de6d9
AM
230 julUserClient = new LTTngTCPSessiondClient(Domain.JUL,
231 julUser,
232 registerSem);
501f6777
CB
233
234 String userThreadName = "LTTng UST agent JUL user thread";
bc7de6d9
AM
235 sessiondThreadJULUser = new Thread(julUserClient, userThreadName);
236 sessiondThreadJULUser.setDaemon(true);
237 sessiondThreadJULUser.start();
501f6777
CB
238
239 /* Handle root session daemon. */
bc7de6d9
AM
240 julRootClient = new LTTngTCPSessiondClient(Domain.JUL,
241 julRoot,
242 registerSem);
501f6777
CB
243
244 String rootThreadName = "LTTng UST agent JUL root thread";
bc7de6d9
AM
245 sessiondThreadJULRoot = new Thread(julRootClient, rootThreadName);
246 sessiondThreadJULRoot.setDaemon(true);
247 sessiondThreadJULRoot.start();
501f6777
CB
248
249 return numThreads;
250 }
251
bc7de6d9 252 private synchronized static Integer initLog4jClientThreads() {
501f6777
CB
253 Integer numThreads = 2;
254
bc7de6d9
AM
255 log4jUserClient = new LTTngTCPSessiondClient(Domain.LOG4J,
256 log4jUser,
257 registerSem);
501f6777
CB
258
259 String userThreadName = "LTTng UST agent Log4j user thread";
bc7de6d9
AM
260 sessiondThreadLog4jUser = new Thread(log4jUserClient, userThreadName);
261 sessiondThreadLog4jUser.setDaemon(true);
262 sessiondThreadLog4jUser.start();
501f6777 263
bc7de6d9
AM
264 log4jRootClient = new LTTngTCPSessiondClient(Domain.LOG4J,
265 log4jRoot,
266 registerSem);
501f6777
CB
267
268 String rootThreadName = "LTTng UST agent Log4j root thread";
bc7de6d9
AM
269 sessiondThreadLog4jRoot = new Thread(log4jRootClient,rootThreadName);
270 sessiondThreadLog4jRoot.setDaemon(true);
271 sessiondThreadLog4jRoot.start();
501f6777
CB
272
273 return numThreads;
274 }
275
276
277 public void dispose() throws IOException {
278 if (this.useJUL) {
bc7de6d9
AM
279 julUserClient.destroy();
280 julRootClient.destroy();
281 julUser.reset();
282 julRoot.reset();
501f6777
CB
283 }
284
285 if (this.useLog4j) {
bc7de6d9
AM
286 log4jUserClient.destroy();
287 log4jRootClient.destroy();
288 log4jUser.reset();
289 log4jRoot.reset();
501f6777
CB
290 }
291
292 try {
293 if (this.useJUL) {
bc7de6d9
AM
294 sessiondThreadJULUser.join();
295 sessiondThreadJULRoot.join();
501f6777
CB
296 }
297
298 if (this.useLog4j) {
bc7de6d9
AM
299 sessiondThreadLog4jUser.join();
300 sessiondThreadLog4jRoot.join();
501f6777
CB
301 }
302
303 } catch (InterruptedException e) {
304 e.printStackTrace();
305 }
306 }
307}
This page took 0.036425 seconds and 4 git commands to generate.