This is an automated email from the ASF dual-hosted git repository.

jiangtian pushed a commit to branch log_tool
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git


The following commit(s) were added to refs/heads/log_tool by this push:
     new 14b86fe  add result export
14b86fe is described below

commit 14b86fe13be260a9b0fcd75184636542ae61b910
Author: jt <[email protected]>
AuthorDate: Tue Sep 3 15:01:57 2019 +0800

    add result export
---
 .../iotdb/db/tools/logvisual/LogVisualizer.java    | 60 +++++++++++++++++++---
 .../db/tools/logvisual/TimeSeriesStatistics.java   | 45 ++++++++++++----
 .../logvisual/exceptions/AnalyzeException.java     | 19 -------
 .../exceptions/NoLogFileLoadedException.java       |  2 +-
 .../logvisual/exceptions/NoSuchPlanException.java  |  2 +-
 .../exceptions/UnmatchedContentException.java      |  2 +-
 .../logvisual/exceptions/VisualizeException.java   | 19 +++++++
 .../iotdb/db/tools/logvisual/gui/MainPanel.java    |  1 -
 .../iotdb/db/tools/logvisual/gui/PlanBox.java      | 40 ++++++++++++---
 9 files changed, 144 insertions(+), 46 deletions(-)

diff --git 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/LogVisualizer.java 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/LogVisualizer.java
index 1fc35e3..04117f1 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/LogVisualizer.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/LogVisualizer.java
@@ -1,8 +1,12 @@
 package org.apache.iotdb.db.tools.logvisual;
 
 import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -12,10 +16,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
-import org.apache.iotdb.db.tools.logvisual.exceptions.AnalyzeException;
 import org.apache.iotdb.db.tools.logvisual.exceptions.NoLogFileLoadedException;
 import 
org.apache.iotdb.db.tools.logvisual.exceptions.UnmatchedContentException;
+import org.apache.iotdb.db.tools.logvisual.exceptions.VisualizeException;
 import org.jfree.chart.ChartFactory;
+import org.jfree.chart.ChartUtils;
 import org.jfree.chart.JFreeChart;
 import org.jfree.chart.plot.XYPlot;
 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
