analysis.lami: Replace Activator info logging with JUL
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.lami.core / src / org / eclipse / tracecompass / internal / provisional / analysis / lami / core / module / LamiAnalysis.java
index f11f6c9e5f4b8520e32a2f58821832f17bc2510f..15beeb8cc9d3392d65afbe4dee0d956b993136a1 100644 (file)
@@ -23,18 +23,26 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.function.Predicate;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Predicate;
+import java.util.logging.Logger;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.common.core.log.TraceCompassLog;
 import org.eclipse.tracecompass.internal.analysis.lami.core.Activator;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.LamiStrings;
+import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiDurationAspect;
+import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiEmptyAspect;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiGenericAspect;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiIRQNameAspect;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiIRQNumberAspect;
@@ -43,8 +51,6 @@ import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.L
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiProcessNameAspect;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiProcessPIDAspect;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiProcessTIDAspect;
-import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiDurationAspect;
-import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiEmptyAspect;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiTableEntryAspect;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiTimeRangeBeginAspect;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiTimeRangeDurationAspect;
@@ -54,13 +60,13 @@ import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.types.La
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.types.LamiData.DataType;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.types.LamiTimeRange;
 import org.eclipse.tracecompass.tmf.core.analysis.ondemand.IOnDemandAnalysis;
-import org.eclipse.tracecompass.tmf.core.analysis.ondemand.OnDemandAnalysisException;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMultimap;
@@ -74,8 +80,14 @@ import com.google.common.collect.Multimap;
  */
 public class LamiAnalysis implements IOnDemandAnalysis {
 
-    /** Maximum major version of the LAMI protocol we support */
-    private static final int MAX_SUPPORTED_MAJOR_VERSION = 1;
+    private static final Logger LOGGER = TraceCompassLog.getLogger(LamiAnalysis.class);
+
+    /**
+     * Maximum major version of the LAMI protocol we support.
+     *
+     * Currently only 0.x/unversioned MI, outputted by lttng-analyses 0.4.x
+     */
+    private static final int MAX_SUPPORTED_MAJOR_VERSION = 0;
 
     private static final String DOUBLE_QUOTES = "\""; //$NON-NLS-1$
 
@@ -85,9 +97,6 @@ public class LamiAnalysis implements IOnDemandAnalysis {
     private static final String BEGIN_FLAG = "--begin"; //$NON-NLS-1$
     private static final String END_FLAG = "--end"; //$NON-NLS-1$
 
-    /** Log message for commands being run */
-    private static final String RUNNING_MESSAGE = "Running command:"; //$NON-NLS-1$
-
     private final List<String> fScriptCommand;
 
     /**
@@ -141,7 +150,7 @@ public class LamiAnalysis implements IOnDemandAnalysis {
     }
 
     @Override
-    public boolean appliesTo(ITmfTrace trace) {
+    public final boolean appliesTo(ITmfTrace trace) {
         return fAppliesTo.test(trace);
     }
 
@@ -151,7 +160,12 @@ public class LamiAnalysis implements IOnDemandAnalysis {
         return fIsAvailable;
     }
 
-    private synchronized void initialize() {
+    /**
+     * Perform initialization of the LAMI script. This means verifying that it
+     * is actually present on disk, and that it returns correct --metadata.
+     */
+    @VisibleForTesting
+    protected synchronized void initialize() {
         if (fInitialized) {
             return;
         }
@@ -174,7 +188,15 @@ public class LamiAnalysis implements IOnDemandAnalysis {
         fInitialized = true;
     }
 
-    private boolean checkMetadata() {
+    /**
+     * Verify that this script returns valid metadata.
+     *
+     * This will populate all remaining non-final fields of this class.
+     *
+     * @return If the metadata is valid or not
+     */
+    @VisibleForTesting
+    protected boolean checkMetadata() {
         /*
          * The initialize() phase of the analysis will be used to check the
          * script's metadata. Actual runs of the script will use the execute()
@@ -183,7 +205,7 @@ public class LamiAnalysis implements IOnDemandAnalysis {
         List<String> command = ImmutableList.<@NonNull String> builder()
                 .addAll(fScriptCommand).add(METADATA_FLAG).build();
 
-        Activator.instance().logInfo(RUNNING_MESSAGE + ' ' + command.toString());
+        LOGGER.info(() -> "[LamiAnalysis:RunningMetadataCommand] command=" + command.toString()); //$NON-NLS-1$
 
         String output = getOutputFromCommand(command);
         if (output == null || output.isEmpty()) {
@@ -284,6 +306,7 @@ public class LamiAnalysis implements IOnDemandAnalysis {
 
         } catch (JSONException e) {
             /* Error in the parsing of the JSON, script is broken? */
+            LOGGER.severe(() -> "[LamiAnalysis:ErrorParsingMetadata] msg=" + e.getMessage()); //$NON-NLS-1$
             Activator.instance().logError(e.getMessage());
             return false;
         }
@@ -473,12 +496,12 @@ public class LamiAnalysis implements IOnDemandAnalysis {
      * @param monitor
      *            The progress monitor used to report progress
      * @return The script's output, formatted into {@link LamiTableEntry}'s.
-     * @throws OnDemandAnalysisException
+     * @throws CoreException
      *             If execution did not terminate normally
      */
     @Override
     public List<LamiResultTable> execute(ITmfTrace trace, @Nullable TmfTimeRange timeRange,
-            String extraParams, IProgressMonitor monitor) throws OnDemandAnalysisException {
+            String extraParams, IProgressMonitor monitor) throws CoreException {
         /* Should have been called already, but in case it was not */
         initialize();
 
@@ -493,11 +516,12 @@ public class LamiAnalysis implements IOnDemandAnalysis {
         builder.add(tracePath);
         List<String> command = builder.build();
 
-        Activator.instance().logInfo(RUNNING_MESSAGE + ' ' + command.toString());
+        LOGGER.info(() -> "[LamiAnalysis:RunningExecuteCommand] command=" + command.toString()); //$NON-NLS-1$
         String output = getResultsFromCommand(command, monitor);
 
         if (output.isEmpty()) {
-            throw new OnDemandAnalysisException(Messages.LamiAnalysis_NoResults);
+            IStatus status = new Status(IStatus.INFO, Activator.instance().getPluginId(), Messages.LamiAnalysis_NoResults);
+            throw new CoreException(status);
         }
 
         /*
@@ -571,7 +595,8 @@ public class LamiAnalysis implements IOnDemandAnalysis {
                  * No results were reported. This may be normal, but warn the
                  * user why a report won't be created.
                  */
-                throw new OnDemandAnalysisException(Messages.LamiAnalysis_NoResults);
+                IStatus status = new Status(IStatus.INFO, Activator.instance().getPluginId(), Messages.LamiAnalysis_NoResults);
+                throw new CoreException(status);
             }
 
             for (int i = 0; i < results.length(); i++) {
@@ -638,9 +663,9 @@ public class LamiAnalysis implements IOnDemandAnalysis {
             }
 
         } catch (JSONException e) {
-            /* Error parsing the output */
-            Activator.instance().logError(nullToEmptyString(e.getMessage()));
-            return Collections.EMPTY_LIST;
+            LOGGER.severe(() -> "[LamiAnalysis:ErrorParsingExecutionOutput] msg=" + e.getMessage()); //$NON-NLS-1$
+            IStatus status = new Status(IStatus.ERROR, Activator.instance().getPluginId(), e.getMessage(), e);
+            throw new CoreException(status);
         }
 
         return resultsBuilder.build();
@@ -660,8 +685,14 @@ public class LamiAnalysis implements IOnDemandAnalysis {
      * Get the output of an external command, used for getting the metadata.
      * Cannot be cancelled, and will not report errors, simply returns null if
      * the process ended abnormally.
+     *
+     * @param command
+     *            The parameters of the command, passed to
+     *            {@link ProcessBuilder}
+     * @return The command output as a string
      */
-    private static @Nullable String getOutputFromCommand(List<String> command) {
+    @VisibleForTesting
+    protected @Nullable String getOutputFromCommand(List<String> command) {
         try {
             ProcessBuilder builder = new ProcessBuilder(command);
             builder.redirectErrorStream(true);
@@ -681,15 +712,21 @@ public class LamiAnalysis implements IOnDemandAnalysis {
     /**
      * Get the results of invoking the specified command.
      *
-     * The result should start with '{"results":...', as specified by the
-     * LAMI JSON protocol. The JSON itself may be split over multiple lines.
+     * The result should start with '{"results":...', as specified by the LAMI
+     * JSON protocol. The JSON itself may be split over multiple lines.
      *
      * @param command
      *            The command to run (program and its arguments)
+     * @param monitor
+     *            The progress monitor
      * @return The analysis results
+     * @throws CoreException
+     *             If the command ended abnormally, and normal results were not
+     *             returned
      */
-    private static String getResultsFromCommand(List<String> command, IProgressMonitor monitor)
-            throws OnDemandAnalysisException {
+    @VisibleForTesting
+    protected String getResultsFromCommand(List<String> command, IProgressMonitor monitor)
+            throws CoreException {
 
         final int scale = 1000;
         double workedSoFar = 0.0;
@@ -768,7 +805,8 @@ public class LamiAnalysis implements IOnDemandAnalysis {
 
             if (monitor.isCanceled()) {
                 /* We were interrupted by the canceller thread. */
-                throw new OnDemandAnalysisException(null);
+                IStatus status = new Status(IStatus.CANCEL, Activator.instance().getPluginId(), null);
+                throw new CoreException(status);
             }
 
             if (ret != 0) {
@@ -777,8 +815,21 @@ public class LamiAnalysis implements IOnDemandAnalysis {
                  * gather the stderr and report it to the user.
                  */
                 BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
-                String stdErrOutput = br.lines().collect(Collectors.joining("\n")); //$NON-NLS-1$
-                throw new OnDemandAnalysisException(stdErrOutput);
+                List<String> stdErrOutput = br.lines().collect(Collectors.toList());
+
+                MultiStatus status = new MultiStatus(Activator.instance().getPluginId(),
+                        IStatus.ERROR, Messages.LamiAnalysis_ErrorDuringExecution, null);
+                for (String str : stdErrOutput) {
+                    status.add(new Status(IStatus.ERROR, Activator.instance().getPluginId(), str));
+                }
+                if (stdErrOutput.isEmpty()) {
+                    /*
+                     * At least say "no output", so an error message actually
+                     * shows up.
+                     */
+                    status.add(new Status(IStatus.ERROR, Activator.instance().getPluginId(), Messages.LamiAnalysis_ErrorNoOutput));
+                }
+                throw new CoreException(status);
             }
 
             /* External script ended successfully, all is fine! */
@@ -786,7 +837,8 @@ public class LamiAnalysis implements IOnDemandAnalysis {
             return checkNotNull(resultsStr);
 
         } catch (IOException | InterruptedException e) {
-            throw new OnDemandAnalysisException(Messages.LamiAnalysis_ExecutionInterrupted);
+            IStatus status = new Status(IStatus.ERROR, Activator.instance().getPluginId(), Messages.LamiAnalysis_ExecutionInterrupted, e);
+            throw new CoreException(status);
 
         } finally {
             if (cancellerRunnable != null) {
This page took 0.031677 seconds and 5 git commands to generate.