ctf: Make CtfTmfTrace trimmable
authorAlexandre Montplaisir <alexmonthy@efficios.com>
Fri, 7 Jul 2017 20:58:57 +0000 (16:58 -0400)
committerAlexandre Montplaisir <alexmonthy@efficios.com>
Fri, 7 Jul 2017 20:58:57 +0000 (16:58 -0400)
Invoke Babeltrace 2, if it is available, to trim the trace to the time
range specified by the user. This will create and import a new, trimmed
trace, so that the original remains available.

Change-Id: Ia2413bb0c5c9e1d67e7b810ddaa17a177eb1d364
Signed-off-by: Alexandre Montplaisir <alexmonthy@efficios.com>
ctf/org.eclipse.tracecompass.tmf.ctf.core/META-INF/MANIFEST.MF
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/trace/CtfTmfTrace.java
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/trace/Messages.java
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/trace/messages.properties

index 179db87af842282b43b56a8e84a06522166ad655..bdefcb68772b5dde88bfbdb0a738bcbbbfe9fdc2 100644 (file)
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name
 Bundle-Vendor: %Bundle-Vendor
-Bundle-Version: 2.1.0.qualifier
+Bundle-Version: 2.2.0.qualifier
 Bundle-Localization: plugin
 Bundle-SymbolicName: org.eclipse.tracecompass.tmf.ctf.core;singleton:=true
 Bundle-Activator: org.eclipse.tracecompass.internal.tmf.ctf.core.Activator
index 22211160ad4385f1a334432495e714b89090ac48..e51558c6d6dd60ad78d51dc1e72f3d9d9784e6de 100644 (file)
 package org.eclipse.tracecompass.tmf.ctf.core.trace;
 
 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+import static org.eclipse.tracecompass.common.core.NonNullUtils.nullToEmptyString;
 
+import java.io.File;
 import java.nio.BufferOverflowException;
 import java.nio.ByteBuffer;
+import java.nio.file.Path;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -30,9 +34,12 @@ import java.util.Set;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.common.core.process.ProcessUtils;
 import org.eclipse.tracecompass.ctf.core.CTFException;
 import org.eclipse.tracecompass.ctf.core.event.CTFClock;
 import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration;
@@ -48,12 +55,14 @@ import org.eclipse.tracecompass.internal.tmf.ctf.core.trace.iterator.CtfIterator
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
 import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
-import org.eclipse.tracecompass.tmf.core.event.aspect.TmfBaseAspects;
 import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
+import org.eclipse.tracecompass.tmf.core.event.aspect.TmfBaseAspects;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
 import org.eclipse.tracecompass.tmf.core.project.model.ITmfPropertiesProvider;
 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceKnownSize;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceWithPreDefinedEvents;
@@ -65,6 +74,7 @@ import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer;
 import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint;
 import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint;
 import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
+import org.eclipse.tracecompass.tmf.core.trace.trim.ITmfTrimmableTrace;
 import org.eclipse.tracecompass.tmf.ctf.core.CtfConstants;
 import org.eclipse.tracecompass.tmf.ctf.core.context.CtfLocation;
 import org.eclipse.tracecompass.tmf.ctf.core.context.CtfLocationInfo;
@@ -86,7 +96,7 @@ import com.google.common.collect.ImmutableSet;
  */
 public class CtfTmfTrace extends TmfTrace
         implements ITmfPropertiesProvider, ITmfPersistentlyIndexable,
