1.解决链路过长,导致页面崩溃的bug

2.将bo包改成dto
3.解决点击搜索页面的按钮会调用两次查询
4.增加调用链过长提示
This commit is contained in:
ascrutae 2016-04-13 20:19:27 +08:00
parent 304b3fc51e
commit 56db909c4d
43 changed files with 519 additions and 189 deletions

View File

@ -1,7 +1,7 @@
package com.ai.cloud.skywalking.web.common;
import com.ai.cloud.skywalking.web.util.Constants;
import com.ai.cloud.skywalking.web.bo.LoginUserInfo;
import com.ai.cloud.skywalking.web.dto.LoginUserInfo;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;

View File

@ -1,8 +1,8 @@
package com.ai.cloud.skywalking.web.controller;
import com.ai.cloud.skywalking.web.bo.AlarmRuleInfo;
import com.ai.cloud.skywalking.web.bo.ConfigArgs;
import com.ai.cloud.skywalking.web.bo.LoginUserInfo;
import com.ai.cloud.skywalking.web.dto.AlarmRuleInfo;
import com.ai.cloud.skywalking.web.dto.ConfigArgs;
import com.ai.cloud.skywalking.web.dto.LoginUserInfo;
import com.ai.cloud.skywalking.web.common.BaseController;
import com.ai.cloud.skywalking.web.dao.inter.IAlarmRuleMaintainDao;
import com.ai.cloud.skywalking.web.entity.AlarmRule;

View File

@ -1,7 +1,7 @@
package com.ai.cloud.skywalking.web.controller;
import com.ai.cloud.skywalking.web.bo.ApplicationInfo;
import com.ai.cloud.skywalking.web.bo.LoginUserInfo;
import com.ai.cloud.skywalking.web.dto.ApplicationInfo;
import com.ai.cloud.skywalking.web.dto.LoginUserInfo;
import com.ai.cloud.skywalking.web.common.BaseController;
import com.ai.cloud.skywalking.web.dao.inter.IAlarmRuleMaintainDao;
import com.ai.cloud.skywalking.web.dao.inter.IApplicationsMaintainDao;

View File

@ -1,6 +1,6 @@
package com.ai.cloud.skywalking.web.controller;
import com.ai.cloud.skywalking.web.bo.LoginUserInfo;
import com.ai.cloud.skywalking.web.dto.LoginUserInfo;
import com.ai.cloud.skywalking.web.common.BaseController;
import com.ai.cloud.skywalking.web.dao.inter.IAuthFileMaintainDao;
import com.ai.cloud.skywalking.web.dao.inter.ISystemConfigMaintainDao;

View File

@ -1,7 +1,7 @@
package com.ai.cloud.skywalking.web.controller;
import com.ai.cloud.skywalking.web.bo.LoginUserInfo;
import com.ai.cloud.skywalking.web.bo.TraceTreeInfo;
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;
@ -70,6 +70,7 @@ public class SearchController extends BaseController {
jsonObject.put("message", "Cannot find TraceId[" + traceId + "]");
}
} catch (Exception e) {
logger.error("Search tree Id ", e);
jsonObject.put("code", "500");
jsonObject.put("result", "Fatal error");
}

View File

@ -1,7 +1,7 @@
package com.ai.cloud.skywalking.web.controller;
import com.ai.cloud.skywalking.web.bo.LoginUserInfo;
import com.ai.cloud.skywalking.web.bo.SignInUserInfo;
import com.ai.cloud.skywalking.web.dto.LoginUserInfo;
import com.ai.cloud.skywalking.web.dto.SignInUserInfo;
import com.ai.cloud.skywalking.web.common.BaseController;
import com.ai.cloud.skywalking.web.dao.inter.IUserMaintainDao;
import com.ai.cloud.skywalking.web.entity.UserInfo;

View File

@ -3,7 +3,7 @@ package com.ai.cloud.skywalking.web.dao.impl;
import com.ai.cloud.skywalking.web.dao.inter.IAlarmRuleMaintainDao;
import com.ai.cloud.skywalking.web.entity.AlarmRule;
import com.ai.cloud.skywalking.web.util.DBConnectUtil;
import com.ai.cloud.skywalking.web.bo.ConfigArgs;
import com.ai.cloud.skywalking.web.dto.ConfigArgs;
import com.google.gson.Gson;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

View File

@ -1,6 +1,6 @@
package com.ai.cloud.skywalking.web.dao.impl;
import com.ai.cloud.skywalking.web.bo.ApplicationInfo;
import com.ai.cloud.skywalking.web.dto.ApplicationInfo;
import com.ai.cloud.skywalking.web.dao.inter.IApplicationsMaintainDao;
import com.ai.cloud.skywalking.web.entity.Application;
import com.ai.cloud.skywalking.web.util.DBConnectUtil;

View File

