You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by ph...@apache.org on 2010/08/27 02:58:56 UTC

svn commit: r989991 - in /avro/trunk: ./ lang/java/src/java/org/apache/avro/ipc/trace/ lang/java/src/java/org/apache/avro/ipc/trace/templates/ lang/java/src/test/java/org/apache/avro/ipc/trace/

Author: philz
Date: Fri Aug 27 00:58:56 2010
New Revision: 989991

URL: http://svn.apache.org/viewvc?rev=989991&view=rev
Log:
AVRO-614. Improve Trace frontend UI. (Patrick Wendell via philz)


Added:
    avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestTracingUtil.java
Modified:
    avro/trunk/CHANGES.txt
    avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/TraceCollection.java
    avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/Util.java
    avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/common.vm
    avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/node.vm
    avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/overview.vm
    avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/traceinput.vm
    avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestBasicTracing.java

Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=989991&r1=989990&r2=989991&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Fri Aug 27 00:58:56 2010
@@ -64,6 +64,8 @@ Avro 1.4.0 (unreleased)
 
   IMPROVEMENTS
 
+    AVRO-614. Improve Trace frontend UI. (Patrick Wendell via philz)
+
     AVRO-629. Prefer the JSON module of python's stdlib over simplejson.
     (Harsh J Chouraria via philz)
 

Modified: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/TraceCollection.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/TraceCollection.java?rev=989991&r1=989990&r2=989991&view=diff
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/TraceCollection.java (original)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/TraceCollection.java Fri Aug 27 00:58:56 2010
@@ -18,11 +18,12 @@
 
 package org.apache.avro.ipc.trace;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.SortedSet;
 import java.util.TreeSet;
 
 