-        ITmfTraceWithPreDefinedEvents, ITmfTraceKnownSize {
+        ITmfTraceWithPreDefinedEvents, ITmfTraceKnownSize, ITmfTrimmableTrace {
 
     // -------------------------------------------
     // Constants
@@ -123,6 +133,9 @@ public class CtfTmfTrace extends TmfTrace
     private static final int CONFIDENCE = 10;
     private static final int MIN_CONFIDENCE = 1;
 
+    /** Timestamp formatter to pass to Babeltrace */
+    private static final TmfTimestampFormat TS_FORMAT = new TmfTimestampFormat("T.SSSSSSSSS"); //$NON-NLS-1$
+
     /**
      * This is a reduction factor to avoid overflows.
      */
@@ -740,4 +753,55 @@ public class CtfTmfTrace extends TmfTrace
     public int progress() {
         return (int) (getNbEvents() / REDUCTION_FACTOR);
     }
+
+    /**
+     * @since 2.2
+     */
+    @Override
+    @SuppressWarnings("nls")
+    public void trim(@NonNull TmfTimeRange range, @NonNull Path destinationPath, @NonNull IProgressMonitor monitor) throws CoreException {
+        List<@NonNull String> command;
+        @Nullable List<String> output;
+
+        /* Verify that Babeltrace 2.0 is installed and available */
+        command = Arrays.asList("babeltrace", "--version");
+        output = ProcessUtils.getOutputFromCommand(command);
+        if (output == null || output.isEmpty() || !output.get(0).contains("Babeltrace 2")) {
+            IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_BabelTrace2NotFound);
+            throw new CoreException(status);
+        }
+
+        /* Trim and save the new trace */
+        String originPath = getPath();
+        if (!originPath.endsWith(File.separator)) {
+            originPath = originPath + File.separator;
+        }
+
+        String rangeStart = TS_FORMAT.format(range.getStartTime().toNanos());
+        String rangeEnd = TS_FORMAT.format(range.getEndTime().toNanos());
+
+        command = Arrays.asList("bash", "-c",
+                "babeltrace"
+                + " \"" + originPath + "\""
+                + " --begin " + rangeStart
+                + " --end " + rangeEnd
+                /* Ignore Babeltrace's debug info generation, we have our own */
+                + " --no-debug-info"
+                + " --component sink.ctf.fs"
+                + " --path \"" + destinationPath.toString() + '\"'
+                /*
+                 * This option outputs the trace exactly in the directory we specify, without
+                 * creating a hierarchy from the host/trace names. Note that it only works if
+                 * there is a single trace as input. It would not work with an experiment.
+                 */
+                + " -p single-trace=true"
+                );
+
+        ProcessUtils.getOutputFromCommandCancellable(command,
+                monitor,
+                nullToEmptyString(Messages.CtfTmfTrace_InvokingBabeltrace),
+                /* We don't need to process the output. */
+                (r, m) -> Collections.emptyList());
+    }
+
 }
index 77b8600499c685a9b70956e6021e286af5f80455..0efb754d286085ca211f9253e154436c6b89c6f2 100644 (file)
@@ -17,6 +17,7 @@ import org.eclipse.osgi.util.NLS;
  * Message bundle for tmf.ctf.core.trace
  *
  * @author Matthew Khouzam
+ * @noreference Messages class
  */
 public class Messages extends NLS {
 
@@ -37,6 +38,12 @@ public class Messages extends NLS {
     /** No event */
     public static String CtfTmfTrace_NoEvent;
 
+    /** Invoking Babeltrace message */
+    public static String CtfTmfTrace_InvokingBabeltrace;
+
+    /** Required Babeltrace 2 binary not found */
+    public static String CtfTmfTrace_BabelTrace2NotFound;
+
     static {
         // initialize resource bundle
         NLS.initializeMessages(BUNDLE_NAME, Messages.class);
index 248e4f22778f265bc27964ec73262a836187e2ab..9ddbe042382c26c2213900ec80400d9a7c5ea3a1 100644 (file)
@@ -14,4 +14,8 @@ CtfTmfTrace_BufferOverflowErrorMessage=Buffer overflow exception, trace is malfo
 CtfTmfTrace_HostID=host ID
 CtfTmfTrace_MajorNotSet=Major version number not set
 CtfTmfTrace_ReadingError=Reading error
-CtfTmfTrace_NoEvent=Trace has no events
\ No newline at end of file
+CtfTmfTrace_NoEvent=Trace has no events
+
+CtfTmfTrace_InvokingBabeltrace = Invoking external Babeltrace tool
+CtfTmfTrace_BabelTrace2NotFound = The trace cutting feature requires external Babeltrace 2.0+ tool. \
+Make sure the 'babeltrace' binary is installed and on the PATH.
This page took 0.028992 seconds and 5 git commands to generate.