@ -1,14 +1,18 @@
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.entity.CallChainTree;
import com.ai.cloud.skywalking.web.util.HBaseUtils;
import com.google.gson.Gson;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@ -17,27 +21,28 @@ import java.io.IOException;
@Repository
public class CallChainTreeDao implements ICallChainTreeDao {
private Logger logger = LogManager.getLogger(CallChainTree.class);
@Autowired
private HBaseUtils hBaseUtils;
@Override
public CallChainTree queryTreeId(String treeId) throws IOException {
public AnlyResult queryEntranceAnlyResult(String entranceColumnName, String treeId) throws IOException {
Table table = hBaseUtils.getConnection().getTable(TableName.valueOf("sw-chain-1day-summary"));
Get get = new Get(treeId.getBytes());
Result result = table.get(get);
if (result.rawCells().length == 0) {
return null;
}
CallChainTree chainTree = new CallChainTree(treeId);
for (Cell cell : result.rawCells()) {
if (cell.getValueArray().length > 0) {
String qualifier = Bytes.toString(cell.getQualifierArray(),
cell.getQualifierOffset(), cell.getQualifierLength());
String[] qualifierArr = qualifier.split("@");
chainTree.addNode(qualifierArr[0],qualifierArr[1]);
}
Cell cell = result.getColumnLatestCell("chain_summary".getBytes(), entranceColumnName.getBytes());
if (cell != null) {
String anlyResultStr = Bytes.toString(cell.getQualifierArray(),
cell.getQualifierOffset(), cell.getQualifierLength());
logger.debug("traceId: {} , entranceColumnName : {}, anlyResultStr : {}",
treeId, entranceColumnName, anlyResultStr);
return new Gson().fromJson(anlyResultStr, AnlyResult.class);
}
return null;
return new AnlyResult();
}
}

View File

@ -1,5 +1,6 @@
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.util.DBConnectUtil;
import org.apache.logging.log4j.LogManager;
@ -23,9 +24,9 @@ public class ChainDetailDao implements IChainDetailDao {
private DBConnectUtil dbConnectUtil;
@Override
public List<String> queryChainTreeIds(String uid, String viewpoint) throws SQLException {
List<String> treeIds = new ArrayList<String>();
String sql = "SELECT treeId FROM sw_chain_detail WHERE uid = ? AND viewpoint like ? ";
public List<HitTreeInfo> queryChainTreeIds(String uid, String viewpoint) throws SQLException {
List<HitTreeInfo> hitTreeInfos = new ArrayList<HitTreeInfo>();
String sql = "SELECT DISTINCT treeId,traceLevelId, viewpoint FROM sw_chain_detail WHERE uid = ? AND viewpoint like ? ";
Connection connection = dbConnectUtil.getConnection();
try {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
@ -34,7 +35,15 @@ public class ChainDetailDao implements IChainDetailDao {
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
treeIds.add(resultSet.getString("treeId"));
HitTreeInfo hitTreeInfo = new HitTreeInfo(resultSet.getString("treeId"), uid);
int index = hitTreeInfos.indexOf(hitTreeInfo);
if (index == -1) {
hitTreeInfos.add(hitTreeInfo);
} else {
hitTreeInfo = hitTreeInfos.get(index);
}
hitTreeInfo.addHitTraceLevelId(resultSet.getString("traceLevelId"), resultSet.getString("viewpoint"));
}
} catch (Exception e) {
logger.error("Failed to query treeIds for Viewpoint[{}]", viewpoint);
@ -44,6 +53,33 @@ public class ChainDetailDao implements IChainDetailDao {
connection.close();
}
}
return treeIds;
return hitTreeInfos;
}
@Override
public String queryChainViewPoint(String traceLevelId, String treeId, String uid) throws SQLException {
String viewpoint = null;
String sql = "SELECT DISTINCT viewpoint FROM sw_chain_detail WHERE uid = ? AND treeId = ? AND traceLevelId = ? ";
Connection connection = dbConnectUtil.getConnection();
try {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, uid);
preparedStatement.setString(2, treeId);
preparedStatement.setString(3, traceLevelId);
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
viewpoint = 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 viewpoint;
}
}

View File

@ -1,7 +1,7 @@
package com.ai.cloud.skywalking.web.dao.impl;
import com.ai.cloud.skywalking.web.bo.TraceNodeInfo;
import com.ai.cloud.skywalking.web.bo.TraceTreeInfo;
import com.ai.cloud.skywalking.web.dto.TraceNodeInfo;
import com.ai.cloud.skywalking.web.dto.TraceNodesResult;
import com.ai.cloud.skywalking.web.dao.inter.ITraceNodeDao;
import com.ai.cloud.skywalking.web.util.Constants;
import com.ai.cloud.skywalking.web.util.HBaseUtils;
@ -11,7 +11,6 @@ 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.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;
import org.apache.hadoop.hbase.util.Bytes;
@ -20,9 +19,8 @@ import org.springframework.stereotype.Repository;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -38,58 +36,59 @@ public class TraceNodeDao implements ITraceNodeDao {
@Override
public TraceTreeInfo queryTraceNodesByTraceId(String traceId) throws IOException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
TraceTreeInfo traceTreeInfo = null;
public TraceNodesResult queryTraceNodesByTraceId(String traceId) throws IOException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Table table = hBaseUtils.getConnection().getTable(TableName.valueOf(CALL_CHAIN_TABLE_NAME));
Get g = new Get(Bytes.toBytes(traceId));
g.setFilter(new ColumnCountGetFilter(10001));
g.setFilter(new ColumnCountGetFilter(Constants.MAX_SEARCH_SPAN_SIZE + 1));
Result r = table.get(g);
Map<String, TraceNodeInfo> traceLogMap = new HashMap<String, TraceNodeInfo>();
Map<String, TraceNodeInfo> rpcMap = new HashMap<String, TraceNodeInfo>();
int totalSize = 10001;
if (r.rawCells().length < 10000) {
TraceNodesResult result = new TraceNodesResult();
if (r.rawCells().length < Constants.MAX_SEARCH_SPAN_SIZE) {
for (Cell cell : r.rawCells()) {
if (cell.getValueArray().length > 0) {
dealSingleSpanCell(traceLogMap, rpcMap, cell);
}
doDealSingleSpan(traceLogMap, rpcMap, cell);
}
totalSize = r.rawCells().length;
} else {
g = new Get(Bytes.toBytes(traceId));
g.addColumn("call-chain".getBytes(), "0".getBytes());
g.addColumn("call-chain".getBytes(), "0.0".getBytes());
r = table.get(g);
//获取0和0.0两个节点
Cell cell = r.getColumnLatestCell("call-chain".getBytes(), "0".getBytes());
dealSingleSpanCell(traceLogMap, rpcMap, cell);
cell = r.getColumnLatestCell("call-chain".getBytes(), "0.0".getBytes());
dealSingleSpanCell(traceLogMap, rpcMap, cell);
computeRPCInfo(rpcMap, traceLogMap);
result.setOverMaxQueryNodeNumber(false);
result.setResult(traceLogMap.values());
}else{
result.setOverMaxQueryNodeNumber(true);
}
computeRPCInfo(rpcMap, traceLogMap);
if (traceLogMap != null && traceLogMap.size() > 0) {
List<TraceNodeInfo> nodes = new ArrayList<TraceNodeInfo>();
nodes.addAll(traceLogMap.values());
traceTreeInfo = new TraceTreeInfo(traceId, nodes);
traceTreeInfo.setNodeSize(totalSize);
}
return traceTreeInfo;
return result;
}
private void dealSingleSpanCell(Map<String, TraceNodeInfo> traceLogMap, Map<String, TraceNodeInfo> rpcMap, Cell cell) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
if (cell.getValueArray().length == 0)
return;
String colId = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
cell.getQualifierLength());
TraceNodeInfo tmpEntry = TraceNodeInfo.convert(
Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()), colId);
// 特殊处理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);
@Override
public Collection<TraceNodeInfo> queryEntranceNodeByTraceId(String traceId) throws IOException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Table table = hBaseUtils.getConnection().getTable(TableName.valueOf(CALL_CHAIN_TABLE_NAME));
Get g = new Get(Bytes.toBytes(traceId));
g.addColumn("call-chain".getBytes(), "0".getBytes());
g.addColumn("call-chain".getBytes(), "0.0".getBytes());
Result r = table.get(g);
Map<String, TraceNodeInfo> traceLogMap = new HashMap<String, TraceNodeInfo>();
Map<String, TraceNodeInfo> rpcMap = new HashMap<String, TraceNodeInfo>();
Cell cell = r.getColumnLatestCell("call-chain".getBytes(), "0".getBytes());
doDealSingleSpan(traceLogMap, rpcMap, cell);
cell = r.getColumnLatestCell("call-chain".getBytes(), "0.0".getBytes());
doDealSingleSpan(traceLogMap, rpcMap, cell);
computeRPCInfo(rpcMap, traceLogMap);
return traceLogMap.values();
}
private void doDealSingleSpan(Map<String, TraceNodeInfo> traceLogMap, Map<String, TraceNodeInfo> rpcMap, Cell cell) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
if (cell != null && cell.getValueArray().length > 0) {
String colId = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
cell.getQualifierLength());
TraceNodeInfo tmpEntry = TraceNodeInfo.convert(
Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()), colId);
// 特殊处理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);
}
}
}
@ -112,7 +111,7 @@ public class TraceNodeDao implements ITraceNodeDao {
clientLog.setAddress(serverLog.getAddress());
if (StringUtil.isBlank(clientLog.getExceptionStack())) {
clientLog.setExceptionStack(serverLog.getExceptionStack());
} else {
}else{
clientLog.setServerExceptionStr(serverLog.getServerExceptionStr());
}
System.out.println("1");

View File

@ -2,8 +2,8 @@ package com.ai.cloud.skywalking.web.dao.impl;
import com.ai.cloud.skywalking.web.dao.inter.IUserMaintainDao;
import com.ai.cloud.skywalking.web.util.DBConnectUtil;
import com.ai.cloud.skywalking.web.bo.LoginUserInfo;
import com.ai.cloud.skywalking.web.bo.SignInUserInfo;
import com.ai.cloud.skywalking.web.dto.LoginUserInfo;
import com.ai.cloud.skywalking.web.dto.SignInUserInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

View File

@ -1,6 +1,6 @@
package com.ai.cloud.skywalking.web.dao.inter;
import com.ai.cloud.skywalking.web.bo.ApplicationInfo;
import com.ai.cloud.skywalking.web.dto.ApplicationInfo;
import com.ai.cloud.skywalking.web.entity.Application;
import java.sql.SQLException;

View File

@ -1,6 +1,6 @@
package com.ai.cloud.skywalking.web.dao.inter;
import com.ai.cloud.skywalking.web.entity.CallChainTree;
import com.ai.cloud.skywalking.web.dto.AnlyResult;
import java.io.IOException;
@ -8,5 +8,5 @@ import java.io.IOException;
* Created by xin on 16-4-6.
*/
public interface ICallChainTreeDao {
CallChainTree queryTreeId(String treeId) throws IOException;
AnlyResult queryEntranceAnlyResult(String entranceColumnName, String treeId) throws IOException;
}

View File

@ -1,5 +1,7 @@
package com.ai.cloud.skywalking.web.dao.inter;
import com.ai.cloud.skywalking.web.dto.HitTreeInfo;
import java.sql.SQLException;
import java.util.List;
@ -7,5 +9,7 @@ import java.util.List;
* Created by xin on 16-4-6.
*/
public interface IChainDetailDao {
List<String> queryChainTreeIds(String uid, String viewpoint) throws SQLException;
List<HitTreeInfo> queryChainTreeIds(String uid, String viewpoint) throws SQLException;
String queryChainViewPoint(String traceLevelId, String treeId, String uid) throws SQLException;
}

View File

@ -1,16 +1,18 @@
package com.ai.cloud.skywalking.web.dao.inter;
import com.ai.cloud.skywalking.web.bo.TraceNodeInfo;
import com.ai.cloud.skywalking.web.bo.TraceTreeInfo;
import com.ai.cloud.skywalking.web.dto.TraceNodeInfo;
import com.ai.cloud.skywalking.web.dto.TraceNodesResult;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Collection;
/**
* Created by xin on 16-3-30.
*/
public interface ITraceNodeDao {
TraceTreeInfo queryTraceNodesByTraceId(String traceId) throws IOException, IllegalAccessException, NoSuchMethodException, InvocationTargetException;
TraceNodesResult queryTraceNodesByTraceId(String traceId) throws IOException, IllegalAccessException, NoSuchMethodException, InvocationTargetException;
Collection<TraceNodeInfo> queryEntranceNodeByTraceId(String traceId) throws IOException, IllegalAccessException, NoSuchMethodException, InvocationTargetException;
}

View File

@ -1,7 +1,7 @@
package com.ai.cloud.skywalking.web.dao.inter;
import com.ai.cloud.skywalking.web.bo.LoginUserInfo;
import com.ai.cloud.skywalking.web.bo.SignInUserInfo;
import com.ai.cloud.skywalking.web.dto.LoginUserInfo;
import com.ai.cloud.skywalking.web.dto.SignInUserInfo;
import java.sql.SQLException;

View File

@ -1,4 +1,4 @@
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.web.entity.AlarmRule;

View File

@ -0,0 +1,27 @@
package com.ai.cloud.skywalking.web.dto;
/**
* Created by xin on 16-4-12.
*/
public class AnlyResult {
private long totalCall;
private long totalCostTime;
private long correctNumber;
private long humanInterruptionNumber;
public long getTotalCall() {
return totalCall;
}
public long getTotalCostTime() {
return totalCostTime;
}
public long getCorrectNumber() {
return correctNumber;
}
public long getHumanInterruptionNumber() {
return humanInterruptionNumber;
}
}

View File

@ -1,4 +1,4 @@
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.web.entity.Application;

View File

@ -1,4 +1,4 @@
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import java.io.Serializable;

View File

@ -0,0 +1,161 @@
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.web.dao.inter.IChainDetailDao;
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;
/**
* Created by xin on 16-4-11.
*/
public class HitTreeInfo {
private Logger logger = LogManager.getLogger(HitTreeInfo.class);
private String treeId;
private Map<String, String> hitTraceLevelId;
private String entranceViewPoint;
private String uid;
public HitTreeInfo(String treeId, String uid) {
this.treeId = treeId;
this.uid = uid;
this.hitTraceLevelId = new HashMap<String, String>();
}
public void addHitTraceLevelId(String traceLevelId, String viewPoint) {
this.hitTraceLevelId.put(traceLevelId, viewPoint);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
HitTreeInfo that = (HitTreeInfo) o;
return treeId != null ? treeId.equals(that.treeId) : that.treeId == null;
}
@Override
public int hashCode() {
return treeId != null ? treeId.hashCode() : 0;
}
public String getTreeId() {
return treeId;
}
public Map<String, String> getHitTraceLevelId() {
return hitTraceLevelId;
}
private String[] spiltParentLevelIdAndLevelId(String levelId) {
String[] result = new String[2];
int indexOf = levelId.lastIndexOf(".");
if (indexOf == -1) {
// 根节点
result[0] = "";
result[1] = levelId;
return result;
}
result[0] = levelId.substring(0, indexOf - 1);
result[1] = levelId.substring(indexOf + 1);
return result;
}
public String getCurrentMonthAnlyTableName() {
Calendar calendar = Calendar.getInstance();
String monthSuffix = "/" + calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) + 1);
return getTreeId() + monthSuffix;
}
public void setEntranceViewPoint(String entranceViewPoint) {
this.entranceViewPoint = entranceViewPoint;
}
public String getEntranceViewPoint() {
return entranceViewPoint;
}
public void guessLevelIdAndSearchViewPoint(IChainDetailDao iChainDetailDao) throws SQLException {
String tmpViewpoint;
for (String levelId : hitTraceLevelId.keySet()) {
String[] result = spiltParentLevelIdAndLevelId(levelId);
if (result[0].length() == 0) {
// 根节点单独处理
// 当前下级
tmpViewpoint = iChainDetailDao.queryChainViewPoint(result[0] + ".0",
treeId, uid);
if (tmpViewpoint != null) {
addHitTraceLevelId(getPreBrotherLevelId(result), tmpViewpoint);
}
} else {
//找上级
guessPreTraceLevelId(iChainDetailDao, result);
//找下级
guessNextTraceLevelId(iChainDetailDao, result);
}
}
logger.debug("hitTraceLevelId : {}", hitTraceLevelId);
}
private void guessNextTraceLevelId(IChainDetailDao iChainDetailDao, String[] result) throws SQLException {
String tmpViewpoint = iChainDetailDao.queryChainViewPoint(getSubTraceLevelId(result),
treeId, uid);
String traceLevelId = null;
if (tmpViewpoint != null) {
traceLevelId = getSubTraceLevelId(result);
} else {
traceLevelId = getBrotherOfParentLevelId(result);
if (traceLevelId != null && traceLevelId.length() > 0)
tmpViewpoint = iChainDetailDao.queryChainViewPoint(traceLevelId, treeId, uid);
}
if (tmpViewpoint != null) {
addHitTraceLevelId(traceLevelId, tmpViewpoint);
}
}
private void guessPreTraceLevelId(IChainDetailDao iChainDetailDao, String[] result) throws SQLException {
String tmpViewpoint = null;
String traceLevelId = null;
if ((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];
tmpViewpoint = iChainDetailDao.queryChainViewPoint(traceLevelId,
treeId, uid);
}
}
if (tmpViewpoint != null) {
addHitTraceLevelId(traceLevelId, tmpViewpoint);
}
}
private String getPreBrotherLevelId(String[] result) {
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);
}
return "";
}
private String getSubTraceLevelId(String[] result) {
return result[0] + "." + (Integer.parseInt(result[1]) + 1);
}
}