@@ -53,13 +54,19 @@ import java.util.TreeSet;
  */
 public class TraceCollection {
   
+  /** 
+   * To keep from overwhelming our browser charts, we cap the number of data
+   * points we display for any chart.
+   */
+  private static final int MAX_DATA_POINTS = 1000;
+  
   /**
    * Class to store the timing data associated with a particluar trace.
    */
   public class TraceTiming implements Comparable<TraceTiming> {
-    public long preLinkTime;
-    public long computeTime;
-    public long postLinkTime;
+    long preLinkTime;
+    long computeTime;
+    long postLinkTime;
     
     public TraceTiming(Long preLinkTime, Long computeTime, Long postLinkTime) {
       this.preLinkTime = preLinkTime;
@@ -74,6 +81,10 @@ public class TraceCollection {
     public int compareTo(TraceTiming other) {
       return this.getTotalTime().compareTo(other.getTotalTime());
     }
+    
+    public long getPreLinkTime() { return this.preLinkTime; }
+    public long getComputeTime() { return this.computeTime; }
+    public long getPostLinkTime() { return this.postLinkTime; }
   }
   
   /**
@@ -83,19 +94,17 @@ public class TraceCollection {
     CharSequence messageName;
     List<TraceNodeStats> children;
     
-    TreeSet<Long> requestPayloads;
-    TreeSet<Long> responsePayloads;
-    
-    // Time can be divided into three components
-    public TreeSet<TraceTiming> traceTimings;
+    List<Long> requestPayloads;
+    List<Long> responsePayloads;
+    List<TraceTiming> traceTimings;
     
     /**
      * Create a TraceNodeStats given a root TraceNode.
      */
     public TraceNodeStats(TraceNode root) {
-      this.requestPayloads = new TreeSet<Long>();
-      this.responsePayloads = new TreeSet<Long>();
-      this.traceTimings = new TreeSet<TraceTiming>();
+      this.requestPayloads = new ArrayList<Long>();
+      this.responsePayloads = new ArrayList<Long>();
+      this.traceTimings = new ArrayList<TraceTiming>();
      
       this.messageName = root.span.messageName;
       this.children = new LinkedList<TraceNodeStats>();
@@ -106,31 +115,47 @@ public class TraceCollection {
     }
     
     // Velocity requires getters
-    public SortedSet<Long> getRequestPayloads() { return this.requestPayloads; }
-    public SortedSet<Long> getResponsePayloads() { return this.responsePayloads; }
-    public SortedSet<TraceTiming> getTraceTimings() { return this.traceTimings; }
+    public List<Long> getRequestPayloads() {
+      return Util.sampledList(this.requestPayloads, MAX_DATA_POINTS);
+    }
+    public List<Long> getResponsePayloads() {
+      return Util.sampledList(this.responsePayloads, MAX_DATA_POINTS);
+    }
+    public List<TraceTiming> getTraceTimings() { 
+      return Util.sampledList(this.traceTimings, MAX_DATA_POINTS);
+    }
+    public List<TraceTiming> getTraceTimingsSorted() { 
+      List<TraceTiming> copy = Util.sampledList(this.traceTimings,
+          MAX_DATA_POINTS);
+      Collections.sort(copy);
+      return copy;
+    }
     public List<TraceNodeStats> getChildren() { return this.children; }
     public CharSequence getMessageName() { return this.messageName; } 
     
     // Convenience methods for templates
-    public String getAverageTime(SortedSet<TraceTiming> input) {
+    public String getAverageTime(List<TraceTiming> input) {
       return Util.printableTime(getTimingAverage(input));
     }
-    public String getMinTime(SortedSet<TraceTiming> input) {
-      return Util.printableTime(input.first().getTotalTime());
-    }
-    public String getMaxTime(SortedSet<TraceTiming> input) {
-      return Util.printableTime(input.last().getTotalTime());
+    public String getMinTime(List<TraceTiming> input) {
+      TraceTiming min = (TraceTiming) Collections.min(input);
+      return Util.printableTime(min.getTotalTime());
+    }
+    public String getMaxTime(List<TraceTiming> input) {
+      TraceTiming max = (TraceTiming) Collections.max(input);
+      return Util.printableTime(max.getTotalTime());
     }
  
-    public String getAverageBytes(SortedSet<Long> input) {
+    public String getAverageBytes(List<Long> input) {
       return Util.printableBytes(getLongAverage(input));
     }
-    public String getMinBytes(SortedSet<Long> input) {
-      return Util.printableBytes(input.first());
-    }
-    public String getMaxBytes(SortedSet<Long> input) {
-      return Util.printableBytes(input.last());
+    public String getMinBytes(List<Long> input) {
+      Long min = (Long) Collections.min(input);
+      return Util.printableBytes(min);
+    }
+    public String getMaxBytes(List<Long> input) {
+      Long max = (Long) Collections.max(input);
+      return Util.printableBytes(max);
     }
     
     public String printBrief() {

Modified: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/Util.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/Util.java?rev=989991&r1=989990&r2=989991&view=diff
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/Util.java (original)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/Util.java Fri Aug 27 00:58:56 2010
@@ -20,6 +20,7 @@ package org.apache.avro.ipc.trace;
 
 import java.nio.ByteBuffer;
 import java.nio.LongBuffer;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.EnumSet;
 import java.util.List;
@@ -197,4 +198,25 @@ class Util {
     if (startTime > start && endTime < end) { return true; }
     return false;
   }
+  
+  /**
+   * Return a copy of input that contains no more than maxEntries items.
+   * If the input list is more than maxEntries items long, the original list
+   * is uniformly sampled.
+   * 
+   * This uses a very simple sampling technique and may result in lists
+   * smaller than maxEntries.
+   */
+  public static <T> List<T> sampledList(List<T> input, int maxEntries) {
+    int timesTooLarge = (int) Math.ceil((double) input.size() / maxEntries);
+    if (timesTooLarge <= 1) { return new ArrayList<T>(input); }
+    
+    ArrayList<T> out = new ArrayList<T>();
+    for (int i = 0; i < input.size(); i++) {
+      if (i % timesTooLarge == 0) {
+        out.add(input.get(i));
+      }
+    } 
+    return out;
+  }
 }

Modified: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/common.vm
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/common.vm?rev=989991&r1=989990&r2=989991&view=diff
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/common.vm (original)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/common.vm Fri Aug 27 00:58:56 2010
@@ -93,12 +93,13 @@ $traceNode.getMessageName()
 
 
 #macro ( mediaIncludes )
-<script type="text/javascript" src="static/protovis-r3.2.js"></script>
-<script type="text/javascript" src="static/tipsy.js"></script>
+<script type="text/javascript" src="/static/protovis-r3.2.js"></script>
+<script type="text/javascript" src="/static/avrotrace.js"></script>
+<script type="text/javascript" src="/static/tipsy.js"></script>
 <script src="static/jquery-1.4.2.min.js" type="text/javascript"></script>
 <script src="static/jquery.tipsy.js" type="text/javascript"></script>
 <script src="static/tipsy.js" type="text/javascript"></script>
 <link href="static/tipsy.css" type="text/css" rel="stylesheet"/>
 <script src="static/avro.js" type="text/javascript"></script>
 <link href="static/avro.css" type="text/css" rel="stylesheet"/>
-#end
\ No newline at end of file
+#end

Modified: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/node.vm
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/node.vm?rev=989991&r1=989990&r2=989991&view=diff
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/node.vm (original)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/node.vm Fri Aug 27 00:58:56 2010
@@ -32,8 +32,67 @@
   #printCollectionSummary( $collection )
   #if( $node )
     <h1>$node.getMessageName()</h1>	
+	<p>
+	<strong>Latency - ms (Time Ordered)</strong><br>
+	<script type="text/javascript">
+	var data = [
+	#set ($forCount = 0)
+	#foreach ( $tim in $node.getTraceTimings() )
+      {index: $forCount, prelink: $tim.PreLinkTime, cpu: $tim.ComputeTime, postlink: $tim.PostLinkTime},
+      #set ($forCount = $forCount + 1)
+	#end 
+	]
+	makeLatencyChart(data);
+	</script>
+  </p>
+  
+  <p>
+  <strong>Latency - ms (Sorted) </strong><br>
+  <script type="text/javascript">
+  var data = [
+  #set ($forCount = 0)
+  #foreach ( $tim in $node.getTraceTimingsSorted() )
+      {index: $forCount, prelink: $tim.PreLinkTime, cpu: $tim.ComputeTime, postlink: $tim.PostLinkTime},
+      #set ($forCount = $forCount + 1)
+  #end 
+  ]
+  makeLatencyChart(data);
+  </script>
+  </p>
+  
+  <p>
+  <strong>Request Payloads - bytes (Time Ordered)</strong><br>
+  <script>
+  var data = [
+  #set ($forCount = 0)
+  #foreach ( $payload in $node.getRequestPayloads() )
+      {x: $forCount, y: $payload},
+      #set ($forCount = $forCount + 1)
+  #end 
+  ]
+  makePayloadChart(data);
+  </script>
+  </p>
+  
+  <p>
+  <strong>Response Payloads - bytes (Time Ordered)</strong><br>
+  <script>
+  var data = [
+  #set ($forCount = 0)
+  #foreach ( $payload in $node.getResponsePayloads() )
+      {x: $forCount, y: $payload},
+      #set ($forCount = $forCount + 1)
+  #end 
+  ]
+  makePayloadChart(data);
+  </script>
+  </p>
+  
+  #else
+    <h1>Node not found</h1>
   #end
-  NOT IMPLEMENTED
+#else
+  <h1>Collection not Found</h2>
 #end
 </body>
 </html>

Modified: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/overview.vm
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/overview.vm?rev=989991&r1=989990&r2=989991&view=diff
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/overview.vm (original)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/overview.vm Fri Aug 27 00:58:56 2010
@@ -42,4 +42,4 @@ You can always <a href="/">collect more 
 </p>
 </table>
 </body>
-</html>
\ No newline at end of file
+</html>

Modified: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/traceinput.vm
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/traceinput.vm?rev=989991&r1=989990&r2=989991&view=diff
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/traceinput.vm (original)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/traceinput.vm Fri Aug 27 00:58:56 2010
@@ -27,7 +27,9 @@
 <p>This input expects newline separated "host:port" pairs. By default, the
 TracePlugin serves tracing data on $default_port.</p>
 
-<textarea rows=10 cols=60 name='servers'>$last_input</textarea>
+<textarea rows="10" cols="60" name="servers">
+$last_input
+</textarea>
 
 
 <input type='submit' name='Start Tracing'>

Modified: avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestBasicTracing.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestBasicTracing.java?rev=989991&r1=989990&r2=989991&view=diff
==============================================================================
--- avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestBasicTracing.java (original)
+++ avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestBasicTracing.java Fri Aug 27 00:58:56 2010
@@ -428,7 +428,7 @@ public class TestBasicTracing {
     while (true){
       r1.request("w", params);
       r2.request("x", params);
-      Thread.sleep(1000);
+      Thread.sleep(100);
     }
   }
 }

Added: avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestTracingUtil.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestTracingUtil.java?rev=989991&view=auto
==============================================================================
--- avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestTracingUtil.java (added)
+++ avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestTracingUtil.java Fri Aug 27 00:58:56 2010
@@ -0,0 +1,29 @@
+package org.apache.avro.ipc.trace;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+public class TestTracingUtil {
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testListSampling() {
+    List<Long> in1 = (List<Long>) 
+      Arrays.asList(new Long[] {0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L});
+    List<Long> out1 = Util.sampledList(in1, 4);
+    assertTrue(Arrays.equals(out1.toArray(), new Long[] {0L, 3L, 6L }));
+    
+    List<Long> in2 = new ArrayList<Long>(50000);
+    for (int i = 0; i < 50000; i++) {
+      in2.add((long)i);
+    }
+    
+    List<Long> out2 = Util.sampledList(in2, 1000);
+    assertEquals(1000, out2.size());
+  }
+}