[유치수] [PINPOINT-227] 서버맵 조회 JSON에서 agent 목록을 물리 서버이름으로 group by.

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-web/trunk@2311 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Chisu Yu
2013-09-12 02:49:59 +00:00
parent 86f444636d
commit a82db0bac5
8 changed files with 328 additions and 50 deletions
@@ -1,11 +1,14 @@
package com.nhn.pinpoint.web.applicationmap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import com.nhn.pinpoint.common.ServiceType;
import com.nhn.pinpoint.common.bo.AgentInfoBo;
@@ -21,9 +24,12 @@ public class Application implements Comparable<Application> {
protected final String applicationName;
protected final ServiceType serviceType;
protected final Map<String, Host> hostList;
protected final Set<AgentInfoBo> agentSet;
public Application(String id, String applicationName, ServiceType serviceType, Map<String, Host> hostList, Set<AgentInfoBo> agentSet) {
protected final Map<String, SortedMap<String, ServerInstance>> serverInstanceList = new TreeMap<String, SortedMap<String, ServerInstance>>();
protected final Map<String, List<AgentInfoBo>> agentList = new TreeMap<String, List<AgentInfoBo>>();
public Application(String id, String applicationName, ServiceType serviceType, Map<String, Host> serverList, Set<AgentInfoBo> agentSet) {
this.id = id;
if (serviceType == ServiceType.CLIENT) {
this.applicationName = "CLIENT";
@@ -31,9 +37,75 @@ public class Application implements Comparable<Application> {
this.applicationName = applicationName;
}
this.hostList = (hostList == null) ? new HashMap<String, Host>() : hostList;
this.agentSet = agentSet;
this.hostList = (serverList == null) ? new HashMap<String, Host>() : serverList;
this.serviceType = serviceType;
fillAgentList(agentSet);
fillServerInstanceList(agentSet, hostList);
// System.out.println("");
// System.out.println("----------------------------------");
// System.out.println("applicationName=" + applicationName);
// System.out.println("SERVERLIST=" + serverList);
// System.out.println("AGENTSET=" + agentSet);
// System.out.println("HOSTLIST=" + hostList);
// System.out.println("serverInstanceList=" + serverInstanceList);
// System.out.println("");
}
public Map<String, SortedMap<String, ServerInstance>> getServerInstanceList() {
return serverInstanceList;
}
private void fillAgentList(final Set<AgentInfoBo> agentSet) {
if (agentSet == null) {
return;
}
for (AgentInfoBo agent : agentSet) {
String key = agent.getHostname();
List<AgentInfoBo> list = agentList.get(key);
if (list == null) {
List<AgentInfoBo> value = new ArrayList<AgentInfoBo>();
value.add(agent);
agentList.put(key, value);
} else {
agentList.get(key).add(agent);
}
}
}
private void fillServerInstanceList(final Set<AgentInfoBo> agentSet, final Map<String, Host> agentHistogram) {
if (agentSet == null) {
return;
}
for (AgentInfoBo agent : agentSet) {
String key = agent.getHostname();
SortedMap<String, ServerInstance> serverInstanceMap = serverInstanceList.get(key);
ResponseHistogram histogram = null;
if (agentHistogram != null) {
Host host = agentHistogram.get(agent.getAgentId());
if (host != null) {
histogram = host.getHistogram();
}
}
ServerInstance serverInstance = new ServerInstance(agent, histogram);
if (serverInstanceMap == null) {
SortedMap<String, ServerInstance> value = new TreeMap<String, ServerInstance>();
value.put(serverInstance.getId(), serverInstance);
serverInstanceList.put(key, value);
} else {
SortedMap<String, ServerInstance> map = serverInstanceList.get(key);
if (map.containsKey(serverInstance.getId())) {
map.get(serverInstance.getId()).mergeWith(serverInstance);
} else {
map.put(key, serverInstance);
}
}
}
}
public String getId() {
@@ -60,7 +132,12 @@ public class Application implements Comparable<Application> {
return hostList;
}
public Map<String, List<AgentInfoBo>> getAgentList() {
return agentList;
}
public void mergeWith(Application application) {
// merge host list
for (Entry<String, Host> entry : application.getHostList().entrySet()) {
Host host = hostList.get(entry.getKey());
if (host != null) {
@@ -69,15 +146,29 @@ public class Application implements Comparable<Application> {
hostList.put(entry.getKey(), entry.getValue());
}
}
// merge server instance list
for (Entry<String, SortedMap<String, ServerInstance>> entry : application.getServerInstanceList().entrySet()) {
SortedMap<String, ServerInstance> exists = serverInstanceList.get(entry.getKey());
if (exists == null) {
serverInstanceList.put(entry.getKey(), entry.getValue());
} else {
SortedMap<String, ServerInstance> srcValueMap = entry.getValue();
for (Entry<String, ServerInstance> valueEntry : srcValueMap.entrySet()) {
if (exists.containsKey(valueEntry.getKey())) {
exists.get(entry.getKey()).mergeWith(valueEntry.getValue());
} else {
exists.put(valueEntry.getKey(), valueEntry.getValue());
}
}
}
}
}
public ServiceType getServiceType() {
return serviceType;
}
public Set<AgentInfoBo> getAgentSet() {
return agentSet;
}
public String getJson() {
StringBuilder sb = new StringBuilder();
@@ -86,18 +177,30 @@ public class Application implements Comparable<Application> {
sb.append("\"sequence\" : ").append(sequence).append(",");
sb.append("\"applicationName\" : \"").append(applicationName).append("\",");
sb.append("\"serviceType\" : \"").append(serviceType).append("\",");
sb.append("\"serviceTypeCode\" : \"").append(serviceType.getCode()).append("\",");
sb.append("\"agents\" : [ ");
if (agentSet != null) {
Iterator<AgentInfoBo> iterator = agentSet.iterator();
while (iterator.hasNext()) {
sb.append(iterator.next().getJson());
if (iterator.hasNext()) {
sb.append(",");
}
}
}
sb.append(" ]");
sb.append("\"serviceTypeCode\" : \"").append(serviceType.getCode()).append("\"");
// sb.append("\"agents\" : [ ");
// if (agentList != null) {
// Iterator<Entry<String, List<AgentInfoBo>>> iterator =
// agentList.entrySet().iterator();
// while (iterator.hasNext()) {
// Entry<String, List<AgentInfoBo>> entry = iterator.next();
// sb.append("{ \"host\":\"").append(entry.getKey()).append("\", \"agentList\":[");
//
// Iterator<AgentInfoBo> agentIterator = entry.getValue().iterator();
// while(agentIterator.hasNext()) {
// sb.append(agentIterator.next().getJson());
// if (agentIterator.hasNext()) {
// sb.append(",");
// }
// }
//
// sb.append("]}");
// if (iterator.hasNext()) {
// sb.append(",");
// }
// }
// }
// sb.append(" ]");
sb.append(" }");
return sb.toString();
@@ -6,6 +6,7 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1,10 +1,8 @@
package com.nhn.pinpoint.web.applicationmap;
import com.nhn.pinpoint.common.ServiceType;
import com.nhn.pinpoint.common.bo.AgentInfoBo;
/**
* application의 host정보.
*
* @author netspider
*
@@ -14,45 +12,45 @@ public class Host {
* UI에서 호스트를 구분하기 위한 목적으로 hostname, agentid, endpoint등 구분할 수 있는 아무거나 넣으면 됨.
*/
private final String host;
private final AgentInfoBo agentInfo;
private final ResponseHistogram histogram;
public Host(String host, ServiceType serviceType, AgentInfoBo agentInfo) {
public Host(String host, ServiceType serviceType) {
this.host = host;
this.histogram = new ResponseHistogram(serviceType);
this.agentInfo = agentInfo;
}
public String getHost() {
return host;
}
public AgentInfoBo getAgentInfo() {
return agentInfo;
}
public ResponseHistogram getHistogram() {
return histogram;
}
public void mergeWith(Host host) {
this.histogram.mergeWith(host.getHistogram());
this.histogram.mergeWith(host.histogram);
}
public String getJson() {
StringBuilder sb = new StringBuilder();
sb.append("{");
sb.append("\"name\":\"").append(host).append("\",");
if (agentInfo != null) {
sb.append("\"agentInfo\":").append(agentInfo.getJson()).append(",");
} else {
sb.append("\"agentInfo\":").append("null").append(",");
}
// sb.append("\"callCount\":").append(histogram.getTotalCount()).append(",");
// sb.append("\"error\":").append(histogram.getErrorCount()).append(",");
// sb.append("\"slow\":").append(histogram.getSlowCount()).append(",");
sb.append("\"histogram\":").append(histogram);
sb.append("\"histogram\":").append(histogram); // .append(",");
// sb.append("\"agentList\":[");
// Iterator<AgentInfoBo> iterator = agentList.iterator();
// while (iterator.hasNext()) {
// AgentInfoBo agent = iterator.next();
// sb.append(agent.getJson());
// if (iterator.hasNext()) {
// sb.append(",");
// }
// }
sb.append("}");
return sb.toString();
}
@Override
public String toString() {
return "Host [host=" + host + ", histogram=" + histogram + "]";
}
}
@@ -110,6 +110,7 @@ public class ResponseHistogram {
return true;
}
// FIXME 나중에 getJson()으로 바꾸기.
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
@@ -0,0 +1,86 @@
package com.nhn.pinpoint.web.applicationmap;
import com.nhn.pinpoint.common.bo.AgentInfoBo;
/**
*
* @author netspider
*
*/
public class ServerInstance implements Comparable<ServerInstance> {
private final String id;
private final AgentInfoBo agentInfo;
private final ResponseHistogram histogram;
public ServerInstance(AgentInfoBo agentInfo, ResponseHistogram histogram) {
this.id = agentInfo.getAgentId();
this.agentInfo = agentInfo;
this.histogram = histogram;
}
public String getId() {
return this.id;
}
public AgentInfoBo getAgentInfo() {
return agentInfo;
}
public ResponseHistogram getHistogram() {
return histogram;
}
public String getJson() {
StringBuilder sb = new StringBuilder();
sb.append("{");
sb.append("\"agentId\":\"").append(id).append("\",");
sb.append("\"agentInfo\":").append(agentInfo.getJson()).append(",");
sb.append("\"histogram\":").append(histogram);
sb.append("}");
return sb.toString();
}
public ServerInstance mergeWith(ServerInstance serverInstance) {
if (this.id.equals(serverInstance.getId())) {
throw new IllegalArgumentException("Server instance id is not equal.");
}
this.histogram.mergeWith(serverInstance.getHistogram());
return this;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ServerInstance other = (ServerInstance) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
@Override
public String toString() {
return "ServerInstance [id=" + id + ", agentInfo=" + agentInfo + ", histogram=" + histogram + "]";
}
@Override
public int compareTo(ServerInstance serverInstance) {
return this.id.compareTo(serverInstance.id);
}
}
@@ -44,7 +44,7 @@ public class TransactionFlowStatistics {
if (toHostList.containsKey(hostname)) {
toHostList.get(hostname).getHistogram().addSample(slot, value);
} else {
Host host = new Host(hostname, ServiceType.findServiceType(serviceTypeCode), null);
Host host = new Host(hostname, ServiceType.findServiceType(serviceTypeCode));
host.getHistogram().addSample(slot, value);
toHostList.put(hostname, host);
}
@@ -15,8 +15,7 @@
<c:when test="${node.serviceType.desc == 'TOMCAT'}">"fig" : "RoundedRectangle"</c:when>
<c:otherwise>"fig" : "Rectangle"</c:otherwise>
</c:choose>,
"hosts" : [
"histogram" : [
<c:forEach items="${node.hostList}" var="host" varStatus="status2">
${host.value.json}
<c:if test="${!status2.last}">,</c:if>
@@ -24,13 +23,20 @@
],
"serviceTypeCode" : "${node.serviceType.code}",
"terminal" : "${node.serviceType.terminal}",
"agents" : [
<c:forEach items="${node.agentSet}" var="agent" varStatus="status3">
${agent.json}
<c:if test="${!status3.last}">,</c:if>
</c:forEach>
],
"histogram" : {}
"serverlist" : [
<c:forEach items="${node.serverInstanceList}" var="serverInstance" varStatus="status5">
{
"name":"${serverInstance.key}",
"agentList":[
<c:forEach items="${serverInstance.value}" var="instance" varStatus="status6">
${instance.value.json}
<c:if test="${!status6.last}">,</c:if>
</c:forEach>
]
}
<c:if test="${!status5.last}">,</c:if>
</c:forEach>
]
} <c:if test="${!status.last}">,</c:if>
</c:forEach>
],
@@ -0,0 +1,83 @@
<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
{
"applicationMapData" : {
"nodeDataArray": [
<c:forEach items="${nodes}" var="node" varStatus="status">
{
"id" : ${status.count},
"key" : ${status.count},
"text" : "${node.applicationName}",
"category" : "${node.serviceType.desc}",
<c:choose>
<c:when test="${node.serviceType.desc == 'CLIENT'}">"fig" : "Ellipse"</c:when>
<c:when test="${node.serviceType.desc == 'TOMCAT'}">"fig" : "RoundedRectangle"</c:when>
<c:otherwise>"fig" : "Rectangle"</c:otherwise>
</c:choose>,
"hosts" : [
<c:forEach items="${node.hostList}" var="host" varStatus="status2">
${host.value.json}
<c:if test="${!status2.last}">,</c:if>
</c:forEach>
],
"serviceTypeCode" : "${node.serviceType.code}",
"terminal" : "${node.serviceType.terminal}",
"agents" : [
<c:forEach items="${node.agentList}" var="agentMap" varStatus="status3">
{
"hostname" : "${agentMap.key}",
"agentList" : [
<c:forEach items="${agentMap.value}" var="agent" varStatus="status4">
${agent.json}
<c:if test="${!status4.last}">,</c:if>
</c:forEach>
]
}
<c:if test="${!status3.last}">,</c:if>
</c:forEach>
],
"serverlist" : [
<c:forEach items="${node.serverInstanceList}" var="serverInstance" varStatus="status5">
{
"name":"${serverInstance.key}",
"agentList":[
<c:forEach items="${serverInstance.value}" var="instance" varStatus="status6">
${instance.json}
<c:if test="${!status6.last}">,</c:if>
</c:forEach>
]
}
<c:if test="${!status5.last}">,</c:if>
</c:forEach>
]
} <c:if test="${!status.last}">,</c:if>
</c:forEach>
],
"linkDataArray": [
<c:forEach items="${links}" var="link" varStatus="status">
{
"id" : "${link.from.sequence + 1}-${link.to.sequence + 1}",
"from" : ${link.from.sequence + 1},
"to" : ${link.to.sequence + 1},
"sourceinfo" : ${link.from.json},
"targetinfo" : ${link.to.json},
"text" : ${link.histogram.totalCount},
"error" : ${link.histogram.errorCount},
"slow" : ${link.histogram.slowCount},
"histogram" : ${link.histogram},
"targetHosts" : [
<c:forEach items="${link.hostList}" var="host" varStatus="status2">
${host.value.json}
<c:if test="${!status2.last}">,</c:if>
</c:forEach>
],
<c:choose>
<c:when test="${(link.histogram.errorCount / link.histogram.totalCount * 100) > 10}">"category" : "bad"</c:when>
<c:otherwise>"category" : "default"</c:otherwise>
</c:choose>
} <c:if test="${!status.last}">,</c:if>
</c:forEach>
]
}
}