提交 2f3917d7 编写于 作者: L lizl9

Merge remote-tracking branch 'refs/remotes/origin/master' into lzLee-dev

### 通过服务器日志的Server Health Collector Report分析运行情况
- Health Report会在服务器定时出现,报告在两次报告时间段内的运行情况
1. ServerReceiver反映服务端接收数据的情况
1. DataBufferThread反映接收到的数据,异步写入log文件的情况
1. PersistenceThread反映log文件中的内容读取情况
1. PersistenceThread extra:hbase反映log文件中的内容,持久化到hbase的情况
1. RedisInspectorThread反映和redis的连接池检测情况
- Health Report示例如下
```
---------Server Health Collector Report---------
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:DataBufferThread_0(27)>
[INFO]DataBuffer flush data to local file:1460445849010-a4ea1e20927b40d290ebd4f5f3e08705(t:1460598787106)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:DataBufferThread_1(28)>
[INFO]DataBuffer flush data to local file:1460445849012-0ec5a44474bc4969a9194fa1b1cadf73(t:1460598848608)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:DataBufferThread_2(29)>
[INFO]DataBuffer flush data to local file:1460445849012-4182e3d0205e48968b59fe9fbb0923b4(t:1460598668464)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:DataBufferThread_4(31)>
[INFO]DataBuffer flush data to local file:1460445849013-54216553363343fe8b39221a0691cf40(t:1460598788488)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:DataBufferThread_5(32)>
[INFO]DataBuffer flush data to local file:1460445849013-531a955690764a56ac0490db531bec10(t:1460598727104)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:DataBufferThread_6(33)>
[INFO]DataBuffer flush data to local file:1460445849014-e0163d8c8b8446d6812a11e89cd48b0e(t:1460598787722)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:DataBufferThread_7(34)>
[INFO]DataBuffer flush data to local file:1460445849014-340435a1dd9e49f088af039c2e9e85af(t:1460598787510)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:DataBufferThread_8(35)>
[INFO]DataBuffer flush data to local file:1460445849015-5dacc5f6fb38442eb484b50a240568df(t:1460598727508)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_0(15)>
[INFO]read 224 chars from local file:1460445849014-340435a1dd9e49f088af039c2e9e85af(t:1460598787534)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_0(15),extra:hbase>
[INFO]save 1 BuriedPointEntries.(t:1460598787549)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_1(16)>
[INFO]read 268 chars from local file:1460445849013-531a955690764a56ac0490db531bec10(t:1460598727121)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_1(16),extra:hbase>
[INFO]save 1 BuriedPointEntries.(t:1460598727129)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_4(19)>
[INFO]read 238 chars from local file:1460445849013-54216553363343fe8b39221a0691cf40(t:1460598788522)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_4(19),extra:hbase>
[INFO]save 1 BuriedPointEntries.(t:1460598788532)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_5(20)>
[INFO]read 526 chars from local file:1460445849014-e0163d8c8b8446d6812a11e89cd48b0e(t:1460598787770)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_5(20),extra:hbase>
[INFO]save 1 BuriedPointEntries.(t:1460598787775)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_6(21)>
[INFO]read 238 chars from local file:1460445849010-a4ea1e20927b40d290ebd4f5f3e08705(t:1460598787126)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_6(21),extra:hbase>
[INFO]save 1 BuriedPointEntries.(t:1460598787135)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_7(22)>
[INFO]read 583 chars from local file:1460445849012-4182e3d0205e48968b59fe9fbb0923b4(t:1460598668466)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_7(22),extra:hbase>
[INFO]save 1 BuriedPointEntries.(t:1460598668473)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_8(23)>
[INFO]read 819 chars from local file:1460445849015-5dacc5f6fb38442eb484b50a240568df(t:1460598727531)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_8(23),extra:hbase>
[INFO]save 2 BuriedPointEntries.(t:1460598727542)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_9(24)>
[INFO]read 462 chars from local file:1460445849012-0ec5a44474bc4969a9194fa1b1cadf73(t:1460598848648)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:PersistenceThread_9(24),extra:hbase>
[INFO]save 3 BuriedPointEntries.(t:1460598848757)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:RedisInspectorThread(65)>
[INFO]alarm redis connectted.(t:1460598845054)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:RegisterPersistenceThread(14)>
[INFO]flush memory register to file.(t:1460598848748)
id<SkyWalkingServer,M:host-10-1-241-17/61.50.248.117,P:18737,T:ServerReceiver(39)>
[INFO]DataBuffer reveiving data.(t:1460598845300)
------------------------------------------------
```
\ No newline at end of file
......@@ -128,6 +128,7 @@ export SKYWALKING_RUN=true
# QA
- [SkyWalking SDK是否已经工作? Is SkyWalking SDK Running?](QA/IS_RUNNING.md)
- [tid在web-ui上无法查询. tid can't be search on web-ui](QA/TID_CANNOT_BE_SEARCH.md)
- [SkyWalking Server的运行情况. The status of SkyWalking Server](QA/SERVER_RUNNING_STAUTS.md)
# 源代码说明
* [追踪日志明细存储结构说明. the storage structure of tracking logs](skywalking-server/doc/hbase_table_desc.md)
......@@ -55,4 +55,5 @@
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
......@@ -41,8 +41,7 @@ public class DBCallChainInfoDao {
preparedStatement.setString(1, callChainDetailForMysql.getTreeToken());
preparedStatement.setString(2, callChainDetailForMysql.getUserId());
preparedStatement.setString(3, chainNode.getTraceLevelId());
preparedStatement.setString(4, chainNode.getViewPoint() + ":"
+ chainNode.getBusinessKey());
preparedStatement.setString(4, chainNode.getViewPoint());
preparedStatement.setTimestamp(5,
new Timestamp(System.currentTimeMillis()));
preparedStatement.addBatch();
......
......@@ -89,24 +89,31 @@ public class SpanEntry {
return serverSpan.getBusinessKey();
}
public void setBusinessKey(String businessKey) {
if (clientSpan != null) {
clientSpan.setBusinessKey(businessKey);
}
serverSpan.setBusinessKey(businessKey);
}
public ChainNode.NodeStatus getSpanStatus() {
if (clientSpan != null) {
if (clientSpan.getExceptionStack() != null && clientSpan.getExceptionStack().length() > 0) {
if(clientSpan.getStatusCode() == 1){
return ChainNode.NodeStatus.ABNORMAL;
}else{
return ChainNode.NodeStatus.HUMAN_INTERRUPTION;
}
if (clientSpan.getStatusCode() == 1) {
return ChainNode.NodeStatus.ABNORMAL;
} else {
return ChainNode.NodeStatus.HUMAN_INTERRUPTION;
}
}
}
if (serverSpan != null) {
if (serverSpan.getExceptionStack() != null && serverSpan.getExceptionStack().length() > 0) {
if(clientSpan != null && clientSpan.getStatusCode() == 1){
return ChainNode.NodeStatus.ABNORMAL;
}else{
return ChainNode.NodeStatus.HUMAN_INTERRUPTION;
}
if (clientSpan != null && clientSpan.getStatusCode() == 1) {
return ChainNode.NodeStatus.ABNORMAL;
} else {
return ChainNode.NodeStatus.HUMAN_INTERRUPTION;
}
}
}
......
......@@ -81,7 +81,7 @@ public class CallChainTreeNode {
}
chainNodeSpecificMonthSummaryContainer.put(keyOfMonthSummaryTable, monthSummary);
}
monthSummary.summary(String.valueOf(calendar.get(Calendar.YEAR)), node);
monthSummary.summary(String.valueOf(calendar.get(Calendar.MONTH) + 1), node);
}
private void summaryDayResult(String treeId, ChainNode node, Calendar calendar) throws IOException {
......
......@@ -29,11 +29,11 @@ public class ChainNodeSpecificMonthSummary {
summaryValueMap = new HashMap<String, ChainNodeSpecificTimeWindowSummaryValue>();
}
public void summary(String minute, ChainNode node) {
ChainNodeSpecificTimeWindowSummaryValue summarValue = summaryValueMap.get(minute);
public void summary(String month, ChainNode node) {
ChainNodeSpecificTimeWindowSummaryValue summarValue = summaryValueMap.get(month);
if (summarValue == null) {
summarValue = new ChainNodeSpecificTimeWindowSummaryValue();
summaryValueMap.put(minute, summarValue);
summaryValueMap.put(month, summarValue);
}
summarValue.summary(node);
......
package com.ai.cloud.skywalking.analysis.chainbuild.filter.impl;
import com.ai.cloud.skywalking.analysis.chainbuild.SpanEntry;
import com.ai.cloud.skywalking.analysis.chainbuild.filter.SpanNodeProcessFilter;
import com.ai.cloud.skywalking.analysis.chainbuild.po.ChainNode;
import com.ai.cloud.skywalking.analysis.chainbuild.util.SubLevelSpanCostCounter;
public class JDBCBusinessKeyHandleFilter extends SpanNodeProcessFilter {
@Override
public void doFilter(SpanEntry spanEntry, ChainNode node, SubLevelSpanCostCounter costMap) {
String businessKey = spanEntry.getBusinessKey();
if (businessKey != null) {
int index = businessKey.lastIndexOf(":");
if (index != -1) {
businessKey = businessKey.substring(index + 1).trim();
String key = businessKey.toUpperCase();
if (key.startsWith("SELECT")) {
businessKey = subBusinessKey(businessKey, key, "WHERE");
} else if (key.startsWith("UPDATE")) {
businessKey = subBusinessKey(businessKey, key, "SET");
} else if (key.startsWith("DELETE")) {
businessKey = subBusinessKey(businessKey, key, "WHERE");
} else if (key.startsWith("INSERT")) {
businessKey = subBusinessKey(businessKey, key, "VALUES");
}
}
}
spanEntry.setBusinessKey(businessKey);
this.doNext(spanEntry, node, costMap);
}
private String subBusinessKey(String businessKey, String key,String keyWord) {
int whereIndex = key.indexOf(keyWord);
if (whereIndex != -1) {
businessKey = businessKey.substring(0, whereIndex - 1).trim();
}
return businessKey;
}
}
#
default=CopyAttrFilter->ReplaceAddressFilter->ProcessCostTimeFilter->TokenGenerateFilter
J=CopyAttrFilter->AppendBusinessKeyFilter->ProcessCostTimeFilter->TokenGenerateFilter
J=CopyAttrFilter->JDBCBusinessKeyHandleFilter->AppendBusinessKeyFilter->ProcessCostTimeFilter->TokenGenerateFilter
......@@ -5,31 +5,42 @@ import static com.ai.cloud.skywalking.conf.Config.BuriedPoint.EXCLUSIVE_EXCEPTIO
import java.util.HashSet;
import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.ai.cloud.skywalking.api.IExceptionHandler;
import com.ai.cloud.skywalking.conf.Config;
import com.ai.cloud.skywalking.context.Context;
import com.ai.cloud.skywalking.protocol.Span;
public class ApplicationExceptionHandler implements IExceptionHandler {
private static Logger logger = LogManager
.getLogger(ApplicationExceptionHandler.class);
private static String EXCEPTION_SPLIT = ",";
private static Set<String> exclusiveExceptionSet = null;
@Override
public void handleException(Throwable th) {
if (exclusiveExceptionSet == null) {
Set<String> exclusiveExceptions = new HashSet<String>();
String[] exceptions = EXCLUSIVE_EXCEPTIONS.split(EXCEPTION_SPLIT);
for(String exception : exceptions){
exclusiveExceptions.add(exception);
try {
if (exclusiveExceptionSet == null) {
Set<String> exclusiveExceptions = new HashSet<String>();
String[] exceptions = EXCLUSIVE_EXCEPTIONS
.split(EXCEPTION_SPLIT);
for (String exception : exceptions) {
exclusiveExceptions.add(exception);
}
exclusiveExceptionSet = exclusiveExceptions;
}
exclusiveExceptionSet = exclusiveExceptions;
}
Span span = Context.getLastSpan();
span.handleException(th, exclusiveExceptionSet,
Config.BuriedPoint.MAX_EXCEPTION_STACK_LENGTH);
Span span = Context.getLastSpan();
span.handleException(th, exclusiveExceptionSet,
Config.BuriedPoint.MAX_EXCEPTION_STACK_LENGTH);
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
}
}
......@@ -14,42 +14,57 @@ import com.ai.cloud.skywalking.model.Identification;
import com.ai.cloud.skywalking.protocol.Span;
import com.ai.cloud.skywalking.util.ContextGenerator;
public class LocalBuriedPointSender extends ApplicationExceptionHandler implements IBuriedPointSender {
private static Logger logger = LogManager.getLogger(LocalBuriedPointSender.class);
public ContextData beforeSend(Identification id) {
if (!AuthDesc.isAuth())
return new EmptyContextData();
Span spanData = ContextGenerator.generateSpanFromThreadLocal(id);
// 将新创建的Context存放到ThreadLocal栈中。
Context.append(spanData);
// 并将当前的Context返回回去
return new ContextData(spanData);
}
public void afterSend() {
if (!AuthDesc.isAuth())
return;
// 弹出上下文的栈顶中的元素
Span spanData = Context.removeLastSpan();
if (spanData == null) {
return;
}
// 加上花费时间
spanData.setCost(System.currentTimeMillis() - spanData.getStartDate());
if (Config.BuriedPoint.PRINTF) {
logger.debug("TraceId:" + spanData.getTraceId() + "\tviewpointId:" + spanData.getViewPointId() + "\tParentLevelId:" + spanData.
getParentLevel() + "\tLevelId:" + spanData.getLevelId() + "\tbusinessKey:" + spanData.getBusinessKey());
}
// 存放到本地发送进程中
if (!Config.Sender.IS_OFF) {
ContextBuffer.save(spanData);
}
}
public class LocalBuriedPointSender extends ApplicationExceptionHandler
implements IBuriedPointSender {
private static Logger logger = LogManager
.getLogger(LocalBuriedPointSender.class);
public ContextData beforeSend(Identification id) {
try {
if (!AuthDesc.isAuth())
return new EmptyContextData();
Span spanData = ContextGenerator.generateSpanFromThreadLocal(id);
// 将新创建的Context存放到ThreadLocal栈中。
Context.append(spanData);
// 并将当前的Context返回回去
return new ContextData(spanData);
} catch (Throwable t) {
logger.error(t.getMessage(), t);
return new EmptyContextData();
}
}
public void afterSend() {
try {
if (!AuthDesc.isAuth())
return;
// 弹出上下文的栈顶中的元素
Span spanData = Context.removeLastSpan();
if (spanData == null) {
return;
}
// 加上花费时间
spanData.setCost(System.currentTimeMillis()
- spanData.getStartDate());
if (Config.BuriedPoint.PRINTF) {
logger.debug("TraceId:" + spanData.getTraceId()
+ "\tviewpointId:" + spanData.getViewPointId()
+ "\tParentLevelId:" + spanData.getParentLevel()
+ "\tLevelId:" + spanData.getLevelId()
+ "\tbusinessKey:" + spanData.getBusinessKey());
}
// 存放到本地发送进程中
if (!Config.Sender.IS_OFF) {
ContextBuffer.save(spanData);
}
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
}
}
......@@ -13,35 +13,49 @@ import com.ai.cloud.skywalking.model.Identification;
import com.ai.cloud.skywalking.protocol.Span;
import com.ai.cloud.skywalking.util.ContextGenerator;
public class RPCBuriedPointReceiver extends ApplicationExceptionHandler implements IBuriedPointReceiver {
private static Logger logger = LogManager.getLogger(RPCBuriedPointReceiver.class);
public void afterReceived() {
if (!AuthDesc.isAuth())
return;
// 获取上下文的栈顶中的元素
Span spanData = Context.removeLastSpan();
// 填上必要信息
spanData.setCost(System.currentTimeMillis() - spanData.getStartDate());
// 存放到本地发送进程中
ContextBuffer.save(spanData);
}
public void beforeReceived(ContextData context, Identification id) {
if (!AuthDesc.isAuth())
return;
Span spanData = ContextGenerator.generateSpanFromContextData(context, id);
//设置是否为接收端
spanData.setReceiver(true);
if (Config.BuriedPoint.PRINTF) {
logger.debug("TraceId:" + spanData.getTraceId() + "\tviewpointId:" + spanData.getViewPointId() + "\tParentLevelId:" + spanData.
getParentLevel() + "\tLevelId:" + spanData.getLevelId());
}
Context.append(spanData);
}
public class RPCBuriedPointReceiver extends ApplicationExceptionHandler
implements IBuriedPointReceiver {
private static Logger logger = LogManager
.getLogger(RPCBuriedPointReceiver.class);
public void afterReceived() {
try {
if (!AuthDesc.isAuth())
return;
// 获取上下文的栈顶中的元素
Span spanData = Context.removeLastSpan();
// 填上必要信息
spanData.setCost(System.currentTimeMillis()
- spanData.getStartDate());
// 存放到本地发送进程中
ContextBuffer.save(spanData);
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
}
public void beforeReceived(ContextData context, Identification id) {
try {
if (!AuthDesc.isAuth())
return;
Span spanData = ContextGenerator.generateSpanFromContextData(
context, id);
// 设置是否为接收端
spanData.setReceiver(true);
if (Config.BuriedPoint.PRINTF) {
logger.debug("TraceId:" + spanData.getTraceId()
+ "\tviewpointId:" + spanData.getViewPointId()
+ "\tParentLevelId:" + spanData.getParentLevel()
+ "\tLevelId:" + spanData.getLevelId());
}
Context.append(spanData);
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
}
}
......@@ -15,7 +15,13 @@ import com.ai.cloud.skywalking.protocol.Span;
import com.ai.cloud.skywalking.util.BuriedPointMachineUtil;
import com.ai.cloud.skywalking.util.TraceIdGenerator;
/**
* 暂不确定多线程的实现方式
*
* @author wusheng
*
*/
@Deprecated
public class ThreadBuriedPointSender extends ApplicationExceptionHandler implements IBuriedPointSender {
private static Logger logger = LogManager.getLogger(ThreadBuriedPointSender.class);
......
......@@ -14,6 +14,13 @@ import com.ai.cloud.skywalking.model.Identification;
import com.ai.cloud.skywalking.protocol.Span;
import com.ai.cloud.skywalking.util.ContextGenerator;
/**
* 暂不确定多线程的实现方式
*
* @author wusheng
*
*/
@Deprecated
public class ThreadFactoryBuriedPointSender extends ApplicationExceptionHandler implements IBuriedPointSender {
private static Logger logger = LogManager.getLogger(ThreadBuriedPointSender.class);
......
......@@ -7,10 +7,10 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>skywalking-httpClient-4.2.x-plugin</artifactId>
<artifactId>skywalking-httpclient-4.2.x-plugin</artifactId>
<packaging>jar</packaging>
<name>httpClient-4.2.x-plugin</name>
<name>httpclient-4.2.x-plugin</name>
<url>http://maven.apache.org</url>
<properties>
......
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>skywalking-sdk-plugin</artifactId>
<groupId>com.ai.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>skywalking-sdk-plugin</artifactId>
<groupId>com.ai.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>skywalking-spring-plugin</artifactId>
<packaging>jar</packaging>
<artifactId>skywalking-spring-plugin</artifactId>
<packaging>jar</packaging>
<name>spring-plugin</name>
<url>http://maven.apache.org</url>
<name>spring-plugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.0.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-auth</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.2.0.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.9.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
<scope>test</scope>
</dependency>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.4.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.0.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-auth</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.2.0.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.9.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
......@@ -93,24 +99,24 @@
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
<!-- 源码插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<!-- 发布时自动将源码同时发布的配置 -->
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
<!-- 源码插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<!-- 发布时自动将源码同时发布的配置 -->
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
......@@ -9,19 +9,7 @@ public class TracingAspect {
public Object doTracing(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
LocalBuriedPointSender _sender = new LocalBuriedPointSender();
try {
StringBuilder viewPoint = new StringBuilder();
viewPoint.append(proceedingJoinPoint.getTarget().getClass().getName() + "." + proceedingJoinPoint.getSignature().getName() + "(");
boolean first = true;
for (Object arg : proceedingJoinPoint.getArgs()) {
if (!first) {
viewPoint.append(",");
} else {
first = false;
}
viewPoint.append(arg.getClass().getName());
}
viewPoint.append(")");
_sender.beforeSend(Identification.newBuilder().viewPoint(viewPoint.toString()).spanType(SpringBuriedPointType.instance()).build());
_sender.beforeSend(Identification.newBuilder().viewPoint(proceedingJoinPoint.getSignature().toString()).spanType(SpringBuriedPointType.instance()).build());
return proceedingJoinPoint.proceed();
} catch (Throwable e) {
_sender.handleException(e);
......
......@@ -5,7 +5,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
//@Transactional
public class TestBean/* implements TestInterface*/ {
private String value;
......
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%t](%F:%L) %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console" />
</Root>
<logger name="com.ai.cloud.skywalking" level="debug">
<AppenderRef ref="Console" />
</logger>
</Loggers>
</Configuration>
\ No newline at end of file
#skyWalking用户ID
skywalking.user_id=123
#skyWalking应用编码
skywalking.application_code=test
#skywalking auth的环境变量名字
skywalking.auth_system_env_name=SKYWALKING_RUN
#skywalking数据编码
skywalking.charset=UTF-8
#是否打印数据
buriedpoint.printf=true
#埋点异常的最大长度
buriedpoint.max_exception_stack_length=4000
#业务字段的最大长度
buriedpoint.businesskey_max_length=300
#过滤异常
buriedpoint.exclusive_exceptions=java.lang.RuntimeException
#最大发送者的连接数阀比例
sender.connect_percent=100
#发送服务端配置
sender.servers_addr=127.0.0.1:34000
#最大发送的副本数量
sender.max_copy_num=2
#发送的最大长度
sender.max_send_length=20000
#当没有Sender时,尝试获取sender的等待周期
sender.retry_get_sender_wait_interval=2000
#是否开启发送消息
sender.is_off=false
#最大消费线程数
consumer.max_consumer=2
#消费者最大等待时间
consumer.max_wait_time=5
#发送失败等待时间
consumer.consumer_fail_retry_wait_interval=50
#每个Buffer的最大个数
buffer.buffer_max_size=18000
#Buffer池的最大长度
buffer.pool_size=5
#发送检查线程检查周期
senderchecker.check_polling_time=200
......@@ -82,12 +82,6 @@
<artifactId>log4j-1.2-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
......
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;
......
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;
......
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;
......
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;
......
......@@ -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";
}
}
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.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.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;
......@@ -17,6 +20,7 @@ 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 org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
......@@ -47,9 +51,9 @@ public class SearchController extends BaseController {
return "";
}
@RequestMapping(value = "/search/traceId/{traceId:.+}", produces = "application/json; charset=UTF-8")
@RequestMapping(value = "/search/traceId", produces = "application/json; charset=UTF-8")
@ResponseBody
public String loadTraceTree(@PathVariable("traceId") String traceId) {
public String loadTraceTree(@RequestParam("traceId") String traceId) {
JSONObject jsonObject = new JSONObject();
try {
if (StringUtil.isBlank(traceId)) {
......@@ -67,6 +71,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");
}
......@@ -79,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)) {
......@@ -97,9 +102,19 @@ public class SearchController extends BaseController {
LoginUserInfo loginUserInfo = fetchLoginUserInfoFromSession(request);
List<CallChainTree> callChainTreeList =
callChainTreeService.queryCurrentMonthCallChainTree(loginUserInfo.getUid(), key);
callChainTreeService.queryCallChainTreeByKey(loginUserInfo.getUid(), key, pageSize);
//List<CallChainTree> 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");
......@@ -108,4 +123,29 @@ public class SearchController extends BaseController {
return jsonObject.toJSONString();
}
private List<CallChainTree> generateCallChainTree() {
List<CallChainTree> callChainTrees = new ArrayList<CallChainTree>();
CallChainTree chainTree = new CallChainTree("test");
chainTree.setEntranceViewpoint("test");
chainTree.setTreeId("test tree id");
List<CallChainNode> 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;
}
}
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;
......
......@@ -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;
......
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;
......
package com.ai.cloud.skywalking.web.dao.impl;
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;
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;
import java.io.IOException;
import java.util.Calendar;
import java.util.Map;
@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 {
Table table = hBaseUtils.getConnection().getTable(TableName.valueOf("sw-chain-1day-summary"));
public AnlyResult queryEntranceAnlyResult(String entranceColumnName, String treeId) throws IOException {
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) + "");
}
AnlyResult anlyResult = null;
Cell cell = result.getColumnLatestCell("chain_summary".getBytes(), columnName.getBytes());
if (cell != null) {
String anlyResultStr = Bytes.toString(cell.getValueArray(),
cell.getValueOffset(), cell.getValueLength());
logger.debug("traceId: {} , entranceColumnName : {}, anlyResultStr : {}",
treeId, columnName, anlyResultStr);
JsonObject jsonObject = (JsonObject) new JsonParser().parse(anlyResultStr);
Map<String, AnlyResult> resultMap = new Gson().fromJson(jsonObject.getAsJsonObject("summaryValueMap"),
new TypeToken<Map<String, AnlyResult>>() {
}.getType());
anlyResult = resultMap.get((Calendar.getInstance().get(Calendar.MONTH)+1) + "");
}
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]);
}
if(anlyResult == null){
anlyResult = new AnlyResult();
}
return null;
anlyResult.setYearOfAnlyResult((Calendar.getInstance().get(Calendar.YEAR)) + "");
anlyResult.setMonthOfAnlyResult((Calendar.getInstance().get(Calendar.MONTH)+1) + "");
return anlyResult;
}
}
package com.ai.cloud.skywalking.web.dao.impl;
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;
......@@ -12,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 {
......@@ -23,18 +27,77 @@ 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, int pageSize) throws SQLException {
List<HitTreeInfo> hitTreeInfos = new ArrayList<HitTreeInfo>();
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);
Map<String, String> result = queryChainTreeId(uid, hitTreeInfo.getTreeId(), viewpoint);
for (Map.Entry<String, String> entry : result.entrySet()) {
hitTreeInfo.addHitTraceLevelId(entry.getKey(), entry.getValue());
}
hitTreeInfos.add(hitTreeInfo);
}
} 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();
}
}
logger.info("hitTreeInfos : {}", hitTreeInfos.size());
return hitTreeInfos;
}
private Map<String, String> queryChainTreeId(String uid, String treeId, String viewpoint) throws SQLException {
Map<String, String> result = new HashMap<String, String>();
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()) {
treeIds.add(resultSet.getString("treeId"));
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;
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);
......@@ -44,6 +107,7 @@ public class ChainDetailDao implements IChainDetailDao {
connection.close();
}
}
return treeIds;
return viewpoint;
}
}
package com.ai.cloud.skywalking.web.dao.impl;
import com.ai.cloud.skywalking.web.bo.TraceNodeInfo;
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,12 +12,14 @@ 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.filter.ColumnCountGetFilter;
import org.apache.hadoop.hbase.util.Bytes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
......@@ -33,28 +36,60 @@ public class TraceNodeDao implements ITraceNodeDao {
@Override
public Map<String, TraceNodeInfo> queryTraceNodesByTraceId(String traceId) throws IOException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
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(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>();
for (Cell cell : r.rawCells()) {
if (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);
}
TraceNodesResult result = new TraceNodesResult();
if (r.rawCells().length < Constants.MAX_SEARCH_SPAN_SIZE) {
for (Cell cell : r.rawCells()) {
doDealSingleSpan(traceLogMap, rpcMap, cell);
}
computeRPCInfo(rpcMap, traceLogMap);
result.setOverMaxQueryNodeNumber(false);
result.setResult(traceLogMap.values());
}else{
result.setOverMaxQueryNodeNumber(true);
}
return result;
}
@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;
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);
}
}
}
private void computeRPCInfo(Map<String, TraceNodeInfo> rpcMap, Map<String, TraceNodeInfo> traceLogMap) {
......
......@@ -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;
......
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;
......
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;
}
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, int pageSize) throws SQLException;
String queryChainViewPoint(String traceLevelId, String treeId, String uid) throws SQLException;
}
package com.ai.cloud.skywalking.web.dao.inter;
import com.ai.cloud.skywalking.web.bo.TraceNodeInfo;
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 {
Map<String, TraceNodeInfo> 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;
}
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;
......
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.web.entity.AlarmRule;
......
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;
private long humanInterruptionNumber;
public long getTotalCall() {
return totalCall;
}
public long getTotalCostTime() {
return totalCostTime;
}
public long getCorrectNumber() {
return correctNumber;
}
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;
}
}
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.web.entity.Application;
......
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;
}
}
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.*;
/**
* 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);
result[1] = levelId.substring(indexOf + 1);
return result;
}
public String getCurrentMonthAnlyTableName() {
Calendar calendar = Calendar.getInstance();
String monthSuffix = "/" + calendar.get(Calendar.YEAR);
return getTreeId() + monthSuffix;
}
public void setEntranceViewPoint(String entranceViewPoint) {
this.entranceViewPoint = entranceViewPoint;
}
public String getEntranceViewPoint() {
return entranceViewPoint;
}
public void guessLevelIdAndSearchViewPoint(IChainDetailDao iChainDetailDao) throws SQLException {
Set<String> 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;
Set<String> leveIds = new HashSet<String>();
leveIds.addAll(hitTraceLevelId.keySet());
for (String levelId : leveIds) {
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, levelId);
//找下级
guessNextTraceLevelId(iChainDetailDao, levelId);
}
}
logger.debug("hitTraceLevelId : {}", hitTraceLevelId);
}
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);
if (tmpViewpoint == null) {
traceLevelId = getBrotherOfParentLevelId(levelId);
if (traceLevelId.length() > 0)
tmpViewpoint = iChainDetailDao.queryChainViewPoint(traceLevelId, treeId, uid);
}
if (tmpViewpoint != null) {
addHitTraceLevelId(traceLevelId, tmpViewpoint);
}
}
private void guessPreTraceLevelId(IChainDetailDao iChainDetailDao, String levelId) throws SQLException {
String tmpViewpoint = null;
String traceLevelId = null;
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 {
if (result[0].length() > 0) {
traceLevelId = result[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 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 levelId) {
String[] result = spiltParentLevelIdAndLevelId(levelId);
return result[0] + "." + (Integer.parseInt(result[1]) + 1);
}
public String getUid() {
return uid;
}
}
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.web.entity.UserInfo;
......
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import java.io.Serializable;
import java.util.Arrays;
......
package com.ai.cloud.skywalking.web.bo;
package com.ai.cloud.skywalking.web.dto;
import com.ai.cloud.skywalking.web.entity.UserInfo;
......
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;
......
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);
}
}
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 {
......@@ -7,10 +10,17 @@ public class TraceTreeInfo {
private long beginTime;
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) {
......@@ -41,7 +51,31 @@ public class TraceTreeInfo {
return nodes;
}
public void setNodes(List<TraceNodeInfo> nodes) {
public void setHasBeenSpiltNodes(List<TraceNodeInfo> nodes) {
this.nodes = nodes;
}
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;
}
}
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;
......
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;
......
package com.ai.cloud.skywalking.web.entity;
import java.util.ArrayList;
import java.util.List;
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.*;
/**
* Created by xin on 16-4-6.
*/
public class CallChainTree {
private String treeId;
private List<CallChainTreeNode> nodes;
private String entranceViewpoint;
private List<CallChainNode> nodes;
private AnlyResult entranceAnlyResult;
public CallChainTree(String treeId) {
this.treeId = treeId;
nodes = new ArrayList<CallChainTreeNode>();
nodes = new ArrayList<CallChainNode>();
}
public void setEntranceAnlyResult(AnlyResult entranceAnlyResult) {
this.entranceAnlyResult = entranceAnlyResult;
}
public void addHitNodes(Map<String, String> nodes) {
for (Map.Entry<String, String> 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<CallChainNode>() {
@Override
public int compare(CallChainNode o1, CallChainNode o2) {
return o1.getTraceLevelId().compareTo(o2.getTraceLevelId());
}
});
}
public void addNode(String levelId, String viewpoint) {
if ("0".equals(levelId)) {
entranceViewpoint = viewpoint;
public void addGuessNodesAndRemoveDuplicate(List<CallChainNode> 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<CallChainNode> getNodes() {
return nodes;
}
public String getTreeId() {
return treeId;
}
public String getEntranceViewpoint() {
return entranceViewpoint;
}
public void setTreeId(String treeId) {
this.treeId = treeId;
}
nodes.add(new CallChainTreeNode(levelId, viewpoint));
public void setNodes(List<CallChainNode> nodes) {
this.nodes = nodes;
}
}
......@@ -12,4 +12,8 @@ public class CallChainTreeNode {
this.traceLevelId = traceLevelId;
this.viewPoint = viewpoint;
}
public String getTraceLevelId() {
return traceLevelId;
}
}
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;
......@@ -24,6 +24,7 @@ public class AccessControllerFilter implements Filter {
contained.add("addApplication");
contained.add("createGlobalApplication");
contained.add("modifyApplication");
contained.add("showAnlyResult");
}
@Override
......
......@@ -2,6 +2,9 @@ package com.ai.cloud.skywalking.web.service.impl;
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;
......@@ -12,7 +15,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
......@@ -21,26 +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<CallChainTree> queryCurrentMonthCallChainTree(String uid, String viewpoint) throws SQLException, IOException {
List<String> chainTreeIds = iChainDetailDao.queryChainTreeIds(uid,viewpoint);
logger.info("viewpoint key :{}, chainTreeIds : {}", viewpoint, chainTreeIds);
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) {
continue;
public List<CallChainTree> queryCallChainTreeByKey(String uid, String viewpoint, int pageSize) throws SQLException, IOException {
List<CallChainTree> trees = new ArrayList<CallChainTree>();
List<HitTreeInfo> 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<CallChainNode> doGuessNodes(HitTreeInfo hitTraceLevelIds) throws SQLException {
List<CallChainNode> guessNodes = new ArrayList<CallChainNode>();
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());
}
callChainTrees.add(chainTree);
//
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 :{}, 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;
}
}
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,15 +27,21 @@ public class TraceTreeService implements ITraceTreeService {
@Override
public TraceTreeInfo queryTraceTreeByTraceId(String traceId) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, IOException {
TraceTreeInfo traceTreeInfo = null;
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());
}
Map<String, TraceNodeInfo> traceLogMap = traceTreeDao.queryTraceNodesByTraceId(traceId);
if (traceLogMap != null && traceLogMap.size() > 0) {
List<TraceNodeInfo> nodes = new ArrayList<TraceNodeInfo>();
nodes.addAll(traceLogMap.values());
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()) {
......@@ -42,9 +53,14 @@ public class TraceTreeService implements ITraceTreeService {
return arg0.getColId().compareTo(arg1.getColId());
}
});
long beginTime = nodes.get(0).getStartDate();
traceTreeInfo = new TraceTreeInfo(traceId, nodes);
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));
}
......
......@@ -10,5 +10,5 @@ import java.util.List;
* Created by xin on 16-4-6.
*/
public interface ICallChainTreeService {
List<CallChainTree> queryCurrentMonthCallChainTree(String uid, String viewpoint) throws SQLException, IOException;
List<CallChainTree> queryCallChainTreeByKey(String uid, String viewpoint, int pageSize) throws SQLException, IOException;
}
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;
......
......@@ -41,4 +41,10 @@ public class Constants {
put("9", "MISSING");
}
};
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;
}
......@@ -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;
......
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("<span class='highlight-viewpoint'>");
result.append(searchKey);
result.append("</span>");
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<String> 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"));
}
}
}
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
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
......
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Configuration status="debug">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t](%F:%L) %-5level %logger{36} - %msg%n" />
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.ai" additivity="false" level="debug">
<appender-ref ref="Console" />
</Logger>
<Root level="debug">
<AppenderRef ref="Console" />
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
......@@ -29,4 +29,8 @@
.progress-bar-c {
background-color: #5bc0de;
}
\ No newline at end of file
}
.highlight-viewpoint {
background-color: #baec7e;
}
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(/&lt;/g, '<');
_str = _str.replace(/&gt;/g, '>');
_str = _str.replace(/&#39;/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
......@@ -14,7 +14,10 @@ function changeData(data) {
var totalTime = result.traceTree.totalTime;
result.traceTree.startTime = data.beginTime;
result.traceTree.endTime = data.endTime;
result.traceTree.totalSize = data.nodes.length;
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;
......@@ -88,12 +91,13 @@ function changeData(data) {
}
function loadTraceTreeData(baseUrl) {
var url = baseUrl + "/search/traceId/" + $("#searchKey").val();
var url = baseUrl + "/search/traceId";
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
async: true,
data: {traceId:$("#searchKey").val()},
async: false,
success: function (data) {
if (data.code == '200') {
var changedData = changeData(jQuery.parseJSON(data.result));
......
<#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">
<#macro anlyResultTmpl>
<script type="text/x-jsrender" id="anlyResultPanelTmpl">
<div class="row">
<div class="col-md-9">
<div class="col-md-8" id="anlyResultmPanel">
</div>
<div class="col-md-3">
<div class="col-md-4">
</div>
</div>
</div>
<hr/>
</script>
</#macro>
<script>
<#macro anlyResultDisplayTmpl>
<script type="text/x-jsrender" id="anlyResultDisplayTmpl">
<div class="row">
<h4><a>{{>entranceViewpoint}}</a></h4>
<p>
{{for nodes}}
{{if isPrintSlipDot}}
<span style="margin-left:15%">....</span></br>
{{/if}}
<span style="margin-left:{{>marginLeftSize}}px" data={{>traceLevelId}}>{{>viewPoint}}</span></br>
{{/for}}
<span style="margin-left:15%">....</span></br>
</p>
<p style="font-color">{{>entranceAnlyResult.yearOfAnlyResult}}年{{>entranceAnlyResult.monthOfAnlyResult}}月已经被调用{{>entranceAnlyResult.totalCall}}次&nbsp;
成功<span class="text-success"><strong>{{>entranceAnlyResult.correctNumber}}</strong></span>次&nbsp;
失败<span class="text-danger"><strong>{{>entranceAnlyResult.humanInterruptionNumber}}</strong></span>次&nbsp;
成功调用率<span class="
{{if correctRate >= 99.00}}
text-success
{{else correctRate >= 97}}
text-warning
{{else}}
text-danger
{{/if}}
"><strong>{{>correctRate}}%</strong></span>
<a class="pull-right"><ins>more</ins></a></p>
<hr/>
</div>
</script>
</#macro>
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();
}
});
}
<#macro pageInfoTmpl>
<script type="text/x-jsrender" id="pageInfoTmpl">
<input type="hidden" value="{{>pageSize}}" id="pageSize"/>
<nav>
<ul class="pager">
{{if hasPreviousPage}}
<li><a href="javascript:void(0);" id="doPreviousPageBtn">Previous</a></li>
{{/if}}
{{if hasNextPage}}
<li disabled><a href="javascript:void(0);" id="doNextPageBtn">Next</a></li>
{{/if}}
</ul>
</nav>
</script>
</body>
</html>
</#macro>
\ No newline at end of file
......@@ -60,10 +60,6 @@
</div>
</nav>
<script>
$("#searchBtn").click(function () {
loadTraceTreeData("${_base}");
});
$("#logoutBtn").click(function () {
var url = "${_base}/usr/doLogout";
$.ajax({
......
......@@ -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}},{{>totalSize}}条调用记录,消耗总时长:{{>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">
......
......@@ -69,7 +69,12 @@
<script>
$(document).ready(function () {
$("#searchBtn").click(function () {
window.location.href = "${_base}/" + $("#key").val();
var searchKey = $("#key").val();
if (searchKey.match(/viewpoint:*/i)) {
window.location.href = "${_base}/" + "mainPage?loadType=showAnlyResult&key=" + searchKey;
} else {
window.location.href = "${_base}/" + searchKey;
}
});
$("#logoutBtn").click(function () {
......
......@@ -2,6 +2,7 @@
<#import "./common/traceInfo.ftl" as traceInfo>
<#import "./usr/applications/applicationMaintain.ftl" as applicationMaintain>
<#import "./usr/authfile/auth.ftl" as auth>
<#import "./anls-result/analysisResult.ftl" as anlyResult>
<!DOCTYPE html>
<html lang="zh-CN">
......@@ -16,6 +17,7 @@
<link href="${_base}/bower_components/skywalking/css/tracelog.css" rel="stylesheet"/>
<script src="${_base}/bower_components/skywalking/js/tracelog.js"></script>
<script src="${_base}/bower_components/skywalking/js/application.js"></script>
<script src="${_base}/bower_components/skywalking/js/analysisresult.js"></script>
<link href="${_base}/bower_components/bootstrap-toggle/css/bootstrap-toggle.min.css" rel="stylesheet">
<script src="${_base}/bower_components/bootstrap-toggle/js/bootstrap-toggle.min.js"></script>
</head>
......@@ -32,6 +34,9 @@
<@applicationMaintain.createglobalConfig/>
<@applicationMaintain.modifyApplication/>
<@auth.downloadAuth/>
<@anlyResult.anlyResultTmpl/>
<@anlyResult.anlyResultDisplayTmpl/>
<@anlyResult.pageInfoTmpl/>
<p id="baseUrl" style="display: none">${_base}</p>
<div class="container" id="mainPanel">
<p id="searchType" style="display: none">${searchType!''}</p>
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册