Print

Print


Author: [log in to unmask]
Date: Mon Mar 16 14:42:56 2015
New Revision: 2466

Log:
Cleanup ET system strip chart code.

Modified:
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/plotting/MonitoringPlotFactory.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartBuilder.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatistics.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatisticsImpl.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/EtSystemStripCharts.java

Modified: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/plotting/MonitoringPlotFactory.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/plotting/MonitoringPlotFactory.java	(original)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/plotting/MonitoringPlotFactory.java	Mon Mar 16 14:42:56 2015
@@ -164,7 +164,7 @@
             RegularTimePeriod timeBase,
             ValueProvider valueProvider,
             long rangeView) {
-        StripChartUpdater updater = StripChartBuilder.createStripChart(
+        StripChartUpdater updater = StripChartBuilder.createDynamicTimeSeriesChart(
                 name, 
                 rangeLabel, 
                 seriesCount, 
@@ -216,6 +216,17 @@
         return stripChart;
     }       
     
+    public JFreeChart createTimeSeriesChart(
+            String title, 
+            String yAxisLabel, 
+            int seriesCount,
+            String[] datasetNames,
+            double rangeSize) {
+        JFreeChart chart = StripChartBuilder.createTimeSeriesChart(title, yAxisLabel, seriesCount, datasetNames, rangeSize);
+        addChart(chart);
+        return chart;
+    }
+    
     /**
      * Get the global registry of plotters.
      * @return The global plotter registry.

Modified: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartBuilder.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartBuilder.java	(original)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartBuilder.java	Mon Mar 16 14:42:56 2015
@@ -26,12 +26,12 @@
      * @param valueProvider The interface for providing values.
      * @return The StripChartUpdater for the chart.
      */
-    static StripChartUpdater createStripChart(
+    static StripChartUpdater createDynamicTimeSeriesChart(
             String name, 
             int seriesCount, 
             RegularTimePeriod timeBase,
             ValueProvider valueProvider) {
-        return createStripChart(name, "Values", seriesCount, null, 9999, timeBase, valueProvider, 10000L);
+        return createDynamicTimeSeriesChart(name, "Values", seriesCount, null, 9999, timeBase, valueProvider, 10000L);
     }
     
     /**
@@ -47,7 +47,7 @@
      * @param rangeView The view in the domain axis around the current data point (milliseconds).
      * @return The StripChartUpdater for the chart.
      */
-    static StripChartUpdater createStripChart(
+    static StripChartUpdater createDynamicTimeSeriesChart(
             String name, 
             String rangeLabel,
             int seriesCount, 
@@ -99,7 +99,7 @@
      * @param maxCount The maximum count of items in the single data set series.
      * @return The chart that was created.
      */
-    public static JFreeChart createTimeSeriesChart(
+    static JFreeChart createTimeSeriesChart(
             String title, 
             String yAxisLabel, 
             int maxAge, 
@@ -149,7 +149,7 @@
      * @param rangeSize The range of values to show for auto-ranging in domain axis (in milliseconds).
      * @return The chart that was created.
      */
-    public static JFreeChart createTimeSeriesChart(
+    static JFreeChart createTimeSeriesChart(
             String title, 
             String yAxisLabel, 
             int seriesCount,

Modified: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatistics.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatistics.java	(original)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatistics.java	Mon Mar 16 14:42:56 2015
@@ -11,13 +11,20 @@
      * Set the desired timer tick length in millis.
      * @param tickLengthMillis The desired tick length in millis.
      */
-    void setTickLengthMillis(long tickLengthMillis);
+    void setNominalTickLengthMillis(long tickLengthMillis);
 
     /**
-     * Get the nominal length of one tick in millis. Actual ticks lengths may vary slightly.
+     * Get the nominal length of one tick in millis.
+     *  Actual tick lengths lengths may vary slightly.
      * @return The nominal tick length in millis.
      */
-    long getTickLengthMillis();
+    long getNominalTickLengthMillis();
+    
+    /**
+     * Get the end of the tick in Unix time (milliseconds since the epoch).
+     * @return The tick end in Unix time.
+     */
+    long getTickEndTimeMillis();
 
     /**
      * Start the timer thread for accumulating statistics.
@@ -40,7 +47,7 @@
      * Get the number of millis since the session started.
      * @return The number of millis since session start.
      */
-    long getTotalElapsedMillis();
+    long getElapsedMillis();
 
     /**
      * Get the Unix start time of the session.
@@ -105,6 +112,13 @@
      * @return The data rate in [bytes/second].
      */
     public double getBytesPerSecond();
+    
+    /**
+     * Get the immediate data rate which is the amount of data in megabytes received in the current tick
+     * over the time elapsed in the tick.
+     * @return The data rate in [bytes/second].
+     */
+    public double getMegabytesPerSecond();
 
     /**
      * Get the number of milliseconds since the last tick.
@@ -123,10 +137,10 @@
      * @param ps The PrintStream for display.
      */
     void printTick(PrintStream ps);
-
+    
     /**
-     * Add subtask which will execute right before a new tick.
-     * @param subtask The subtask to execute.
+     * 
+     * @param listener
      */
-    //void addSubTask(TimerTask subtask);
+    void addSystemStatisticsListener(SystemStatisticsListener listener);   
 }

Modified: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatisticsImpl.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatisticsImpl.java	(original)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatisticsImpl.java	Mon Mar 16 14:42:56 2015
@@ -2,6 +2,8 @@
 
 import java.io.PrintStream;
 import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -12,21 +14,28 @@
  */
 public class SystemStatisticsImpl implements SystemStatistics {
 
-    long tickLengthMillis = 1000; // default is 1 second tick
-    long totalElapsedMillis;
+    long nominalTickLengthMillis = 1000; // default is 1 second tick
+    long tickStartTimeMillis;
+    long tickEndTimeMillis;    
+
+    long eventsInTick;
+    long bytesInTick;
+    
+    long elapsedMillis;
     long startTimeMillis;
     long stopTimeMillis;
-    long eventsSinceTick;
-    long bytesSinceTick;
+    
     long totalEvents;
     long totalBytes;
-    long tickStartMillis;
+
     static final long Kb = 1 * 1024;
     static final long Mb = Kb * 1024;
     static final double milliToSecond = 0.001;
     static final DecimalFormat decimalFormat = new DecimalFormat("#.####");
     Timer timer;
     
+    List<SystemStatisticsListener> listeners = new ArrayList<SystemStatisticsListener>();
+    
     @Override
     public void update(int size) {
         addEvent();
@@ -35,18 +44,18 @@
     }
 
     @Override
-    public void setTickLengthMillis(long tickLengthMillis) {
-        this.tickLengthMillis = tickLengthMillis;
-    }
-
-    @Override
-    public long getTickLengthMillis() {
-        return tickLengthMillis;
-    }
-
-    @Override
-    public long getTotalElapsedMillis() {
-        return totalElapsedMillis;
+    public void setNominalTickLengthMillis(long tickLengthMillis) {
+        this.nominalTickLengthMillis = tickLengthMillis;
+    }
+
+    @Override
+    public long getNominalTickLengthMillis() {
+        return nominalTickLengthMillis;
+    }
+
+    @Override
+    public long getElapsedMillis() {
+        return System.currentTimeMillis() - startTimeMillis;
     }
 
     @Override
@@ -61,7 +70,12 @@
     
     @Override
     public long getTickElapsedMillis() {
-        return System.currentTimeMillis() - tickStartMillis;
+        return System.currentTimeMillis() - tickStartTimeMillis;
+    }
+    
+    @Override
+    public long getTickEndTimeMillis() {
+        return tickEndTimeMillis;
     }
 
     /**
@@ -70,7 +84,7 @@
     
     @Override
     public long getEventsReceived() {
-        return eventsSinceTick;
+        return eventsInTick;
     }
      
     @Override
@@ -80,8 +94,8 @@
     
     @Override
     public double getEventsPerSecond() {
-        if (eventsSinceTick > 0 && getTickElapsedMillis() > 0) {
-            return (double) eventsSinceTick / millisToSeconds(getTickElapsedMillis());
+        if (eventsInTick > 0 && getTickElapsedMillis() > 0) {
+            return (double) eventsInTick / millisToSeconds(getTickElapsedMillis());
         } else {
             return 0.;
         }
@@ -90,7 +104,7 @@
     @Override
     public double getAverageEventsPerSecond() {
         try {
-            return Double.parseDouble(decimalFormat.format(totalEvents / millisToSeconds(getTotalElapsedMillis())));
+            return Double.parseDouble(decimalFormat.format(totalEvents / millisToSeconds(getElapsedMillis())));
         } catch (NumberFormatException e) {
             return 0;
         }
@@ -102,7 +116,7 @@
     
     @Override
     public long getBytesReceived() {
-        return bytesSinceTick;
+        return bytesInTick;
     }
     
     @Override
@@ -113,7 +127,7 @@
     @Override
     public double getAverageMegabytesPerSecond() {
         try {
-            return Double.parseDouble(decimalFormat.format(bytesToMb(totalBytes) / millisToSeconds(getTotalElapsedMillis())));
+            return Double.parseDouble(decimalFormat.format(bytesToMb(totalBytes) / millisToSeconds(getElapsedMillis())));
         } catch (NumberFormatException e) {
             return Double.NaN;
         }
@@ -121,28 +135,59 @@
    
     @Override
     public double getBytesPerSecond() {
-        if (bytesSinceTick > 0 && getTickElapsedMillis() > 0)
-            return (double) bytesSinceTick / millisToSeconds(getTickElapsedMillis());
+        if (bytesInTick > 0 && getTickElapsedMillis() > 0)
+            return (double) bytesInTick / millisToSeconds(getTickElapsedMillis());
         else
             return 0.;
     }
-
+    
+    @Override
+    public double getMegabytesPerSecond() {
+        double bytes = getBytesPerSecond();
+        if (bytes > 0) {
+            return bytesToMb(bytes);
+        } else {
+            return 0;
+        }
+    }
+    
     @Override
     public void start() {
 
         // Set session start time variables.
         long currentTimeMillis = System.currentTimeMillis();
         startTimeMillis = currentTimeMillis;
-        tickStartMillis = currentTimeMillis;
-
+        tickStartTimeMillis = currentTimeMillis;
+        
+        // Notify listeners of start.
+        for (SystemStatisticsListener listener : listeners) {
+            listener.started(this);
+        }
+        
         // Start timer task which executes at the nominal tick length to calculate statistics periodically.
         TimerTask task = new TimerTask() {
             public void run() {
+                
+                // End the current tick.
+                endTick();
+               
+                // Start the new tick.
                 nextTick();
             }
         };
         timer = new Timer();
-        timer.schedule(task, 0, tickLengthMillis);
+        timer.schedule(task, 0, nominalTickLengthMillis);
+    }
+    
+    void endTick() {
+ 
+        // Set absolute end time of current tick.
+        this.tickEndTimeMillis = System.currentTimeMillis();
+        
+        // Activate listeners.
+        for (SystemStatisticsListener listener : listeners) {
+            listener.endTick(this);
+        }
     }
 
     @Override
@@ -155,12 +200,21 @@
 
         // Set stop time.
         stopTimeMillis = System.currentTimeMillis();
-    }
-
+        
+        // Notify listeners of stop.
+        for (SystemStatisticsListener listener : listeners) {
+            listener.stopped(this);
+        }
+    }
+    
+    public void addSystemStatisticsListener(SystemStatisticsListener listener) {
+        listeners.add(listener);
+    }    
+    
     @Override
     public void printSession(PrintStream ps) {
         ps.println("session statistics ...");
-        ps.println("  timeElapsedMillis = " + this.getTotalElapsedMillis());
+        ps.println("  timeElapsedMillis = " + this.getElapsedMillis());
         ps.println("  cumulativeEvents = " + this.getTotalEvents());
         ps.println("  averageEventsPerSecond = " + this.getAverageEventsPerSecond());
         ps.println("  averageMegaBytesPerSecond = " + this.getAverageMegabytesPerSecond());
@@ -176,37 +230,42 @@
     }
    
     void addEvent() {
-        eventsSinceTick += 1;
+        eventsInTick += 1;
         totalEvents += 1;
     }
 
     void addData(int size) {
-        bytesSinceTick += size;
+        bytesInTick += size;
         totalBytes += size;
     }
 
     void updateElapsedTime() {
-        totalElapsedMillis = System.currentTimeMillis() - startTimeMillis;
+        elapsedMillis = System.currentTimeMillis() - startTimeMillis;
     }
 
     // Bytes to megabytes to 2 decimal places.
     static final double bytesToMb(long size) {
         return Double.parseDouble(decimalFormat.format((double) size / Mb));
     }
+    
+    // Bytes to megabytes to 2 decimal places.
+    static final double bytesToMb(double size) {
+        return Double.parseDouble(decimalFormat.format(size / Mb));
+    }
 
     static final double millisToSeconds(long millis) {
         return ((double) millis) / 1000.;
     }
 
     synchronized void nextTick() {
-        eventsSinceTick = 0;
-        bytesSinceTick = 0;
-        tickStartMillis = System.currentTimeMillis();
+        eventsInTick = 0;
+        bytesInTick = 0;
+        tickStartTimeMillis = System.currentTimeMillis();
     }
     
     public abstract class SystemStatisticsProvider implements ValueProvider {
     }
-    
+
     public class AverageEventsPerSecondProvider extends SystemStatisticsProvider {
 
         @Override

Modified: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/EtSystemStripCharts.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/EtSystemStripCharts.java	(original)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/EtSystemStripCharts.java	Mon Mar 16 14:42:56 2015
@@ -1,27 +1,53 @@
+/**
+ * 
+ */
 package org.hps.monitoring.subsys.et;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 import org.hps.monitoring.plotting.MonitoringPlotFactory;
-import org.hps.monitoring.plotting.StripChartUpdater;
+import org.hps.monitoring.subsys.SystemStatistics;
 import org.hps.monitoring.subsys.SystemStatisticsImpl;
+import org.hps.monitoring.subsys.SystemStatisticsListener;
 import org.hps.record.et.EtEventProcessor;
+import org.jfree.chart.JFreeChart;
 import org.jfree.data.time.Second;
+import org.jfree.data.time.TimeSeriesCollection;
 import org.jlab.coda.et.EtEvent;
 import org.lcsim.util.aida.AIDA;
 
 /**
- * A basic set of strip charts for monitoring the ET system.
+ * This will show a series of strip charts from ET system performance statistics
+ * such as event and data rates.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
  */
-public final class EtSystemStripCharts extends EtEventProcessor {
+public class EtSystemStripCharts extends EtEventProcessor implements SystemStatisticsListener {
 
+    // The system statistics.
     SystemStatisticsImpl stats = new SystemStatisticsImpl();
-    MonitoringPlotFactory plotFactory = (MonitoringPlotFactory) AIDA.defaultInstance().analysisFactory().createPlotterFactory("ET System Monitoring");
-    List<StripChartUpdater> updaters = new ArrayList<StripChartUpdater>();
     
-    public EtSystemStripCharts() {
-        stats.setTickLengthMillis(1000);
+    // Plotting API.
+    MonitoringPlotFactory plotFactory = 
+            (MonitoringPlotFactory) AIDA.defaultInstance().analysisFactory().createPlotterFactory("ET System Monitoring");
+    
+    // List of charts.
+    List<JFreeChart> charts = new ArrayList<JFreeChart>();
+    
+    // Range size in milliseconds.
+    static final double RANGE_SIZE = 200000;
+    
+    // Chart collection indices.
+    static final int DATA_RATE_COLLECTION_INDEX = 0;    
+    static final int TOTAL_DATA_COLLECTION_INDEX = 1;    
+    static final int EVENT_RATE_COLLECTION_INDEX = 2;
+    static final int TOTAL_EVENTS_COLLECTION_INDEX = 3;
+        
+    public EtSystemStripCharts() {          
+        // Set 2 seconds between statistics updates.
+        stats.setNominalTickLengthMillis(1000);
     }
     
     /**
@@ -29,57 +55,37 @@
      */
     @Override
     public void startJob() {
-
-        // Create the ET system strip charts.
-        createStripCharts();
+        
+        System.out.println("EtSystemStripChartsNew.startJob");
+   
+        // Register this class as a listener to activate update at end of statistics clock tick.
+        stats.addSystemStatisticsListener(this);
 
         // Start systems statistics task.
         stats.start();
     }
 
     /**
-     * 
+     * Create the strip charts for plotting the basic ET system statistics.
      */
     private void createStripCharts() {
-        updaters.add(plotFactory.createStripChart(
-                "Data Rate", 
-                "MB / second", 
-                1, 
-                new String[] { "Data" }, 
-                999, 
-                new Second(), 
-                stats.new MegabytesPerSecondProvider(), 
-                200000L));
+        
+        System.out.println("EtSystemStripChartsNew.createStripCharts");
 
-        updaters.add(plotFactory.createStripChart(
-                "Total Data", 
-                "Megabytes", 
-                1, 
-                new String[] { "Data" },
-                999,
-                new Second(), 
-                stats.new TotalMegabytesProvider(), 
-                200000L));
+        // Data rate in megabytes per second.
+        // TODO: Add to same chart the average MB / second.
+        charts.add(plotFactory.createTimeSeriesChart("Data Rate", "MB / second", 1, null, RANGE_SIZE));
+                
+        // Total megabytes received.
+        charts.add(plotFactory.createTimeSeriesChart("Total Data", "Megabytes", 1, null, RANGE_SIZE));
         
-        updaters.add(plotFactory.createStripChart(
-                "Event Rate", 
-                "Events / s", 
-                1, 
-                new String[] { "Data" }, 
-                999, 
-                new Second(), 
-                stats.new EventsPerSecondProvider(), 
-                200000L));
+        // Event rate in hertz.
+        // TODO: Add to same chart the average event rate.
+        charts.add(plotFactory.createTimeSeriesChart("Event Rate", "Hz", 1, null, RANGE_SIZE));
         
-        updaters.add(plotFactory.createStripChart(
-                "Total Events", 
-                "Number of Events", 
-                1, 
-                new String[] { "Data" }, 
-                999, 
-                new Second(), 
-                stats.new TotalEventsProvider(), 
-                200000L));
+        // Total number of events received.
+        charts.add(plotFactory.createTimeSeriesChart("Total Events", "Number of Events", 1, null, RANGE_SIZE));
+              
     }
 
     @Override
@@ -88,13 +94,39 @@
     }
 
     public void endJob() {
-
-        // Stop the strip chart updaters.
-        for (StripChartUpdater updater : updaters) {
-            updater.stop();
-        }
-        
         // Stop system statistics task.
         stats.stop();
     }
-}
+    
+    TimeSeriesCollection getTimeSeriesCollection(int chartIndex) {
+        return (TimeSeriesCollection) charts.get(chartIndex).getXYPlot().getDataset();
+    }
+
+    /**
+     * Hook for updating the charts at end of statistics clock tick.
+     * @param stats The statistics with the system information.
+     */
+    @Override
+    public void endTick(SystemStatistics stats) {
+        
+        Date now = new Date(stats.getTickEndTimeMillis());
+                
+        getTimeSeriesCollection(DATA_RATE_COLLECTION_INDEX).getSeries(0).addOrUpdate(
+                new Second(now), stats.getBytesPerSecond() / 1000000);
+        getTimeSeriesCollection(TOTAL_DATA_COLLECTION_INDEX).getSeries(0).addOrUpdate(
+                new Second(now), stats.getTotalMegabytes());
+        getTimeSeriesCollection(EVENT_RATE_COLLECTION_INDEX).getSeries(0).addOrUpdate(
+                new Second(now), stats.getEventsPerSecond());
+        getTimeSeriesCollection(TOTAL_EVENTS_COLLECTION_INDEX).getSeries(0).addOrUpdate(
+                new Second(now), stats.getTotalEvents());
+    }
+     
+    @Override
+    public void started(SystemStatistics stats) {
+        createStripCharts();
+    }
+   
+    @Override
+    public void stopped(SystemStatistics stats) {
+    }
+}