1 package org
.lttng
.ust
.agent
.utils
;
3 import java
.io
.IOException
;
4 import java
.lang
.ProcessBuilder
.Redirect
;
5 import java
.nio
.file
.FileVisitResult
;
6 import java
.nio
.file
.Files
;
7 import java
.nio
.file
.Path
;
8 import java
.nio
.file
.Paths
;
9 import java
.nio
.file
.SimpleFileVisitor
;
10 import java
.nio
.file
.attribute
.BasicFileAttributes
;
11 import java
.util
.ArrayList
;
12 import java
.util
.Arrays
;
13 import java
.util
.List
;
14 import java
.util
.stream
.Collectors
;
16 public final class LttngSessionControl
{
18 private LttngSessionControl() {}
24 private final String flag
;
26 private Domain(String flag
) {
30 public String
flag() {
35 // ------------------------------------------------------------------------
36 // Public utility methods
37 // ------------------------------------------------------------------------
40 * Setup a LTTng session by enabling certain events (or none).
43 * The name of the session to create. May be null to use the
44 * default one from lttng-tools.
47 * @param enabledEvents
48 * The list of events to enable. May be null or empty, to not
50 * @return If the command executed successfully (return code = 0).
52 public static boolean setupSession(String sessionName
, Domain domain
, String
... enabledEvents
) {
53 String
[] createCommand
= (sessionName
== null ?
54 new String
[] { "lttng", "create" } :
55 new String
[] { "lttng", "create", sessionName
}
58 String eventsToEnable
= (enabledEvents
== null || enabledEvents
.length
== 0 ?
60 * We have to enable a channel for 'lttng start' to work.
61 * However, we cannot enable a channel directly, see
62 * https://bugs.lttng.org/issues/894 . Instead we will enable an
63 * event we know does not exist
66 Arrays
.stream(enabledEvents
).collect(Collectors
.joining(","))
69 return executeCommands(new String
[][] {
71 { "lttng", "enable-event", domain
.flag(), eventsToEnable
},
77 * Setup a LTTng session with all events enabled (lttng enable-event -a).
80 * The name of the session to create. May be null to use the
81 * default one from lttng-tools.
84 * @return If the command executed successfully (return code = 0).
86 public static boolean setupSessionAllEvents(String sessionName
, Domain domain
) {
87 String
[] createCommand
= (sessionName
== null ?
88 new String
[] { "lttng", "create" } :
89 new String
[] { "lttng", "create", sessionName
}
92 return executeCommands(new String
[][] {
94 { "lttng", "enable-event", domain
.flag(), "-a" },
100 * Send a separate enable-event command.
103 * Name of the session in which to enable events. Use null for
107 * @param enabledEvents
108 * The list of events to enable. Should not be null or empty
109 * @return If the command executed successfully (return code = 0).
111 public static boolean enableEvents(String sessionName
, Domain domain
, String
... enabledEvents
) {
112 if (enabledEvents
== null || enabledEvents
.length
== 0) {
113 throw new IllegalArgumentException();
115 List
<String
> command
= new ArrayList
<String
>();
116 command
.add("lttng");
117 command
.add("enable-event");
118 command
.add(domain
.flag());
119 command
.add(Arrays
.stream(enabledEvents
).collect(Collectors
.joining(",")));
120 if (sessionName
!= null) {
122 command
.add(sessionName
);
124 return executeCommand(command
.toArray(new String
[0]));
128 * Send a disable-event command. Used to disable events that were previously
132 * Name of the session in which to disable events. Use null for
136 * @param disabledEvents
137 * The list of disabled events. Should not be null or empty
138 * @return If the command executed successfully (return code = 0).
140 public static boolean disableEvents(String sessionName
, Domain domain
, String
... disabledEvents
) {
141 if (disabledEvents
== null || disabledEvents
.length
== 0) {
142 throw new IllegalArgumentException();
144 List
<String
> command
= new ArrayList
<String
>();
145 command
.add("lttng");
146 command
.add("disable-event");
147 command
.add(domain
.flag());
148 command
.add(Arrays
.stream(disabledEvents
).collect(Collectors
.joining(",")));
149 if (sessionName
!= null) {
151 command
.add(sessionName
);
153 return executeCommand(command
.toArray(new String
[0]));
157 * Stop the current tracing session
160 * The name of the session to stop. Use null for the current
162 * @return If the command executed successfully (return code = 0).
164 public static boolean stopSession(String sessionName
) {
165 List
<String
> command
= new ArrayList
<String
>();
166 command
.add("lttng");
168 if (sessionName
!= null) {
169 command
.add(sessionName
);
171 return executeCommand(command
.toArray(new String
[0]));
175 * Issue a "lttng view" command on the provided session, and returns its
176 * output. This effectively returns the current content of the trace in text
180 * The name of the session to print. Use null for the current
182 * @return The output of Babeltrace on the session's current trace
184 public static List
<String
> viewSession(String sessionName
) {
185 List
<String
> command
= new ArrayList
<String
>();
186 command
.add("lttng");
188 if (sessionName
!= null) {
189 command
.add(sessionName
);
191 return getOutputFromCommand(command
.toArray(new String
[0]));
195 * Destroy the current tracing session
198 * The name of the session to destroy. Use null for the current
200 * @return If the command executed successfully (return code = 0).
202 public static boolean destroySession(String sessionName
) {
203 List
<String
> command
= new ArrayList
<String
>();
204 command
.add("lttng");
205 command
.add("destroy");
206 if (sessionName
!= null) {
207 command
.add(sessionName
);
209 return executeCommand(command
.toArray(new String
[0]));
213 * Try destroying the given tracing session, fail silently if there is no
217 * The name of the session to destroy. Use null for the current
220 public static void tryDestroySession(String sessionName
) {
221 getOutputFromCommand(false, new String
[] { "lttng", "destroy" });
225 * Outside of the scope of lttng-tools, but this utility method can be used
226 * to delete all traces currently under ~/lttng-traces/. This can be used by
227 * tests to cleanup a trace they have created.
229 * @return True if the command completes successfully, false if there was an
232 public static boolean deleteAllTracee() {
233 String tracesDir
= new String(System
.getProperty("user.home") + "/lttng-traces/");
234 return deleteDirectory(Paths
.get(tracesDir
));
237 private static boolean deleteDirectory(Path directory
) {
239 Files
.walkFileTree(directory
, new SimpleFileVisitor
<Path
>() {
241 public FileVisitResult
visitFile(Path file
, BasicFileAttributes attrs
) throws IOException
{
243 return FileVisitResult
.CONTINUE
;
247 public FileVisitResult
postVisitDirectory(Path dir
, IOException exc
) throws IOException
{
249 return FileVisitResult
.CONTINUE
;
252 } catch (IOException e
) {
253 /* At least we tried... */
259 // ------------------------------------------------------------------------
260 // Private helper methods
261 // ------------------------------------------------------------------------
263 private static boolean executeCommands(String
[][] commands
) {
264 for (String
[] command
: commands
) {
265 if (executeCommand(command
) == false) {
273 * Just to test the environment / stdout are working correctly
275 public static void main(String
[] args
) {
276 executeCommand(new String
[] {"ls", "-l"});
279 private static boolean executeCommand(String
[] command
) {
281 ProcessBuilder builder
= new ProcessBuilder(command
);
282 builder
.redirectErrorStream(true);
283 builder
.redirectOutput(Redirect
.INHERIT
);
285 Process p
= builder
.start();
286 int ret
= p
.waitFor();
289 } catch (IOException
| InterruptedException e
) {
294 private static List
<String
> getOutputFromCommand(String
[] command
) {
295 return getOutputFromCommand(true, command
);
298 private static List
<String
> getOutputFromCommand(boolean print
, String
[] command
) {
300 Path tempFile
= Files
.createTempFile("test-output", null);
302 ProcessBuilder builder
= new ProcessBuilder(command
);
303 builder
.redirectErrorStream(true);
304 builder
.redirectOutput(Redirect
.to(tempFile
.toFile()));
306 Process p
= builder
.start();
309 List
<String
> lines
= Files
.readAllLines(tempFile
);
310 Files
.delete(tempFile
);
313 /* Also print the output to the console */
314 lines
.stream().forEach(s
-> System
.out
.println(s
));
319 } catch (IOException
| InterruptedException e
) {