1 /**********************************************************************
2 * Copyright (c) 2014 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Jonathan Rajotte - Initial support for machine interface lttng 2.6
11 **********************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.lttng2
.control
.ui
.views
.service
;
15 import java
.io
.IOException
;
16 import java
.io
.StringReader
;
18 import java
.util
.ArrayList
;
19 import java
.util
.List
;
20 import java
.util
.regex
.Matcher
;
22 import javax
.xml
.parsers
.DocumentBuilder
;
23 import javax
.xml
.parsers
.DocumentBuilderFactory
;
24 import javax
.xml
.parsers
.ParserConfigurationException
;
26 import org
.eclipse
.core
.commands
.ExecutionException
;
27 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
28 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.IBaseEventInfo
;
29 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.IChannelInfo
;
30 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.IDomainInfo
;
31 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.IEventInfo
;
32 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.IFieldInfo
;
33 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.IProbeEventInfo
;
34 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.ISessionInfo
;
35 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.ISnapshotInfo
;
36 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.IUstProviderInfo
;
37 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.LogLevelType
;
38 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.TraceDomainType
;
39 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.TraceEnablement
;
40 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.TraceEventType
;
41 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.TraceLogLevel
;
42 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.impl
.BaseEventInfo
;
43 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.impl
.BufferType
;
44 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.impl
.ChannelInfo
;
45 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.impl
.DomainInfo
;
46 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.impl
.EventInfo
;
47 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.impl
.FieldInfo
;
48 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.impl
.ProbeEventInfo
;
49 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.impl
.SessionInfo
;
50 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.impl
.SnapshotInfo
;
51 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.core
.model
.impl
.UstProviderInfo
;
52 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.ui
.views
.handlers
.XmlMiValidationErrorHandler
;
53 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.ui
.views
.messages
.Messages
;
54 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.ui
.views
.remote
.ICommandResult
;
55 import org
.eclipse
.linuxtools
.internal
.lttng2
.control
.ui
.views
.remote
.ICommandShell
;
56 import org
.eclipse
.osgi
.util
.NLS
;
57 import org
.w3c
.dom
.Document
;
58 import org
.w3c
.dom
.Node
;
59 import org
.w3c
.dom
.NodeList
;
60 import org
.xml
.sax
.InputSource
;
61 import org
.xml
.sax
.SAXException
;
64 * Service for sending LTTng trace control commands to remote host via machine
67 * @author Jonathan Rajotte
69 public class LTTngControlServiceMI
extends LTTngControlService
{
71 // ------------------------------------------------------------------------
73 // ------------------------------------------------------------------------
75 private final DocumentBuilder fDocumentBuilder
;
77 // ------------------------------------------------------------------------
79 // ------------------------------------------------------------------------
85 * the command shell implementation to use
87 * the xsd schema file for validation
88 * @throws ExecutionException
89 * if the creation of the Schema and DocumentBuilder objects
92 public LTTngControlServiceMI(ICommandShell shell
, URL xsdUrl
) throws ExecutionException
{
95 DocumentBuilderFactory docBuilderFactory
= DocumentBuilderFactory
.newInstance();
96 docBuilderFactory
.setValidating(false);
98 // TODO: Add xsd validation for machine interface via mi_lttng.xsd from LTTng
100 fDocumentBuilder
= docBuilderFactory
.newDocumentBuilder();
101 } catch (ParserConfigurationException e
) {
102 throw new ExecutionException(Messages
.TraceControl_XmlDocumentBuilderError
, e
);
105 fDocumentBuilder
.setErrorHandler(new XmlMiValidationErrorHandler());
110 * Generate a Document object from an array of String.
113 * array of strings representing an xml input
114 * @return Document generated from strings input
115 * @throws ExecutionException
116 * when parsing has failed
118 private Document
getDocumentFromStrings(String
[] xmlStrings
) throws ExecutionException
{
119 StringBuilder concatenedString
= new StringBuilder();
120 for (String string
: xmlStrings
) {
121 concatenedString
.append(string
);
123 InputSource stream
= new InputSource(new StringReader(concatenedString
.toString()));
127 document
= fDocumentBuilder
.parse(stream
);
128 } catch (SAXException
| IOException e
) {
129 throw new ExecutionException(Messages
.TraceControl_XmlParsingError
, e
);
136 * Parse, populate and set the internal LTTngVersion variable
139 * the mi xml output of lttng version
140 * @throws ExecutionException
141 * when xml extraction fail
143 public void setVersion(String
[] xmlOutput
) throws ExecutionException
{
144 Document doc
= getDocumentFromStrings(xmlOutput
);
145 NodeList element
= doc
.getElementsByTagName(MIStrings
.VERSION
);
149 String license
= ""; //$NON-NLS-1$
150 String commit
= ""; //$NON-NLS-1$
151 String name
= ""; //$NON-NLS-1$
152 String description
= ""; //$NON-NLS-1$
153 String url
= ""; //$NON-NLS-1$
154 String fullVersion
= ""; //$NON-NLS-1$
155 if (element
.getLength() == 1) {
156 NodeList child
= element
.item(0).getChildNodes();
157 // Get basic information
158 for (int i
= 0; i
< child
.getLength(); i
++) {
159 Node node
= child
.item(i
);
160 switch (node
.getNodeName()) {
161 case MIStrings
.VERSION_MAJOR
:
162 major
= Integer
.parseInt(node
.getTextContent());
164 case MIStrings
.VERSION_MINOR
:
165 minor
= Integer
.parseInt(node
.getTextContent());
167 case MIStrings
.VERSION_PATCH_LEVEL
:
168 patchLevel
= Integer
.parseInt(node
.getTextContent());
170 case MIStrings
.VERSION_COMMIT
:
171 commit
= node
.getTextContent();
173 case MIStrings
.VERSION_DESCRIPTION
:
174 description
= node
.getTextContent();
176 case MIStrings
.VERSION_LICENSE
:
177 license
= node
.getTextContent();
179 case MIStrings
.VERSION_NAME
:
180 name
= node
.getTextContent();
182 case MIStrings
.VERSION_STR
:
183 fullVersion
= node
.getTextContent();
185 case MIStrings
.VERSION_WEB
:
186 url
= node
.getTextContent();
192 setVersion(new LttngVersion(major
, minor
, patchLevel
, license
, commit
, name
, description
, url
, fullVersion
));
194 throw new ExecutionException(Messages
.TraceControl_UnsupportedVersionError
);
199 public String
[] getSessionNames(IProgressMonitor monitor
) throws ExecutionException
{
200 StringBuffer command
= createCommand(LTTngControlServiceConstants
.COMMAND_LIST
);
201 ICommandResult result
= executeCommand(command
.toString(), monitor
);
203 Document doc
= getDocumentFromStrings(result
.getOutput());
205 NodeList elements
= doc
.getElementsByTagName(MIStrings
.NAME
);
207 ArrayList
<String
> retArray
= new ArrayList
<>();
208 for (int i
= 0; i
< elements
.getLength(); i
++) {
209 Node node
= elements
.item(i
);
210 if (node
.getParentNode().getNodeName().equalsIgnoreCase(MIStrings
.SESSION
)) {
211 retArray
.add(node
.getTextContent());
214 return retArray
.toArray(new String
[retArray
.size()]);
218 public ISessionInfo
getSession(String sessionName
, IProgressMonitor monitor
) throws ExecutionException
{
219 StringBuffer command
= createCommand(LTTngControlServiceConstants
.COMMAND_LIST
, sessionName
);
220 ICommandResult result
= executeCommand(command
.toString(), monitor
);
222 ISessionInfo sessionInfo
= new SessionInfo(sessionName
);
223 Document document
= getDocumentFromStrings(result
.getOutput());
225 NodeList sessionsNode
= document
.getElementsByTagName(MIStrings
.SESSION
);
226 // There should be only one session
227 if (sessionsNode
.getLength() != 1) {
228 throw new ExecutionException(NLS
.bind(Messages
.TraceControl_MiInvalidNumberOfElementError
, MIStrings
.SESSION
));
231 // Populate session information
232 Node rawSession
= sessionsNode
.item(0);
233 parseSession(sessionInfo
, rawSession
);
235 // Fetch the snapshot info
236 if (sessionInfo
.isSnapshotSession()) {
237 ISnapshotInfo snapshot
= getSnapshotInfo(sessionName
, monitor
);
238 sessionInfo
.setSnapshotInfo(snapshot
);
247 * @throws ExecutionException
249 private void parseSession(ISessionInfo sessionInfo
, Node rawSession
) throws ExecutionException
{
250 if (!rawSession
.getNodeName().equalsIgnoreCase(MIStrings
.SESSION
)) {
251 throw new ExecutionException(Messages
.TraceControl_MiInvalidElementError
);
253 NodeList rawSessionInfos
= rawSession
.getChildNodes();
254 for (int i
= 0; i
< rawSessionInfos
.getLength(); i
++) {
255 Node rawInfo
= rawSessionInfos
.item(i
);
256 switch (rawInfo
.getNodeName()) {
258 sessionInfo
.setName(rawInfo
.getTextContent());
261 sessionInfo
.setSessionPath(rawInfo
.getTextContent());
263 case MIStrings
.ENABLED
:
264 sessionInfo
.setSessionState(rawInfo
.getTextContent());
266 case MIStrings
.SNAPSHOT_MODE
:
267 if (rawInfo
.getTextContent().equals(LTTngControlServiceConstants
.TRUE_NUMERICAL
)) {
268 // real name will be set later
269 ISnapshotInfo snapshotInfo
= new SnapshotInfo(""); //$NON-NLS-1$
270 sessionInfo
.setSnapshotInfo(snapshotInfo
);
273 case MIStrings
.LIVE_TIMER_INTERVAL
:
274 // TODO : live mode not supported yet in TMF:lttng-control
276 case MIStrings
.DOMAINS
:
277 // Extract the domains node
278 NodeList rawDomains
= rawInfo
.getChildNodes();
279 IDomainInfo domain
= null;
280 for (int j
= 0; j
< rawDomains
.getLength(); j
++) {
281 if (rawDomains
.item(j
).getNodeName().equalsIgnoreCase(MIStrings
.DOMAIN
)) {
282 domain
= parseDomain(rawDomains
.item(j
));
283 sessionInfo
.addDomain(domain
);
292 if (!sessionInfo
.isSnapshotSession()) {
293 Matcher matcher
= LTTngControlServiceConstants
.TRACE_NETWORK_PATTERN
.matcher(sessionInfo
.getSessionPath());
294 if (matcher
.matches()) {
295 sessionInfo
.setStreamedTrace(true);
301 * Parse a raw domain XML node to a IDomainInfo object
305 * @return a populated {@link DomainInfo} object
306 * @throws ExecutionException
307 * when missing required xml element (type)
309 protected IDomainInfo
parseDomain(Node rawDomain
) throws ExecutionException
{
310 IDomainInfo domain
= null;
312 Node rawType
= getFirstOf(rawDomain
.getChildNodes(), MIStrings
.TYPE
);
313 if (rawType
== null) {
314 throw new ExecutionException(Messages
.TraceControl_MiMissingRequiredError
);
316 String rawTypeString
= rawType
.getTextContent().toLowerCase();
317 TraceDomainType domainType
= TraceDomainType
.valueOfString(rawTypeString
);
318 switch (domainType
) {
320 domain
= new DomainInfo(Messages
.TraceControl_KernelProviderDisplayName
);
321 domain
.setIsKernel(true);
324 domain
= new DomainInfo(Messages
.TraceControl_UstGlobalDomainDisplayName
);
325 domain
.setIsKernel(false);
329 * TODO: Support for JUL JUL substructure and semantic is not the
330 * same as a regular UST or Kernel Domain There is no channel under
331 * JUL domain only events. The channel is activated in UST Channel
333 domain
= new DomainInfo(Messages
.TraceControl_JULDomainDisplayName
);
334 domain
.setIsKernel(false);
337 domain
= new DomainInfo(Messages
.TraceControl_UnknownDomainDisplayName
);
338 domain
.setIsKernel(false);
341 throw new ExecutionException(Messages
.TraceControl_MiInvalidElementError
);
344 NodeList rawInfos
= rawDomain
.getChildNodes();
345 for (int i
= 0; i
< rawInfos
.getLength(); i
++) {
346 Node rawInfo
= rawInfos
.item(i
);
347 switch (rawInfo
.getNodeName()) {
348 case MIStrings
.BUFFER_TYPE
:
349 BufferType bufferType
= BufferType
.valueOfString(rawInfo
.getTextContent());
350 domain
.setBufferType(bufferType
);
352 case MIStrings
.CHANNELS
:
353 ArrayList
<IChannelInfo
> channels
= new ArrayList
<>();
354 parseChannels(rawInfo
.getChildNodes(), channels
);
355 if (channels
.size() > 0) {
356 domain
.setChannels(channels
);
368 * Parse a list of raw channel XML node into an ArrayList of IChannelInfo
371 * List of raw channel XML node
373 * the parsed channels list
374 * @throws ExecutionException
375 * when missing required xml element (type)
377 private static void parseChannels(NodeList rawChannels
, ArrayList
<IChannelInfo
> channels
) throws ExecutionException
{
378 IChannelInfo channel
= null;
379 for (int i
= 0; i
< rawChannels
.getLength(); i
++) {
380 Node rawChannel
= rawChannels
.item(i
);
381 if (rawChannel
.getNodeName().equalsIgnoreCase(MIStrings
.CHANNEL
)) {
382 channel
= new ChannelInfo(""); //$NON-NLS-1$
384 // Populate the channel
385 NodeList rawInfos
= rawChannel
.getChildNodes();
387 for (int j
= 0; j
< rawInfos
.getLength(); j
++) {
388 rawInfo
= rawInfos
.item(j
);
389 switch (rawInfo
.getNodeName()) {
391 channel
.setName(rawInfo
.getTextContent());
393 case MIStrings
.ENABLED
:
394 channel
.setState(TraceEnablement
.valueOfString(rawInfo
.getTextContent()));
396 case MIStrings
.EVENTS
:
397 List
<IEventInfo
> events
= new ArrayList
<>();
398 getEventInfo(rawInfo
.getChildNodes(), events
);
399 channel
.setEvents(events
);
401 case MIStrings
.ATTRIBUTES
:
402 NodeList rawAttributes
= rawInfo
.getChildNodes();
403 for (int k
= 0; k
< rawAttributes
.getLength(); k
++) {
404 Node attribute
= rawAttributes
.item(k
);
405 switch (attribute
.getNodeName()) {
406 case MIStrings
.OVERWRITE_MODE
:
407 channel
.setOverwriteMode(!LTTngControlServiceConstants
.OVERWRITE_MODE_ATTRIBUTE_FALSE_MI
.equalsIgnoreCase(attribute
.getTextContent()));
409 case MIStrings
.SUBBUF_SIZE
:
410 channel
.setSubBufferSize(Long
.valueOf(attribute
.getTextContent()));
412 case MIStrings
.NUM_SUBBUF
:
413 channel
.setNumberOfSubBuffers(Integer
.valueOf(attribute
.getTextContent()));
415 case MIStrings
.SWITCH_TIMER_INTERVAL
:
416 channel
.setSwitchTimer(Long
.valueOf(attribute
.getTextContent()));
418 case MIStrings
.READ_TIMER_INTERVAL
:
419 channel
.setReadTimer(Long
.valueOf(attribute
.getTextContent()));
421 case MIStrings
.OUTPUT_TYPE
:
422 channel
.setOutputType(attribute
.getTextContent());
424 case MIStrings
.TRACEFILE_SIZE
:
425 channel
.setMaxSizeTraceFiles(Integer
.parseInt(attribute
.getTextContent()));
427 case MIStrings
.TRACEFILE_COUNT
:
428 channel
.setMaxNumberTraceFiles(Integer
.parseInt(attribute
.getTextContent()));
430 case MIStrings
.LIVE_TIMER_INTERVAL
:
431 // TODO: currently not supported by tmf
442 channels
.add(channel
);
449 public ISnapshotInfo
getSnapshotInfo(String sessionName
, IProgressMonitor monitor
) throws ExecutionException
{
455 public List
<IBaseEventInfo
> getKernelProvider(IProgressMonitor monitor
) throws ExecutionException
{
456 StringBuffer command
= createCommand(LTTngControlServiceConstants
.COMMAND_LIST_KERNEL
);
457 ICommandResult result
= executeCommand(command
.toString(), monitor
, false);
458 List
<IBaseEventInfo
> events
= new ArrayList
<>();
460 if (isError(result
) && result
.getErrorOutput() != null) {
461 // Ignore the following 2 cases:
462 // Spawning a session daemon
463 // Error: Unable to list kernel events
465 // Error: Unable to list kernel events
466 if (ignoredPattern(result
.getErrorOutput(), LTTngControlServiceConstants
.LIST_KERNEL_NO_KERNEL_PROVIDER_PATTERN
)) {
469 throw new ExecutionException(Messages
.TraceControl_CommandError
+ LTTngControlServiceConstants
.COMMAND_LIST_KERNEL
);
472 Document document
= getDocumentFromStrings(result
.getOutput());
473 NodeList rawEvents
= document
.getElementsByTagName(MIStrings
.EVENT
);
474 getBaseEventInfo(rawEvents
, events
);
479 public List
<IUstProviderInfo
> getUstProvider(IProgressMonitor monitor
) throws ExecutionException
{
480 StringBuffer command
= createCommand(LTTngControlServiceConstants
.COMMAND_LIST_UST
);
482 command
.append(LTTngControlServiceConstants
.OPTION_FIELDS
);
485 ICommandResult result
= executeCommand(command
.toString(), monitor
, false);
486 List
<IUstProviderInfo
> allProviders
= new ArrayList
<>();
488 if (isError(result
) && result
.getErrorOutput() != null) {
489 // Ignore the following 2 cases:
490 // Spawning a session daemon
491 // Error: Unable to list UST events: Listing UST events failed
493 // Error: Unable to list UST events: Listing UST events failed
494 if (ignoredPattern(result
.getErrorOutput(), LTTngControlServiceConstants
.LIST_UST_NO_UST_PROVIDER_PATTERN
)) {
497 throw new ExecutionException(Messages
.TraceControl_CommandError
+ LTTngControlServiceConstants
.COMMAND_LIST_UST
);
500 Document document
= getDocumentFromStrings(result
.getOutput());
501 NodeList rawProviders
= document
.getElementsByTagName(MIStrings
.PID
);
503 IUstProviderInfo providerInfo
= null;
505 for (int i
= 0; i
< rawProviders
.getLength(); i
++) {
506 Node provider
= rawProviders
.item(i
);
507 Node name
= getFirstOf(provider
.getChildNodes(), MIStrings
.NAME
);
509 throw new ExecutionException(Messages
.TraceControl_MiInvalidProviderError
);
511 providerInfo
= new UstProviderInfo(name
.getTextContent());
514 NodeList infos
= provider
.getChildNodes();
515 for (int j
= 0; j
< infos
.getLength(); j
++) {
516 Node info
= infos
.item(j
);
517 switch (info
.getNodeName()) {
518 case MIStrings
.PID_ID
:
519 providerInfo
.setPid(Integer
.parseInt(info
.getTextContent()));
521 case MIStrings
.EVENTS
:
522 List
<IBaseEventInfo
> events
= new ArrayList
<>();
523 NodeList rawEvents
= info
.getChildNodes();
524 getBaseEventInfo(rawEvents
, events
);
525 providerInfo
.setEvents(events
);
531 allProviders
.add(providerInfo
);
538 public ISessionInfo
createSession(ISessionInfo sessionInfo
, IProgressMonitor monitor
) throws ExecutionException
{
539 if (sessionInfo
.isStreamedTrace()) {
540 return createStreamedSession(sessionInfo
, monitor
);
543 StringBuffer command
= prepareSessionCreationCommand(sessionInfo
);
545 ICommandResult result
= executeCommand(command
.toString(), monitor
);
547 Document document
= getDocumentFromStrings(result
.getOutput());
548 NodeList sessions
= document
.getElementsByTagName(MIStrings
.SESSION
);
550 // Number of session should be equal to 1
551 if (sessions
.getLength() != 1) {
552 throw new ExecutionException(Messages
.TraceControl_CommandError
+ " " + command
+ "\n" //$NON-NLS-1$//$NON-NLS-2$
553 + NLS
.bind(Messages
.TraceControl_UnexpectedNumberOfElementError
, MIStrings
.SESSION
) + " " + sessions
.getLength()); //$NON-NLS-1$
556 // Fetch a session from output
557 ISessionInfo outputSession
= new SessionInfo(""); //$NON-NLS-1$
558 parseSession(outputSession
, sessions
.item(0));
560 // Verify session name
561 if ((outputSession
.getName().equals("")) || (!"".equals(sessionInfo
.getName()) && !outputSession
.getName().equals(sessionInfo
.getName()))) { //$NON-NLS-1$ //$NON-NLS-2$
562 // Unexpected name returned
563 throw new ExecutionException(Messages
.TraceControl_CommandError
+ " " + command
+ "\n" + //$NON-NLS-1$ //$NON-NLS-2$
564 Messages
.TraceControl_UnexpectedNameError
+ ": " + outputSession
.getName()); //$NON-NLS-1$
567 // Verify session path
568 if (!sessionInfo
.isSnapshotSession() &&
569 ((outputSession
.getSessionPath() == null) || ((sessionInfo
.getSessionPath() != null) && (!outputSession
.getSessionPath().contains(sessionInfo
.getSessionPath()))))) {
571 throw new ExecutionException(Messages
.TraceControl_CommandError
+ " " + command
+ "\n" + //$NON-NLS-1$ //$NON-NLS-2$
572 Messages
.TraceControl_UnexpectedPathError
+ ": " + outputSession
.getName()); //$NON-NLS-1$
575 if (sessionInfo
.isSnapshotSession()) {
576 // Make it a snapshot session - content of snapshot info need to
577 // set afterwards using getSession() or getSnapshotInfo()
578 outputSession
.setSnapshotInfo(new SnapshotInfo("")); //$NON-NLS-1$
581 return outputSession
;
584 private ISessionInfo
createStreamedSession(ISessionInfo sessionInfo
, IProgressMonitor monitor
) throws ExecutionException
{
586 StringBuffer command
= prepareStreamedSessionCreationCommand(sessionInfo
);
588 ICommandResult result
= executeCommand(command
.toString(), monitor
);
590 Document document
= getDocumentFromStrings(result
.getOutput());
591 NodeList sessions
= document
.getElementsByTagName(MIStrings
.SESSION
);
593 // Number of session should be equal to 1
594 if (sessions
.getLength() != 1) {
595 throw new ExecutionException(Messages
.TraceControl_CommandError
+ " " + command
+ "\n" //$NON-NLS-1$//$NON-NLS-2$
596 + NLS
.bind(Messages
.TraceControl_UnexpectedNumberOfElementError
, MIStrings
.SESSION
) + " " + sessions
.getLength()); //$NON-NLS-1$
599 // Fetch a session from output
600 ISessionInfo outputSession
= new SessionInfo(""); //$NON-NLS-1$
601 parseSession(outputSession
, sessions
.item(0));
603 // Verify session name
604 if ((outputSession
.getName().equals("")) || (!"".equals(sessionInfo
.getName()) && !outputSession
.getName().equals(sessionInfo
.getName()))) { //$NON-NLS-1$ //$NON-NLS-2$
605 // Unexpected name returned
606 throw new ExecutionException(Messages
.TraceControl_CommandError
+ " " + command
+ "\n" + //$NON-NLS-1$ //$NON-NLS-2$
607 Messages
.TraceControl_UnexpectedNameError
+ ": " + outputSession
.getName()); //$NON-NLS-1$
610 sessionInfo
.setName(outputSession
.getName());
611 sessionInfo
.setStreamedTrace(true);
613 // Verify session path
614 if (sessionInfo
.getNetworkUrl() != null) {
615 if (!sessionInfo
.isSnapshotSession() && (outputSession
.getSessionPath() == null)) {
617 throw new ExecutionException(Messages
.TraceControl_CommandError
+ " " + command
+ "\n" + //$NON-NLS-1$ //$NON-NLS-2$
618 Messages
.TraceControl_UnexpectedPathError
+ ": " + outputSession
.getName()); //$NON-NLS-1$
621 if (sessionInfo
.isSnapshotSession()) {
622 sessionInfo
.setStreamedTrace(false);
624 sessionInfo
.setSessionPath(outputSession
.getSessionPath());
625 // Check file protocol
626 Matcher matcher
= LTTngControlServiceConstants
.TRACE_FILE_PROTOCOL_PATTERN
.matcher(outputSession
.getSessionPath());
627 if (matcher
.matches()) {
628 sessionInfo
.setStreamedTrace(false);
633 // When using controlUrl and dataUrl the full session path is not known
635 // and will be set later on when listing the session
641 public void destroySession(String sessionName
, IProgressMonitor monitor
) throws ExecutionException
{
642 String newName
= formatParameter(sessionName
);
644 StringBuffer command
= createCommand(LTTngControlServiceConstants
.COMMAND_DESTROY_SESSION
, newName
);
646 ICommandResult result
= executeCommand(command
.toString(), monitor
, false);
647 String
[] errorOutput
= result
.getErrorOutput();
649 if (isError(result
) && (errorOutput
!= null)) {
650 // Don't treat this as an error
651 if (ignoredPattern(errorOutput
, LTTngControlServiceConstants
.SESSION_NOT_FOUND_ERROR_PATTERN
)) {
655 throw new ExecutionException(Messages
.TraceControl_CommandError
+ " " + command
.toString() + "\n" + formatOutput(result
)); //$NON-NLS-1$ //$NON-NLS-2$
658 // Check for action effect
659 Document doc
= getDocumentFromStrings(result
.getOutput());
660 NodeList sessions
= doc
.getElementsByTagName(MIStrings
.SESSION
);
661 if (sessions
.getLength() != 1) {
662 throw new ExecutionException(NLS
.bind(Messages
.TraceControl_MiInvalidNumberOfElementError
, MIStrings
.SESSION
));
665 Node rawSessionName
= getFirstOf(sessions
.item(0).getChildNodes(), MIStrings
.NAME
);
666 if (rawSessionName
== null) {
667 throw new ExecutionException(Messages
.TraceControl_MiMissingRequiredError
);
671 if (!rawSessionName
.getTextContent().equals(sessionName
)) {
672 throw new ExecutionException(NLS
.bind(Messages
.TraceControl_UnexpectedValueError
, rawSessionName
.getTextContent(), sessionName
));
677 public void enableChannels(String sessionName
, List
<String
> channelNames
, boolean isKernel
, IChannelInfo info
, IProgressMonitor monitor
) throws ExecutionException
{
678 // TODO Auto-generated method stub
683 public void disableChannels(String sessionName
, List
<String
> channelNames
, boolean isKernel
, IProgressMonitor monitor
) throws ExecutionException
{
684 // TODO Auto-generated method stub
689 public void enableEvents(String sessionName
, String channelName
, List
<String
> eventNames
, boolean isKernel
, String filterExpression
, IProgressMonitor monitor
) throws ExecutionException
{
690 // TODO Auto-generated method stub
695 public void enableSyscalls(String sessionName
, String channelName
, IProgressMonitor monitor
) throws ExecutionException
{
696 // TODO Auto-generated method stub
701 public void enableProbe(String sessionName
, String channelName
, String eventName
, boolean isFunction
, String probe
, IProgressMonitor monitor
) throws ExecutionException
{
702 // TODO Auto-generated method stub
707 public void enableLogLevel(String sessionName
, String channelName
, String eventName
, LogLevelType logLevelType
, TraceLogLevel level
, String filterExpression
, IProgressMonitor monitor
) throws ExecutionException
{
708 // TODO Auto-generated method stub
713 public void disableEvent(String sessionName
, String channelName
, List
<String
> eventNames
, boolean isKernel
, IProgressMonitor monitor
) throws ExecutionException
{
714 // TODO Auto-generated method stub
719 public List
<String
> getContextList(IProgressMonitor monitor
) throws ExecutionException
{
720 // TODO Auto-generated method stub
725 public void addContexts(String sessionName
, String channelName
, String eventName
, boolean isKernel
, List
<String
> contexts
, IProgressMonitor monitor
) throws ExecutionException
{
726 // TODO Auto-generated method stub
731 public void calibrate(boolean isKernel
, IProgressMonitor monitor
) throws ExecutionException
{
732 // TODO Auto-generated method stub
737 public void recordSnapshot(String sessionName
, IProgressMonitor monitor
) throws ExecutionException
{
738 // TODO Auto-generated method stub
743 public void runCommands(IProgressMonitor monitor
, List
<String
> commands
) throws ExecutionException
{
744 // TODO Auto-generated method stub
750 * array of string that make up a command line
751 * @return string buffer with created command line
754 protected StringBuffer
createCommand(String
... strings
) {
755 StringBuffer command
= new StringBuffer();
756 command
.append(LTTngControlServiceConstants
.CONTROL_COMMAND_MI_XML
);
757 command
.append(getTracingGroupOption());
758 for (String string
: strings
) {
759 command
.append(string
);
765 * @param xmlBaseEvents
766 * a Node list of base xml event element
768 * list of event generated by the parsing of the xml event
770 * @throws ExecutionException
771 * when a raw event is not a complete/valid xml event
773 private static void getBaseEventInfo(NodeList xmlBaseEvents
, List
<IBaseEventInfo
> events
) throws ExecutionException
{
774 IBaseEventInfo eventInfo
= null;
775 for (int i
= 0; i
< xmlBaseEvents
.getLength(); i
++) {
776 NodeList rawInfos
= xmlBaseEvents
.item(i
).getChildNodes();
778 if (xmlBaseEvents
.item(i
).getNodeName().equalsIgnoreCase(MIStrings
.EVENT
)) {
779 Node rawName
= getFirstOf(rawInfos
, MIStrings
.NAME
);
780 if (rawName
== null) {
781 throw new ExecutionException(Messages
.TraceControl_MiMissingRequiredError
);
783 eventInfo
= new BaseEventInfo(rawName
.getTextContent());
785 // Populate the event
786 for (int j
= 0; j
< rawInfos
.getLength(); j
++) {
787 Node infoNode
= rawInfos
.item(j
);
788 switch (infoNode
.getNodeName()) {
790 eventInfo
.setEventType(infoNode
.getTextContent());
792 case MIStrings
.LOGLEVEL
:
793 eventInfo
.setLogLevel(infoNode
.getTextContent());
795 case MIStrings
.EVENT_FIELDS
:
796 List
<IFieldInfo
> fields
= new ArrayList
<>();
797 getFieldInfo(infoNode
.getChildNodes(), fields
);
798 eventInfo
.setFields(fields
);
804 events
.add(eventInfo
);
810 * @param xmlBaseEvents
811 * a Node list of xml event element linked to a session
813 * list of event generated by the parsing of the xml event
815 * @throws ExecutionException
816 * when a raw event is not a complete/valid xml event
818 static void getEventInfo(NodeList xmlEvents
, List
<IEventInfo
> events
) throws ExecutionException
{
819 IEventInfo eventInfo
= null;
820 for (int i
= 0; i
< xmlEvents
.getLength(); i
++) {
821 NodeList rawInfos
= xmlEvents
.item(i
).getChildNodes();
823 if (xmlEvents
.item(i
).getNodeName().equalsIgnoreCase(MIStrings
.EVENT
)) {
824 Node rawName
= getFirstOf(rawInfos
, MIStrings
.NAME
);
825 if (rawName
== null) {
826 throw new ExecutionException(Messages
.TraceControl_MiMissingRequiredError
);
829 eventInfo
= new EventInfo(rawName
.getTextContent());
832 for (int j
= 0; j
< rawInfos
.getLength(); j
++) {
833 Node infoNode
= rawInfos
.item(j
);
834 switch (infoNode
.getNodeName()) {
836 eventInfo
.setEventType(infoNode
.getTextContent());
838 case MIStrings
.LOGLEVEL_TYPE
:
839 eventInfo
.setLogLevelType(LogLevelType
.valueOfString(infoNode
.getTextContent()));
841 case MIStrings
.LOGLEVEL
:
842 eventInfo
.setLogLevel(TraceLogLevel
.valueOfString(infoNode
.getTextContent()));
844 case MIStrings
.ENABLED
:
845 eventInfo
.setState(TraceEnablement
.valueOfString(infoNode
.getTextContent()));
847 case MIStrings
.FILTER
:
849 // See bug 334 http://bugs.lttng.org/issues/334 from
851 // For now we emulate the a behavior, and simply put
853 eventInfo
.setFilterExpression("with filter"); //$NON-NLS-1$
855 case MIStrings
.EXCLUSION
:
856 // TODO:Currently not supported by tmf
857 // ExclusionS element is ignored
864 boolean isProbeFunction
= (eventInfo
.getEventType().equals(TraceEventType
.PROBE
)) || (eventInfo
.getEventType().equals(TraceEventType
.FUNCTION
));
865 if (isProbeFunction
) {
866 IProbeEventInfo probeEvent
= new ProbeEventInfo(eventInfo
);
867 eventInfo
= probeEvent
;
869 Node rawAttributes
= getFirstOf(rawInfos
, MIStrings
.ATTRIBUTES
);
870 if (rawAttributes
== null) {
871 throw new ExecutionException(Messages
.TraceControl_MiMissingRequiredError
);
874 Node rawDataNode
= null;
875 switch (probeEvent
.getEventType()) {
877 rawDataNode
= getFirstOf(rawAttributes
.getChildNodes(), MIStrings
.PROBE_ATTRIBUTES
);
880 rawDataNode
= getFirstOf(rawAttributes
.getChildNodes(), MIStrings
.FUNCTION_ATTRIBUTES
);
886 throw new ExecutionException(Messages
.TraceControl_MiInvalidElementError
);
889 if (rawDataNode
== null) {
890 throw new ExecutionException(Messages
.TraceControl_MiInvalidElementError
);
894 NodeList rawDatas
= rawDataNode
.getChildNodes();
895 for (int j
= 0; j
< rawDatas
.getLength(); j
++) {
896 Node rawData
= rawDatas
.item(j
);
897 switch (rawData
.getNodeName()) {
898 case MIStrings
.SYMBOL_NAME
:
899 probeEvent
.setSymbol(rawData
.getTextContent());
901 case MIStrings
.ADDRESS
:
902 probeEvent
.setAddress(rawData
.getTextContent());
904 case MIStrings
.OFFSET
:
905 probeEvent
.setOffset(rawData
.getTextContent());
913 // Syscalls does not have name.
914 // Let put one to make sure this is user friendly via UI
915 if (eventInfo
.getEventType().equals(TraceEventType
.SYSCALL
)) {
916 eventInfo
.setName(TraceEventType
.SYSCALL
.getInName());
920 events
.add(eventInfo
);
927 * a list of xml event_field element
929 * a list of field generated by xml parsing
930 * @throws ExecutionException
931 * when parsing fail or required elements are missing
933 private static void getFieldInfo(NodeList fieldsList
, List
<IFieldInfo
> fields
) throws ExecutionException
{
934 IFieldInfo fieldInfo
= null;
935 for (int i
= 0; i
< fieldsList
.getLength(); i
++) {
936 Node field
= fieldsList
.item(i
);
937 if (field
.getNodeName().equalsIgnoreCase(MIStrings
.EVENT_FIELD
)) {
939 Node name
= getFirstOf(field
.getChildNodes(), MIStrings
.NAME
);
941 throw new ExecutionException(Messages
.TraceControl_MiMissingRequiredError
);
943 fieldInfo
= new FieldInfo(name
.getTextContent());
945 // Populate the field information
946 NodeList infos
= field
.getChildNodes();
947 for (int j
= 0; j
< infos
.getLength(); j
++) {
948 Node info
= infos
.item(j
);
949 switch (info
.getNodeName()) {
951 fieldInfo
.setFieldType(info
.getTextContent());
957 fields
.add(fieldInfo
);
963 * Retrieve the fist instance of a given node with tag name equal to tagName
967 * the list of Node to search against
969 * the tag name of the desired node
970 * @return the first occurrence of a node with a tag name equals to tagName
972 private static Node
getFirstOf(NodeList nodeList
, String tagName
) {
974 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
975 if (nodeList
.item(i
).getNodeName() == tagName
) {
976 node
= nodeList
.item(i
);