From dbb880732141f3f342cbf754a60aee84e02106fa Mon Sep 17 00:00:00 2001 From: Chisu Yu Date: Tue, 23 Oct 2012 06:21:20 +0000 Subject: [PATCH] =?UTF-8?q?[=EC=9C=A0=EC=B9=98=EC=88=98]=20[NOBTS]=20add?= =?UTF-8?q?=20scatter=20chart?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-web/trunk@817 84d0f5b1-2673-498c-a247-62c4ff18d310 --- .../web/controller/FlowChartController.java | 3 +- .../nhn/hippo/web/vo/BusinessTransaction.java | 4 +- .../hippo/web/vo/BusinessTransactions.java | 78 +++++++---- src/main/java/com/nhn/hippo/web/vo/Trace.java | 16 ++- src/main/webapp/WEB-INF/views/flowserver.jsp | 97 +++++++------ src/main/webapp/index.html | 127 +++++++++++++++++- 6 files changed, 241 insertions(+), 84 deletions(-) diff --git a/src/main/java/com/nhn/hippo/web/controller/FlowChartController.java b/src/main/java/com/nhn/hippo/web/controller/FlowChartController.java index 526caf998..0a6a3ff1f 100644 --- a/src/main/java/com/nhn/hippo/web/controller/FlowChartController.java +++ b/src/main/java/com/nhn/hippo/web/controller/FlowChartController.java @@ -53,7 +53,8 @@ public class FlowChartController { model.addAttribute("nodes", callTree.getNodes()); model.addAttribute("links", callTree.getLinks()); - model.addAttribute("businessTransactions", callTree.getBusinessTransactions().iterator()); + model.addAttribute("businessTransactions", callTree.getBusinessTransactions().getBusinessTransactionIterator()); + model.addAttribute("traces", callTree.getBusinessTransactions().getTracesIterator()); logger.debug("callTree:{}", callTree); diff --git a/src/main/java/com/nhn/hippo/web/vo/BusinessTransaction.java b/src/main/java/com/nhn/hippo/web/vo/BusinessTransaction.java index 9fcacb402..172a75dc7 100644 --- a/src/main/java/com/nhn/hippo/web/vo/BusinessTransaction.java +++ b/src/main/java/com/nhn/hippo/web/vo/BusinessTransaction.java @@ -33,7 +33,7 @@ public class BusinessTransaction { long elapsed = end - begin; totalTime = maxTime = minTime = elapsed; - this.traces.add(new Trace(new UUID(span.getMostTraceId(), span.getLeastTraceId()).toString(), elapsed)); + this.traces.add(new Trace(new UUID(span.getMostTraceId(), span.getLeastTraceId()).toString(), elapsed, span.getTimestamp())); calls++; } @@ -56,7 +56,7 @@ public class BusinessTransaction { if (minTime > elapsed) minTime = elapsed; - this.traces.add(new Trace(new UUID(span.getMostTraceId(), span.getLeastTraceId()).toString(), elapsed)); + this.traces.add(new Trace(new UUID(span.getMostTraceId(), span.getLeastTraceId()).toString(), elapsed, span.getTimestamp())); if (span.getParentSpanId() == -1) { calls++; diff --git a/src/main/java/com/nhn/hippo/web/vo/BusinessTransactions.java b/src/main/java/com/nhn/hippo/web/vo/BusinessTransactions.java index 8752e0543..2f773698e 100644 --- a/src/main/java/com/nhn/hippo/web/vo/BusinessTransactions.java +++ b/src/main/java/com/nhn/hippo/web/vo/BusinessTransactions.java @@ -6,41 +6,61 @@ import java.util.Map; import java.util.Map.Entry; import com.profiler.common.bo.SpanBo; -import com.profiler.common.dto.thrift.Span; -public final class BusinessTransactions implements Iterable { +public final class BusinessTransactions { - private final Map transactions = new HashMap(); - private Iterator> iterator; + private final Map transactions = new HashMap(); + private Iterator> iterator; + private Iterator> traceIterator; - public void add(SpanBo span) { - String name = span.getName(); - if (transactions.containsKey(name)) { - transactions.get(name).add(span); - } else { - transactions.put(name, new BusinessTransaction(span)); - } - } + public void add(SpanBo span) { + String name = span.getName(); + if (transactions.containsKey(name)) { + transactions.get(name).add(span); + } else { + transactions.put(name, new BusinessTransaction(span)); + } + } - @Override - public Iterator iterator() { - iterator = transactions.entrySet().iterator(); + public Iterator getBusinessTransactionIterator() { + iterator = transactions.entrySet().iterator(); - return new Iterator() { - @Override - public boolean hasNext() { - return iterator.hasNext(); - } + return new Iterator() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } - @Override - public BusinessTransaction next() { - return iterator.next().getValue(); - } + @Override + public BusinessTransaction next() { + return iterator.next().getValue(); + } - @Override - public void remove() { + @Override + public void remove() { - } - }; - } + } + }; + } + + public Iterator getTracesIterator() { + traceIterator = transactions.entrySet().iterator(); + + return new Iterator() { + @Override + public boolean hasNext() { + return traceIterator.hasNext(); + } + + @Override + public BusinessTransaction next() { + return traceIterator.next().getValue(); + } + + @Override + public void remove() { + + } + }; + } } diff --git a/src/main/java/com/nhn/hippo/web/vo/Trace.java b/src/main/java/com/nhn/hippo/web/vo/Trace.java index f88652259..78bd03ed9 100644 --- a/src/main/java/com/nhn/hippo/web/vo/Trace.java +++ b/src/main/java/com/nhn/hippo/web/vo/Trace.java @@ -3,18 +3,24 @@ package com.nhn.hippo.web.vo; public class Trace { private final String traceId; - private final long time; + private final long executionTime; + private final long timestamp; - public Trace(String traceId, long time) { + public Trace(String traceId, long executionTime, long timestamp) { this.traceId = traceId; - this.time = time; + this.executionTime = executionTime; + this.timestamp = timestamp; } public String getTraceId() { return traceId; } - public long getTime() { - return time; + public long getExecutionTime() { + return executionTime; + } + + public long getTimestamp() { + return timestamp; } } diff --git a/src/main/webapp/WEB-INF/views/flowserver.jsp b/src/main/webapp/WEB-INF/views/flowserver.jsp index 9ce52ac69..896470635 100644 --- a/src/main/webapp/WEB-INF/views/flowserver.jsp +++ b/src/main/webapp/WEB-INF/views/flowserver.jsp @@ -1,48 +1,57 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> { -"graphdata": -{ -"nodes" : -[ - - - { "name" : "${node.endPoint}" } - - - { "name" : "${node}" } - - , - -], -"links" : -[ - - {"source" : ${link.from.sequence}, "target" : ${link.to.sequence}, "value" : ${link.callCount}} - , - -] -}, - -"businessTransactions" : -[ - - { - "name" : "${t.name}", - "calls" : ${t.calls}, - "time" : ${t.totalTime / t.calls}, - "minTime" : ${t.minTime}, - "maxTime" : ${t.maxTime}, - "health" : 1, - "traces" : - [ - - { "traceId" : "${trace.traceId}", "time" : ${trace.time} } - , - - ] - } - , - -] + "graphdata" : { + "nodes" : [ + + + { "name" : "${node.endPoint}" } + + + { "name" : "${node}" } + + , + + ], + "links" : [ + + {"source" : ${link.from.sequence}, "target" : ${link.to.sequence}, "value" : ${link.callCount}} + , + + ] + }, + + "businessTransactions" : [ + + { + "name" : "${t.name}", + "calls" : ${t.calls}, + "time" : ${t.totalTime / t.calls}, + "minTime" : ${t.minTime}, + "maxTime" : ${t.maxTime}, + "health" : 1, + "traces" : [ + + { "traceId" : "${trace.traceId}", "time" : ${trace.executionTime} } + , + + ] + } + , + + ], + + "scatter" : [ + + + { + "timestamp" : ${trace.timestamp}, + "executionTime" : ${trace.executionTime}, + "name" : "${t.name}" + } + , + + , + + ] } \ No newline at end of file diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index 6e79e223f..6540d7421 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -26,6 +26,10 @@ + + @@ -117,7 +134,16 @@
-

+

+
+
+ +
+
Scatterplot
+
+
+
+

@@ -179,7 +205,7 @@ function getEndTime() { } function cleanupChart() { - $("#chart").empty(); + $("#graph").empty(); } function cleanupTracesTable() { @@ -204,7 +230,7 @@ function drawChart(chartType) { var hosts = $("#servers").val(); - var svg = d3.select("#chart").append("svg") + var svg = d3.select("#graph").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); @@ -330,6 +356,8 @@ function drawChart(chartType) { } $("#businessTransactions TBODY").append(html.join('')); + drawScatter(traces.scatter); + }); // end of d3.json } // end of draw chart @@ -375,6 +403,99 @@ function openTransactionDetails(index, row) { function openTrace(uuid) { window.open("/selectTransaction.hippo?traceId=" + uuid); } + + +function drawScatter(data) { + var margin = {top: 20, right: 20, bottom: 30, left: 40}, + width = 960 - margin.left - margin.right, + height = 500 - margin.top - margin.bottom; + + var x = d3.scale.linear() + .range([0, width]); + + var y = d3.scale.linear() + .range([height, 0]); + + var color = d3.scale.category10(); + + var xAxis = d3.svg.axis() + .scale(x) + .orient("bottom"); + + var yAxis = d3.svg.axis() + .scale(y) + .orient("left"); + + var svg = d3.select("#scatter").append("svg") + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.top + margin.bottom) + .append("g") + .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + + //d3.json("/data.tsv", function (data) { + //d3.tsv("data.tsv", function(error, data) { + + data.forEach(function(d) { + d.sepalLength = +d.sepalLength; + d.sepalWidth = +d.sepalWidth; + }); + + x.domain(d3.extent(data, function(d) { return d.timestamp; })).nice(); + y.domain(d3.extent(data, function(d) { return d.executionTime; })).nice(); + + svg.append("g") + .attr("class", "x axis") + .attr("transform", "translate(0," + height + ")") + .call(xAxis) + .append("text") + .attr("class", "label") + .attr("x", width) + .attr("y", -6) + .style("text-anchor", "end") + .text("Timestamp (HH:mm)"); + + svg.append("g") + .attr("class", "y axis") + .call(yAxis) + .append("text") + .attr("class", "label") + .attr("transform", "rotate(-90)") + .attr("y", 6) + .attr("dy", ".71em") + .style("text-anchor", "end") + .text("Execute time (ms)") + + svg.selectAll(".dot") + .data(data) + .enter().append("circle") + .attr("class", "dot") + .attr("r", 3.5) + .attr("cx", function(d) { return x(d.timestamp); }) + .attr("cy", function(d) { return y(d.executionTime); }) + .style("fill", function(d) { return color(d.name); }); + + var legend = svg.selectAll(".legend") + .data(color.domain()) + .enter().append("g") + .attr("class", "legend") + .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); + + legend.append("rect") + .attr("x", width - 18) + .attr("width", 18) + .attr("height", 18) + .style("fill", color); + + legend.append("text") + .attr("x", width - 24) + .attr("y", 9) + .attr("dy", ".35em") + .style("text-anchor", "end") + .text(function(d) { return d; }); + + //}); + +}