From fc2d5f18adfa953c0ddd018efae0c1e647ba97bc Mon Sep 17 00:00:00 2001 From: tanzhen <55846420@qq.com> Date: Thu, 19 Nov 2015 19:16:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=8C=BF=E5=90=8DURL?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E9=93=BE=E8=B7=AF=E8=B0=83=E8=AF=95=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E5=B1=95=E7=8E=B0=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/HelloSkyWalkingUICtl.java | 53 ++++- .../ai/cloud/dao/impl/BuriedPointSDAO.java | 91 ++++++++ .../ai/cloud/dao/inter/IBuriedPointSDAO.java | 21 ++ .../service/impl/QueryTraceLogSerImpl.java | 34 +++ .../service/inter/IQueryTraceLogSer.java | 21 ++ .../java/com/ai/cloud/util/Constants.java | 37 ++- .../ai/cloud/util/HBaseConnectionUtil.java | 39 +--- .../com/ai/cloud/util/common/SortUtil.java | 187 +++++++++++++++ .../com/ai/cloud/vo/mvo/BuriedPointEntry.java | 220 ++++++++++++------ .../com/ai/cloud/vo/mvo/TimeLineEntry.java | 43 ++++ .../src/main/webapp/ftl/index.ftl | 4 +- .../main/webapp/ftl/lib/ai.cloud/common.ftl | 107 +++++++++ .../src/main/webapp/ftl/login.ftl | 6 +- .../src/main/webapp/ftl/marco/common.ftl | 62 ----- .../src/main/webapp/ftl/traceLog.ftl | 205 +--------------- .../src/main/webapp/js/webui-0.1.js | 18 +- 16 files changed, 755 insertions(+), 393 deletions(-) create mode 100644 skywalking-webui/src/main/java/com/ai/cloud/dao/impl/BuriedPointSDAO.java create mode 100644 skywalking-webui/src/main/java/com/ai/cloud/dao/inter/IBuriedPointSDAO.java create mode 100644 skywalking-webui/src/main/java/com/ai/cloud/service/impl/QueryTraceLogSerImpl.java create mode 100644 skywalking-webui/src/main/java/com/ai/cloud/service/inter/IQueryTraceLogSer.java create mode 100644 skywalking-webui/src/main/java/com/ai/cloud/util/common/SortUtil.java create mode 100644 skywalking-webui/src/main/java/com/ai/cloud/vo/mvo/TimeLineEntry.java create mode 100644 skywalking-webui/src/main/webapp/ftl/lib/ai.cloud/common.ftl delete mode 100644 skywalking-webui/src/main/webapp/ftl/marco/common.ftl diff --git a/skywalking-webui/src/main/java/com/ai/cloud/controller/HelloSkyWalkingUICtl.java b/skywalking-webui/src/main/java/com/ai/cloud/controller/HelloSkyWalkingUICtl.java index e03117c9b..b0e7705bb 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/controller/HelloSkyWalkingUICtl.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/controller/HelloSkyWalkingUICtl.java @@ -3,14 +3,25 @@ */ package com.ai.cloud.controller; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; +import com.ai.cloud.service.inter.IQueryTraceLogSer; import com.ai.cloud.util.Constants; +import com.ai.cloud.vo.mvo.BuriedPointEntry; + +import freemarker.template.SimpleSequence; /** * 首面请求处理 @@ -21,7 +32,10 @@ import com.ai.cloud.util.Constants; */ @Controller public class HelloSkyWalkingUICtl { - + + @Autowired + IQueryTraceLogSer traceLogSer; + private static Logger logger = LogManager.getLogger(HelloSkyWalkingUICtl.class); /*** @@ -75,9 +89,40 @@ public class HelloSkyWalkingUICtl { * @return * @throws Exception */ - @RequestMapping(value = "/showTraceLog") - public String showTraceLog(ModelMap root) throws Exception { - this.showIndexPage(root, null); + @RequestMapping(value = "/showTraceLog/{traceId}") + public String showTraceLog(ModelMap root, @PathVariable("traceId") String traceId) throws Exception { +// traceId = "bcb759bc12db474aa54bc4bea605cb81123"; + Map traceLogMap = traceLogSer.queryLogByTraceId(traceId); + + if (traceLogMap != null && traceLogMap.size() > 0) { + List valueList = new ArrayList(); + valueList.addAll(traceLogMap.values()); + final List endTime = new ArrayList(); + endTime.add(0, 0l); + Collections.sort(valueList, new Comparator() { + @Override + public int compare(BuriedPointEntry arg0, BuriedPointEntry arg1) { + /** 顺道取出日志最大的结束时间 */ + if (endTime.get(0) < arg0.getEndDate()) { + endTime.set(0, arg0.getEndDate()); + } + if (endTime.get(0) < arg1.getEndDate()) { + endTime.set(0, arg1.getEndDate()); + } + return arg0.getColId().compareTo(arg1.getColId()); + } + }); + // int m = 1; + // for (BuriedPointEntry tmpEntry : valueList) { + // logger.info("sort result level:{} : {}", m++, tmpEntry); + // } + long beginTime = valueList.get(0).getStartDate(); + root.put("valueList", valueList); + root.put("spanTypeMap", Constants.SPAN_TYPE_MAP); + root.put("statusCodeMap", Constants.STATUS_CODE_MAP); + root.put("beginTime", beginTime); + root.put("endTime", endTime.get(0)); + } return "traceLog"; } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/dao/impl/BuriedPointSDAO.java b/skywalking-webui/src/main/java/com/ai/cloud/dao/impl/BuriedPointSDAO.java new file mode 100644 index 000000000..7438e8f4c --- /dev/null +++ b/skywalking-webui/src/main/java/com/ai/cloud/dao/impl/BuriedPointSDAO.java @@ -0,0 +1,91 @@ +/** + * + */ +package com.ai.cloud.dao.impl; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Get; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.Table; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.stereotype.Repository; + +import com.ai.cloud.dao.inter.IBuriedPointSDAO; +import com.ai.cloud.util.Constants; +import com.ai.cloud.util.HBaseConnectionUtil; +import com.ai.cloud.util.common.SortUtil; +import com.ai.cloud.vo.mvo.BuriedPointEntry; +import com.sun.tools.internal.ws.wsdl.framework.Entity; + +/** + * + * @author tz + * @date 2015年11月18日 下午3:21:26 + * @version V0.1 + */ +@Repository +public class BuriedPointSDAO implements IBuriedPointSDAO { + + private static Logger logger = LogManager.getLogger(BuriedPointSDAO.class); + + /*** + * 查询指定traceId的调用链日志 + * + * @param tableName + * @param traceId + * @return + * @throws IOException + */ + public Map queryLogByTraceId(String tableName, String traceId) throws IOException { + Table table = HBaseConnectionUtil.getConnection().getTable(TableName.valueOf(tableName)); + Get g = new Get(Bytes.toBytes(traceId)); + Result r = table.get(g); + Map traceLogMap = new HashMap(); + Map rpcMap = new HashMap(); + for (Cell cell : r.rawCells()) { + if (cell.getValueArray().length > 0) { + String colId = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), + cell.getQualifierLength()); + BuriedPointEntry tmpEntry = BuriedPointEntry.convert( + Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()), colId); + System.out.println("=========" + tmpEntry); + // 特殊处理RPC的服务端信息 + if (colId.endsWith(Constants.RPC_END_FLAG)) { + rpcMap.put(colId.substring(0, colId.lastIndexOf(Constants.RPC_END_FLAG)), tmpEntry); + } else { + SortUtil.addCurNodeTreeMapKey(traceLogMap, colId, tmpEntry); + } + } + } + computeRPCInfo(rpcMap, traceLogMap); + //合并处理RPC日志信息 + return traceLogMap; + } + + /*** + * 合并处理RPC日志信息 + * @param rpcMap + * @param traceLogMap + */ + private void computeRPCInfo(Map rpcMap, Map traceLogMap) { + // 合并处理 + if (rpcMap.size() > 0) { + for (Entry rpcVO : rpcMap.entrySet()) { + String colId = rpcVO.getKey(); + if(traceLogMap.containsKey(colId)){ + BuriedPointEntry logVO = traceLogMap.get(colId); + logVO.addTimeLine(rpcVO.getValue().getStartDate(), rpcVO.getValue().getCost()); + } + } + } + } + +} diff --git a/skywalking-webui/src/main/java/com/ai/cloud/dao/inter/IBuriedPointSDAO.java b/skywalking-webui/src/main/java/com/ai/cloud/dao/inter/IBuriedPointSDAO.java new file mode 100644 index 000000000..43e7c2a73 --- /dev/null +++ b/skywalking-webui/src/main/java/com/ai/cloud/dao/inter/IBuriedPointSDAO.java @@ -0,0 +1,21 @@ +/** + * + */ +package com.ai.cloud.dao.inter; + +import java.io.IOException; +import java.util.Map; + +import com.ai.cloud.vo.mvo.BuriedPointEntry; + +/** + * + * @author tz + * @date 2015年11月18日 下午3:21:49 + * @version V0.1 + */ +public interface IBuriedPointSDAO { + + public Map queryLogByTraceId(String tableName, String traceId) throws IOException; + +} diff --git a/skywalking-webui/src/main/java/com/ai/cloud/service/impl/QueryTraceLogSerImpl.java b/skywalking-webui/src/main/java/com/ai/cloud/service/impl/QueryTraceLogSerImpl.java new file mode 100644 index 000000000..f332882a4 --- /dev/null +++ b/skywalking-webui/src/main/java/com/ai/cloud/service/impl/QueryTraceLogSerImpl.java @@ -0,0 +1,34 @@ +/** + * + */ +package com.ai.cloud.service.impl; + +import java.io.IOException; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.ai.cloud.dao.inter.IBuriedPointSDAO; +import com.ai.cloud.service.inter.IQueryTraceLogSer; +import com.ai.cloud.util.Constants; +import com.ai.cloud.vo.mvo.BuriedPointEntry; + +/** + * + * @author tz + * @date 2015年11月18日 下午5:57:11 + * @version V0.1 + */ +@Service +public class QueryTraceLogSerImpl implements IQueryTraceLogSer { + + @Autowired + IBuriedPointSDAO buriedPointSDAO; + + @Override + public Map queryLogByTraceId(String traceId) throws IOException { + return buriedPointSDAO.queryLogByTraceId(Constants.TABLE_NAME_CHAIN, traceId); + } + +} diff --git a/skywalking-webui/src/main/java/com/ai/cloud/service/inter/IQueryTraceLogSer.java b/skywalking-webui/src/main/java/com/ai/cloud/service/inter/IQueryTraceLogSer.java new file mode 100644 index 000000000..45cea8b27 --- /dev/null +++ b/skywalking-webui/src/main/java/com/ai/cloud/service/inter/IQueryTraceLogSer.java @@ -0,0 +1,21 @@ +/** + * + */ +package com.ai.cloud.service.inter; + +import java.io.IOException; +import java.util.Map; + +import com.ai.cloud.vo.mvo.BuriedPointEntry; + +/** + * + * @author tz + * @date 2015年11月18日 下午5:56:04 + * @version V0.1 + */ +public interface IQueryTraceLogSer { + + public Map queryLogByTraceId(String traceId) throws IOException; + +} diff --git a/skywalking-webui/src/main/java/com/ai/cloud/util/Constants.java b/skywalking-webui/src/main/java/com/ai/cloud/util/Constants.java index ecfcd1f04..37a1f0bcc 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/util/Constants.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/util/Constants.java @@ -3,6 +3,9 @@ */ package com.ai.cloud.util; +import java.util.HashMap; +import java.util.Map; + /** * 常量类 * @author tz @@ -15,10 +18,40 @@ public class Constants { public static final String VERSION_VAL = "0.1"; + /** hbase集群*/ public static final String QUORUM = "10.1.235.197,10.1.235.198,10.1.235.199"; - + /** zk端口*/ public static final String CLIENT_PORT = "29181"; - + /** hbase表名*/ public static final String TABLE_NAME_CHAIN = "sw-call-chain"; + /**层级分割符*/ + public static final char VAL_SPLIT_CHAR = '.'; + /** RPC远端调用节点结束标识*/ + public static final String RPC_END_FLAG = "-S"; + + public static final String SPAN_TYPE_M = "M"; + public static final String SPAN_TYPE_J = "J"; + public static final String SPAN_TYPE_W = "W"; + public static final String SPAN_TYPE_D = "D"; + /** SPAN_TYPE码表*/ + public static Map SPAN_TYPE_MAP = new HashMap(){{ + put("M", "JAVA"); + put("J", "JDBC"); + put("W", "WEB SERVLET"); + put("D", "DUBBO/DUBBOX"); + }}; + + public static final char STATUS_CODE_0 = '0'; + public static final char STATUS_CODE_1 = '1'; + public static final char STATUS_CODE_9 = '9'; + /** STATUS_CODE码表*/ + public static Map STATUS_CODE_MAP = new HashMap(){{ + put("0", "OK"); + put("1", "FAIL"); + put("9", "MISSING"); + }}; + + + } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/util/HBaseConnectionUtil.java b/skywalking-webui/src/main/java/com/ai/cloud/util/HBaseConnectionUtil.java index 5b0c1745b..dbab3b33e 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/util/HBaseConnectionUtil.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/util/HBaseConnectionUtil.java @@ -3,25 +3,13 @@ */ package com.ai.cloud.util; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.HBaseConfiguration; -import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.ConnectionFactory; -import org.apache.hadoop.hbase.client.Get; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.client.Table; -import org.apache.hadoop.hbase.util.Bytes; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.ai.cloud.vo.mvo.BuriedPointEntry; - /** * * @author tz @@ -35,7 +23,7 @@ public class HBaseConnectionUtil { private static Configuration configuration = null; private static Connection connection = null; - static { + public synchronized static Connection getConnection(){ try { if (configuration == null) { configuration = HBaseConfiguration.create(); @@ -46,29 +34,6 @@ public class HBaseConnectionUtil { } catch (Exception e) { logger.error("Create table[{}] failed", "connection hbase fail", e); } - } - - public static List selectByTraceId(String traceId) throws IOException { - List entries = new ArrayList(); - Table table = connection.getTable(TableName.valueOf(Constants.TABLE_NAME_CHAIN)); - Get g = new Get(Bytes.toBytes(traceId)); - Result r = table.get(g); - for (Cell cell : r.listCells()) { - if (cell.getValueArray().length > 0) - entries.add(BuriedPointEntry.convert(new String(cell.getValue(), "UTF-8"))); - } - return entries; - } - - /** - * @throws IOException - * - */ - public static void main(String[] args) throws IOException { - List bpe = HBaseConnectionUtil.selectByTraceId("08388950294948ef91e30e70c4ec183e123"); - - for (BuriedPointEntry tmpVO : bpe) { - logger.info(tmpVO); - } + return connection; } } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/util/common/SortUtil.java b/skywalking-webui/src/main/java/com/ai/cloud/util/common/SortUtil.java new file mode 100644 index 000000000..c7037936d --- /dev/null +++ b/skywalking-webui/src/main/java/com/ai/cloud/util/common/SortUtil.java @@ -0,0 +1,187 @@ +/** + * + */ +package com.ai.cloud.util.common; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.Test; + +import com.ai.cloud.dao.impl.BuriedPointSDAO; +import com.ai.cloud.util.Constants; +import com.ai.cloud.vo.mvo.BuriedPointEntry; + +/** + * + * @author tz + * @date 2015年11月18日 下午2:03:10 + * @version V0.1 + */ +public class SortUtil { + + private static Logger logger = LogManager.getLogger(SortUtil.class); + + /*** + * 增加调度链路节点信息 + * + * @param reMap + * @param colId + * @param tmpEntry + */ + public static void addCurNodeTreeMapKey(Map reMap, String colId, + BuriedPointEntry tmpEntry) { + reMap.put(colId, tmpEntry); + // 根据当前Id查找上级,如果不存在,插入空,再看上级,如果不存在还插入空,直到根"0" + while (colId.indexOf(Constants.VAL_SPLIT_CHAR) > -1) { + colId = colId.substring(0, colId.lastIndexOf(Constants.VAL_SPLIT_CHAR)); + if (!addParentNodeTreeMapKey(reMap, colId)) { + break; + } + } + } + + /*** + * 补充父级调度链路各节点信息 + * + * @param reMap + * @param colId + * @return + */ + private static boolean addParentNodeTreeMapKey(Map reMap, String colId) { + if (reMap.containsKey(colId)) { + logger.info("key hash exist: {}", colId); + return false; + } else { + // 增加虚拟节点 + reMap.put(colId, BuriedPointEntry.addLostBuriedPointEntry(colId)); + // 根据当前Id查找上级,如果不存在,插入空,再看上级,如果不存在还插入空,直到根"0" + while (colId.indexOf(Constants.VAL_SPLIT_CHAR) > -1) { + colId = colId.substring(0, colId.lastIndexOf(Constants.VAL_SPLIT_CHAR)); + if (!addParentNodeTreeMapKey(reMap, colId)) { + break; + } + } + return false; + } + } + + /** + * 测试读取hbase 测试自动补充父级节点 测试排序 + * + * @throws IOException + * + */ + @Test + public void testSelectByTraceId() throws IOException { + BuriedPointSDAO sdao = new BuriedPointSDAO(); + Map bpe = sdao.queryLogByTraceId(Constants.TABLE_NAME_CHAIN, + "6305eb1d1e1b46529a7eb57912a5766e123"); + + List keyList = new ArrayList(); + + keyList.addAll(bpe.values()); + + Collections.sort(keyList, new Comparator() { + @Override + public int compare(BuriedPointEntry arg0, BuriedPointEntry arg1) { + return arg0.getColId().compareTo(arg1.getColId()); + } + }); + + int m = 1; + for (BuriedPointEntry tmpEntry : keyList) { + logger.info("sort result level:{} : {}", m++, tmpEntry); + } + + } + + /*** + * 深度补全测试 + * + * @throws IOException + */ + @Test + public void testGenTreeMapKey() throws IOException { + + StringBuffer sb = new StringBuffer("0"); + + /*** + * 深度测试 level 5 [ 11ms ] level 10[ 11ms ] level 15[ 11ms ] level 20[ + * 12ms ] level 50[ 12ms ] level 100[ 12ms ] level 500[ 12ms ] level + * 1000[ 16ms ] level 2000[ 28ms ] level 5000[ 144ms ] level10000[ 445ms + * ] + */ + for (int i = 1; i < 10000; i++) { + sb.append(".0"); + } + + String colId = sb.toString(); + BuriedPointEntry tmpEntry = null; + Map reMap = new HashMap(); + long startTime = System.currentTimeMillis(); + logger.info("start time : {}", startTime); + + addCurNodeTreeMapKey(reMap, colId, tmpEntry); + + long endTime = System.currentTimeMillis(); + logger.info("end time : {}", endTime); + logger.info("run time : {} ms", (endTime - startTime)); + + // List keyList = new ArrayList(); + // keyList.addAll(reMap.keySet()); + // Collections.sort(keyList); + // int m = 1; + // for (String str : keyList) { + // logger.info("sort result level:{} : {}", m++, str); + // } + + } + + /*** + * collection sort 性能测试 + * + * @param args + */ + @Test + public void testSortList() { + List StrList = new ArrayList(); + Random random = new Random(System.currentTimeMillis()); + StrList.add("0"); + + /*** + * Collections.sort(StrList)性能 1000条/19 ms 10000条/42 ms 100000条/129 ms + * 1000000条/1070 ms + */ + for (int m = 0; m < 1000; m++) { + String radNum = "" + Math.abs(random.nextLong()); + StringBuffer tmpBf = new StringBuffer("0"); + for (int n = 0; n < radNum.length(); n++) { + tmpBf.append(".").append(radNum.charAt(n)); + } + StrList.add(tmpBf.toString()); + } + + long startTime = System.currentTimeMillis(); + logger.info("start time : {}", startTime); + + Collections.sort(StrList); + + long endTime = System.currentTimeMillis(); + logger.info("end time : {}", endTime); + logger.info("run time : {} ms", (endTime - startTime)); + + // int i = 1; + // for (String tmpStr : StrList) { + // logger.info("sort {} : {}", i++, tmpStr); + // } + } +} diff --git a/skywalking-webui/src/main/java/com/ai/cloud/vo/mvo/BuriedPointEntry.java b/skywalking-webui/src/main/java/com/ai/cloud/vo/mvo/BuriedPointEntry.java index 5fd4045ec..1d5ebbad5 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/vo/mvo/BuriedPointEntry.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/vo/mvo/BuriedPointEntry.java @@ -1,104 +1,172 @@ package com.ai.cloud.vo.mvo; +import java.util.ArrayList; import java.util.Date; +import java.util.List; +import com.ai.cloud.util.Constants; + +/*** + * hbase存储的链路信息模型 + * + * @author tz + * @date 2015年11月18日 下午5:45:14 + * @version V0.1 + */ public class BuriedPointEntry { - private String traceId; - private String parentLevel; - private int levelId; - private String viewPointId; - private Date startDate; - private long cost; - private String address; - private byte statusCode = 0; - private String exceptionStack; - private char spanType; - private boolean isReceiver = false; - private String businessKey; - private String processNo; + private String traceId; + private String parentLevel; + private int levelId; + private String viewPointId; + private long startDate; + private long cost; + private String address; + private char statusCode = Constants.STATUS_CODE_9; + private String exceptionStack; + private char spanType; + private boolean isReceiver = false; + private String businessKey; + private String processNo; + private String colId; + private long endDate; + private List timeLineList = new ArrayList(); - private BuriedPointEntry() { + private BuriedPointEntry() { - } + } - public String getTraceId() { - return traceId; - } + public String getTraceId() { + return traceId; + } - public String getParentLevel() { - return parentLevel; - } + public String getParentLevel() { + return parentLevel; + } - public int getLevelId() { - return levelId; - } + public int getLevelId() { + return levelId; + } - public String getViewPointId() { - return viewPointId; - } + public String getViewPointId() { + return viewPointId; + } - public Date getStartDate() { - return startDate; - } + public long getStartDate() { + return startDate; + } - public long getCost() { - return cost; - } + public long getCost() { + return cost; + } - public String getAddress() { - return address; - } + public String getAddress() { + return address; + } - public byte getStatusCode() { - return statusCode; - } + public char getStatusCode() { + return statusCode; + } - public String getExceptionStack() { - return exceptionStack; - } + public String getExceptionStack() { + return exceptionStack; + } - public char getSpanType() { - return spanType; - } + public char getSpanType() { + return spanType; + } - public boolean isReceiver() { - return isReceiver; - } + public boolean isReceiver() { + return isReceiver; + } - public String getBusinessKey() { - return businessKey; - } + public String getBusinessKey() { + return businessKey; + } - public String getProcessNo() { - return processNo; - } + public String getProcessNo() { + return processNo; + } - public static BuriedPointEntry convert(String str) { - BuriedPointEntry result = new BuriedPointEntry(); - String[] fieldValues = str.split("-"); - result.traceId = fieldValues[0].trim(); - result.parentLevel = fieldValues[1].trim(); - result.levelId = Integer.valueOf(fieldValues[2]); - result.viewPointId = fieldValues[3].trim(); - result.startDate = new Date(Long.valueOf(fieldValues[4])); - result.cost = Long.parseLong(fieldValues[5]); - result.address = fieldValues[6].trim(); - result.exceptionStack = fieldValues[7].trim(); - result.spanType = fieldValues[8].charAt(0); - result.isReceiver = Boolean.getBoolean(fieldValues[9]); - result.businessKey = fieldValues[10].replace('-', '^').trim(); - result.processNo = fieldValues[11].trim(); - return result; - } + public String getColId() { + return colId; + } + + public void setColId(String colId) { + this.colId = colId; + } + + public long getEndDate() { + return endDate; + } + + public List getTimeLineList() { + return timeLineList; + } + + private static BuriedPointEntry convert(String str) { + BuriedPointEntry result = new BuriedPointEntry(); + String[] fieldValues = str.split("\\^\\~"); + result.traceId = fieldValues[0].trim(); + result.parentLevel = fieldValues[1].trim(); + result.levelId = Integer.valueOf(fieldValues[2]); + result.viewPointId = fieldValues[3].trim(); + result.startDate = Long.valueOf(fieldValues[4]); + result.cost = Long.parseLong(fieldValues[5]); + result.address = fieldValues[6].trim(); + result.statusCode = fieldValues[7].charAt(0); + result.exceptionStack = fieldValues[8].trim(); + result.spanType = fieldValues[9].charAt(0); + result.isReceiver = Boolean.getBoolean(fieldValues[10]); + result.businessKey = fieldValues[11].trim(); + result.processNo = fieldValues[12].trim(); + return result; + } + + /*** + * 增加时间轴信息 + * @param startDate + * @param cost + */ + public void addTimeLine(long startDate, long cost) { + timeLineList.add(new TimeLineEntry(startDate, cost)); + } + + public static BuriedPointEntry convert(String str, String colId) { + BuriedPointEntry result = convert(str); + result.addTimeLine(result.startDate, result.cost); + result.colId = colId; + result.endDate = result.startDate + result.cost; + return result; + } + + /*** + * 补充丢失的链路信息 + * + * @param colId + * @return + */ + public static BuriedPointEntry addLostBuriedPointEntry(String colId) { + BuriedPointEntry result = new BuriedPointEntry(); + result.colId = colId; + if (colId.indexOf(Constants.VAL_SPLIT_CHAR) > -1) { + result.parentLevel = colId.substring(0, colId.lastIndexOf(Constants.VAL_SPLIT_CHAR)); + } else { + result.parentLevel = ""; + } + result.timeLineList.add(new TimeLineEntry()); + + // 其它默认值 + return result; + } @Override public String toString() { - return "BuriedPointEntry [traceId=" + traceId + ", parentLevel=" + parentLevel + ", levelId=" + levelId - + ", viewPointId=" + viewPointId + ", startDate=" + startDate + ", cost=" + cost + ", address=" - + address + ", statusCode=" + statusCode + ", exceptionStack=" + exceptionStack + ", spanType=" - + spanType + ", isReceiver=" + isReceiver + ", businessKey=" + businessKey + ", processNo=" + processNo - + "]"; + return "BuriedPointEntry [colId=" + colId + ", traceId=" + traceId + ", parentLevel=" + parentLevel + + ", levelId=" + levelId + ", viewPointId=" + viewPointId + ", startDate=" + startDate + ", cost=" + + cost + ", address=" + address + ", statusCode=" + statusCode + ", exceptionStack=" + exceptionStack + + ", spanType=" + spanType + ", isReceiver=" + isReceiver + ", businessKey=" + businessKey + + ", processNo=" + processNo + "]"; } } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/vo/mvo/TimeLineEntry.java b/skywalking-webui/src/main/java/com/ai/cloud/vo/mvo/TimeLineEntry.java new file mode 100644 index 000000000..49b80630f --- /dev/null +++ b/skywalking-webui/src/main/java/com/ai/cloud/vo/mvo/TimeLineEntry.java @@ -0,0 +1,43 @@ +/** + * + */ +package com.ai.cloud.vo.mvo; + +/** + * + * 支持当前节点为RPC调用时,可以在一个tr中展现多个调用时间轴 + * + * @author tz + * @date 2015年11月19日 下午3:45:31 + * @version V0.1 + */ +public class TimeLineEntry { + + private long startTime = 0l; + + private long cost = 0l; + + public TimeLineEntry(){ + } + + public TimeLineEntry(long startTime, long cost){ + this.startTime = startTime; + this.cost = cost; + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public long getCost() { + return cost; + } + + public void setCost(long cost) { + this.cost = cost; + } +} diff --git a/skywalking-webui/src/main/webapp/ftl/index.ftl b/skywalking-webui/src/main/webapp/ftl/index.ftl index a6beaa270..a0d1e1d61 100644 --- a/skywalking-webui/src/main/webapp/ftl/index.ftl +++ b/skywalking-webui/src/main/webapp/ftl/index.ftl @@ -1,4 +1,4 @@ -<#import "./marco/common.ftl" as common> +<#import "./lib/ai.cloud/common.ftl" as common> @@ -35,7 +35,7 @@ -
+
diff --git a/skywalking-webui/src/main/webapp/ftl/lib/ai.cloud/common.ftl b/skywalking-webui/src/main/webapp/ftl/lib/ai.cloud/common.ftl new file mode 100644 index 000000000..325a17f48 --- /dev/null +++ b/skywalking-webui/src/main/webapp/ftl/lib/ai.cloud/common.ftl @@ -0,0 +1,107 @@ +<#-- importJavaScript --> +<#macro importJavaScript> + + + + + + +<#-- importMenuInfo --> +<#macro importMenuInfo menuInfo> + + + +<#-- importSearchInfo --> +<#macro importSearchInfo isLogin> + + + +<#-- importUserInfo --> +<#macro importUserInfo userInfo> + + + +<#-- dealTraceLog --> +<#macro dealTraceLog> +<#if valueList??> +
+
+ + + + + + + + + + + + + +<#list valueList as logInfo> +<#if logInfo.colId == "0"> + +<#else> + + + + + + + + + + +
+ Expand all +   + Collapse all +
调用序列类型状态业务信息主机信息时间轴
${logInfo.viewPointId!}${spanTypeMap[logInfo.spanType]!'-'}${statusCodeMap[logInfo.statusCode]!}${logInfo.businessKey!}${logInfo.address!} +<#assign totalTime=(endTime-beginTime)> +<#list logInfo.timeLineList as log> +
+
+
${log.cost}ms
+ +
+
+
+ + \ No newline at end of file diff --git a/skywalking-webui/src/main/webapp/ftl/login.ftl b/skywalking-webui/src/main/webapp/ftl/login.ftl index f974e0582..e9627d457 100644 --- a/skywalking-webui/src/main/webapp/ftl/login.ftl +++ b/skywalking-webui/src/main/webapp/ftl/login.ftl @@ -1,4 +1,4 @@ -<#import "./marco/common.ftl" as common> +<#import "./lib/ai.cloud/common.ftl" as common> @@ -8,11 +8,11 @@ - + - +
diff --git a/skywalking-webui/src/main/webapp/ftl/marco/common.ftl b/skywalking-webui/src/main/webapp/ftl/marco/common.ftl deleted file mode 100644 index 013b65d65..000000000 --- a/skywalking-webui/src/main/webapp/ftl/marco/common.ftl +++ /dev/null @@ -1,62 +0,0 @@ - -<#-- script --> -<#macro importJavaScript> - - - - - - - -<#-- menuInfo --> -<#macro importMenuInfo menuInfo> - - - -<#-- SearchInfo --> -<#macro importSearchInfo isLogin> - - - -<#-- userInfo --> -<#macro importUserInfo userInfo> - - \ No newline at end of file diff --git a/skywalking-webui/src/main/webapp/ftl/traceLog.ftl b/skywalking-webui/src/main/webapp/ftl/traceLog.ftl index 5d1974f54..fcc586f65 100644 --- a/skywalking-webui/src/main/webapp/ftl/traceLog.ftl +++ b/skywalking-webui/src/main/webapp/ftl/traceLog.ftl @@ -1,5 +1,6 @@ -<#import "./marco/common.ftl" as common> +<#import "./lib/ai.cloud/common.ftl" as common> + @@ -8,211 +9,17 @@ - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Expand all -   - Collapse all -
应用名类型状态大小服务/方法时间轴
- tf_buy - - TRACE - - OK - - - - - http://buy.taobao.com/auction/buy_now.html - -
-
- 239ms -
-
-
- tradeplatform - - HSF - - OK - - 670B - - tc.TcTradeService@getOutOrderSwqIdByBuyerId~1 - -
-
- -
-
- 0ms -
- -
-
- tradeplatform - - HSF - - OK - - 8.0KB - - trade.ICreatingOrderService@createOrdersForTaobao~R - -
-
- -
-
- -
-
- 46ms -
-
- -
-
-
- Itemcenter - - HSF - - OK - - 5.0KB - - item.IItermQueryService@queryItermAndSkWithPVToText~L - -
-
- -
- -
- 8ms -
- -
-
- Itemcenter - - HSF - - OK - - 3.0KB - - item.SpuService@getSpu~l - -
-
- -
- -
- 3ms -
- -
-
- misccenter - - HSF - - OK - - 3.0KB - - misccenter.EcardOrderService@insertEcardOrder~E - -
-
- -
- -
- 6ms -
- -
-
-
-
+ + + <@common.dealTraceLog /> <@common.importJavaScript />