blob: 576ab896dccae75d4c46e3d3d05d93261e7cc884 [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2012, 2016 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Bernd Hufmann - Initial API and implementation
* Bernd Hufmann - Updated for support of LTTng Tools 2.1
* Simon Delisle - Updated for support of LTTng Tools 2.2
* Marc-Andre Laperle - Support for creating a live session
* Markus Schorn - Bug 448058: Use org.eclipse.remote in favor of RSE
**********************************************************************/
package org.eclipse.tracecompass.internal.lttng2.control.ui.views.service;
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
import static org.eclipse.tracecompass.common.core.NonNullUtils.nullToEmptyString;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.IBaseEventInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.IChannelInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.IDomainInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.IEventInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.IFieldInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.IProbeEventInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.ISessionInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.ISnapshotInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.ITraceLogLevel;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.IUstProviderInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.LogLevelType;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceDomainType;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceEventType;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.TraceLogLevel;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.BaseEventInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.BufferType;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.ChannelInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.DomainInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.EventInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.FieldInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.ProbeEventInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.SessionInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.SnapshotInfo;
import org.eclipse.tracecompass.internal.lttng2.control.core.model.impl.UstProviderInfo;
import org.eclipse.tracecompass.internal.lttng2.control.ui.views.logging.ControlCommandLogger;
import org.eclipse.tracecompass.internal.lttng2.control.ui.views.messages.Messages;
import org.eclipse.tracecompass.internal.lttng2.control.ui.views.preferences.ControlPreferences;
import org.eclipse.tracecompass.tmf.remote.core.shell.ICommandInput;
import org.eclipse.tracecompass.tmf.remote.core.shell.ICommandResult;
import org.eclipse.tracecompass.tmf.remote.core.shell.ICommandShell;
/**
* <p>
* Service for sending LTTng trace control commands to remote host.
* </p>
*
* @author Bernd Hufmann
*/
public class LTTngControlService implements ILttngControlService {
// ------------------------------------------------------------------------
// Attributes
// ------------------------------------------------------------------------
/**
* The command shell implementation
*/
private final @NonNull ICommandShell fCommandShell;
/**
* The version string.
*/
private @NonNull LttngVersion fVersion = LttngVersion.NULL_VERSION;
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
/**
* Constructor
*
* @param shell
* - the command shell implementation to use
*/
public LTTngControlService(@NonNull ICommandShell shell) {
fCommandShell = shell;
}
// ------------------------------------------------------------------------
// Accessors
// ------------------------------------------------------------------------
@Override
public String getVersionString() {
return nullToEmptyString(fVersion.toString());
}
@Override
public LttngVersion getVersion() {
return fVersion;
}
/**
* Sets the version of the LTTng 2.0 control service.
*
* @param version
* - a version to set
*/
public void setVersion(@Nullable String version) {
if (version != null) {
fVersion = new LttngVersion(version);
}
}
/**
* Sets the version of the LTTng 2.x control service.
*
* @param version
* - a version to set
*/
protected void setVersion(LttngVersion version) {
if (version != null) {
fVersion = version;
}
}
@Override
public boolean isVersionSupported(String version) {
LttngVersion tmp = new LttngVersion(version);
return (fVersion.compareTo(tmp) >= 0) ? true : false;
}
/**
* Returns the command shell implementation.
*
* @return the command shell implementation
*/
protected ICommandShell getCommandShell() {
return fCommandShell;
}
// ------------------------------------------------------------------------
// Operations
// ------------------------------------------------------------------------
@Override
public List<String> getSessionNames(IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_LIST);
ICommandResult result = executeCommand(command, monitor);
// Output:
// Available tracing sessions:
// 1) mysession1 (/home/user/lttng-traces/mysession1-20120123-083928)
// [inactive]
// 2) mysession (/home/user/lttng-traces/mysession-20120123-083318)
// [inactive]
//
// Use lttng list <session_name> for more details
ArrayList<String> retArray = new ArrayList<>();
for (String line : result.getOutput()) {
Matcher matcher = LTTngControlServiceConstants.SESSION_PATTERN.matcher(line);
if (matcher.matches()) {
retArray.add(matcher.group(2).trim());
}
}
return retArray;
}
/**
* Check if there is a pattern to be ignored into a sequence of string
*
* @param input
* an input list of Strings
* @param pattern
* the pattern to search for
* @return if the pattern exist in the array of string
*/
protected boolean ignoredPattern(List<String> input, Pattern pattern) {
for (String line : input) {
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
return true;
}
}
return false;
}
@Override
public ISessionInfo getSession(String sessionName, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_LIST, sessionName);
ICommandResult result = executeCommand(command, monitor);
int index = 0;
// Output:
// Tracing session mysession2: [inactive]
// Trace path: /home/eedbhu/lttng-traces/mysession2-20120123-110330
ISessionInfo sessionInfo = new SessionInfo(sessionName);
while (index < result.getOutput().size()) {
// Tracing session mysession2: [inactive]
// Trace path: /home/eedbhu/lttng-traces/mysession2-20120123-110330
//
// === Domain: Kernel ===
//
String line = result.getOutput().get(index);
Matcher matcher = LTTngControlServiceConstants.TRACE_SESSION_PATTERN.matcher(line);
if (matcher.matches()) {
sessionInfo.setSessionState(matcher.group(2));
index++;
continue;
}
matcher = LTTngControlServiceConstants.TRACE_SNAPSHOT_SESSION_PATTERN.matcher(line);
if (matcher.matches()) {
sessionInfo.setSessionState(matcher.group(2));
// real name will be set later
ISnapshotInfo snapshotInfo = new SnapshotInfo(""); //$NON-NLS-1$
sessionInfo.setSnapshotInfo(snapshotInfo);
index++;
continue;
}
if (!sessionInfo.isSnapshotSession()) {
matcher = LTTngControlServiceConstants.TRACE_NETWORK_PATH_PATTERN.matcher(line);
if (matcher.matches()) {
sessionInfo.setStreamedTrace(true);
}
matcher = LTTngControlServiceConstants.TRACE_SESSION_PATH_PATTERN.matcher(line);
if (matcher.matches()) {
sessionInfo.setSessionPath(matcher.group(1).trim());
index++;
continue;
}
}
matcher = LTTngControlServiceConstants.DOMAIN_KERNEL_PATTERN.matcher(line);
if (matcher.matches()) {
// Create Domain
IDomainInfo domainInfo = new DomainInfo(Messages.TraceControl_KernelDomainDisplayName);
// set kernel domain
domainInfo.setDomain(TraceDomainType.KERNEL);
// in domain kernel
ArrayList<IChannelInfo> channels = new ArrayList<>();
index = parseDomain(result.getOutput(), index, channels, domainInfo);
if (!channels.isEmpty()) {
// add domain
sessionInfo.addDomain(domainInfo);
// set channels
domainInfo.setChannels(channels);
}
continue;
}
matcher = LTTngControlServiceConstants.DOMAIN_UST_GLOBAL_PATTERN.matcher(line);
if (matcher.matches()) {
IDomainInfo domainInfo = new DomainInfo(Messages.TraceControl_UstGlobalDomainDisplayName);
// set kernel domain
domainInfo.setDomain(TraceDomainType.UST);
// in domain UST
ArrayList<IChannelInfo> channels = new ArrayList<>();
index = parseDomain(result.getOutput(), index, channels, domainInfo);
if (!channels.isEmpty()) {
// add domain
sessionInfo.addDomain(domainInfo);
// set channels
domainInfo.setChannels(channels);
}
continue;
}
matcher = LTTngControlServiceConstants.LIST_LIVE_TIMER_INTERVAL_PATTERN.matcher(line);
if (matcher.matches()) {
long liveDelay = Long.parseLong(matcher.group(1));
if ((liveDelay > 0) && (liveDelay <= LTTngControlServiceConstants.MAX_LIVE_TIMER_INTERVAL)) {
sessionInfo.setLive(true);
sessionInfo.setLiveUrl(SessionInfo.DEFAULT_LIVE_NETWORK_URL);
sessionInfo.setLivePort(SessionInfo.DEFAULT_LIVE_PORT);
sessionInfo.setLiveDelay(liveDelay);
}
index++;
continue;
}
index++;
}
if (sessionInfo.isSnapshotSession()) {
ISnapshotInfo snapshot = getSnapshotInfo(sessionName, monitor);
sessionInfo.setSnapshotInfo(snapshot);
}
return sessionInfo;
}
@Override
public ISnapshotInfo getSnapshotInfo(String sessionName, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_SNAPSHOT, LTTngControlServiceConstants.COMMAND_LIST_SNAPSHOT_OUTPUT, LTTngControlServiceConstants.OPTION_SESSION, sessionName);
ICommandResult result = executeCommand(command, monitor);
int index = 0;
// Output:
// [1] snapshot-1: /home/user/lttng-traces/my-20130909-114431
// or
// [3] snapshot-3: net4://172.0.0.1/
ISnapshotInfo snapshotInfo = new SnapshotInfo(""); //$NON-NLS-1$
while (index < result.getOutput().size()) {
String line = result.getOutput().get(index);
Matcher matcher = LTTngControlServiceConstants.LIST_SNAPSHOT_OUTPUT_PATTERN.matcher(line);
if (matcher.matches()) {
snapshotInfo.setId(Integer.valueOf(matcher.group(1)));
snapshotInfo.setName(matcher.group(2));
snapshotInfo.setSnapshotPath(matcher.group(3));
Matcher matcher2 = LTTngControlServiceConstants.SNAPSHOT_NETWORK_PATH_PATTERN.matcher(snapshotInfo.getSnapshotPath());
if (matcher2.matches()) {
snapshotInfo.setStreamedSnapshot(true);
}
index++;
break;
}
index++;
}
return snapshotInfo;
}
@Override
public List<IBaseEventInfo> getKernelProvider(IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_LIST, LTTngControlServiceConstants.OPTION_KERNEL);
ICommandResult result = executeCommand(command, monitor, false);
List<IBaseEventInfo> events = new ArrayList<>();
// Ignore the following 2 cases:
// Spawning a session daemon
// Error: Unable to list kernel events
// or:
// Error: Unable to list kernel events
//
if (ignoredPattern(result.getErrorOutput(), LTTngControlServiceConstants.LIST_KERNEL_NO_KERNEL_PROVIDER_PATTERN)) {
return events;
}
if (isError(result)) {
throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + result.toString()); //$NON-NLS-1$ //$NON-NLS-2$
}
// Kernel events:
// -------------
// sched_kthread_stop (type: tracepoint)
getProviderEventInfo(result.getOutput(), 0, events);
return events;
}
@Override
public List<IUstProviderInfo> getUstProvider() throws ExecutionException {
return getUstProvider(new NullProgressMonitor());
}
@Override
public List<IUstProviderInfo> getUstProvider(IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_LIST, LTTngControlServiceConstants.OPTION_UST);
if (isVersionSupported("2.1.0")) { //$NON-NLS-1$
command.add(LTTngControlServiceConstants.OPTION_FIELDS);
}
ICommandResult result = executeCommand(command, monitor, false);
List<IUstProviderInfo> allProviders = new ArrayList<>();
// Workaround for versions 2.0.x which causes a segmentation fault for
// this command
// if LTTng Tools is compiled without UST support.
if (!isVersionSupported("2.1.0") && (result.getResult() != 0)) { //$NON-NLS-1$
return allProviders;
}
// Ignore the following 2 cases:
// Spawning a session daemon
// Error: Unable to list UST events: Listing UST events failed
// or:
// Error: Unable to list UST events: Listing UST events failed
//
if (ignoredPattern(result.getErrorOutput(), LTTngControlServiceConstants.LIST_UST_NO_UST_PROVIDER_PATTERN)) {
return allProviders;
}
if (isError(result)) {
throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + result.toString()); //$NON-NLS-1$ //$NON-NLS-2$
}
// Note that field print-outs exists for version >= 2.1.0
//
// UST events:
// -------------
//
// PID: 3635 - Name:
// /home/user/git/lttng-ust/tests/hello.cxx/.libs/lt-hello
// ust_tests_hello:tptest_sighandler (loglevel: TRACE_EMERG0) (type:
// tracepoint)
// ust_tests_hello:tptest (loglevel: TRACE_EMERG0) (type: tracepoint)
// field: doublefield (float)
// field: floatfield (float)
// field: stringfield (string)
//
// PID: 6459 - Name:
// /home/user/git/lttng-ust/tests/hello.cxx/.libs/lt-hello
// ust_tests_hello:tptest_sighandler (loglevel: TRACE_EMERG0) (type:
// tracepoint)
// ust_tests_hello:tptest (loglevel: TRACE_EMERG0) (type: tracepoint)
// field: doublefield (float)
// field: floatfield (float)
// field: stringfield (string)
IUstProviderInfo provider = null;
int index = 0;
while (index < result.getOutput().size()) {
String line = result.getOutput().get(index);
Matcher matcher = LTTngControlServiceConstants.UST_PROVIDER_PATTERN.matcher(line);
if (matcher.matches()) {
provider = new UstProviderInfo(matcher.group(2).trim());
provider.setPid(Integer.valueOf(matcher.group(1).trim()));
List<IBaseEventInfo> events = new ArrayList<>();
index = getProviderEventInfo(result.getOutput(), ++index, events);
provider.setEvents(events);
allProviders.add(provider);
} else {
index++;
}
}
return allProviders;
}
@Override
public ISessionInfo createSession(ISessionInfo sessionInfo, IProgressMonitor monitor) throws ExecutionException {
if (sessionInfo.isStreamedTrace()) {
return createStreamedSession(sessionInfo, monitor);
}
ICommandInput command = prepareSessionCreationCommand(sessionInfo);
ICommandResult result = executeCommand(command, monitor);
// Session myssession2 created.
// Traces will be written in
// /home/user/lttng-traces/myssession2-20120209-095418
List<String> output = result.getOutput();
// Get and session name and path
String name = null;
String path = null;
for (String line : output) {
Matcher nameMatcher = LTTngControlServiceConstants.CREATE_SESSION_NAME_PATTERN.matcher(line);
Matcher pathMatcher = LTTngControlServiceConstants.CREATE_SESSION_PATH_PATTERN.matcher(line);
if (nameMatcher.matches()) {
name = String.valueOf(nameMatcher.group(1).trim());
} else if (pathMatcher.matches()) {
path = String.valueOf(pathMatcher.group(1).trim());
}
}
// Verify session name
if ((name == null) || (!"".equals(sessionInfo.getName()) && !name.equals(sessionInfo.getName()))) { //$NON-NLS-1$
// Unexpected name returned
throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
Messages.TraceControl_UnexpectedNameError + ": " + name); //$NON-NLS-1$
}
sessionInfo.setName(name);
// Verify session path
if (!sessionInfo.isSnapshotSession() &&
((path == null) || ((sessionInfo.getSessionPath() != null) && (!path.contains(sessionInfo.getSessionPath()))))) {
// Unexpected path
throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
Messages.TraceControl_UnexpectedPathError + ": " + name); //$NON-NLS-1$
}
if (sessionInfo.isSnapshotSession()) {
// Make it a snapshot session - content of snapshot info need to
// set afterwards using getSession() or getSnapshotInfo()
sessionInfo.setSnapshotInfo(new SnapshotInfo("")); //$NON-NLS-1$
} else {
sessionInfo.setSessionPath(path);
}
return sessionInfo;
}
/**
* Basic generation of command for session creation
*
* @param sessionInfo
* the session to create
* @return the basic command for command creation
*/
protected @NonNull ICommandInput prepareSessionCreationCommand(ISessionInfo sessionInfo) {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_CREATE_SESSION);
if (!sessionInfo.getName().isEmpty()) {
command.add(sessionInfo.getName());
}
String newPath = sessionInfo.getSessionPath();
if (newPath != null && !"".equals(newPath)) { //$NON-NLS-1$
command.add(LTTngControlServiceConstants.OPTION_OUTPUT_PATH);
command.add(newPath);
}
if (sessionInfo.isSnapshotSession()) {
command.add(LTTngControlServiceConstants.OPTION_SNAPSHOT);
}
return command;
}
private @NonNull ISessionInfo createStreamedSession(ISessionInfo sessionInfo, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = prepareStreamedSessionCreationCommand(sessionInfo);
ICommandResult result = executeCommand(command, monitor);
// Verify output
List<String> output = result.getOutput();
// Get and session name and path
String name = null;
String path = null;
for (String line : output) {
Matcher nameMatcher = LTTngControlServiceConstants.CREATE_SESSION_NAME_PATTERN.matcher(line);
Matcher pathMatcher = LTTngControlServiceConstants.CREATE_SESSION_PATH_PATTERN.matcher(line);
if (nameMatcher.matches()) {
name = String.valueOf(nameMatcher.group(1).trim());
} else if (pathMatcher.matches() && (sessionInfo.getNetworkUrl() != null)) {
path = String.valueOf(pathMatcher.group(1).trim());
}
}
// Verify session name
if ((name == null) || (!"".equals(sessionInfo.getName()) && !name.equals(sessionInfo.getName()))) { //$NON-NLS-1$
// Unexpected name returned
throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
Messages.TraceControl_UnexpectedNameError + ": " + name); //$NON-NLS-1$
}
sessionInfo.setName(name);
sessionInfo.setStreamedTrace(true);
// Verify session path
if (sessionInfo.getNetworkUrl() != null) {
if (!sessionInfo.isSnapshotSession() && (path == null)) {
// Unexpected path
throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
Messages.TraceControl_UnexpectedPathError + ": " + name); //$NON-NLS-1$
}
if (sessionInfo.isSnapshotSession()) {
sessionInfo.setStreamedTrace(false);
} else {
sessionInfo.setSessionPath(path);
// Check file protocol
Matcher matcher = LTTngControlServiceConstants.TRACE_FILE_PROTOCOL_PATTERN.matcher(path);
if (matcher.matches()) {
sessionInfo.setStreamedTrace(false);
}
}
}
// When using controlUrl and dataUrl the full session path is not known
// yet and will be set later on when listing the session
return sessionInfo;
}
/**
* Basic generation of command for streamed session creation
*
* @param sessionInfo
* the session to create
* @return the basic command for command creation
*/
protected @NonNull ICommandInput prepareStreamedSessionCreationCommand(ISessionInfo sessionInfo) {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_CREATE_SESSION);
if (!sessionInfo.getName().isEmpty()) {
command.add(sessionInfo.getName());
}
if (sessionInfo.isSnapshotSession()) {
command.add(LTTngControlServiceConstants.OPTION_SNAPSHOT);
} else if (sessionInfo.isLive()) {
command.add(LTTngControlServiceConstants.OPTION_LIVE);
if (sessionInfo.getLiveDelay() != LTTngControlServiceConstants.UNUSED_VALUE) {
command.add(String.valueOf(sessionInfo.getLiveDelay()));
}
}
if (sessionInfo.getNetworkUrl() != null) {
command.add(LTTngControlServiceConstants.OPTION_NETWORK_URL);
command.add(sessionInfo.getNetworkUrl());
} else {
command.add(LTTngControlServiceConstants.OPTION_CONTROL_URL);
command.add(sessionInfo.getControlUrl());
command.add(LTTngControlServiceConstants.OPTION_DATA_URL);
command.add(sessionInfo.getDataUrl());
}
return command;
}
@Override
public void destroySession(String sessionName, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_DESTROY_SESSION, sessionName);
ICommandResult result = executeCommand(command, monitor, false);
boolean isError = isError(result);
if (isError && !ignoredPattern(result.getErrorOutput(), LTTngControlServiceConstants.SESSION_NOT_FOUND_ERROR_PATTERN)) {
throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + result.toString()); //$NON-NLS-1$ //$NON-NLS-2$
}
// Session <sessionName> destroyed
}
@Override
public void startSession(String sessionName, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_START_SESSION, sessionName);
executeCommand(command, monitor);
// Session <sessionName> started
}
@Override
public void stopSession(String sessionName, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_STOP_SESSION, sessionName);
executeCommand(command, monitor);
// Session <sessionName> stopped
}
@Override
public void enableChannels(String sessionName, List<String> channelNames, TraceDomainType domain, IChannelInfo info, IProgressMonitor monitor) throws ExecutionException {
// no channels to enable
if (channelNames.isEmpty()) {
return;
}
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_ENABLE_CHANNEL);
command.add(toCsv(channelNames));
command.add(getDomainOption(domain));
command.add(LTTngControlServiceConstants.OPTION_SESSION);
command.add(sessionName);
if (info != null) {
// --discard Discard event when buffers are full (default)
// --overwrite Flight recorder mode
if (info.isOverwriteMode()) {
command.add(LTTngControlServiceConstants.OPTION_OVERWRITE);
}
// --subbuf-size SIZE Subbuffer size in bytes
// (default: 4096, kernel default: 262144)
if (info.getSubBufferSize() != LTTngControlServiceConstants.UNUSED_VALUE) {
command.add(LTTngControlServiceConstants.OPTION_SUB_BUFFER_SIZE);
command.add(String.valueOf(info.getSubBufferSize()));
}
// --num-subbuf NUM Number of subbufers
if (info.getNumberOfSubBuffers() != LTTngControlServiceConstants.UNUSED_VALUE) {
command.add(LTTngControlServiceConstants.OPTION_NUM_SUB_BUFFERS);
command.add(String.valueOf(info.getNumberOfSubBuffers()));
}
// --switch-timer USEC Switch timer interval in usec
if (info.getSwitchTimer() != LTTngControlServiceConstants.UNUSED_VALUE) {
command.add(LTTngControlServiceConstants.OPTION_SWITCH_TIMER);
command.add(String.valueOf(info.getSwitchTimer()));
}
// --read-timer USEC Read timer interval in usec
if (info.getReadTimer() != LTTngControlServiceConstants.UNUSED_VALUE) {
command.add(LTTngControlServiceConstants.OPTION_READ_TIMER);
command.add(String.valueOf(info.getReadTimer()));
}
if (isVersionSupported("2.2.0")) { //$NON-NLS-1$
// --buffers-uid Every application sharing the same UID use the
// same buffers --buffers-pid Buffers are allocated per PID
if (domain.equals(TraceDomainType.UST)) {
if (info.getBufferType() == BufferType.BUFFER_PER_PID) {
command.add(LTTngControlServiceConstants.OPTION_PER_PID_BUFFERS);
} else if (info.getBufferType() == BufferType.BUFFER_PER_UID) {
command.add(LTTngControlServiceConstants.OPTION_PER_UID_BUFFERS);
}
}
// -C SIZE Maximum size of trace files in bytes
if (info.getMaxSizeTraceFiles() != LTTngControlServiceConstants.UNUSED_VALUE) {
command.add(LTTngControlServiceConstants.OPTION_MAX_SIZE_TRACE_FILES);
command.add(String.valueOf(info.getMaxSizeTraceFiles()));
}
// -W NUM Maximum number of trace files
if (info.getMaxNumberTraceFiles() != LTTngControlServiceConstants.UNUSED_VALUE) {
command.add(LTTngControlServiceConstants.OPTION_MAX_TRACE_FILES);
command.add(String.valueOf(info.getMaxNumberTraceFiles()));
}
}
}
executeCommand(command, monitor);
}
@Override
public void disableChannels(String sessionName, List<String> channelNames, TraceDomainType domain, IProgressMonitor monitor) throws ExecutionException {
// no channels to enable
if (channelNames.isEmpty()) {
return;
}
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_DISABLE_CHANNEL);
command.add(toCsv(channelNames));
command.add(getDomainOption(domain));
command.add(LTTngControlServiceConstants.OPTION_SESSION);
command.add(sessionName);
executeCommand(command, monitor);
}
@Override
public void enableEvents(String sessionName, String channelName, List<String> eventNames, TraceDomainType domain, String filterExpression, List<String> excludedEvents, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_ENABLE_EVENT);
boolean isAllEvents = ALL_EVENTS.equals(eventNames);
if (isAllEvents || (eventNames == null) || (eventNames.isEmpty())) {
command.add(LTTngControlServiceConstants.OPTION_ALL);
} else {
command.add(toCsv(eventNames));
}
command.add(getDomainOption(domain));
command.add(LTTngControlServiceConstants.OPTION_SESSION);
command.add(sessionName);
if (channelName != null) {
command.add(LTTngControlServiceConstants.OPTION_CHANNEL);
command.add(channelName);
}
if (!isAllEvents) {
command.add(LTTngControlServiceConstants.OPTION_TRACEPOINT);
}
if (filterExpression != null) {
command.add(LTTngControlServiceConstants.OPTION_FILTER);
command.add(filterExpression);
}
if (excludedEvents != null && !excludedEvents.isEmpty()) {
command.add(LTTngControlServiceConstants.OPTION_EXCLUDE);
command.add(toCsv(excludedEvents));
}
executeCommand(command, monitor);
}
@Override
public void enableSyscalls(String sessionName, String channelName, List<String> syscallNames, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_ENABLE_EVENT);
boolean isAllSyscalls = ALL_EVENTS.equals(syscallNames);
if (isAllSyscalls || (syscallNames == null) || (syscallNames.isEmpty())) {
command.add(LTTngControlServiceConstants.OPTION_ALL);
} else {
command.add(toCsv(syscallNames));
}
command.add(LTTngControlServiceConstants.OPTION_KERNEL);
command.add(LTTngControlServiceConstants.OPTION_SESSION);
command.add(sessionName);
if (channelName != null) {
command.add(LTTngControlServiceConstants.OPTION_CHANNEL);
command.add(channelName);
}
command.add(LTTngControlServiceConstants.OPTION_SYSCALL);
executeCommand(command, monitor);
}
@Override
public void enableProbe(String sessionName, String channelName, String eventName, boolean isFunction, String probe, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_ENABLE_EVENT);
command.add(eventName);
command.add(LTTngControlServiceConstants.OPTION_KERNEL);
command.add(LTTngControlServiceConstants.OPTION_SESSION);
command.add(sessionName);
if (channelName != null) {
command.add(LTTngControlServiceConstants.OPTION_CHANNEL);
command.add(channelName);
}
if (isFunction) {
command.add(LTTngControlServiceConstants.OPTION_FUNCTION_PROBE);
} else {
command.add(LTTngControlServiceConstants.OPTION_PROBE);
}
command.add(probe);
executeCommand(command, monitor);
}
@Override
public void enableLogLevel(String sessionName, String channelName, List<String> eventNames, LogLevelType logLevelType, ITraceLogLevel level, String filterExpression, TraceDomainType domain, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_ENABLE_EVENT);
// Checking if we should enable all events (with option '-a')
boolean isAllEvents = ALL_EVENTS.equals(eventNames);
if (isAllEvents || (eventNames == null) || (eventNames.isEmpty())) {
command.add(LTTngControlServiceConstants.OPTION_ALL);
} else {
command.add(toCsv(eventNames));
}
command.add(getDomainOption(domain));
command.add(LTTngControlServiceConstants.OPTION_SESSION);
command.add(sessionName);
if (channelName != null) {
command.add(LTTngControlServiceConstants.OPTION_CHANNEL);
command.add(channelName);
}
if (logLevelType == LogLevelType.LOGLEVEL) {
command.add(LTTngControlServiceConstants.OPTION_LOGLEVEL);
} else if (logLevelType == LogLevelType.LOGLEVEL_ONLY) {
command.add(LTTngControlServiceConstants.OPTION_LOGLEVEL_ONLY);
} else {
return;
}
command.add(level.getInName());
executeCommand(command, monitor);
}
@Override
public void disableEvent(String sessionName, String channelName, List<String> eventNames, TraceDomainType domain, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_DISABLE_EVENT);
if (eventNames == null) {
command.add(LTTngControlServiceConstants.OPTION_ALL);
} else {
// no events to disable
if (eventNames.isEmpty()) {
return;
}
StringBuffer eventNameParameter = new StringBuffer();
for (Iterator<String> iterator = eventNames.iterator(); iterator.hasNext();) {
String event = iterator.next();
eventNameParameter.append(event);
if (iterator.hasNext()) {
eventNameParameter.append(',');
}
}
command.add(eventNameParameter.toString());
}
command.add(getDomainOption(domain));
command.add(LTTngControlServiceConstants.OPTION_SESSION);
command.add(sessionName);
if (channelName != null) {
command.add(LTTngControlServiceConstants.OPTION_CHANNEL);
command.add(channelName);
}
executeCommand(command, monitor);
}
@Override
public List<String> getContextList(IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_ADD_CONTEXT, LTTngControlServiceConstants.OPTION_HELP);
ICommandResult result = executeCommand(command, monitor);
List<String> output = result.getOutput();
List<String> contexts = new ArrayList<>(0);
int index = 0;
boolean inList = false;
while (index < output.size()) {
String line = output.get(index);
Matcher startMatcher = LTTngControlServiceConstants.ADD_CONTEXT_HELP_CONTEXTS_INTRO.matcher(line);
Matcher endMatcher = LTTngControlServiceConstants.ADD_CONTEXT_HELP_CONTEXTS_END_LINE.matcher(line);
if (startMatcher.matches()) {
inList = true;
} else if (endMatcher.matches()) {
break;
} else if (inList) {
String[] tmp = line.split(","); //$NON-NLS-1$
for (int i = 0; i < tmp.length; i++) {
contexts.add(tmp[i].trim());
}
}
index++;
}
return contexts;
}
@Override
public void addContexts(String sessionName, String channelName, String eventName, TraceDomainType domain, List<String> contextNames, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_ADD_CONTEXT);
command.add(LTTngControlServiceConstants.OPTION_SESSION);
command.add(sessionName);
if (channelName != null) {
command.add(LTTngControlServiceConstants.OPTION_CHANNEL);
command.add(channelName);
}
if (eventName != null) {
command.add(LTTngControlServiceConstants.OPTION_EVENT);
command.add(eventName);
}
command.add(getDomainOption(domain));
for (Iterator<String> iterator = contextNames.iterator(); iterator.hasNext();) {
String context = iterator.next();
command.add(LTTngControlServiceConstants.OPTION_CONTEXT_TYPE);
command.add(context);
}
executeCommand(command, monitor);
}
@Override
public void recordSnapshot(String sessionName, IProgressMonitor monitor)
throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_SNAPSHOT, LTTngControlServiceConstants.COMMAND_RECORD_SNAPSHOT);
String newSessionName = sessionName;
command.add(LTTngControlServiceConstants.OPTION_SESSION);
command.add(newSessionName);
executeCommand(command, monitor);
}
@Override
public void loadSession(String inputPath, boolean isForce, IProgressMonitor monitor)
throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_LOAD_SESSION);
if (inputPath != null) {
command.add(LTTngControlServiceConstants.OPTION_INPUT_PATH);
command.add(inputPath);
}
if (isForce) {
command.add(LTTngControlServiceConstants.OPTION_FORCE);
}
executeCommand(command, monitor);
}
@Override
public void saveSession(String session, String outputPath, boolean isForce, IProgressMonitor monitor) throws ExecutionException {
ICommandInput command = createCommand(LTTngControlServiceConstants.COMMAND_SAVE_SESSION);
if (outputPath != null) {
command.add(LTTngControlServiceConstants.OPTION_OUTPUT_PATH);
command.add(outputPath);
}
if (isForce) {
command.add(LTTngControlServiceConstants.OPTION_FORCE);
}
if (session != null) {
command.add(session);
}
executeCommand(command, monitor);
}
@Override
public void runCommands(IProgressMonitor monitor, List<String> commandLines) throws ExecutionException {
for (String commandLine : commandLines) {
if (monitor.isCanceled()) {
return;
}
if (commandLine.isEmpty() || commandLine.startsWith("#")) { //$NON-NLS-1$
continue;
}
String[] args = commandLine.split("\\s+"); //$NON-NLS-1$
ICommandInput command = fCommandShell.createCommand();
command.addAll(Arrays.asList(args));
ICommandResult result = executeCommand(command, monitor);
if (isError(result)) {
throw new ExecutionException(Messages.TraceControl_CommandError + " " + command.toString() + "\n" + result.toString()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
// ------------------------------------------------------------------------
// Helper methods
// ------------------------------------------------------------------------
private static @NonNull String getDomainOption(TraceDomainType domain) {
switch (domain) {
case KERNEL:
return LTTngControlServiceConstants.OPTION_KERNEL;
case UST:
return LTTngControlServiceConstants.OPTION_UST;
case JUL:
return LTTngControlServiceConstants.OPTION_JUL;
case LOG4J:
return LTTngControlServiceConstants.OPTION_LOG4J;
case PYTHON:
return LTTngControlServiceConstants.OPTION_PYTHON;
case UNKNOWN:
default:
return TraceDomainType.UNKNOWN.name();
}
}
/**
* Checks if command result is an error result.
*
* @param result
* - the command result to check
* @return true if error else false
*/
protected boolean isError(ICommandResult result) {
// Check return code and length of returned strings
if ((result.getResult()) != 0) {
return true;
}
// Look for error pattern
for (String line : result.getErrorOutput()) {
Matcher matcher = LTTngControlServiceConstants.ERROR_PATTERN.matcher(line);
if (matcher.matches()) {
return true;
}
}
return false;
}
/**
* Creates a comma separated string from list of names
*
* @param names
* List of name to convert
* @return comma separated string
*/
protected String toCsv(List<String> names) {
StringBuilder csvString = new StringBuilder();
for (Iterator<String> iterator = names.iterator(); iterator.hasNext();) {
String name = iterator.next();
csvString.append(name);
if (iterator.hasNext()) {
csvString.append(',');
}
}
return csvString.toString();
}
/**
* Parses the domain information.
*
* @param output
* a command output list
* @param currentIndex
* current index in command output list
* @param channels
* list for returning channel information
* @param domainInfo
* The domain information
* @return the new current index in command output list
*/
protected int parseDomain(List<String> output, int currentIndex, List<IChannelInfo> channels, IDomainInfo domainInfo) {
int index = currentIndex;
// if kernel set the buffer type to shared
if (domainInfo.getDomain().equals(TraceDomainType.KERNEL)) {
domainInfo.setBufferType(BufferType.BUFFER_SHARED);
}
// Channels:
// -------------
// - channnel1: [enabled]
//
// Attributes:
// overwrite mode: 0
// subbufers size: 262144
// number of subbufers: 4
// switch timer interval: 0
// read timer interval: 200
// output: splice()
while (index < output.size()) {
String line = output.get(index);
if (isVersionSupported("2.2.0")) { //$NON-NLS-1$
Matcher bufferTypeMatcher = LTTngControlServiceConstants.BUFFER_TYPE_PATTERN.matcher(line);
if (bufferTypeMatcher.matches()) {
String bufferTypeString = getAttributeValue(line);
if (BufferType.BUFFER_PER_PID.getInName().equals(bufferTypeString)) {
domainInfo.setBufferType(BufferType.BUFFER_PER_PID);
} else if (BufferType.BUFFER_PER_UID.getInName().equals(bufferTypeString)) {
domainInfo.setBufferType(BufferType.BUFFER_PER_UID);
} else {
domainInfo.setBufferType(BufferType.BUFFER_TYPE_UNKNOWN);
}
}
} else {
domainInfo.setBufferType(BufferType.BUFFER_TYPE_UNKNOWN);
}
Matcher outerMatcher = LTTngControlServiceConstants.CHANNELS_SECTION_PATTERN.matcher(line);
Matcher noKernelChannelMatcher = LTTngControlServiceConstants.DOMAIN_NO_KERNEL_CHANNEL_PATTERN.matcher(line);
Matcher noUstChannelMatcher = LTTngControlServiceConstants.DOMAIN_NO_UST_CHANNEL_PATTERN.matcher(line);
if (outerMatcher.matches()) {
IChannelInfo channelInfo = null;
while (index < output.size()) {
String subLine = output.get(index);
Matcher innerMatcher = LTTngControlServiceConstants.CHANNEL_PATTERN.matcher(subLine);
if (innerMatcher.matches()) {
channelInfo = new ChannelInfo(""); //$NON-NLS-1$
// get channel name
channelInfo.setName(innerMatcher.group(1));
// get channel enablement
channelInfo.setState(innerMatcher.group(2));
// set BufferType
channelInfo.setBufferType(domainInfo.getBufferType());
// add channel
channels.add(channelInfo);
} else if (LTTngControlServiceConstants.OVERWRITE_MODE_ATTRIBUTE.matcher(subLine).matches()) {
String value = getAttributeValue(subLine);
if (channelInfo != null) {
channelInfo.setOverwriteMode(!LTTngControlServiceConstants.OVERWRITE_MODE_ATTRIBUTE_FALSE.equals(value));
}
} else if (LTTngControlServiceConstants.SUBBUFFER_SIZE_ATTRIBUTE.matcher(subLine).matches()) {
if (channelInfo != null) {
channelInfo.setSubBufferSize(Long.valueOf(getAttributeValue(subLine)));
}
} else if (LTTngControlServiceConstants.NUM_SUBBUFFERS_ATTRIBUTE.matcher(subLine).matches()) {
if (channelInfo != null) {
channelInfo.setNumberOfSubBuffers(Integer.valueOf(getAttributeValue(subLine)));
}
} else if (LTTngControlServiceConstants.SWITCH_TIMER_ATTRIBUTE.matcher(subLine).matches()) {
if (channelInfo != null) {
channelInfo.setSwitchTimer(Long.valueOf(getAttributeValue(subLine)));
}
} else if (LTTngControlServiceConstants.READ_TIMER_ATTRIBUTE.matcher(subLine).matches()) {
if (channelInfo != null) {
channelInfo.setReadTimer(Long.valueOf(getAttributeValue(subLine)));
}
} else if (LTTngControlServiceConstants.OUTPUT_ATTRIBUTE.matcher(subLine).matches()) {
if (channelInfo != null) {
channelInfo.setOutputType(getAttributeValue(subLine));
}
} else if (LTTngControlServiceConstants.TRACE_FILE_COUNT_ATTRIBUTE.matcher(subLine).matches()) {
if (channelInfo != null) {
channelInfo.setMaxNumberTraceFiles(Integer.valueOf(getAttributeValue(subLine)));
}
} else if (LTTngControlServiceConstants.TRACE_FILE_SIZE_ATTRIBUTE.matcher(subLine).matches()) {
if (channelInfo != null) {
channelInfo.setMaxSizeTraceFiles(Long.valueOf(getAttributeValue(subLine)));
}
} else if (LTTngControlServiceConstants.EVENT_SECTION_PATTERN.matcher(subLine).matches()) {
List<IEventInfo> events = new ArrayList<>();
index = parseEvents(output, index, events);
if (channelInfo != null) {
channelInfo.setEvents(events);
}
// we want to stay at the current index to be able to
// exit the domain
continue;
} else if (LTTngControlServiceConstants.DOMAIN_KERNEL_PATTERN.matcher(subLine).matches()) {
return index;
} else if (LTTngControlServiceConstants.DOMAIN_UST_GLOBAL_PATTERN.matcher(subLine).matches()) {
return index;
}
index++;
}
} else if (noKernelChannelMatcher.matches() || noUstChannelMatcher.matches()) {
// domain indicates that no channels were found -> return
index++;
return index;
}
index++;
}
return index;
}
/**
* Parses the event information within a domain.
*
* @param output
* a command output list
* @param currentIndex
* current index in command output list
* @param events
* list for returning event information
* @return the new current index in command output list
*/
protected int parseEvents(List<String> output, int currentIndex, List<IEventInfo> events) {
int index = currentIndex;
while (index < output.size()) {
String line = output.get(index);
if (LTTngControlServiceConstants.CHANNEL_PATTERN.matcher(line).matches()) {
// end of channel
return index;
} else if (LTTngControlServiceConstants.DOMAIN_KERNEL_PATTERN.matcher(line).matches()) {
// end of domain
return index;
} else if (LTTngControlServiceConstants.DOMAIN_UST_GLOBAL_PATTERN.matcher(line).matches()) {
// end of domain
return index;
}
Matcher matcher = LTTngControlServiceConstants.EVENT_PATTERN.matcher(line);
Matcher matcher2 = LTTngControlServiceConstants.WILDCARD_EVENT_PATTERN.matcher(line);
if (matcher.matches()) {
IEventInfo eventInfo = new EventInfo(matcher.group(1).trim());
eventInfo.setLogLevelType(matcher.group(2).trim());
eventInfo.setLogLevel(matcher.group(3).trim());
eventInfo.setEventType(matcher.group(4).trim());
eventInfo.setState(matcher.group(5));
if (("[" + LTTngControlServiceConstants.HAS_EXCLUSIONS + "]").equals(matcher.group(6))) { //$NON-NLS-1$ //$NON-NLS-2$
eventInfo.setExcludedEvents(LTTngControlServiceConstants.HAS_EXCLUSIONS);
}
if (("[" + LTTngControlServiceConstants.WITH_FILTER + "]").equals(matcher.group(7))) { //$NON-NLS-1$ //$NON-NLS-2$
eventInfo.setFilterExpression(LTTngControlServiceConstants.WITH_FILTER);
}
events.add(eventInfo);
index++;
} else if (matcher2.matches()) {
IEventInfo eventInfo = new EventInfo(matcher2.group(1).trim());
eventInfo.setLogLevel(TraceLogLevel.LEVEL_UNKNOWN);
eventInfo.setEventType(matcher2.group(2).trim());
eventInfo.setState(matcher2.group(3));
if (("[" + LTTngControlServiceConstants.HAS_EXCLUSIONS + "]").equals(matcher2.group(4))) { //$NON-NLS-1$ //$NON-NLS-2$
eventInfo.setExcludedEvents(LTTngControlServiceConstants.HAS_EXCLUSIONS);
}
if (("[" + LTTngControlServiceConstants.WITH_FILTER + "]").equals(matcher2.group(5))) { //$NON-NLS-1$ //$NON-NLS-2$
eventInfo.setFilterExpression(LTTngControlServiceConstants.WITH_FILTER);
}
if ((eventInfo.getEventType() == TraceEventType.PROBE) ||
(eventInfo.getEventType() == TraceEventType.FUNCTION)) {
IProbeEventInfo probeEvent = new ProbeEventInfo(eventInfo.getName());
probeEvent.setLogLevel(eventInfo.getLogLevel());
probeEvent.setEventType(eventInfo.getEventType());
probeEvent.setState(eventInfo.getState());
// Overwrite eventinfo
eventInfo = probeEvent;
// myevent2 (type: probe) [enabled]
// addr: 0xc0101340
// myevent0 (type: function) [enabled]
// offset: 0x0
// symbol: init_post
index++;
while (index < output.size()) {
String probeLine = output.get(index);
// parse probe
Matcher addrMatcher = LTTngControlServiceConstants.PROBE_ADDRESS_PATTERN.matcher(probeLine);
Matcher offsetMatcher = LTTngControlServiceConstants.PROBE_OFFSET_PATTERN.matcher(probeLine);
Matcher symbolMatcher = LTTngControlServiceConstants.PROBE_SYMBOL_PATTERN.matcher(probeLine);
if (addrMatcher.matches()) {
String addr = addrMatcher.group(2).trim();
probeEvent.setAddress(addr);
} else if (offsetMatcher.matches()) {
String offset = offsetMatcher.group(2).trim();
probeEvent.setOffset(offset);
} else if (symbolMatcher.matches()) {
String symbol = symbolMatcher.group(2).trim();
probeEvent.setSymbol(symbol);
} else if ((LTTngControlServiceConstants.EVENT_PATTERN.matcher(probeLine).matches()) || (LTTngControlServiceConstants.WILDCARD_EVENT_PATTERN.matcher(probeLine).matches())) {
break;
} else if (LTTngControlServiceConstants.CHANNEL_PATTERN.matcher(probeLine).matches()) {
break;
} else if (LTTngControlServiceConstants.DOMAIN_KERNEL_PATTERN.matcher(probeLine).matches()) {
// end of domain
break;
} else if (LTTngControlServiceConstants.DOMAIN_UST_GLOBAL_PATTERN.matcher(probeLine).matches()) {
// end of domain
break;
}
index++;
}
events.add(eventInfo);
} else {
events.add(eventInfo);
index++;
continue;
}
} else {
index++;
}
}
return index;
}
/**
* Parses a line with attributes: <attribute Name>: <attribute value>
*
* @param line
* - attribute line to parse
* @return the attribute value as string
*/
protected String getAttributeValue(String line) {
String[] temp = line.split("\\: "); //$NON-NLS-1$
return temp[1];
}
/**
* Parses the event information within a provider.
*
* @param output
* a command output list
* @param currentIndex
* current index in command output list
* @param events
* list for returning event information
* @return the new current index in command output list
*/
protected int getProviderEventInfo(List<String> output, int currentIndex, List<IBaseEventInfo> events) {
int index = currentIndex;
IBaseEventInfo eventInfo = null;
while (index < output.size()) {
String line = output.get(index);
Matcher matcher = LTTngControlServiceConstants.PROVIDER_EVENT_PATTERN.matcher(line);
if (matcher.matches()) {
// sched_kthread_stop (loglevel: TRACE_EMERG0) (type:
// tracepoint)
eventInfo = new BaseEventInfo(matcher.group(1).trim());
eventInfo.setLogLevel(matcher.group(2).trim());
eventInfo.setEventType(matcher.group(3).trim());
events.add(eventInfo);
index++;
} else if (LTTngControlServiceConstants.EVENT_FIELD_PATTERN.matcher(line).matches()) {
if (eventInfo != null) {
List<IFieldInfo> fields = new ArrayList<>();
index = getFieldInfo(output, index, fields);
eventInfo.setFields(fields);
} else {
index++;
}
} else if (LTTngControlServiceConstants.UST_PROVIDER_PATTERN.matcher(line).matches()) {
return index;
} else {
index++;
}
}
return index;
}
/**
* Parse a field's information.
*
* @param output
* A command output list
* @param currentIndex
* The current index in the command output list
* @param fields
* List for returning the field information
* @return The new current index in the command output list
*/
protected int getFieldInfo(List<String> output, int currentIndex, List<IFieldInfo> fields) {
int index = currentIndex;
IFieldInfo fieldInfo = null;
while (index < output.size()) {
String line = output.get(index);
Matcher matcher = LTTngControlServiceConstants.EVENT_FIELD_PATTERN.matcher(line);
if (matcher.matches()) {
// field: content (string)
fieldInfo = new FieldInfo(matcher.group(2).trim());
fieldInfo.setFieldType(matcher.group(3).trim());
fields.add(fieldInfo);
} else if (LTTngControlServiceConstants.PROVIDER_EVENT_PATTERN.matcher(line).matches()) {
return index;
} else if (LTTngControlServiceConstants.UST_PROVIDER_PATTERN.matcher(line).matches()) {
return index;
}
index++;
}
return index;
}
/**
* Creates a command input instance
*
* @param segments
* array of string that makes up a command line
* @return {@link ICommandInput} instance
*/
protected @NonNull ICommandInput createCommand(String... segments) {
ICommandInput command = fCommandShell.createCommand();
command.add(LTTngControlServiceConstants.CONTROL_COMMAND);
List<@NonNull String> groupOption = getTracingGroupOption();
if (!groupOption.isEmpty()) {
command.addAll(groupOption);
}
String verboseOption = getVerboseOption();
if (!verboseOption.isEmpty()) {
command.add(verboseOption);
}
for (String string : segments) {
command.add(checkNotNull(string));
}
return command;
}
/**
* @return the tracing group option if configured in the preferences
*/
protected @NonNull List<@NonNull String> getTracingGroupOption() {
List<@NonNull String> groupOption = new ArrayList<>();
if (!ControlPreferences.getInstance().isDefaultTracingGroup() && !ControlPreferences.getInstance().getTracingGroup().equals("")) { //$NON-NLS-1$
groupOption.add(LTTngControlServiceConstants.OPTION_TRACING_GROUP);
groupOption.add(ControlPreferences.getInstance().getTracingGroup());
}
return groupOption;
}
/**
* @return the verbose option as configured in the preferences
*/
protected String getVerboseOption() {
if (ControlPreferences.getInstance().isLoggingEnabled()) {
String level = ControlPreferences.getInstance().getVerboseLevel();
if (ControlPreferences.TRACE_CONTROL_VERBOSE_LEVEL_VERBOSE.equals(level)) {
return LTTngControlServiceConstants.OPTION_VERBOSE;
}
if (ControlPreferences.TRACE_CONTROL_VERBOSE_LEVEL_V_VERBOSE.equals(level)) {
return LTTngControlServiceConstants.OPTION_VERY_VERBOSE;
}
if (ControlPreferences.TRACE_CONTROL_VERBOSE_LEVEL_V_V_VERBOSE.equals(level)) {
return LTTngControlServiceConstants.OPTION_VERY_VERY_VERBOSE;
}
}
return ""; //$NON-NLS-1$
}
/**
* Method that logs the command and command result if logging is enabled as
* well as forwards the command execution to the shell.
*
* @param command
* - the command to execute
* @param monitor
* - a progress monitor
* @return the command result
* @throws ExecutionException
* If the command fails
*/
protected ICommandResult executeCommand(@NonNull ICommandInput command,
@Nullable IProgressMonitor monitor) throws ExecutionException {
return executeCommand(command, monitor, true);
}
/**
* Method that logs the command and command result if logging is enabled as
* well as forwards the command execution to the shell.
*
* @param command
* - the command to execute
* @param monitor
* - a progress monitor
* @param checkForError
* - true to verify command result, else false
* @return the command result
* @throws ExecutionException
* in case of error result
*/
protected ICommandResult executeCommand(@NonNull ICommandInput command,
@Nullable IProgressMonitor monitor, boolean checkForError)
throws ExecutionException {
if (ControlPreferences.getInstance().isLoggingEnabled()) {
ControlCommandLogger.log(command.toString());
}
ICommandResult result = fCommandShell.executeCommand(command, monitor);
if (ControlPreferences.getInstance().isLoggingEnabled()) {
ControlCommandLogger.log(result.toString());
}
if (checkForError && isError(result)) {
throw new ExecutionException(Messages.TraceControl_CommandError
+ " " + command.toString() + "\n" + result.toString()); //$NON-NLS-1$ //$NON-NLS-2$
}
return result;
}
}