Commit | Line | Data |
---|---|---|
45d1768c AM |
1 | /* |
2 | * Copyright (C) 2015, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com> | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along | |
15 | * with this program; if not, write to the Free Software Foundation, Inc., | |
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
17 | */ | |
18 | ||
19 | package org.lttng.tools; | |
20 | ||
21 | import static org.lttng.tools.utils.ShellUtils.executeCommand; | |
22 | ||
f37120c3 | 23 | import java.util.ArrayList; |
45d1768c AM |
24 | import java.util.Arrays; |
25 | import java.util.List; | |
26 | import java.util.UUID; | |
27 | import java.util.stream.Collectors; | |
28 | ||
29 | import org.lttng.tools.utils.ShellUtils; | |
30 | ||
31 | /** | |
32 | * Implementation of {@link ILttngSession} which uses the command-line "lttng" | |
33 | * tool to manipulate the session. Creating an instance will run "lttng create", | |
34 | * close()'ing it will run "lttng destroy". | |
35 | * | |
36 | * @author Alexandre Montplaisir | |
37 | */ | |
38 | class LttngCommandLineSession implements ILttngSession { | |
39 | ||
40 | private final String sessionName; | |
41 | private final Domain domain; | |
42 | ||
43 | private volatile boolean channelCreated = false; | |
44 | ||
45 | /** | |
46 | * Constructor to create a new LTTng tracing session. | |
47 | * | |
48 | * @param sessionName | |
49 | * The name of the session to use. It can be null, in which case | |
50 | * we will provide a unique random name. | |
51 | * @param domain | |
52 | * The tracing domain of this session | |
53 | */ | |
54 | public LttngCommandLineSession(String sessionName, Domain domain) { | |
55 | if (sessionName != null) { | |
56 | this.sessionName = sessionName; | |
57 | } else { | |
58 | this.sessionName = UUID.randomUUID().toString(); | |
59 | } | |
60 | this.domain = domain; | |
61 | ||
62 | /* Create the session in LTTng */ | |
63 | executeCommand(Arrays.asList("lttng", "create", this.sessionName)); | |
64 | } | |
65 | ||
66 | @Override | |
67 | public void close() { | |
68 | /* Destroy the session */ | |
69 | executeCommand(Arrays.asList("lttng", "destroy", sessionName)); | |
70 | // FIXME also delete the trace we generated ? | |
71 | } | |
72 | ||
f37120c3 AM |
73 | @Override |
74 | public boolean enableEvent(String eventName, String loglevel, boolean loglevelOnly, String filter) { | |
75 | channelCreated = true; | |
76 | ||
77 | List<String> command = new ArrayList<>(); | |
78 | command.add("lttng"); | |
79 | command.add("enable-event"); | |
80 | command.add(domain.flag()); | |
81 | command.add(eventName); | |
82 | ||
83 | if (loglevel != null) { | |
84 | if (loglevelOnly) { | |
85 | command.add("--loglevel-only"); | |
86 | } else { | |
87 | command.add("--loglevel"); | |
88 | } | |
89 | command.add(loglevel); | |
90 | } | |
91 | ||
92 | if (filter != null) { | |
93 | command.add("--filter"); | |
94 | command.add(filter); | |
95 | } | |
96 | ||
97 | command.add("-s"); | |
98 | command.add(sessionName); | |
99 | ||
100 | return executeCommand(command); | |
101 | } | |
102 | ||
45d1768c AM |
103 | @Override |
104 | public boolean enableAllEvents() { | |
105 | channelCreated = true; | |
106 | return executeCommand(Arrays.asList( | |
107 | "lttng", "enable-event", domain.flag(), "-a", "-s", sessionName)); | |
108 | } | |
109 | ||
110 | @Override | |
111 | public boolean enableEvents(String... enabledEvents) { | |
112 | if (enabledEvents == null || enabledEvents.length == 0) { | |
113 | throw new IllegalArgumentException(); | |
114 | } | |
115 | channelCreated = true; | |
116 | return executeCommand(Arrays.asList( | |
117 | "lttng", "enable-event", domain.flag(), | |
118 | Arrays.stream(enabledEvents).collect(Collectors.joining(",")), | |
119 | "-s", sessionName)); | |
120 | } | |
121 | ||
122 | @Override | |
123 | public boolean disableEvents(String... disabledEvents) { | |
124 | if (disabledEvents == null || disabledEvents.length == 0) { | |
125 | throw new IllegalArgumentException(); | |
126 | } | |
127 | return executeCommand(Arrays.asList( | |
128 | "lttng", "disable-event", domain.flag(), | |
129 | Arrays.stream(disabledEvents).collect(Collectors.joining(",")), | |
130 | "-s", sessionName)); | |
131 | } | |
132 | ||
f37120c3 AM |
133 | @Override |
134 | public boolean disableAllEvents() { | |
135 | return executeCommand(Arrays.asList( | |
136 | "lttng", "disable-event", domain.flag(), "-a", "-s", sessionName)); | |
137 | } | |
138 | ||
b34f80ae | 139 | @Override |
8f21b7d2 | 140 | public List<String> listEvents() { |
b34f80ae AM |
141 | List<String> output = ShellUtils.getOutputFromCommand(true, Arrays.asList("lttng", "list", domain.flag())); |
142 | return output.stream() | |
143 | .map(e -> e.trim()) | |
144 | .filter(e -> e.startsWith("- ")) | |
145 | .map(e -> e.substring(2)) | |
8f21b7d2 | 146 | .collect(Collectors.toList()); |
b34f80ae AM |
147 | } |
148 | ||
73fb6785 AM |
149 | @Override |
150 | public boolean enableAppContext(String retrieverName, String contextName) { | |
151 | return executeCommand(Arrays.asList( | |
152 | "lttng", "add-context", domain.flag(), | |
153 | "-t", "$app." + retrieverName + ':' + contextName, | |
154 | "-s", sessionName)); | |
155 | } | |
156 | ||
45d1768c AM |
157 | @Override |
158 | public boolean start() { | |
159 | /* | |
160 | * We have to enable a channel for 'lttng start' to work. However, we | |
161 | * cannot enable a channel directly, see | |
162 | * https://bugs.lttng.org/issues/894 . Instead we will enable an event | |
163 | * we know does not exist | |
164 | */ | |
165 | if (!channelCreated) { | |
166 | enableEvents("non-event"); | |
167 | } | |
168 | return executeCommand(Arrays.asList("lttng", "start", sessionName)); | |
169 | } | |
170 | ||
171 | @Override | |
172 | public boolean stop() { | |
173 | return executeCommand(Arrays.asList("lttng", "stop", sessionName)); | |
174 | } | |
175 | ||
176 | @Override | |
177 | public List<String> view() { | |
178 | return ShellUtils.getOutputFromCommand(true, Arrays.asList("lttng", "view", sessionName)); | |
179 | } | |
180 | } |