diff --git a/skywalking-webui/pom.xml b/skywalking-webui/pom.xml index 853e10d55..3fa6afd3b 100644 --- a/skywalking-webui/pom.xml +++ b/skywalking-webui/pom.xml @@ -82,12 +82,6 @@ log4j-1.2-api 2.2 - - org.apache.logging.log4j - log4j-slf4j-impl - 2.2 - - javax.servlet javax.servlet-api diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/controller/MainPageController.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/controller/MainPageController.java index 68ff11b1c..cd2092fe7 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/controller/MainPageController.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/controller/MainPageController.java @@ -13,8 +13,9 @@ import javax.servlet.http.HttpServletRequest; public class MainPageController extends BaseController{ @RequestMapping("/mainPage") - public String mainPage(String loadType, HttpServletRequest request){ + public String mainPage(String loadType, String key,HttpServletRequest request){ request.setAttribute("loadType", loadType); + request.setAttribute("key", key); return "main"; } } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/controller/SearchController.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/controller/SearchController.java index d8961e9e4..71e32dda5 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/controller/SearchController.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/controller/SearchController.java @@ -1,16 +1,18 @@ package com.ai.cloud.skywalking.web.controller; +import com.ai.cloud.skywalking.web.common.BaseController; +import com.ai.cloud.skywalking.web.dto.AnlyResult; +import com.ai.cloud.skywalking.web.dto.CallChainNode; import com.ai.cloud.skywalking.web.dto.LoginUserInfo; import com.ai.cloud.skywalking.web.dto.TraceTreeInfo; -import com.ai.cloud.skywalking.web.common.BaseController; import com.ai.cloud.skywalking.web.entity.CallChainTree; import com.ai.cloud.skywalking.web.service.inter.ICallChainTreeService; import com.ai.cloud.skywalking.web.service.inter.ITraceTreeService; +import com.ai.cloud.skywalking.web.util.Constants; import com.ai.cloud.skywalking.web.util.StringUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import com.google.gson.Gson; - +import com.google.gson.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -22,7 +24,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; - import java.util.ArrayList; import java.util.List; @@ -83,13 +84,13 @@ public class SearchController extends BaseController { System.out.println("search Trace....."); request.setAttribute("key", traceId); request.setAttribute("searchType", "TRACE_ID"); - request.setAttribute("loadType","showTraceInfo"); + request.setAttribute("loadType", "showTraceInfo"); return "main"; } @RequestMapping(value = "/search/chainTree", produces = "application/json; charset=UTF-8") @ResponseBody - public String searchCallChainTree(String key, HttpServletRequest request) { + public String searchCallChainTree(String key, HttpServletRequest request, int pageSize) { JSONObject jsonObject = new JSONObject(); try { if (StringUtil.isBlank(key)) { @@ -101,9 +102,19 @@ public class SearchController extends BaseController { LoginUserInfo loginUserInfo = fetchLoginUserInfoFromSession(request); List callChainTreeList = - callChainTreeService.queryCurrentMonthCallChainTree(loginUserInfo.getUid(), key); + callChainTreeService.queryCallChainTreeByKey(loginUserInfo.getUid(), key, pageSize); + //List callChainTreeList = generateCallChainTree(); + JsonObject result = new JsonObject(); + if (callChainTreeList.size() > Constants.MAX_ANALYSIS_RESULT_PAGE_SIZE) { + result.addProperty("hasNextPage", true); + callChainTreeList.remove(callChainTreeList.size() - 1); + } else { + result.addProperty("hasNexPage", false); + } + JsonElement jsonElements = new JsonParser().parse(new Gson().toJson(callChainTreeList)); + result.add("children", jsonElements); jsonObject.put("code", "200"); - jsonObject.put("result", new Gson().toJson(callChainTreeList)); + jsonObject.put("result", result.toString()); } catch (Exception e) { logger.error("Failed to search chain tree:{}", key, e); jsonObject.put("code", "500"); @@ -112,4 +123,29 @@ public class SearchController extends BaseController { return jsonObject.toJSONString(); } + private List generateCallChainTree() { + List callChainTrees = new ArrayList(); + CallChainTree chainTree = new CallChainTree("test"); + chainTree.setEntranceViewpoint("test"); + chainTree.setTreeId("test tree id"); + List callChainNodes = new ArrayList<>(); + CallChainNode callChainNode = new CallChainNode("0.0", "test view point id", true); + CallChainNode callChainNode1 = new CallChainNode("0.0.0", "test view point id", true); + CallChainNode callChainNode2 = new CallChainNode("0.1", "test view point id", true); + CallChainNode callChainNode3 = new CallChainNode("0.2", "test view point id", true); + callChainNodes.add(callChainNode); + callChainNodes.add(callChainNode1); + callChainNodes.add(callChainNode2); + callChainNodes.add(callChainNode3); + chainTree.setNodes(callChainNodes); + callChainTrees.add(chainTree); + AnlyResult anlyResult = new AnlyResult(); + anlyResult.setTotalCostTime(1000); + anlyResult.setTotalCall(20); + anlyResult.setHumanInterruptionNumber(10); + anlyResult.setCorrectNumber(10); + chainTree.setEntranceAnlyResult(anlyResult); + return callChainTrees; + } + } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/impl/CallChainTreeDao.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/impl/CallChainTreeDao.java index 2a608138b..7d3092db5 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/impl/CallChainTreeDao.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/impl/CallChainTreeDao.java @@ -1,10 +1,13 @@ package com.ai.cloud.skywalking.web.dao.impl; -import com.ai.cloud.skywalking.web.dto.AnlyResult; import com.ai.cloud.skywalking.web.dao.inter.ICallChainTreeDao; +import com.ai.cloud.skywalking.web.dto.AnlyResult; import com.ai.cloud.skywalking.web.entity.CallChainTree; import com.ai.cloud.skywalking.web.util.HBaseUtils; import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.Get; @@ -17,6 +20,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.io.IOException; +import java.util.Calendar; +import java.util.Map; @Repository public class CallChainTreeDao implements ICallChainTreeDao { @@ -28,21 +33,36 @@ public class CallChainTreeDao implements ICallChainTreeDao { @Override public AnlyResult queryEntranceAnlyResult(String entranceColumnName, String treeId) throws IOException { - Table table = hBaseUtils.getConnection().getTable(TableName.valueOf("sw-chain-1day-summary")); + String columnName = null; + if (entranceColumnName.lastIndexOf(":") != -1) { + columnName = entranceColumnName.substring(0, entranceColumnName.length() - 1); + } + Table table = hBaseUtils.getConnection().getTable(TableName.valueOf("sw-chain-1month-summary")); Get get = new Get(treeId.getBytes()); Result result = table.get(get); if (result.rawCells().length == 0) { - return null; + Calendar calendar = Calendar.getInstance(); + return new AnlyResult(calendar.get(Calendar.YEAR) + "",(calendar.get(Calendar.MONTH)+1) + ""); } - Cell cell = result.getColumnLatestCell("chain_summary".getBytes(), entranceColumnName.getBytes()); + AnlyResult anlyResult = null; + Cell cell = result.getColumnLatestCell("chain_summary".getBytes(), columnName.getBytes()); if (cell != null) { - String anlyResultStr = Bytes.toString(cell.getQualifierArray(), - cell.getQualifierOffset(), cell.getQualifierLength()); + String anlyResultStr = Bytes.toString(cell.getValueArray(), + cell.getValueOffset(), cell.getValueLength()); logger.debug("traceId: {} , entranceColumnName : {}, anlyResultStr : {}", - treeId, entranceColumnName, anlyResultStr); - return new Gson().fromJson(anlyResultStr, AnlyResult.class); + treeId, columnName, anlyResultStr); + JsonObject jsonObject = (JsonObject) new JsonParser().parse(anlyResultStr); + Map resultMap = new Gson().fromJson(jsonObject.getAsJsonObject("summaryValueMap"), + new TypeToken>() { + }.getType()); + anlyResult = resultMap.get((Calendar.getInstance().get(Calendar.MONTH)+1) + ""); } - return new AnlyResult(); + if(anlyResult == null){ + anlyResult = new AnlyResult(); + } + anlyResult.setYearOfAnlyResult((Calendar.getInstance().get(Calendar.YEAR)) + ""); + anlyResult.setMonthOfAnlyResult((Calendar.getInstance().get(Calendar.MONTH)+1) + ""); + return anlyResult; } } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/impl/ChainDetailDao.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/impl/ChainDetailDao.java index 10664a5a2..a4f7996c8 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/impl/ChainDetailDao.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/impl/ChainDetailDao.java @@ -1,7 +1,8 @@ package com.ai.cloud.skywalking.web.dao.impl; -import com.ai.cloud.skywalking.web.dto.HitTreeInfo; import com.ai.cloud.skywalking.web.dao.inter.IChainDetailDao; +import com.ai.cloud.skywalking.web.dto.HitTreeInfo; +import com.ai.cloud.skywalking.web.util.Constants; import com.ai.cloud.skywalking.web.util.DBConnectUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -13,7 +14,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Repository public class ChainDetailDao implements IChainDetailDao { @@ -24,26 +27,25 @@ public class ChainDetailDao implements IChainDetailDao { private DBConnectUtil dbConnectUtil; @Override - public List queryChainTreeIds(String uid, String viewpoint) throws SQLException { + public List queryChainTreeIds(String uid, String viewpoint, int pageSize) throws SQLException { List hitTreeInfos = new ArrayList(); - String sql = "SELECT DISTINCT treeId,traceLevelId, viewpoint FROM sw_chain_detail WHERE uid = ? AND viewpoint like ? "; + String sql = "SELECT DISTINCT treeId FROM sw_chain_detail WHERE uid = ? AND viewpoint like ? LIMIT ?, ?"; Connection connection = dbConnectUtil.getConnection(); try { PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, uid); preparedStatement.setString(2, "%" + viewpoint + "%"); - + preparedStatement.setInt(3, (pageSize - 1) * Constants.MAX_ANALYSIS_RESULT_PAGE_SIZE); + preparedStatement.setInt(4, Constants.MAX_ANALYSIS_RESULT_PAGE_SIZE + 1); + logger.info("startsize : {} ", (pageSize - 1) * Constants.MAX_ANALYSIS_RESULT_PAGE_SIZE); ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { HitTreeInfo hitTreeInfo = new HitTreeInfo(resultSet.getString("treeId"), uid); - int index = hitTreeInfos.indexOf(hitTreeInfo); - if (index == -1) { - hitTreeInfos.add(hitTreeInfo); - } else { - hitTreeInfo = hitTreeInfos.get(index); + Map result = queryChainTreeId(uid, hitTreeInfo.getTreeId(), viewpoint); + for (Map.Entry entry : result.entrySet()) { + hitTreeInfo.addHitTraceLevelId(entry.getKey(), entry.getValue()); } - - hitTreeInfo.addHitTraceLevelId(resultSet.getString("traceLevelId"), resultSet.getString("viewpoint")); + hitTreeInfos.add(hitTreeInfo); } } catch (Exception e) { logger.error("Failed to query treeIds for Viewpoint[{}]", viewpoint); @@ -53,9 +55,35 @@ public class ChainDetailDao implements IChainDetailDao { connection.close(); } } + logger.info("hitTreeInfos : {}", hitTreeInfos.size()); return hitTreeInfos; } + private Map queryChainTreeId(String uid, String treeId, String viewpoint) throws SQLException { + Map result = new HashMap(); + String sql = "SELECT DISTINCT traceLevelId, viewpoint FROM sw_chain_detail WHERE uid = ? AND treeId=? AND viewpoint like ?"; + Connection connection = dbConnectUtil.getConnection(); + try { + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.setString(1, uid); + preparedStatement.setString(2, treeId); + preparedStatement.setString(3, "%" + viewpoint + "%"); + ResultSet resultSet = preparedStatement.executeQuery(); + while (resultSet.next()) { + result.put(resultSet.getString("traceLevelId"), resultSet.getString("viewpoint")); + } + } catch (Exception e) { + logger.error("Failed to query treeIds for Viewpoint[{}]", viewpoint); + throw new RuntimeException("Failed to query treeIds for " + viewpoint, e); + } finally { + if (connection != null) { + connection.close(); + } + } + return result; + } + + @Override public String queryChainViewPoint(String traceLevelId, String treeId, String uid) throws SQLException { String viewpoint = null; diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/inter/IChainDetailDao.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/inter/IChainDetailDao.java index f3722a53b..0655b4cae 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/inter/IChainDetailDao.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dao/inter/IChainDetailDao.java @@ -9,7 +9,7 @@ import java.util.List; * Created by xin on 16-4-6. */ public interface IChainDetailDao { - List queryChainTreeIds(String uid, String viewpoint) throws SQLException; + List queryChainTreeIds(String uid, String viewpoint, int pageSize) throws SQLException; String queryChainViewPoint(String traceLevelId, String treeId, String uid) throws SQLException; } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/AnlyResult.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/AnlyResult.java index 17b9c686f..0c51156e6 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/AnlyResult.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/AnlyResult.java @@ -4,6 +4,8 @@ package com.ai.cloud.skywalking.web.dto; * Created by xin on 16-4-12. */ public class AnlyResult { + private String yearOfAnlyResult; + private String monthOfAnlyResult; private long totalCall; private long totalCostTime; private long correctNumber; @@ -24,4 +26,44 @@ public class AnlyResult { public long getHumanInterruptionNumber() { return humanInterruptionNumber; } + + public void setTotalCall(long totalCall) { + this.totalCall = totalCall; + } + + public void setTotalCostTime(long totalCostTime) { + this.totalCostTime = totalCostTime; + } + + public void setCorrectNumber(long correctNumber) { + this.correctNumber = correctNumber; + } + + public void setHumanInterruptionNumber(long humanInterruptionNumber) { + this.humanInterruptionNumber = humanInterruptionNumber; + } + + public String getMonthOfAnlyResult() { + return monthOfAnlyResult; + } + + public void setMonthOfAnlyResult(String monthOfAnlyResult) { + this.monthOfAnlyResult = monthOfAnlyResult; + } + + public AnlyResult(String yearOfAnlyResult, String monthOfAnlyResult) { + this.yearOfAnlyResult = yearOfAnlyResult; + this.monthOfAnlyResult = monthOfAnlyResult; + } + + public AnlyResult() { + } + + public String getYearOfAnlyResult() { + return yearOfAnlyResult; + } + + public void setYearOfAnlyResult(String yearOfAnlyResult) { + this.yearOfAnlyResult = yearOfAnlyResult; + } } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/CallChainNode.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/CallChainNode.java new file mode 100644 index 000000000..ede75e76a --- /dev/null +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/CallChainNode.java @@ -0,0 +1,55 @@ +package com.ai.cloud.skywalking.web.dto; + +import com.ai.cloud.skywalking.web.util.ViewPointBeautiUtil; + +/** + * Created by xin on 16-4-14. + */ +public class CallChainNode { + private String traceLevelId=""; + private String viewPoint; + private boolean isGuess; + public CallChainNode(String traceLevelId, String viewPoint, boolean isGuess) { + this.traceLevelId = traceLevelId; + this.viewPoint = viewPoint; + this.isGuess = isGuess; + } + + public String getTraceLevelId() { + return traceLevelId; + } + + public void setTraceLevelId(String traceLevelId) { + this.traceLevelId = traceLevelId; + } + + public String getViewPoint() { + return viewPoint; + } + + public void setViewPoint(String viewPoint) { + this.viewPoint = viewPoint; + } + + public void beautiViewPointString(String searchKey) { + if (viewPoint.length() > 100) { + viewPoint = ViewPointBeautiUtil.beautifulViewPoint(viewPoint, searchKey); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CallChainNode that = (CallChainNode) o; + + return traceLevelId != null ? traceLevelId.equals(that.traceLevelId) : that.traceLevelId == null; + + } + + @Override + public int hashCode() { + return traceLevelId != null ? traceLevelId.hashCode() : 0; + } +} diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/HitTreeInfo.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/HitTreeInfo.java index 41d348cd9..7011ec1ea 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/HitTreeInfo.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/dto/HitTreeInfo.java @@ -5,9 +5,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.sql.SQLException; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * Created by xin on 16-4-11. @@ -61,8 +59,7 @@ public class HitTreeInfo { result[1] = levelId; return result; } - - result[0] = levelId.substring(0, indexOf - 1); + result[0] = levelId.substring(0, indexOf); result[1] = levelId.substring(indexOf + 1); return result; @@ -70,7 +67,7 @@ public class HitTreeInfo { public String getCurrentMonthAnlyTableName() { Calendar calendar = Calendar.getInstance(); - String monthSuffix = "/" + calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) + 1); + String monthSuffix = "/" + calendar.get(Calendar.YEAR); return getTreeId() + monthSuffix; } @@ -83,8 +80,78 @@ public class HitTreeInfo { } public void guessLevelIdAndSearchViewPoint(IChainDetailDao iChainDetailDao) throws SQLException { + Set levelIds = new HashSet<>(); + for (String levelId : levelIds) { + String[] levelIdArray = levelId.split("."); + if (levelId.length() < 2) { + // 当前节点为根节点 + String tmpViewpoint = iChainDetailDao.queryChainViewPoint("0.0", + treeId, uid); + if (tmpViewpoint != null) { + addHitTraceLevelId("0.0", tmpViewpoint); + } + } else { + // 找上级 + guessPreLevelId(iChainDetailDao, levelId); + //找下级 + guessNexLevelId(iChainDetailDao, levelId); + } + } + } + + private void guessNexLevelId(IChainDetailDao iChainDetailDao, String levelId) throws SQLException { + String[] levelIdArray = levelId.split("."); + String parentLevelId = levelId.substring(0, levelId.lastIndexOf('.')); + String nextLevelId = parentLevelId +"." + (Integer.parseInt(levelIdArray[levelIdArray.length - 1]) + 1); + String tmpViewpoint = iChainDetailDao.queryChainViewPoint(nextLevelId, + treeId, uid); + if (tmpViewpoint != null) { + addHitTraceLevelId(nextLevelId, tmpViewpoint); + } else { + levelIdArray = parentLevelId.split("."); + parentLevelId = levelId.substring(0, levelId.lastIndexOf('.')); + nextLevelId = parentLevelId + "." + (Integer.parseInt(levelIdArray[levelIdArray.length - 1]) + 1); + tmpViewpoint = iChainDetailDao.queryChainViewPoint(nextLevelId, + treeId, uid); + if (tmpViewpoint != null) { + addHitTraceLevelId(nextLevelId, tmpViewpoint); + } + } + + logger.info("LevelId :{}, nextLevelId :{} ", levelId, nextLevelId); + } + + private void guessPreLevelId(IChainDetailDao iChainDetailDao, String levelId) throws SQLException { + String[] levelIdArray = levelId.split("."); + String parentLevelId = levelId.substring(0, levelId.lastIndexOf('.')); + if (levelIdArray.length == 2 && "0".equals(parentLevelId)) { + //当前节点的父节点位根节点,不查询 + return; + } + + if ("0".equals(levelIdArray[levelIdArray.length - 1])) { + String tmpViewpoint = iChainDetailDao.queryChainViewPoint(parentLevelId, + treeId, uid); + if (tmpViewpoint != null) { + addHitTraceLevelId(parentLevelId, tmpViewpoint); + } + } else { + parentLevelId += "." + (Integer.parseInt(levelIdArray[levelIdArray.length - 1]) - 1); + String tmpViewpoint = iChainDetailDao.queryChainViewPoint(parentLevelId, + treeId, uid); + if (tmpViewpoint != null) { + addHitTraceLevelId(parentLevelId, tmpViewpoint); + } + } + + logger.info("LevelId :{}, preLevelId :{} ", levelId, parentLevelId); + } + + public void guessLevelIdAndSearchViewPoint1(IChainDetailDao iChainDetailDao) throws SQLException { String tmpViewpoint; - for (String levelId : hitTraceLevelId.keySet()) { + Set leveIds = new HashSet(); + leveIds.addAll(hitTraceLevelId.keySet()); + for (String levelId : leveIds) { String[] result = spiltParentLevelIdAndLevelId(levelId); if (result[0].length() == 0) { // 根节点,单独处理 @@ -96,23 +163,24 @@ public class HitTreeInfo { } } else { //找上级 - guessPreTraceLevelId(iChainDetailDao, result); + guessPreTraceLevelId(iChainDetailDao, levelId); //找下级 - guessNextTraceLevelId(iChainDetailDao, result); + guessNextTraceLevelId(iChainDetailDao, levelId); } } logger.debug("hitTraceLevelId : {}", hitTraceLevelId); } - private void guessNextTraceLevelId(IChainDetailDao iChainDetailDao, String[] result) throws SQLException { - String tmpViewpoint = iChainDetailDao.queryChainViewPoint(getSubTraceLevelId(result), + private void guessNextTraceLevelId(IChainDetailDao iChainDetailDao, String levelId) throws SQLException { + String traceLevelId = getSubTraceLevelId(levelId); + if (hitTraceLevelId.containsKey(traceLevelId)) { + return; + } + String tmpViewpoint = iChainDetailDao.queryChainViewPoint(traceLevelId, treeId, uid); - String traceLevelId = null; - if (tmpViewpoint != null) { - traceLevelId = getSubTraceLevelId(result); - } else { - traceLevelId = getBrotherOfParentLevelId(result); - if (traceLevelId != null && traceLevelId.length() > 0) + if (tmpViewpoint == null) { + traceLevelId = getBrotherOfParentLevelId(levelId); + if (traceLevelId.length() > 0) tmpViewpoint = iChainDetailDao.queryChainViewPoint(traceLevelId, treeId, uid); } @@ -121,17 +189,17 @@ public class HitTreeInfo { } } - private void guessPreTraceLevelId(IChainDetailDao iChainDetailDao, String[] result) throws SQLException { + private void guessPreTraceLevelId(IChainDetailDao iChainDetailDao, String levelId) throws SQLException { String tmpViewpoint = null; String traceLevelId = null; - if ((Integer.parseInt(result[1]) - 1) != -1) { + String[] result = spiltParentLevelIdAndLevelId(levelId); + if (result[0].length() > 0 && (Integer.parseInt(result[1]) - 1) != -1) { traceLevelId = getPreBrotherLevelId(result); tmpViewpoint = iChainDetailDao.queryChainViewPoint(traceLevelId, treeId, uid); } else { - String[] resultA = spiltParentLevelIdAndLevelId(result[0]); - if (result[0].length() != 0) { - traceLevelId = resultA[0]; + if (result[0].length() > 0) { + traceLevelId = result[0]; tmpViewpoint = iChainDetailDao.queryChainViewPoint(traceLevelId, treeId, uid); } @@ -146,16 +214,24 @@ public class HitTreeInfo { return result[0] + "." + (Integer.parseInt(result[1]) - 1); } - private String getBrotherOfParentLevelId(String[] result) { - String[] resultB = spiltParentLevelIdAndLevelId(result[0]); - if (resultB[1] != null && resultB.length > 0) { - return resultB[0] + (Integer.parseInt(resultB[1]) + 1); + private String getBrotherOfParentLevelId(String levelId) { + String[] result = spiltParentLevelIdAndLevelId(levelId); + if (result[0].length() > 0) { + result = spiltParentLevelIdAndLevelId(result[0]); + if (result[1] != null && result[1].length() > 0) { + return result[0] + (Integer.parseInt(result[1]) + 1); + } } return ""; } - private String getSubTraceLevelId(String[] result) { + private String getSubTraceLevelId(String levelId) { + String[] result = spiltParentLevelIdAndLevelId(levelId); return result[0] + "." + (Integer.parseInt(result[1]) + 1); } + + public String getUid() { + return uid; + } } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/entity/CallChainTree.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/entity/CallChainTree.java index 2f8e46736..919cb5b84 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/entity/CallChainTree.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/entity/CallChainTree.java @@ -1,9 +1,10 @@ package com.ai.cloud.skywalking.web.entity; import com.ai.cloud.skywalking.web.dto.AnlyResult; +import com.ai.cloud.skywalking.web.dto.CallChainNode; +import com.ai.cloud.skywalking.web.util.ViewPointBeautiUtil; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * Created by xin on 16-4-6. @@ -11,20 +12,79 @@ import java.util.Map; public class CallChainTree { private String treeId; private String entranceViewpoint; - private Map nodes; + private List nodes; private AnlyResult entranceAnlyResult; - public CallChainTree(String treeId, String entranceViewpoint) { + public CallChainTree(String treeId) { this.treeId = treeId; - this.entranceViewpoint = entranceViewpoint; - nodes = new HashMap(); + nodes = new ArrayList(); } public void setEntranceAnlyResult(AnlyResult entranceAnlyResult) { this.entranceAnlyResult = entranceAnlyResult; } - public void addNodes(Map nodes) { - this.nodes.putAll(nodes); + public void addHitNodes(Map nodes) { + for (Map.Entry entry : nodes.entrySet()) { + CallChainNode callChainNode = new CallChainNode(entry.getKey(), entry.getValue(), false); + this.nodes.add(callChainNode); + } + } + + public void beautiViewPointString(String searchKey) { + if (entranceViewpoint.length() > 100) { + entranceViewpoint = ViewPointBeautiUtil.beautifulViewPoint(entranceViewpoint, searchKey); + // + } + + for (CallChainNode chainNode : nodes) { + //高亮 + chainNode.beautiViewPointString(searchKey); + } + } + + public void sortNodes() { + Collections.sort(nodes, new Comparator() { + @Override + public int compare(CallChainNode o1, CallChainNode o2) { + return o1.getTraceLevelId().compareTo(o2.getTraceLevelId()); + } + }); + } + + public void addGuessNodesAndRemoveDuplicate(List nodes) { + for (CallChainNode node : nodes) { + if (!this.nodes.contains(node)) { + this.nodes.add(node); + } + } + } + + public void setEntranceViewpoint(String entranceViewpoint) { + this.entranceViewpoint = entranceViewpoint; + } + + public AnlyResult getEntranceAnlyResult() { + return entranceAnlyResult; + } + + public List getNodes() { + return nodes; + } + + public String getTreeId() { + return treeId; + } + + public String getEntranceViewpoint() { + return entranceViewpoint; + } + + public void setTreeId(String treeId) { + this.treeId = treeId; + } + + public void setNodes(List nodes) { + this.nodes = nodes; } } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/filter/AccessControllerFilter.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/filter/AccessControllerFilter.java index 7447ad9c0..4e0a95006 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/filter/AccessControllerFilter.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/filter/AccessControllerFilter.java @@ -24,6 +24,7 @@ public class AccessControllerFilter implements Filter { contained.add("addApplication"); contained.add("createGlobalApplication"); contained.add("modifyApplication"); + contained.add("showAnlyResult"); } @Override diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/service/impl/CallChainTreeService.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/service/impl/CallChainTreeService.java index dbde46fce..dc3ba0312 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/service/impl/CallChainTreeService.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/service/impl/CallChainTreeService.java @@ -1,8 +1,10 @@ package com.ai.cloud.skywalking.web.service.impl; -import com.ai.cloud.skywalking.web.dto.HitTreeInfo; import com.ai.cloud.skywalking.web.dao.inter.ICallChainTreeDao; import com.ai.cloud.skywalking.web.dao.inter.IChainDetailDao; +import com.ai.cloud.skywalking.web.dto.AnlyResult; +import com.ai.cloud.skywalking.web.dto.CallChainNode; +import com.ai.cloud.skywalking.web.dto.HitTreeInfo; import com.ai.cloud.skywalking.web.entity.CallChainTree; import com.ai.cloud.skywalking.web.service.inter.ICallChainTreeService; import org.apache.logging.log4j.LogManager; @@ -21,34 +23,113 @@ public class CallChainTreeService implements ICallChainTreeService { private Logger logger = LogManager.getLogger(CallChainTreeService.class); @Autowired - private IChainDetailDao iChainDetailDao; + private IChainDetailDao chainDetailDao; @Autowired private ICallChainTreeDao chainTreeDao; @Override - public List queryCurrentMonthCallChainTree(String uid, String viewpoint) throws SQLException, IOException { - List hitTreeInfos = iChainDetailDao.queryChainTreeIds(uid, viewpoint); - for (HitTreeInfo hitTreeInfo : hitTreeInfos) { - hitTreeInfo.guessLevelIdAndSearchViewPoint(iChainDetailDao); + public List queryCallChainTreeByKey(String uid, String viewpoint, int pageSize) throws SQLException, IOException { + List trees = new ArrayList(); + List hitTrees = chainDetailDao.queryChainTreeIds(uid, viewpoint, pageSize); + for (HitTreeInfo hitTree : hitTrees) { + CallChainTree chainTree = new CallChainTree(hitTree.getTreeId()); + chainTree.setEntranceViewpoint(chainDetailDao.queryChainViewPoint("0", hitTree.getTreeId(), uid)); + + chainTree.addHitNodes(hitTree.getHitTraceLevelId()); + //臆测TraceLevelId + chainTree.addGuessNodesAndRemoveDuplicate(doGuessNodes(hitTree)); + //获取统计结果 + AnlyResult anlyResult = chainTreeDao.queryEntranceAnlyResult("0@" + chainTree.getEntranceViewpoint(), hitTree.getCurrentMonthAnlyTableName()); + chainTree.setEntranceAnlyResult(anlyResult); + chainTree.sortNodes(); + //美化显示 + chainTree.beautiViewPointString(viewpoint); + trees.add(chainTree); + } + return trees; + } + + private List doGuessNodes(HitTreeInfo hitTraceLevelIds) throws SQLException { + List guessNodes = new ArrayList(); + for (String traceLevelId : hitTraceLevelIds.getHitTraceLevelId().keySet()) { + // + CallChainNode preTraceLevelNode = guessPreTraceLevelId(traceLevelId, hitTraceLevelIds.getTreeId(), hitTraceLevelIds.getUid()); + if (preTraceLevelNode != null) { + guessNodes.add(preTraceLevelNode); + logger.info("treeId:{}, traceLevelId :{}, preTraceLevelId:{}", hitTraceLevelIds.getTreeId(), traceLevelId, preTraceLevelNode.getTraceLevelId()); + } + + // + CallChainNode nextTraceLevelNode = guessNextTraceLevelId(traceLevelId, hitTraceLevelIds.getTreeId(), hitTraceLevelIds.getUid()); + if (nextTraceLevelNode != null) { + guessNodes.add(nextTraceLevelNode); + logger.info("treeId:{}, traceLevelId :{}, nextTraceLevelId:{}", hitTraceLevelIds.getTreeId(), traceLevelId, nextTraceLevelNode.getTraceLevelId()); + } + } - logger.info("viewpoint key :{}, chainTreeIds : {}", viewpoint, hitTreeInfos); - List callChainTrees = new ArrayList(); - for (HitTreeInfo hitTreeInfo : hitTreeInfos) { - String entranceViewpoint = iChainDetailDao.queryChainViewPoint("0", hitTreeInfo.getTreeId(), uid); - if (entranceViewpoint == null || entranceViewpoint.length() == 0) { - continue; - } - hitTreeInfo.setEntranceViewPoint(entranceViewpoint); - CallChainTree chainTree = new CallChainTree(hitTreeInfo.getTreeId(), entranceViewpoint); - chainTree.setEntranceAnlyResult(chainTreeDao.queryEntranceAnlyResult( - "0@" + hitTreeInfo.getEntranceViewPoint(), - hitTreeInfo.getCurrentMonthAnlyTableName())); - chainTree.addNodes(hitTreeInfo.getHitTraceLevelId()); - callChainTrees.add(chainTree); - } - logger.info("viewpoint key :{}, chainTree size : {}", viewpoint, callChainTrees.size()); - return callChainTrees; + return guessNodes; } + + private CallChainNode guessNextTraceLevelId(String traceLevelId, String treeId, String uid) throws SQLException { + String[] levelIdArray = traceLevelId.split("\\."); + if (traceLevelId.lastIndexOf('.') == -1) { + return null; + } + String parentLevelId = traceLevelId.substring(0, traceLevelId.lastIndexOf('.')); + if (levelIdArray.length == 0) + return null; + String subLevelId = parentLevelId + "." + (Integer.parseInt(levelIdArray[levelIdArray.length - 1]) + 1); + String tmpViewpoint = chainDetailDao.queryChainViewPoint(subLevelId, + treeId, uid); + CallChainNode result = null; + if (tmpViewpoint == null) { + levelIdArray = parentLevelId.split("\\."); + if (levelIdArray.length != 1) { + // 不为根节点 + String grandParentLevelId = traceLevelId.substring(0, parentLevelId.lastIndexOf('.')); + subLevelId = grandParentLevelId + "." + (Integer.parseInt(levelIdArray[levelIdArray.length - 1]) + 1); + tmpViewpoint = chainDetailDao.queryChainViewPoint(subLevelId, + treeId, uid); + logger.info("treeId:{} TreeLevelId:{}, subLevel[{}] is null, find the brother of parent LevelId :{}", treeId, subLevelId, traceLevelId, subLevelId); + } + } + + if (tmpViewpoint != null) { + result = new CallChainNode(subLevelId, tmpViewpoint, true); + } + + return result; + } + + private CallChainNode guessPreTraceLevelId(String traceLevelId, String treeId, String uid) throws SQLException { + String[] levelIdArray = traceLevelId.split("\\."); + if (levelIdArray.length <= 2) { + //上级节点为根节点,不用臆测,页面自动展示 + return null; + } + + CallChainNode result = null; + String parentLevelId = traceLevelId.substring(0, traceLevelId.lastIndexOf('.')); + if ("0".equals(levelIdArray[levelIdArray.length - 1])) { + // 本机节点为0,找父级 + String tmpViewpoint = chainDetailDao.queryChainViewPoint(parentLevelId, + treeId, uid); + if (tmpViewpoint != null) { + result = new CallChainNode(parentLevelId, tmpViewpoint, true); + } + } else { + // 本机节点不为0,找上级 + String preLevelId = parentLevelId + "." + (Integer.parseInt(levelIdArray[levelIdArray.length - 1]) - 1); + String tmpViewpoint = chainDetailDao.queryChainViewPoint(preLevelId, + treeId, uid); + if (tmpViewpoint != null) { + result = new CallChainNode(preLevelId, tmpViewpoint, true); + } + } + + return result; + } + } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/service/inter/ICallChainTreeService.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/service/inter/ICallChainTreeService.java index dd64aa89e..48a1f8002 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/service/inter/ICallChainTreeService.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/service/inter/ICallChainTreeService.java @@ -10,5 +10,5 @@ import java.util.List; * Created by xin on 16-4-6. */ public interface ICallChainTreeService { - List queryCurrentMonthCallChainTree(String uid, String viewpoint) throws SQLException, IOException; + List queryCallChainTreeByKey(String uid, String viewpoint, int pageSize) throws SQLException, IOException; } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/util/Constants.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/util/Constants.java index bea7dae31..37e219a0c 100644 --- a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/util/Constants.java +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/util/Constants.java @@ -45,4 +45,6 @@ public class Constants { public static int MAX_SEARCH_SPAN_SIZE = 10000; public static int MAX_SHOW_SPAN_SIZE = 200; + + public static int MAX_ANALYSIS_RESULT_PAGE_SIZE = 10; } diff --git a/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/util/ViewPointBeautiUtil.java b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/util/ViewPointBeautiUtil.java new file mode 100644 index 000000000..7d4204a77 --- /dev/null +++ b/skywalking-webui/src/main/java/com/ai/cloud/skywalking/web/util/ViewPointBeautiUtil.java @@ -0,0 +1,71 @@ +package com.ai.cloud.skywalking.web.util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by xin on 16-4-19. + */ +public class ViewPointBeautiUtil { + + + public static String beautifulViewPoint(String viewPoint, String searchKey) { + String highLightViewPoint = ViewPointBeautiUtil.addViewPoint(viewPoint, searchKey); + return ViewPointBeautiUtil.highLightViewPoint(highLightViewPoint, searchKey); + } + + private static String highLightViewPoint(String viewPoint, String searchKey) { + int index = viewPoint.indexOf(searchKey); + if (index == -1) { + return viewPoint; + } + StringBuilder result = new StringBuilder(viewPoint.substring(0, index - 1)); + result.append(""); + result.append(searchKey); + result.append(""); + result.append(viewPoint.substring(index + searchKey.length() + 1)); + return result.toString(); + } + + private static String addViewPoint(String viewPoint, String searchKey) { + StringBuilder result = new StringBuilder(); + int startSize = 0; + int index = viewPoint.indexOf(searchKey); + int suffixLength = 50; + if (index > suffixLength) { + result.append(viewPoint.substring(0, suffixLength)); + result.append("..."); + result.append(viewPoint.substring(index, index + searchKey.length())); + startSize = index + searchKey.length(); + } else if (index == suffixLength) { + result.append(viewPoint.substring(0, suffixLength + searchKey.length())); + startSize = suffixLength + searchKey.length(); + } else { + result.append(viewPoint.substring(0, suffixLength)); + startSize = suffixLength; + } + if (startSize < viewPoint.length() - 40) { + result.append("..."); + result.append(viewPoint.substring(viewPoint.length() - 40, viewPoint.length() - 20)); + result.append("...."); + } else if (startSize == viewPoint.length() - 40) { + result.append(viewPoint.substring(viewPoint.length() - 40, viewPoint.length() - 20)); + result.append("...."); + } else { + result.append(viewPoint.substring(startSize, viewPoint.length() - 10)); + } + return result.toString(); + } + + public static void main(String[] args) { + List list = new ArrayList<>(); + list.add("tracing:jdbc:oracle:thin:@10.1.1.61:1521:OAPROD(aisse)preaparedStatement.executeQuery:select a.ACCOUNT_TYPE,a.PHONE_ACCOUNT,a.PHONE_NUMBER,a.ATTRIBUTE4 from AISSE_EMPLOYEE_MOBILE_INFO_V a where PHONE_NUMBER is not null and NT_ACCOUNT = ? and ACCOUNT_TYPE not in ('统一充值','United Voucher'):preaparedStatement.executeQuery:select a.ACCOUNT_TYPE,a.PHONE_ACCOUNT,a.PHONE_NUMBER,a.ATTRIBUTE4 from AISSE_EMPLOYEE_MOBILE_INFO_V a where PHONE_NUMBER is not null and NT_ACCOUNT = ? and ACCOUNT_TYPE not in ('统一充值','United Voucher')"); + list.add("tracing:jdbc:oracle:thin:@10.1.1.61:1521:OAPROD(aisse)preaparedStatement.executeQuery:select a.ACCOUNT_TYPE,a.PHONE_ACCOUNT,a.PHONE_NUMBER,a.ATTRIBUTE4 from AISSE_EMPLOYEE_MOBILE_INFO_V a where lower(a.NT_ACCOUNT) = ?:preaparedStatement.executeQuery:select a.ACCOUNT_TYPE,a.PHONE_ACCOUNT,a.PHONE_NUMBER,a.ATTRIBUTE4 from AISSE_EMPLOYEE_MOBILE_INFO_V a where lower(a.NT_ACCOUNT) = ?"); + list.add("dubbo://aisse-mobile-web/com.ai.aisse.core.rest.ExpenseInitApi.searchMembersinfo(String):"); + list.add("com.ai.aisse.core.dao.impl.QueryUserMessageDaoImpl.selectDemoList(java.lang.String):"); + list.add("com.ai.aisse.controller.common.CommonController.toAisseMobilePage(com.ai.net.xss.wrapper.XssRequestWrapper,org.apache.catalina.connector.ResponseFacade,org.springframework.validation.support.BindingAwareModelMap):"); + for (String string : list) { + System.out.println(beautifulViewPoint(string, "ACCOUNT_TYPE")); + } + } +} diff --git a/skywalking-webui/src/main/resources/config.properties b/skywalking-webui/src/main/resources/config.properties index e930f433a..5ce38db81 100644 --- a/skywalking-webui/src/main/resources/config.properties +++ b/skywalking-webui/src/main/resources/config.properties @@ -1,2 +1,2 @@ -hbaseconfig.quorum=10.1.241.18,10.1.241.19,10.1.241.20 +hbaseconfig.quorum=10.1.235.197,10.1.235.198,10.1.235.199 hbaseconfig.client_port=29181 \ No newline at end of file diff --git a/skywalking-webui/src/main/resources/jdbc.properties b/skywalking-webui/src/main/resources/jdbc.properties index fcbb2a288..2cbdf3dac 100644 --- a/skywalking-webui/src/main/resources/jdbc.properties +++ b/skywalking-webui/src/main/resources/jdbc.properties @@ -1,7 +1,7 @@ jdbc.driverClassName=com.mysql.jdbc.Driver -jdbc.url=jdbc:mysql://10.1.241.20:31306/sw_db -jdbc.username=sw_dbusr01 -jdbc.password=sw_dbusr01 +jdbc.url=jdbc:mysql://10.1.228.202:31316/test +jdbc.username=devrdbusr21 +jdbc.password=devrdbusr21 jdbc.maxTotal=200 jdbc.maxIdle=50 jdbc.maxWaitMillis=1000 diff --git a/skywalking-webui/src/main/resources/log4j2.xml b/skywalking-webui/src/main/resources/log4j2.xml index 862afd156..5d274655b 100644 --- a/skywalking-webui/src/main/resources/log4j2.xml +++ b/skywalking-webui/src/main/resources/log4j2.xml @@ -1,18 +1,13 @@ - + - + - - - - - + \ No newline at end of file diff --git a/skywalking-webui/src/main/webapp/bower_components/skywalking/css/tracelog.css b/skywalking-webui/src/main/webapp/bower_components/skywalking/css/tracelog.css index 1e349df6b..83eb4b1f7 100644 --- a/skywalking-webui/src/main/webapp/bower_components/skywalking/css/tracelog.css +++ b/skywalking-webui/src/main/webapp/bower_components/skywalking/css/tracelog.css @@ -29,4 +29,8 @@ .progress-bar-c { background-color: #5bc0de; -} \ No newline at end of file +} + +.highlight-viewpoint { + background-color: #baec7e; +} diff --git a/skywalking-webui/src/main/webapp/bower_components/skywalking/js/analysisresult.js b/skywalking-webui/src/main/webapp/bower_components/skywalking/js/analysisresult.js new file mode 100644 index 000000000..551cbdc8a --- /dev/null +++ b/skywalking-webui/src/main/webapp/bower_components/skywalking/js/analysisresult.js @@ -0,0 +1,139 @@ +function toSearchAnlyResult(searchKey) { + loadAnalyResult(searchKey, 1); +} + +function bindPagerBtn() { + $("#doPreviousPageBtn").click(function () { + var pageSize = $("#pageSize").val(); + $("#anlyResultmPanel").empty(); + loadAnalyResult(parseInt(pageSize) - 1); + }); + + $("#doNextPageBtn").click(function () { + var pageSize = $("#pageSize").val(); + $("#anlyResultmPanel").empty(); + loadAnalyResult(parseInt(pageSize) + 1); + }); +} + +function loadAnalyResult(searchKey, pageSize) { + var baseUrl = $("#baseUrl").text(); + var url = baseUrl + '/search/chainTree?key=' + searchKey; + $.ajax({ + type: 'POST', + url: url, + dataType: 'json', + data: { + pageSize: pageSize + }, + success: function (data) { + if (data.code == '200') { + var template = $.templates("#anlyResultDisplayTmpl"); + var jsonValue = JSON.parse(data.result); + var showResult = jsonValue.children; + if (showResult != undefined && showResult.length > 0) { + for (var i = 0; i < showResult.length; i++) { + var tmpNodes = showResult[i].nodes; + var preNodesTraceleveId = "0"; + for (var j = 0; j < tmpNodes.length; j++) { + //preNodeLenght = spiltArray.length; + tmpNodes[j].isPrintSlipDot = !compareTraceLevelId(preNodesTraceleveId, tmpNodes[j].traceLevelId); + if (tmpNodes[j].isPrintSlipDot) { + tmpNodes[j].marginLeftSize = 0; + } else { + var spiltArray = tmpNodes[j].traceLevelId.split("."); + var preSplitArray = preNodesTraceleveId.split("."); + var flag = false; + var length = spiltArray.length; + if (length > preSplitArray.length) { + length = preSplitArray.length; + flag = true; + } + if (preSplitArray[length - 1] == spiltArray[length - 1]) { + if (flag){ + tmpNodes[j].marginLeftSize = 10; + }else{ + tmpNodes[j].marginLeftSize = 0; + } + } else if (preSplitArray[length - 1] < spiltArray[length - 1]) { + //异常情况 + tmpNodes[j].marginLeftSize = 0; + } else { + tmpNodes[j].marginLeftSize = 10; + } + } + preNodesTraceleveId = tmpNodes[j].traceLevelId; + } + if (showResult[i].entranceAnlyResult.totalCall != 0) { + showResult[i].correctRate = (parseFloat(showResult[i].entranceAnlyResult.correctNumber) + / parseFloat(showResult[i].entranceAnlyResult.totalCall) * 100).toFixed(2); + } else { + showResult[i].correctRate = (0).toFixed(2); + } + } + + var htmlOutput = template.render(jsonValue.children); + $("#anlyResultmPanel").empty(); + $("#anlyResultmPanel").html(htmlDecode(htmlOutput)); + + template = $.templates("#pageInfoTmpl"); + var hasPreviousPage = true; + if (pageSize == 1) { + hasPreviousPage = false; + } + htmlOutput = template.render({ + "pageSize": pageSize, + "hasPreviousPage": hasPreviousPage, + "hasNextPage": jsonValue.hasNextPage + }); + $("#anlyResultmPanel").append(htmlOutput); + bindPagerBtn(); + } + } + }, + error: function () { + $("#errorMessage").text("Fatal Error, please try it again."); + $("#alertMessageBox").show(); + } + }); +} +function htmlDecode(str) { + var _str = ''; + if (str.length == 0) return ''; + _str = str.replace(/</g, '<'); + _str = _str.replace(/>/g, '>'); + _str = _str.replace(/'/g, "'"); + return _str; +} + +function compareTraceLevelId(preTraceLevelId, currentTraceLevelId) { + var preLevelArray = preTraceLevelId.split('.'); + var curLevelArray = currentTraceLevelId.split('.'); + + if (Math.abs(preLevelArray.length - curLevelArray.length) > 1) { + return false; + } + + var length = preLevelArray.length; + if (curLevelArray.length > length) { + length = curLevelArray.length; + } + + var result = true; + for (var index = 0; index < length; index++) { + var value = parseInt(preLevelArray[index]) - parseInt(curLevelArray[index]); + if (value < -1) { + result = false; + break; + } + + if (value == -1) { + if (preLevelArray.length < index + 1 && curLevelArray[index + 1] != "0") { + result = false; + break; + } + } + } + + return result; +} \ No newline at end of file diff --git a/skywalking-webui/src/main/webapp/bower_components/skywalking/js/tracelog.js b/skywalking-webui/src/main/webapp/bower_components/skywalking/js/tracelog.js index 81fa494e1..29dd40e93 100644 --- a/skywalking-webui/src/main/webapp/bower_components/skywalking/js/tracelog.js +++ b/skywalking-webui/src/main/webapp/bower_components/skywalking/js/tracelog.js @@ -97,7 +97,7 @@ function loadTraceTreeData(baseUrl) { url: url, dataType: 'json', data: {traceId:$("#searchKey").val()}, - async: true, + async: false, success: function (data) { if (data.code == '200') { var changedData = changeData(jQuery.parseJSON(data.result)); diff --git a/skywalking-webui/src/main/webapp/pages/anls-result/analysisResult.ftl b/skywalking-webui/src/main/webapp/pages/anls-result/analysisResult.ftl index f2ddca6ee..7d60e80f9 100644 --- a/skywalking-webui/src/main/webapp/pages/anls-result/analysisResult.ftl +++ b/skywalking-webui/src/main/webapp/pages/anls-result/analysisResult.ftl @@ -1,25 +1,58 @@ -<#macro analysisResult> - + +<#macro anlyResultDisplayTmpl> + + + +<#macro pageInfoTmpl> + \ No newline at end of file diff --git a/skywalking-webui/src/main/webapp/pages/index.ftl b/skywalking-webui/src/main/webapp/pages/index.ftl index 560f9f00b..ba7cd1d1b 100644 --- a/skywalking-webui/src/main/webapp/pages/index.ftl +++ b/skywalking-webui/src/main/webapp/pages/index.ftl @@ -69,7 +69,12 @@ + @@ -32,6 +34,9 @@ <@applicationMaintain.createglobalConfig/> <@applicationMaintain.modifyApplication/> <@auth.downloadAuth/> +<@anlyResult.anlyResultTmpl/> +<@anlyResult.anlyResultDisplayTmpl/> +<@anlyResult.pageInfoTmpl/>
@@ -45,7 +50,12 @@ loadContent(loadType); // bind $("#searchBtn").click(function () { - loadTraceTreeData("${_base}"); + var searchKey = $("#searchKey").val(); + if (searchKey.match(/viewpoint:*/i)){ + loadContent("showAnlyResult") + }else { + loadContent("showTraceInfo"); + } }) }); @@ -55,6 +65,20 @@ loadTraceTreeData("${_base}"); } + if (loadType == "showAnlyResult"){ + var template = $.templates("#anlyResultPanelTmpl"); + var htmlOutput = template.render({}); + $("#mainPanel").empty(); + $("#mainPanel").html(htmlOutput); + var searchKey = $("#searchKey").val(); + var index = searchKey.indexOf(':'); + if (index != -1) { + searchKey = searchKey.substr(index + 1); + } + toSearchAnlyResult(searchKey); + return; + } + if (loadType == "applicationList") { loadAllApplications(); return;