View File

@ -1,4 +1,4 @@
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.web.entity.UserInfo;

View File

@ -1,4 +1,4 @@
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import java.io.Serializable;
import java.util.Arrays;

View File

@ -1,4 +1,4 @@
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.web.entity.UserInfo;

View File

@ -1,7 +1,7 @@
/**
*
*/
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
public class TimeLineEntry {

View File

@ -1,4 +1,4 @@
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.protocol.Span;
import com.ai.cloud.skywalking.web.util.Constants;

View File

@ -0,0 +1,35 @@
package com.ai.cloud.skywalking.web.dto;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Created by xin on 16-4-13.
*/
public class TraceNodesResult {
private boolean isOverMaxQueryNodeNumber;
private List<TraceNodeInfo> result;
public TraceNodesResult(){
result = new ArrayList<TraceNodeInfo>();
}
public boolean isOverMaxQueryNodeNumber() {
return isOverMaxQueryNodeNumber;
}
public void setOverMaxQueryNodeNumber(boolean overMaxQueryNodeNumber) {
isOverMaxQueryNodeNumber = overMaxQueryNodeNumber;
}
public List<TraceNodeInfo> getResult() {
return result;
}
public void setResult(Collection<TraceNodeInfo> result) {
this.result.addAll(result);
}
}

View File

@ -1,5 +1,8 @@
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.web.util.Constants;
import java.util.ArrayList;
import java.util.List;
public class TraceTreeInfo {
@ -8,10 +11,16 @@ public class TraceTreeInfo {
private long endTime;
private List<TraceNodeInfo> nodes;
private int nodeSize;
private int maxShowNodeSize = Constants.MAX_SHOW_SPAN_SIZE;
private int maxQueryNodeSize = Constants.MAX_SEARCH_SPAN_SIZE;
public TraceTreeInfo(String traceId) {
this.traceId = traceId;
}
public TraceTreeInfo(String traceId, List<TraceNodeInfo> nodes) {
this.traceId = traceId;
this.nodes = nodes;
nodeSize = nodes.size();
}
public void setBeginTime(long beginTime) {
@ -42,15 +51,31 @@ public class TraceTreeInfo {
return nodes;
}
public void setNodes(List<TraceNodeInfo> nodes) {
public void setHasBeenSpiltNodes(List<TraceNodeInfo> nodes) {
this.nodes = nodes;
}
public void setNodeSize(int nodeSize) {
public void setRealNodeSize(int nodeSize) {
this.nodeSize = nodeSize;
}
public int getNodeSize() {
return nodeSize;
}
public int getMaxShowNodeSize() {
return maxShowNodeSize;
}
public void setMaxShowNodeSize(int maxShowNodeSize) {
this.maxShowNodeSize = maxShowNodeSize;
}
public int getMaxQueryNodeSize() {
return maxQueryNodeSize;
}
public void setMaxQueryNodeSize(int maxQueryNodeSize) {
this.maxQueryNodeSize = maxQueryNodeSize;
}
}

View File

@ -1,6 +1,6 @@
package com.ai.cloud.skywalking.web.entity;
import com.ai.cloud.skywalking.web.bo.ConfigArgs;
import com.ai.cloud.skywalking.web.dto.ConfigArgs;
import java.sql.Timestamp;

View File

@ -1,6 +1,6 @@
package com.ai.cloud.skywalking.web.entity;
import com.ai.cloud.skywalking.web.bo.ConfigArgs;
import com.ai.cloud.skywalking.web.dto.ConfigArgs;
import java.sql.Timestamp;

View File

@ -1,27 +1,30 @@
package com.ai.cloud.skywalking.web.entity;
import java.util.ArrayList;
import java.util.List;
import com.ai.cloud.skywalking.web.dto.AnlyResult;
import java.util.HashMap;
import java.util.Map;
/**
* Created by xin on 16-4-6.
*/
public class CallChainTree {
private String treeId;
private List<CallChainTreeNode> nodes;
private String entranceViewpoint;
private Map<String, String> nodes;
private AnlyResult entranceAnlyResult;
public CallChainTree(String treeId) {
public CallChainTree(String treeId, String entranceViewpoint) {
this.treeId = treeId;
nodes = new ArrayList<CallChainTreeNode>();
this.entranceViewpoint = entranceViewpoint;
nodes = new HashMap<String, String>();
}
public void addNode(String levelId, String viewpoint) {
if ("0".equals(levelId)) {
entranceViewpoint = viewpoint;
}
public void setEntranceAnlyResult(AnlyResult entranceAnlyResult) {
this.entranceAnlyResult = entranceAnlyResult;
}
nodes.add(new CallChainTreeNode(levelId, viewpoint));
public void addNodes(Map<String, String> nodes) {
this.nodes.putAll(nodes);
}
}

View File

@ -12,4 +12,8 @@ public class CallChainTreeNode {
this.traceLevelId = traceLevelId;
this.viewPoint = viewpoint;
}
public String getTraceLevelId() {
return traceLevelId;
}
}

View File

@ -1,7 +1,7 @@
package com.ai.cloud.skywalking.web.filter;
import com.ai.cloud.skywalking.web.util.Constants;
import com.ai.cloud.skywalking.web.bo.LoginUserInfo;
import com.ai.cloud.skywalking.web.dto.LoginUserInfo;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;

View File

@ -1,5 +1,6 @@
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.entity.CallChainTree;
@ -12,7 +13,6 @@ import org.springframework.stereotype.Service;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
@Service
@ -28,16 +28,24 @@ public class CallChainTreeService implements ICallChainTreeService {
@Override
public List<CallChainTree> queryCurrentMonthCallChainTree(String uid, String viewpoint) throws SQLException, IOException {
List<String> chainTreeIds = iChainDetailDao.queryChainTreeIds(uid,viewpoint);
logger.info("viewpoint key :{}, chainTreeIds : {}", viewpoint, chainTreeIds);
List<HitTreeInfo> hitTreeInfos = iChainDetailDao.queryChainTreeIds(uid, viewpoint);
for (HitTreeInfo hitTreeInfo : hitTreeInfos) {
hitTreeInfo.guessLevelIdAndSearchViewPoint(iChainDetailDao);
}
logger.info("viewpoint key :{}, chainTreeIds : {}", viewpoint, hitTreeInfos);
List<CallChainTree> callChainTrees = new ArrayList<CallChainTree>();
Calendar calendar = Calendar.getInstance();
String monthSuffix = "/" + calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) + 1);
for (String treeId : chainTreeIds) {
CallChainTree chainTree = chainTreeDao.queryTreeId(treeId + monthSuffix);
if (chainTree == null) {
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());

View File

@ -1,15 +1,20 @@
package com.ai.cloud.skywalking.web.service.impl;
import com.ai.cloud.skywalking.web.bo.TraceNodeInfo;
import com.ai.cloud.skywalking.web.bo.TraceTreeInfo;
import com.ai.cloud.skywalking.web.dao.inter.ITraceNodeDao;
import com.ai.cloud.skywalking.web.dto.TraceNodeInfo;
import com.ai.cloud.skywalking.web.dto.TraceNodesResult;
import com.ai.cloud.skywalking.web.dto.TraceTreeInfo;
import com.ai.cloud.skywalking.web.service.inter.ITraceTreeService;
import com.ai.cloud.skywalking.web.util.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Created by xin on 16-3-30.
@ -22,13 +27,21 @@ public class TraceTreeService implements ITraceTreeService {
@Override
public TraceTreeInfo queryTraceTreeByTraceId(String traceId) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, IOException {
TraceTreeInfo traceTreeInfo = new TraceTreeInfo(traceId);
TraceNodesResult traceNodesResult = traceTreeDao.queryTraceNodesByTraceId(traceId);
List<TraceNodeInfo> traceNodeInfoList = traceNodesResult.getResult();
if (traceNodesResult.isOverMaxQueryNodeNumber()) {
traceNodeInfoList = new ArrayList<TraceNodeInfo>();
traceNodeInfoList.addAll(traceTreeDao.queryEntranceNodeByTraceId(traceId));
traceTreeInfo.setRealNodeSize(Constants.MAX_SEARCH_SPAN_SIZE + 1);
}else{
traceTreeInfo.setRealNodeSize(traceNodeInfoList.size());
}
TraceTreeInfo traceTreeInfo = traceTreeDao.queryTraceNodesByTraceId(traceId);
if (traceTreeInfo != null) {
List<TraceNodeInfo> nodes = traceTreeInfo.getNodes();
if (traceNodeInfoList.size() > 0){
final List<Long> endTime = new ArrayList<Long>();
endTime.add(0, nodes.get(0).getEndDate());
Collections.sort(nodes, new Comparator<TraceNodeInfo>() {
endTime.add(0, traceNodeInfoList.get(0).getEndDate());
Collections.sort(traceNodeInfoList, new Comparator<TraceNodeInfo>() {
@Override
public int compare(TraceNodeInfo arg0, TraceNodeInfo arg1) {
if (endTime.get(0) < arg0.getEndDate()) {
@ -40,8 +53,14 @@ public class TraceTreeService implements ITraceTreeService {
return arg0.getColId().compareTo(arg1.getColId());
}
});
long beginTime = nodes.get(0).getStartDate();
traceTreeInfo.setBeginTime(beginTime);
// 截断
int subIndex = traceNodeInfoList.size();
if (subIndex > Constants.MAX_SHOW_SPAN_SIZE){
subIndex = Constants.MAX_SHOW_SPAN_SIZE;
}
traceTreeInfo.setHasBeenSpiltNodes(traceNodeInfoList.subList(0, subIndex));
traceTreeInfo.setBeginTime(traceNodeInfoList.get(0).getStartDate());
traceTreeInfo.setEndTime(endTime.get(0));
}

View File

@ -1,6 +1,6 @@
package com.ai.cloud.skywalking.web.service.inter;
import com.ai.cloud.skywalking.web.bo.TraceTreeInfo;
import com.ai.cloud.skywalking.web.dto.TraceTreeInfo;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

View File

@ -41,4 +41,8 @@ public class Constants {
put("9", "MISSING");
}
};
public static int MAX_SEARCH_SPAN_SIZE = 10000;
public static int MAX_SHOW_SPAN_SIZE = 200;
}

View File

@ -3,7 +3,7 @@
*/
package com.ai.cloud.skywalking.web.util;
import com.ai.cloud.skywalking.web.bo.TraceNodeInfo;
import com.ai.cloud.skywalking.web.dto.TraceNodeInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

View File

@ -15,6 +15,9 @@ function changeData(data) {
result.traceTree.startTime = data.beginTime;
result.traceTree.endTime = data.endTime;
result.traceTree.totalSize = data.nodeSize;
result.traceTree.showSize = data.nodes.length;
result.traceTree.maxShowNodeSize = data.maxShowNodeSize;
result.traceTree.maxQueryNodeSize = data.maxQueryNodeSize;
result.traceTree.startTimeStr = convertDate(new Date(result.traceTree.startTime));
result.traceTree.callIP = data.nodes[0].address;
var tmpNode;

View File

@ -1,54 +1,25 @@
<#import "../common/commons.ftl" as common>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<@common.importResources />
<script src="${_base}/bower_components/jsrender/jsrender.min.js"></script>
<script src="${_base}/bower_components/jquery-ui/jquery-ui.min.js"></script>
<link href="${_base}/bower_components/jquery-treetable/css/jquery.treetable.css" rel="stylesheet" type="text/css"/>
<link rel="stylesheet" href="${base}/bower_components/jquery-treetable/css/jquery.treetable.theme.default.css"/>
<script src="${_base}/bower_components/jquery-treetable/jquery.treetable.js"></script>
<link href="${_base}/bower_components/jquery-treetable/css/jquery.treetable.css" rel="stylesheet"/>
<link href="${_base}/bower_components/skywalking/css/tracelog.css" rel="stylesheet"/>
<script src="${_base}/bower_components/skywalking/js/tracelog.js"></script>
</head>
<body style="padding-top:80px">
<@common.navbar/>
<div class="container" id="mainPanel">
<div class="row">
<div class="col-md-9">
<#macro analysisResult>
<script type="text/x-jsrender" id="analysisResultList">
<div class="row">
<div class="col-md-9">
{{for trees}}
<div class="row">
<h4><a>{{>entranceViewpoint}}</a></h4>
<p>{{>entranceViewpoint}}<br/>
&nbsp;&nbsp;com.ai.test.controller.com.ai.test.controllersaveOrder()<br/>
&nbsp;&nbsp;&nbsp;&nbsp;com.ai.test.controller.saveOrder()<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; com.ai.test.controller.saveOrder()<br/>
&nbsp;&nbsp;com.ai.test.controller.saveOrder()<br/>
....
</p>
<p style="font-color">2016年03月已经被调用100次成功100次失败0次 <a class="pull-right"><ins>more</ins></a></p>
<hr/>
</div>
<div class="col-md-3">
{{/for}}
</div>
<div class="col-md-3">
</div>
</div>
</div>
<script>
function loadAnalysisResult(){
var url = "${_base}/usr/doLogout";
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
async: true,
success: function (data) {
if (data.code == '200') {
location.href = "${_base}/index";
}
},
error: function () {
$("#errorMessage").text("Fatal Error, please try it again.");
$("#alertMessageBox").show();
}
});
}
</script>
</body>
</html>
</#macro>

View File

@ -60,10 +60,6 @@
</div>
</nav>
<script>
$("#searchBtn").click(function () {
loadTraceTreeData("${_base}");
});
$("#logoutBtn").click(function () {
var url = "${_base}/usr/doLogout";
$.ajax({

View File

@ -75,6 +75,26 @@
</td>
</tr>
{{/for}}
{{if totalSize > maxQueryNodeSize}}
<tr data-tt-parent-id='0' data-tt-id="greatThanMaxQueryNodeSize">
<td>....</td>
<td>....</td>
<td>....</td>
<td style="text-align:center;color:green;">该调用链超过{{>maxQueryNodeSize}}个节点仅展现调用入口具体调用情况可查询HBase</td>
<td>....</td>
<td>....</td>
</tr>
{{/if}}
{{if totalSize > maxShowNodeSize && totalSize <= maxQueryNodeSize}}
<tr data-tt-parent-id='0' data-tt-id="greatThanMaxShowNodeSize">
<td>....</td>
<td>....</td>
<td>....</td>
<td style="text-align:center;color:green;">该调用链共{{>totalSize}}个调用节点,已超过最大展示节点数({{>maxShowNodeSize}}个),仅展现前{{>showSize}}个节点的缩略图</td>
<td>....</td>
<td>....</td>
</tr>
{{/if}}
</tbody>
</table>
</script>
@ -125,7 +145,14 @@
<div class="row">
<h5>
{{>traceId}}</br>
调度入口IP{{>callIP}},开始时间:{{>startTimeStr}}{{if totalSize > 10000}}<strong>调用记录大于10000条无法展示全部</strong>{{else}}{{>totalSize}}条调用记录,{{/if}}消耗总时长:{{>totalTime}}ms。
调度入口IP{{>callIP}},开始时间:{{>startTimeStr}}
{{if totalSize > maxQueryNodeSize}}
调用超过{{>maxQueryNodeSize}}个节点,仅展示入口调用,
{{else totalSize > maxShowNodeSize}}
共{{>totalSize}}个调用节点,仅展示前{{>showSize}}个调用节点,
{{else}}
{{>totalSize}}个调用节点,
{{/if}}消耗总时长:{{>totalTime}}ms。
</h5>
</div>
<ul id="myTab" class="nav nav-tabs">