@@ -56,10 +61,12 @@ public class LogVisualizer {
 
   /**
    * the timeseries plots generated for each group of logs.
+   * measurement name -> the chart of the measurement
    */
   private Map<String, JFreeChart> charts;
   /**
    * the statistics (count, mean, min, max) of each group of logs.
+   * measurement name -> the statistics of the measurement of each group
    */
   private Map<String, List<TimeSeriesStatistics>> statisticsMap;
 
@@ -139,7 +146,7 @@ public class LogVisualizer {
     return plans.values();
   }
 
-  public void executePlan(VisualizationPlan plan) throws AnalyzeException {
+  public void executePlan(VisualizationPlan plan) throws VisualizeException {
     if (logParser == null) {
       throw new NoLogFileLoadedException();
     }
@@ -147,7 +154,7 @@ public class LogVisualizer {
       // read the logs fom the beginning
       logParser.reset();
     } catch (IOException e) {
-      throw new AnalyzeException(e);
+      throw new VisualizeException(e);
     }
     collectLogs(plan);
     groupLogs();
@@ -161,9 +168,9 @@ public class LogVisualizer {
   /**
    * Read all logs from the logParser and filter unwanted or malformed ones.
    * @param plan
-   * @throws AnalyzeException
+   * @throws VisualizeException
    */
-  private void collectLogs(VisualizationPlan plan) throws AnalyzeException {
+  private void collectLogs(VisualizationPlan plan) throws VisualizeException {
     LogFilter logFilter = plan.getLogFilter();
     try {
       LogEntry logEntry;
@@ -186,7 +193,7 @@ public class LogVisualizer {
         }
       }
     } catch (IOException e) {
-      throw new AnalyzeException(e);
+      throw new VisualizeException(e);
     }
     logger.info("Collected {} logs from {}", logCache.size(), 
logFile.getPath());
   }
@@ -300,6 +307,47 @@ public class LogVisualizer {
     return ret;
   }
 
+  public void saveResults(String destDirPath, int width, int height) throws 
VisualizeException {
+    if (charts == null || statisticsMap == null) {
+      throw new VisualizeException("No results to be saved");
+    }
+
+    File destDir = new File(destDirPath);
+    if (destDir.exists() && !destDir.isDirectory()) {
+      throw new VisualizeException(String.format("%s exists and is not a 
directory", destDirPath));
+    }
+    if (!destDir.exists() && !destDir.mkdirs()) {
+      throw new VisualizeException(String.format("Cannot create directory %s", 
destDirPath));
+    }
+    destDir.mkdirs();
+
+    // save charts
+    for (Entry<String, JFreeChart> chartEntry : charts.entrySet()) {
+      File chartFile = new File(destDir, chartEntry.getKey() + ".png");
+      JFreeChart chart = chartEntry.getValue();
+      try (FileOutputStream fileOutputStream = new FileOutputStream(chartFile);
+          BufferedOutputStream bufferedOutputStream = new 
BufferedOutputStream(fileOutputStream)) {
+        ChartUtils.writeChartAsPNG(bufferedOutputStream, chart, width, height);
+      } catch (IOException e) {
+        throw new VisualizeException(String.format("Cannot save chart of %s", 
chartEntry.getKey()), e);
+      }
+    }
+
+    // save statistics
+    File statisticFile = new File(destDir, "statistic.csv");
+    try (FileWriter fileWriter = new FileWriter(statisticFile);
+        BufferedWriter writer = new BufferedWriter(fileWriter)) {
+      TimeSeriesStatistics.serializeHeader(writer);
+      for (Entry<String, List<TimeSeriesStatistics>> statisticEntry : 
statisticsMap.entrySet()) {
+        for (TimeSeriesStatistics timeSeriesStatistics : 
statisticEntry.getValue()) {
+          timeSeriesStatistics.serialize(writer);
+        }
+      }
+    } catch (IOException e) {
+      throw new VisualizeException(String.format("Cannot save statistics to 
%s", destDirPath), e);
+    }
+  }
+
   public Map<String, List<TimeSeriesStatistics>> getStatisticsMap() {
     return statisticsMap;
   }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/TimeSeriesStatistics.java
 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/TimeSeriesStatistics.java
index eb993af..6985aee 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/TimeSeriesStatistics.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/TimeSeriesStatistics.java
@@ -19,6 +19,11 @@
 
 package org.apache.iotdb.db.tools.logvisual;
 
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
 import java.util.Date;
 import org.apache.iotdb.tsfile.utils.StringContainer;
 import org.jfree.data.time.TimeSeries;
@@ -42,6 +47,8 @@ public class TimeSeriesStatistics {
   private double maxVal = Double.MIN_VALUE;
   private double minVal = Double.MAX_VALUE;
   private double valSum = 0.0;
+  
+  private Object[] statisticArray;
 
   TimeSeriesStatistics(TimeSeries timeSeries) {
     Date lastDate = null;
@@ -76,17 +83,33 @@ public class TimeSeriesStatistics {
   }
 
   public Object[] toArray() {
-    Object[] ret = new Object[HEADER.length];
+    if (statisticArray != null) {
+      return statisticArray;
+    }
+    statisticArray = new Object[HEADER.length];
     int i = 0;
-    ret[i++] = name;
-    ret[i++] = size;
-    ret[i++] = meanInterval;
-    ret[i++] = maxInterval;
-    ret[i++] = minInterval;
-    ret[i++] = meanVal;
-    ret[i++] = maxVal;
-    ret[i++] = minVal;
-    ret[i] = valSum;
-    return ret;
+    statisticArray[i++] = name;
+    statisticArray[i++] = size;
+    statisticArray[i++] = meanInterval;
+    statisticArray[i++] = maxInterval;
+    statisticArray[i++] = minInterval;
+    statisticArray[i++] = meanVal;
+    statisticArray[i++] = maxVal;
+    statisticArray[i++] = minVal;
+    statisticArray[i] = valSum;
+    return statisticArray;
+  }
+
+  public static void serializeHeader(Writer writer) throws IOException {
+    writer.write(String.join(",", HEADER) + "\n");
+  }
+  
+  public void serialize(Writer writer) throws IOException {
+    StringBuilder builder = new StringBuilder(statisticArray[0].toString());
+    for (int i = 1; i < statisticArray.length; i++) {
+      builder.append(",").append(statisticArray[i]);
+    }
+    builder.append("\n");
+    writer.write(builder.toString());
   }
 }
\ No newline at end of file
diff --git 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/AnalyzeException.java
 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/AnalyzeException.java
deleted file mode 100644
index 0bc72c0..0000000
--- 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/AnalyzeException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.apache.iotdb.db.tools.logvisual.exceptions;
-
-public class AnalyzeException extends Exception {
-
-  public AnalyzeException() {
-  }
-
-  public AnalyzeException(String message) {
-    super(message);
-  }
-
-  public AnalyzeException(String message, Throwable cause) {
-    super(message, cause);
-  }
-
-  public AnalyzeException(Throwable cause) {
-    super(cause);
-  }
-}
\ No newline at end of file
diff --git 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/NoLogFileLoadedException.java
 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/NoLogFileLoadedException.java
index 54338f3..d0d94e5 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/NoLogFileLoadedException.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/NoLogFileLoadedException.java
@@ -1,6 +1,6 @@
 package org.apache.iotdb.db.tools.logvisual.exceptions;
 
-public class NoLogFileLoadedException extends AnalyzeException {
+public class NoLogFileLoadedException extends VisualizeException {
 
   public NoLogFileLoadedException() {
     super("No log file is loaded, please load a log file first");
diff --git 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/NoSuchPlanException.java
 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/NoSuchPlanException.java
index 32c04fc..d60f3db 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/NoSuchPlanException.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/NoSuchPlanException.java
@@ -1,6 +1,6 @@
 package org.apache.iotdb.db.tools.logvisual.exceptions;
 
-public class NoSuchPlanException extends AnalyzeException {
+public class NoSuchPlanException extends VisualizeException {
 
   public NoSuchPlanException(String planName) {
     super(String.format("No such plan %s", planName));
diff --git 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/UnmatchedContentException.java
 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/UnmatchedContentException.java
index 9c015a9..1e0245b 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/UnmatchedContentException.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/UnmatchedContentException.java
@@ -1,6 +1,6 @@
 package org.apache.iotdb.db.tools.logvisual.exceptions;
 
-public class UnmatchedContentException extends AnalyzeException {
+public class UnmatchedContentException extends VisualizeException {
 
   public UnmatchedContentException(String content, String pattern) {
     super(String.format("%s cannot match %s", content, pattern));
diff --git 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/VisualizeException.java
 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/VisualizeException.java
new file mode 100644
index 0000000..19ed8a5
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/exceptions/VisualizeException.java
@@ -0,0 +1,19 @@
+package org.apache.iotdb.db.tools.logvisual.exceptions;
+
+public class VisualizeException extends Exception {
+
+  public VisualizeException() {
+  }
+
+  public VisualizeException(String message) {
+    super(message);
+  }
+
+  public VisualizeException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public VisualizeException(Throwable cause) {
+    super(cause);
+  }
+}
\ No newline at end of file
diff --git 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/gui/MainPanel.java 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/gui/MainPanel.java
index 8ff49ca..352e36b 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/gui/MainPanel.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/gui/MainPanel.java
@@ -103,5 +103,4 @@ class MainPanel extends JPanel {
     
propertyChangeCallback.call(PropertyKeys.DEFAULT_PARSER_FILE_PATH.getKey(), 
parserPropertyFile
         .getPath());
   }
-
 }
\ No newline at end of file
diff --git 
a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/gui/PlanBox.java 
b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/gui/PlanBox.java
index 986869b..d252754 100644
--- a/server/src/main/java/org/apache/iotdb/db/tools/logvisual/gui/PlanBox.java
+++ b/server/src/main/java/org/apache/iotdb/db/tools/logvisual/gui/PlanBox.java
@@ -42,7 +42,7 @@ import org.apache.iotdb.db.tools.logvisual.LogVisualizer;
 import org.apache.iotdb.db.tools.logvisual.TimeSeriesStatistics;
 import org.apache.iotdb.db.tools.logvisual.VisualizationPlan;
 import org.apache.iotdb.db.tools.logvisual.conf.PropertyKeys;
-import org.apache.iotdb.db.tools.logvisual.exceptions.AnalyzeException;
+import org.apache.iotdb.db.tools.logvisual.exceptions.VisualizeException;
 import 
org.apache.iotdb.db.tools.logvisual.gui.LogVisualizationGui.PropertyChangeCallback;
 import org.jfree.chart.JFreeChart;
 
@@ -57,6 +57,7 @@ class PlanBox extends Box{
   private JButton savePlanButton;
   private JButton createPlanButton;
   private JButton deletePlanButton;
+  private JButton exportResultButton;
 
   // display of plans
   private JScrollPane scrollPane;
@@ -86,12 +87,14 @@ class PlanBox extends Box{
     savePlanButton = new JButton("Save plan");
     createPlanButton = new JButton("Create plan");
     deletePlanButton = new JButton("Delete plan");
+    exportResultButton = new JButton("Export result");
     panelName.setAlignmentX(CENTER_ALIGNMENT);
     loadPlanButton.setAlignmentX(CENTER_ALIGNMENT);
     executePlanButton.setAlignmentX(CENTER_ALIGNMENT);
     savePlanButton.setAlignmentX(CENTER_ALIGNMENT);
     createPlanButton.setAlignmentX(CENTER_ALIGNMENT);
     deletePlanButton.setAlignmentX(CENTER_ALIGNMENT);
+    exportResultButton.setAlignmentX(CENTER_ALIGNMENT);
 
     planListModel = new DefaultListModel<>();
     planList = new JList<>(planListModel);
@@ -111,6 +114,8 @@ class PlanBox extends Box{
     vBox.add(deletePlanButton);
     vBox.add(Box.createVerticalStrut(5));
     vBox.add(executePlanButton);
+    vBox.add(Box.createVerticalStrut(5));
+    vBox.add(exportResultButton);
     vBox.add(Box.createGlue());
     add(vBox);
 
@@ -119,11 +124,14 @@ class PlanBox extends Box{
     add(planDetailPanel);
 
     planList.addListSelectionListener(this::onPlanSelectionChanged);
-    loadPlanButton.addActionListener(this::onLoadPlanButtonClick);
-    executePlanButton.addActionListener(this::onExecutePlanButtonClick);
+    loadPlanButton.addActionListener(this::onLoadPlan);
+    executePlanButton.addActionListener(this::onExecutePlan);
     savePlanButton.addActionListener(this::onPlanSave);
     createPlanButton.addActionListener(this::onCreatePlan);
     deletePlanButton.addActionListener(this::onDeletePlan);
+    exportResultButton.addActionListener(this::onExportResult);
+
+    exportResultButton.setEnabled(false);
 
     if (defaultPlanPath != null) {
       // load default plans if given
@@ -144,7 +152,7 @@ class PlanBox extends Box{
     }
   }
 
-  private void onLoadPlanButtonClick(ActionEvent e) {
+  private void onLoadPlan(ActionEvent e) {
     JFileChooser fileChooser = new JFileChooser();
     fileChooser.setMultiSelectionEnabled(true);
     fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
@@ -180,21 +188,25 @@ class PlanBox extends Box{
     }
   }
 
-  private void onExecutePlanButtonClick(ActionEvent e) {
+  private void onExecutePlan(ActionEvent e) {
     VisualizationPlan plan = (VisualizationPlan) planList.getSelectedValue();
     if (plan == null) {
       return;
     }
     try {
       visualizer.executePlan(plan);
-    } catch (AnalyzeException e1) {
+    } catch (VisualizeException e1) {
       JOptionPane.showMessageDialog(this, "Cannot execute plan: " + 
e1.getMessage());
+      return;
     }
     // timeseries plots of each measurement in the visualization plan
     Map<String, JFreeChart> charts = visualizer.getCharts();
     // statistics (count, mean, max, min) of each measurement
     Map<String, List<TimeSeriesStatistics>> statisticMap = 
visualizer.getStatisticsMap();
     executePlanCallback.call(plan.getName(), charts, statisticMap);
+    exportResultButton.setEnabled(true);
+    JOptionPane.showMessageDialog(this,
+        String.format("Plan is successfully executed, found %d log groups", 
charts.size()));
   }
 
   private void onPlanSelectionChanged(ListSelectionEvent e) {
@@ -248,6 +260,22 @@ class PlanBox extends Box{
     }
   }
 
+  private void onExportResult(ActionEvent e) {
+    JFileChooser fileChooser = new JFileChooser();
+    fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+    // let the user choose plan files or directories that contain 
visualization plans
+    int status = fileChooser.showOpenDialog(this);
+    if (status == JFileChooser.APPROVE_OPTION) {
+      File distDir = fileChooser.getSelectedFile();
+      try {
+        visualizer.saveResults(distDir.getPath(), 800, 600);
+        JOptionPane.showMessageDialog(this, "Export successfully");
+      } catch (VisualizeException e1) {
+        JOptionPane.showMessageDialog(this,"Cannot export results:" + 
e1.getMessage());
+      }
+    }
+  }
+
   public interface ExecutePlanCallback {
     // call this to create new tabs to show the results after the plan is 
executed
     void call(String planName, Map<String, JFreeChart> charts, Map<String,

Reply via email to