Compare commits
22 Commits
feature#or
...
feature#de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0113b57b4 | ||
|
|
709d51d4d5 | ||
|
|
ce528808c7 | ||
|
|
51266aab87 | ||
|
|
e99dd2e870 | ||
|
|
95c36fd9a3 | ||
|
|
2553c6f61e | ||
|
|
cc92f82472 | ||
|
|
8dd2c1e47f | ||
|
|
6a9d65ba5d | ||
|
|
3c48b4c71f | ||
|
|
636303021f | ||
|
|
0cf66f32ff | ||
|
|
fbf7ebd834 | ||
|
|
327f527082 | ||
|
|
2f52ff5e63 | ||
|
|
abe24914d3 | ||
|
|
491ca17106 | ||
|
|
feef3e7054 | ||
|
|
5c7bb4b14e | ||
|
|
bb636c9bae | ||
|
|
d871572438 |
@@ -76,7 +76,7 @@
|
|||||||
|
|
||||||
##### 安装TDengine
|
##### 安装TDengine
|
||||||
1. docker安装TDengine
|
1. docker安装TDengine
|
||||||
`docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/udp --name tdengine tdengine/tdengine:2.4.0.12`
|
`docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/tcp -p 6030-6049:6030-6049/udp --name tdengine tdengine/tdengine:2.4.0.12`
|
||||||
2. 创建名称为hertzbeat的数据库
|
2. 创建名称为hertzbeat的数据库
|
||||||
|
|
||||||
详细步骤参考 [依赖服务TDengine安装初始化](https://hertzbeat.com/docs/start/tdengine-init)
|
详细步骤参考 [依赖服务TDengine安装初始化](https://hertzbeat.com/docs/start/tdengine-init)
|
||||||
@@ -138,7 +138,8 @@ HertzBeat赫兹跳动为 [Dromara开源社区](https://dromara.org/) 孵化项
|
|||||||
|
|
||||||
##### 赞助
|
##### 赞助
|
||||||
|
|
||||||
感谢[吉实信息(构建全新的微波+光交易网络)](https://www.flarespeed.com)赞助服务器采集节点
|
感谢[吉实信息(构建全新的微波+光交易网络)](https://www.flarespeed.com) 赞助服务器采集节点
|
||||||
|
感谢[天上云计算(全新智慧上云)](https://www.tsyvps.com/aff/BZBEGYLX) 赞助服务器采集节点
|
||||||
|
|
||||||
## 🛡️ License
|
## 🛡️ License
|
||||||
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)
|
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ public class CalculateAlarm {
|
|||||||
} else {
|
} else {
|
||||||
// 其他异常
|
// 其他异常
|
||||||
alertBuilder.target(CommonConstants.AVAILABLE)
|
alertBuilder.target(CommonConstants.AVAILABLE)
|
||||||
.content("监控紧急可用性告警: " + metricsData.getCode().name());
|
.content("监控可用性告警: " + metricsData.getCode().name() + " : " + metricsData.getMsg());
|
||||||
triggeredMonitorStateAlertMap.put(monitorId, metricsData.getCode());
|
triggeredMonitorStateAlertMap.put(monitorId, metricsData.getCode());
|
||||||
dataQueue.addAlertData(alertBuilder.build());
|
dataQueue.addAlertData(alertBuilder.build());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,12 +109,11 @@
|
|||||||
<artifactId>mssql-jdbc</artifactId>
|
<artifactId>mssql-jdbc</artifactId>
|
||||||
<version>10.2.0.jre8</version>
|
<version>10.2.0.jre8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- oracle -->
|
<!-- oracle -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.oracle</groupId>
|
<groupId>com.oracle.database.jdbc</groupId>
|
||||||
<artifactId>ojdbc6</artifactId>
|
<artifactId>ojdbc8</artifactId>
|
||||||
<version>11.2.0.3</version>
|
<version>21.5.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ import javax.net.ssl.SSLContext;
|
|||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.CertificateExpiredException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,7 +77,18 @@ public class CommonHttpClient {
|
|||||||
@Override
|
@Override
|
||||||
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { }
|
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { }
|
||||||
@Override
|
@Override
|
||||||
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { }
|
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||||
|
// 判断服务器证书有效期时间
|
||||||
|
Date now = new Date();
|
||||||
|
if (x509Certificates != null && x509Certificates.length > 0) {
|
||||||
|
for (X509Certificate certificate : x509Certificates) {
|
||||||
|
Date deadline = certificate.getNotAfter();
|
||||||
|
if (deadline != null && now.after(deadline)) {
|
||||||
|
throw new CertificateExpiredException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public X509Certificate[] getAcceptedIssuers() { return null; }
|
public X509Certificate[] getAcceptedIssuers() { return null; }
|
||||||
};
|
};
|
||||||
@@ -95,8 +108,8 @@ public class CommonHttpClient {
|
|||||||
.setConnectTimeout(CONNECT_TIMEOUT)
|
.setConnectTimeout(CONNECT_TIMEOUT)
|
||||||
// 数据传输最大响应间隔时间
|
// 数据传输最大响应间隔时间
|
||||||
.setSocketTimeout(SOCKET_TIMEOUT)
|
.setSocketTimeout(SOCKET_TIMEOUT)
|
||||||
// 遇到301 302不自动重定向跳转
|
// 遇到301 302自动重定向跳转
|
||||||
.setRedirectsEnabled(false)
|
.setRedirectsEnabled(true)
|
||||||
.build();
|
.build();
|
||||||
// 连接池
|
// 连接池
|
||||||
connectionManager = new PoolingHttpClientConnectionManager(registry);
|
connectionManager = new PoolingHttpClientConnectionManager(registry);
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package com.usthe.collector.collect.common.ssh;
|
|||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.sshd.client.SshClient;
|
import org.apache.sshd.client.SshClient;
|
||||||
|
import org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier;
|
||||||
|
import org.apache.sshd.common.PropertyResolverUtils;
|
||||||
|
import org.apache.sshd.core.CoreModuleProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ssh公共client
|
* ssh公共client
|
||||||
@@ -16,6 +19,14 @@ public class CommonSshClient {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
sshClient = SshClient.setUpDefaultClient();
|
sshClient = SshClient.setUpDefaultClient();
|
||||||
|
// 接受所有服务端公钥校验,会打印warn日志 Server at {} presented unverified {} key: {}
|
||||||
|
AcceptAllServerKeyVerifier verifier = AcceptAllServerKeyVerifier.INSTANCE;
|
||||||
|
sshClient.setServerKeyVerifier(verifier);
|
||||||
|
// 设置链接保活心跳10000毫秒一次, 客户端等待保活心跳超时响应时间3000毫秒
|
||||||
|
PropertyResolverUtils.updateProperty(
|
||||||
|
sshClient, CoreModuleProperties.HEARTBEAT_INTERVAL.getName(), 10000);
|
||||||
|
PropertyResolverUtils.updateProperty(
|
||||||
|
sshClient, CoreModuleProperties.HEARTBEAT_REPLY_WAIT.getName(), 3000);
|
||||||
sshClient.start();
|
sshClient.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ public class JdbcCommonCollect extends AbstractCollect {
|
|||||||
}
|
}
|
||||||
JdbcProtocol jdbcProtocol = metrics.getJdbc();
|
JdbcProtocol jdbcProtocol = metrics.getJdbc();
|
||||||
String databaseUrl = constructDatabaseUrl(jdbcProtocol);
|
String databaseUrl = constructDatabaseUrl(jdbcProtocol);
|
||||||
// 查询超时时间默认3000毫秒
|
// 查询超时时间默认6000毫秒
|
||||||
int timeout = 3000;
|
int timeout = 6000;
|
||||||
try {
|
try {
|
||||||
// 获取查询语句超时时间
|
// 获取查询语句超时时间
|
||||||
if (jdbcProtocol.getTimeout() != null) {
|
if (jdbcProtocol.getTimeout() != null) {
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ public class IcmpCollectImpl extends AbstractCollect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IcmpProtocol icmp = metrics.getIcmp();
|
IcmpProtocol icmp = metrics.getIcmp();
|
||||||
// 超时时间默认300毫秒
|
// 超时时间默认6000毫秒
|
||||||
int timeout = 300;
|
int timeout = 6000;
|
||||||
try {
|
try {
|
||||||
timeout = Integer.parseInt(icmp.getTimeout());
|
timeout = Integer.parseInt(icmp.getTimeout());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.usthe.collector.collect.common.cache.CacheIdentifier;
|
|||||||
import com.usthe.collector.collect.common.cache.CommonCache;
|
import com.usthe.collector.collect.common.cache.CommonCache;
|
||||||
import com.usthe.collector.collect.common.ssh.CommonSshClient;
|
import com.usthe.collector.collect.common.ssh.CommonSshClient;
|
||||||
import com.usthe.collector.util.CollectorConstants;
|
import com.usthe.collector.util.CollectorConstants;
|
||||||
|
import com.usthe.collector.util.KeyPairUtil;
|
||||||
import com.usthe.common.entity.job.Metrics;
|
import com.usthe.common.entity.job.Metrics;
|
||||||
import com.usthe.common.entity.job.protocol.SshProtocol;
|
import com.usthe.common.entity.job.protocol.SshProtocol;
|
||||||
import com.usthe.common.entity.message.CollectRep;
|
import com.usthe.common.entity.message.CollectRep;
|
||||||
@@ -19,6 +20,7 @@ import org.springframework.util.StringUtils;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
|
import java.security.KeyPair;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -56,8 +58,8 @@ public class SshCollectImpl extends AbstractCollect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SshProtocol sshProtocol = metrics.getSsh();
|
SshProtocol sshProtocol = metrics.getSsh();
|
||||||
// 超时时间默认300毫秒
|
// 超时时间默认6000毫秒
|
||||||
int timeout = 3000;
|
int timeout = 6000;
|
||||||
try {
|
try {
|
||||||
timeout = Integer.parseInt(sshProtocol.getTimeout());
|
timeout = Integer.parseInt(sshProtocol.getTimeout());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -181,6 +183,13 @@ public class SshCollectImpl extends AbstractCollect {
|
|||||||
.verify(timeout, TimeUnit.MILLISECONDS).getSession();
|
.verify(timeout, TimeUnit.MILLISECONDS).getSession();
|
||||||
if (StringUtils.hasText(sshProtocol.getPassword())) {
|
if (StringUtils.hasText(sshProtocol.getPassword())) {
|
||||||
clientSession.addPasswordIdentity(sshProtocol.getPassword());
|
clientSession.addPasswordIdentity(sshProtocol.getPassword());
|
||||||
|
} else if (StringUtils.hasText(sshProtocol.getPublicKey())) {
|
||||||
|
KeyPair keyPair = KeyPairUtil.getKeyPairFromPublicKey(sshProtocol.getPublicKey());
|
||||||
|
if (keyPair != null) {
|
||||||
|
clientSession.addPublicKeyIdentity(keyPair);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("需填写账户登陆密码或公钥");
|
||||||
}
|
}
|
||||||
// 进行认证
|
// 进行认证
|
||||||
if (!clientSession.auth().verify(timeout, TimeUnit.MILLISECONDS).isSuccess()) {
|
if (!clientSession.auth().verify(timeout, TimeUnit.MILLISECONDS).isSuccess()) {
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ public class TelnetCollectImpl extends AbstractCollect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TelnetProtocol telnet = metrics.getTelnet();
|
TelnetProtocol telnet = metrics.getTelnet();
|
||||||
// 超时时间默认300毫秒
|
// 超时时间默认6000毫秒
|
||||||
int timeout = 300;
|
int timeout = 6000;
|
||||||
try {
|
try {
|
||||||
timeout = Integer.parseInt(telnet.getTimeout());
|
timeout = Integer.parseInt(telnet.getTimeout());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -105,9 +105,13 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
|||||||
.setId(timerJob.getJob().getMonitorId())
|
.setId(timerJob.getJob().getMonitorId())
|
||||||
.setApp(timerJob.getJob().getApp())
|
.setApp(timerJob.getJob().getApp())
|
||||||
.setMetrics(metricsTime.getMetrics().getName())
|
.setMetrics(metricsTime.getMetrics().getName())
|
||||||
|
.setPriority(metricsTime.getMetrics().getPriority())
|
||||||
.setTime(System.currentTimeMillis())
|
.setTime(System.currentTimeMillis())
|
||||||
.setCode(CollectRep.Code.TIMEOUT).setMsg("collect timeout").build();
|
.setCode(CollectRep.Code.TIMEOUT).setMsg("collect timeout").build();
|
||||||
dispatchCollectData(metricsTime.timeout, metricsTime.getMetrics(), metricsData);
|
log.error("[Collect Timeout]: \n{}", metricsData);
|
||||||
|
if (metricsData.getPriority() == 0) {
|
||||||
|
dispatchCollectData(metricsTime.timeout, metricsTime.getMetrics(), metricsData);
|
||||||
|
}
|
||||||
metricsTimeoutMonitorMap.remove(entry.getKey());
|
metricsTimeoutMonitorMap.remove(entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,8 +169,8 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
|||||||
metricsSet.forEach(metricItem -> {
|
metricsSet.forEach(metricItem -> {
|
||||||
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this);
|
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this);
|
||||||
jobRequestQueue.addJob(metricsCollect);
|
jobRequestQueue.addJob(metricsCollect);
|
||||||
metricsTimeoutMonitorMap.put(job.getId() + "-" + metrics.getName(),
|
metricsTimeoutMonitorMap.put(job.getId() + "-" + metricItem.getName(),
|
||||||
new MetricsTime(System.currentTimeMillis(), metrics, timeout));
|
new MetricsTime(System.currentTimeMillis(), metricItem, timeout));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 当前执行级别的指标组列表未全执行完成,
|
// 当前执行级别的指标组列表未全执行完成,
|
||||||
@@ -185,8 +189,8 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
|||||||
metricsSet.forEach(metricItem -> {
|
metricsSet.forEach(metricItem -> {
|
||||||
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this);
|
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this);
|
||||||
jobRequestQueue.addJob(metricsCollect);
|
jobRequestQueue.addJob(metricsCollect);
|
||||||
metricsTimeoutMonitorMap.put(job.getId() + "-" + metrics.getName(),
|
metricsTimeoutMonitorMap.put(job.getId() + "-" + metricItem.getName(),
|
||||||
new MetricsTime(System.currentTimeMillis(), metrics, timeout));
|
new MetricsTime(System.currentTimeMillis(), metricItem, timeout));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 当前执行级别的指标组列表未全执行完成,
|
// 当前执行级别的指标组列表未全执行完成,
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ import java.util.stream.Collectors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Data
|
@Data
|
||||||
public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
|
public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
|
||||||
|
/**
|
||||||
|
* 调度告警阈值时间 100ms
|
||||||
|
*/
|
||||||
|
private static final long WARN_DISPATCH_TIME = 100;
|
||||||
/**
|
/**
|
||||||
* 监控ID
|
* 监控ID
|
||||||
*/
|
*/
|
||||||
@@ -267,11 +271,15 @@ public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
|
|||||||
private CollectRep.MetricsData validateResponse(CollectRep.MetricsData.Builder builder) {
|
private CollectRep.MetricsData validateResponse(CollectRep.MetricsData.Builder builder) {
|
||||||
long endTime = System.currentTimeMillis();
|
long endTime = System.currentTimeMillis();
|
||||||
builder.setTime(endTime);
|
builder.setTime(endTime);
|
||||||
log.debug("[Collect]: newTime: {}, startTime: {}, spendTime: {}.", newTime, startTime, endTime - startTime);
|
long runningTime = endTime - startTime;
|
||||||
|
long allTime = endTime - newTime;
|
||||||
|
if (startTime - newTime >= WARN_DISPATCH_TIME) {
|
||||||
|
log.warn("[Collector Dispatch Warn, Dispatch Use {}ms.", startTime - newTime);
|
||||||
|
}
|
||||||
if (builder.getCode() != CollectRep.Code.SUCCESS) {
|
if (builder.getCode() != CollectRep.Code.SUCCESS) {
|
||||||
log.info("[Collect Fail] Reason: {}", builder.getMsg());
|
log.info("[Collect Failed, Run {}ms, All {}ms] Reason: {}", runningTime, allTime, builder.getMsg());
|
||||||
} else {
|
} else {
|
||||||
log.info("[Collect Success].");
|
log.info("[Collect Success, Run {}ms, All {}ms].", runningTime, allTime);
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import com.usthe.common.entity.job.Job;
|
|||||||
import com.usthe.common.entity.job.Metrics;
|
import com.usthe.common.entity.job.Metrics;
|
||||||
import com.usthe.common.util.AesUtil;
|
import com.usthe.common.util.AesUtil;
|
||||||
import com.usthe.common.util.CommonConstants;
|
import com.usthe.common.util.CommonConstants;
|
||||||
|
import com.usthe.common.util.GsonUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -84,6 +85,26 @@ public class WheelTimerTask implements TimerTask {
|
|||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
Map.Entry<String, JsonElement> entry = iterator.next();
|
Map.Entry<String, JsonElement> entry = iterator.next();
|
||||||
JsonElement element = entry.getValue();
|
JsonElement element = entry.getValue();
|
||||||
|
String key = entry.getKey();
|
||||||
|
// 替换KEY-VALUE情况的属性 比如http headers params
|
||||||
|
if (key != null && key.startsWith("^_^") && key.endsWith("^_^")) {
|
||||||
|
key = key.replaceAll("\\^_\\^", "");
|
||||||
|
Configmap param = configmap.get(key);
|
||||||
|
if (param != null && param.getType() == (byte) 3) {
|
||||||
|
String jsonValue = (String) param.getValue();
|
||||||
|
Map<String, String> map = GsonUtil.fromJson(jsonValue, Map.class);
|
||||||
|
if (map != null) {
|
||||||
|
map.forEach((name, value) -> {
|
||||||
|
if (name != null && !"".equals(name.trim())) {
|
||||||
|
jsonObject.addProperty(name, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 替换正常的VALUE值
|
||||||
if (element.isJsonPrimitive()) {
|
if (element.isJsonPrimitive()) {
|
||||||
// 判断是否含有特殊字符 替换
|
// 判断是否含有特殊字符 替换
|
||||||
String value = element.getAsString();
|
String value = element.getAsString();
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.usthe.collector.util;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.security.KeyFactory;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密钥工具类
|
||||||
|
* @author tom
|
||||||
|
* @date 2022/4/2 17:04
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class KeyPairUtil {
|
||||||
|
|
||||||
|
private static KeyFactory keyFactory;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取密钥对
|
||||||
|
*/
|
||||||
|
public static KeyPair getKeyPairFromPublicKey(String publicKeyStr) {
|
||||||
|
try {
|
||||||
|
if (publicKeyStr == null || "".equals(publicKeyStr)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// todo fix 公钥解析
|
||||||
|
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
|
||||||
|
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
|
||||||
|
PublicKey publicKey = keyFactory.generatePublic(keySpec);
|
||||||
|
return new KeyPair(publicKey, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("[keyPair] parse failed, {}." + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ public class Configmap {
|
|||||||
private Object value;
|
private Object value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 参数类型 0:数字 1:字符串 2:加密串
|
* 参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串
|
||||||
* number,string,secret
|
* number,string,secret
|
||||||
* 数字,非加密字符串,加密字符串
|
* 数字,非加密字符串,加密字符串
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class SshProtocol {
|
|||||||
/**
|
/**
|
||||||
* 超时时间
|
* 超时时间
|
||||||
*/
|
*/
|
||||||
private String timeout = "3000";
|
private String timeout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户名
|
* 用户名
|
||||||
|
|||||||
@@ -59,15 +59,15 @@ public class Param {
|
|||||||
* 参数值
|
* 参数值
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "参数值", example = "8080", accessMode = READ_WRITE, position = 3)
|
@ApiModelProperty(value = "参数值", example = "8080", accessMode = READ_WRITE, position = 3)
|
||||||
@Length(max = 255)
|
@Length(max = 8126)
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 参数类型 0:数字 1:字符串 2:加密串
|
* 参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "参数类型 0:数字 1:字符串 2:加密串", accessMode = READ_WRITE, position = 4)
|
@ApiModelProperty(value = "参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串", accessMode = READ_WRITE, position = 4)
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@Max(2)
|
@Max(3)
|
||||||
private byte type;
|
private byte type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -110,29 +110,47 @@ public class ParamDefine {
|
|||||||
@Convert(converter = JsonOptionListAttributeConverter.class)
|
@Convert(converter = JsonOptionListAttributeConverter.class)
|
||||||
private List<Option> options;
|
private List<Option> options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当type为key-value时有效,表示key的别名描述
|
||||||
|
*/
|
||||||
|
@ApiModelProperty(value = "当type为key-value时有效,表示key的别名描述", example = "Name", accessMode = READ_WRITE, position = 9)
|
||||||
|
private String keyAlias;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当type为key-value时有效,表示value的别名描述
|
||||||
|
*/
|
||||||
|
@ApiModelProperty(value = "当type为key-value时有效,表示value的别名描述", example = "Value", accessMode = READ_WRITE, position = 10)
|
||||||
|
private String valueAlias;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是高级隐藏参数 true-是 false-否
|
||||||
|
*/
|
||||||
|
@ApiModelProperty(value = "是否是高级隐藏参数 true-是 false-否", example = "true", accessMode = READ_WRITE, position = 11)
|
||||||
|
private boolean hide = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 此条记录创建者
|
* 此条记录创建者
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 9)
|
@ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 11)
|
||||||
private String creator;
|
private String creator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 此条记录最新修改者
|
* 此条记录最新修改者
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 10)
|
@ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 12)
|
||||||
private String modifier;
|
private String modifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录创建时间
|
* 记录创建时间
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 11)
|
@ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 13)
|
||||||
@Column(insertable = false, updatable = false)
|
@Column(insertable = false, updatable = false)
|
||||||
private LocalDateTime gmtCreate;
|
private LocalDateTime gmtCreate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录最新修改时间
|
* 记录最新修改时间
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 12)
|
@ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 14)
|
||||||
@Column(insertable = false, updatable = false)
|
@Column(insertable = false, updatable = false)
|
||||||
private LocalDateTime gmtUpdate;
|
private LocalDateTime gmtUpdate;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ sidebar_label: 帮助入门
|
|||||||
|
|
||||||
### 数据库监控
|
### 数据库监控
|
||||||
|
|
||||||
[MYSQL数据库监控](mysql)      [MariaDB数据库监控](mariadb)      [PostgreSQL数据库监控](postgresql)      [SqlServer数据库监控](sqlserver)
|
[MYSQL数据库监控](mysql)      [MariaDB数据库监控](mariadb)      [PostgreSQL数据库监控](postgresql)      [SqlServer数据库监控](sqlserver)      [Oracle数据库监控](oracle)
|
||||||
|
|
||||||
### 操作系统监控
|
### 操作系统监控
|
||||||
|
|
||||||
|
|||||||
62
home/docs/help/oracle.md
Normal file
62
home/docs/help/oracle.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
---
|
||||||
|
id: oracle
|
||||||
|
title: 监控:ORACLE数据库监控
|
||||||
|
sidebar_label: ORACLE数据库
|
||||||
|
---
|
||||||
|
|
||||||
|
> 对ORACLE数据库的通用性能指标进行采集监控。
|
||||||
|
|
||||||
|
### 配置参数
|
||||||
|
|
||||||
|
| 参数名称 | 参数帮助描述 |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| 监控Host | 被监控的对端IPV4,IPV6或域名。注意⚠️不带协议头(eg: https://, http://)。 |
|
||||||
|
| 监控名称 | 标识此监控的名称,名称需要保证唯一性。 |
|
||||||
|
| 端口 | 数据库对外提供的端口,默认为1521。 |
|
||||||
|
| 查询超时时间 | 设置SQL查询未响应数据时的超时时间,单位ms毫秒,默认3000毫秒。 |
|
||||||
|
| 数据库名称 | 数据库实例名称,可选。 |
|
||||||
|
| 用户名 | 数据库连接用户名,可选 |
|
||||||
|
| 密码 | 数据库连接密码,可选 |
|
||||||
|
| URL | 数据库连接URL,可选,若配置,则URL里面的数据库名称,用户名密码等参数会覆盖上面配置的参数 |
|
||||||
|
| 采集间隔 | 监控周期性采集数据间隔时间,单位秒,可设置的最小间隔为10秒 |
|
||||||
|
| 是否探测 | 新增监控前是否先探测检查监控可用性,探测成功才会继续新增修改操作 |
|
||||||
|
| 描述备注 | 更多标识和描述此监控的备注信息,用户可以在这里备注信息 |
|
||||||
|
|
||||||
|
### 采集指标
|
||||||
|
|
||||||
|
#### 指标集合:basic
|
||||||
|
|
||||||
|
| 指标名称 | 指标单位 | 指标帮助描述 |
|
||||||
|
| ----------- | ----------- | ----------- |
|
||||||
|
| database_version | 无 | 数据库版本 |
|
||||||
|
| database_type | 无 | 数据库类型 |
|
||||||
|
| hostname | 无 | 主机名称 |
|
||||||
|
| instance_name | 无 | 数据库实例名称 |
|
||||||
|
| startup_time | 无 | 数据库启动时间 |
|
||||||
|
| status | 无 | 数据库状态 |
|
||||||
|
|
||||||
|
#### 指标集合:tablespace
|
||||||
|
|
||||||
|
| 指标名称 | 指标单位 | 指标帮助描述 |
|
||||||
|
| ----------- | ----------- | ----------- |
|
||||||
|
| file_id | 无 | 文件ID |
|
||||||
|
| file_name | 无 | 文件名称 |
|
||||||
|
| tablespace_name | 无 | 所属表空间名称 |
|
||||||
|
| status | 无 | 状态 |
|
||||||
|
| bytes | MB | 大小 |
|
||||||
|
| blocks | 无 | 区块数量 |
|
||||||
|
|
||||||
|
#### 指标集合:user_connect
|
||||||
|
|
||||||
|
| 指标名称 | 指标单位 | 指标帮助描述 |
|
||||||
|
| ----------- | ----------- | ----------- |
|
||||||
|
| username | 无 | 用户名 |
|
||||||
|
| counts | 个数 | 当前连接数量 |
|
||||||
|
|
||||||
|
#### 指标集合:performance
|
||||||
|
|
||||||
|
| 指标名称 | 指标单位 | 指标帮助描述 |
|
||||||
|
| ----------- | ----------- | ----------- |
|
||||||
|
| qps | QPS | I/O Requests per Second 每秒IO请求数量 |
|
||||||
|
| tps | TPS | User Transaction Per Sec 每秒用户事物处理数量 |
|
||||||
|
| mbps | MBPS | I/O Megabytes per Second 每秒 I/O 兆字节数量 |
|
||||||
@@ -11,8 +11,9 @@ sidebar_label: 赞助
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
感谢[吉实信息(构建全新的微波+光交易网络)](https://www.flarespeed.com)赞助服务器采集节点
|
感谢[吉实信息(构建全新的微波+光交易网络)](https://www.flarespeed.com) 赞助服务器采集节点
|
||||||
|
感谢[天上云计算(全新智慧上云)](https://www.tsyvps.com/aff/BZBEGYLX) 赞助服务器采集节点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,56 @@ sidebar_label: Docker方式部署
|
|||||||
HertzBeat默认内置三个用户账户,分别为 admin/admin tom/tom@123 lili/lili
|
HertzBeat默认内置三个用户账户,分别为 admin/admin tom/tom@123 lili/lili
|
||||||
若需要新增删除修改账户或密码,可以通过配置 `sureness.yml` 实现,若无此需求可忽略此步骤
|
若需要新增删除修改账户或密码,可以通过配置 `sureness.yml` 实现,若无此需求可忽略此步骤
|
||||||
在主机目录下创建sureness.yml,eg:/opt/sureness.yml
|
在主机目录下创建sureness.yml,eg:/opt/sureness.yml
|
||||||
配置文件内容参考 项目仓库[/script/sureness.yml](https://gitee.com/dromara/hertzbeat/blob/master/script/sureness.yml)
|
配置文件内容参考 项目仓库[/script/sureness.yml](https://gitee.com/dromara/hertzbeat/blob/master/script/sureness.yml)
|
||||||
修改sureness.yml的如下部分参数:[注意⚠️sureness配置的其它默认参数需保留]
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
|
||||||
|
resourceRole:
|
||||||
|
- /account/auth/refresh===post===[role1,role2,role3,role4]
|
||||||
|
|
||||||
|
excludedResource:
|
||||||
|
- /account/auth/**===*
|
||||||
|
- /===get
|
||||||
|
- /i18n/**===get
|
||||||
|
- /apps/hierarchy===get
|
||||||
|
- /console/**===get
|
||||||
|
- /**/*.html===get
|
||||||
|
- /**/*.js===get
|
||||||
|
- /**/*.css===get
|
||||||
|
- /**/*.ico===get
|
||||||
|
- /**/*.ttf===get
|
||||||
|
- /**/*.png===get
|
||||||
|
- /**/*.gif===get
|
||||||
|
- /**/*.png===*
|
||||||
|
- /swagger-resources/**===get
|
||||||
|
- /v2/api-docs===get
|
||||||
|
- /v3/api-docs===get
|
||||||
|
|
||||||
|
# 用户账户信息
|
||||||
|
# 下面有 admin tom lili 三个账户
|
||||||
|
# eg: admin 拥有[role1,role2]角色,密码为admin
|
||||||
|
# eg: tom 拥有[role1,role2,role3],密码为tom@123
|
||||||
|
# eg: lili 拥有[role1,role2],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289
|
||||||
|
account:
|
||||||
|
- appId: admin
|
||||||
|
credential: admin
|
||||||
|
role: [role1,role2]
|
||||||
|
- appId: tom
|
||||||
|
credential: tom@123
|
||||||
|
role: [role1,role2,role3]
|
||||||
|
- appId: lili
|
||||||
|
# 注意 Digest认证不支持加盐加密的密码账户
|
||||||
|
# 加盐加密的密码,通过 MD5(password+salt)计算
|
||||||
|
# 此账户的原始密码为 lili
|
||||||
|
credential: 1A676730B0C7F54654B0E09184448289
|
||||||
|
salt: 123
|
||||||
|
role: [role1,role2]
|
||||||
|
```
|
||||||
|
|
||||||
|
修改sureness.yml的如下**部分参数**:**[注意⚠️sureness配置的其它默认参数需保留]**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
|
||||||
# 用户账户信息
|
# 用户账户信息
|
||||||
# 下面有 admin tom lili 三个账户
|
# 下面有 admin tom lili 三个账户
|
||||||
# eg: admin 拥有[role1,role2]角色,密码为admin
|
# eg: admin 拥有[role1,role2]角色,密码为admin
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ sidebar_label: 安装包方式部署
|
|||||||
4. 配置用户配置文件(非必须,配置账户需要)
|
4. 配置用户配置文件(非必须,配置账户需要)
|
||||||
HertzBeat默认内置三个用户账户,分别为 admin/admin tom/tom@123 lili/lili
|
HertzBeat默认内置三个用户账户,分别为 admin/admin tom/tom@123 lili/lili
|
||||||
若需要新增删除修改账户或密码,可以通过修改位于 `hertzbeat/config/sureness.yml` 的配置文件实现,若无此需求可忽略此步骤
|
若需要新增删除修改账户或密码,可以通过修改位于 `hertzbeat/config/sureness.yml` 的配置文件实现,若无此需求可忽略此步骤
|
||||||
修改sureness.yml的如下部分参数:[注意⚠️sureness配置的其它默认参数需保留]
|
修改sureness.yml的如下**部分参数**:**[注意⚠️sureness配置的其它默认参数需保留]**
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# 用户账户信息
|
# 用户账户信息
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ const repoUrl = `https://github.com/dromara/${projectName}`
|
|||||||
const cdnUrl = 'https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/'
|
const cdnUrl = 'https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
title: 'TANCLOUD探云',
|
title: 'HertzBeat',
|
||||||
tagline: '易用友好的高性能监控云',
|
tagline: '易用友好的云监控系统',
|
||||||
url: 'https://hertzbeat.com',
|
url: 'https://hertzbeat.com',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
onBrokenLinks: 'throw',
|
onBrokenLinks: 'throw',
|
||||||
|
|||||||
@@ -65,7 +65,8 @@
|
|||||||
"help/mysql",
|
"help/mysql",
|
||||||
"help/mariadb",
|
"help/mariadb",
|
||||||
"help/postgresql",
|
"help/postgresql",
|
||||||
"help/sqlserver"
|
"help/sqlserver",
|
||||||
|
"help/oracle"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
4
home/static/img/hertzbeat-brand-white.svg
Normal file
4
home/static/img/hertzbeat-brand-white.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 8.9 KiB |
4
home/static/img/tancloud-brand-white.svg
Normal file
4
home/static/img/tancloud-brand-white.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg width="199" height="53" viewBox="0 0 199 53" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M60.0112 15.3828V36H57.3208V15.3828H60.0112ZM66.6382 15.3828V17.6201H50.708V15.3828H66.6382ZM76.1963 17.2095L69.3711 36H66.5815L74.4404 15.3828H76.2388L76.1963 17.2095ZM81.917 36L75.0776 17.2095L75.0352 15.3828H76.8335L84.7207 36H81.917ZM81.563 28.3677V30.605H69.98V28.3677H81.563ZM103.341 15.3828V36H100.594L90.2148 20.0981V36H87.4819V15.3828H90.2148L100.637 31.3271V15.3828H103.341ZM120.631 29.4438H123.35C123.208 30.7466 122.835 31.9124 122.231 32.9414C121.627 33.9704 120.772 34.7869 119.668 35.3911C118.563 35.9858 117.185 36.2832 115.533 36.2832C114.325 36.2832 113.225 36.0566 112.234 35.6035C111.252 35.1504 110.407 34.5085 109.699 33.6777C108.991 32.8376 108.444 31.8322 108.057 30.6616C107.679 29.4816 107.49 28.1694 107.49 26.7251V24.6719C107.49 23.2275 107.679 21.9201 108.057 20.7495C108.444 19.5695 108.996 18.5594 109.713 17.7192C110.44 16.8791 111.313 16.2324 112.333 15.7793C113.353 15.3262 114.5 15.0996 115.774 15.0996C117.332 15.0996 118.648 15.3923 119.725 15.9775C120.801 16.5628 121.636 17.3747 122.231 18.4131C122.835 19.4421 123.208 20.6362 123.35 21.9956H120.631C120.499 21.0327 120.253 20.2067 119.895 19.5176C119.536 18.819 119.026 18.2809 118.365 17.9033C117.704 17.5257 116.841 17.3369 115.774 17.3369C114.858 17.3369 114.051 17.5116 113.353 17.8608C112.663 18.2101 112.083 18.7057 111.611 19.3477C111.148 19.9896 110.799 20.759 110.563 21.6558C110.327 22.5526 110.209 23.5485 110.209 24.6436V26.7251C110.209 27.7352 110.313 28.6839 110.521 29.5713C110.738 30.4587 111.063 31.2375 111.498 31.9077C111.932 32.578 112.484 33.1066 113.154 33.4937C113.825 33.8713 114.618 34.0601 115.533 34.0601C116.694 34.0601 117.619 33.876 118.309 33.5078C118.998 33.1396 119.517 32.611 119.866 31.9219C120.225 31.2327 120.48 30.4067 120.631 29.4438ZM139.577 33.7769V36H129.269V33.7769H139.577ZM129.807 15.3828V36H127.074V15.3828H129.807ZM157.646 25.04V26.3428C157.646 27.891 157.452 29.2786 157.065 30.5059C156.678 31.7331 156.121 32.7762 155.394 33.6353C154.667 34.4943 153.794 35.1504 152.774 35.6035C151.764 36.0566 150.632 36.2832 149.376 36.2832C148.158 36.2832 147.04 36.0566 146.02 35.6035C145.01 35.1504 144.132 34.4943 143.386 33.6353C142.65 32.7762 142.079 31.7331 141.673 30.5059C141.267 29.2786 141.064 27.891 141.064 26.3428V25.04C141.064 23.4919 141.262 22.1089 141.659 20.8911C142.065 19.6639 142.636 18.6208 143.372 17.7617C144.108 16.8932 144.982 16.2324 145.992 15.7793C147.011 15.3262 148.13 15.0996 149.348 15.0996C150.603 15.0996 151.736 15.3262 152.746 15.7793C153.766 16.2324 154.639 16.8932 155.366 17.7617C156.102 18.6208 156.664 19.6639 157.051 20.8911C157.447 22.1089 157.646 23.4919 157.646 25.04ZM154.941 26.3428V25.0117C154.941 23.7845 154.813 22.6989 154.559 21.7549C154.313 20.8109 153.95 20.0179 153.468 19.376C152.987 18.734 152.397 18.2479 151.698 17.9175C151.009 17.5871 150.226 17.4219 149.348 17.4219C148.498 17.4219 147.729 17.5871 147.04 17.9175C146.36 18.2479 145.775 18.734 145.284 19.376C144.802 20.0179 144.429 20.8109 144.165 21.7549C143.901 22.6989 143.769 23.7845 143.769 25.0117V26.3428C143.769 27.5794 143.901 28.6745 144.165 29.6279C144.429 30.5719 144.807 31.3696 145.298 32.021C145.798 32.6629 146.388 33.1491 147.068 33.4795C147.757 33.8099 148.526 33.9751 149.376 33.9751C150.263 33.9751 151.052 33.8099 151.741 33.4795C152.43 33.1491 153.01 32.6629 153.482 32.021C153.964 31.3696 154.327 30.5719 154.573 29.6279C154.818 28.6745 154.941 27.5794 154.941 26.3428ZM173.533 15.3828H176.252V29.3306C176.252 30.8787 175.907 32.1673 175.218 33.1963C174.529 34.2253 173.613 34.9993 172.471 35.5186C171.338 36.0283 170.106 36.2832 168.775 36.2832C167.378 36.2832 166.113 36.0283 164.98 35.5186C163.857 34.9993 162.965 34.2253 162.304 33.1963C161.653 32.1673 161.327 30.8787 161.327 29.3306V15.3828H164.032V29.3306C164.032 30.4067 164.23 31.2941 164.626 31.9927C165.023 32.6912 165.575 33.2104 166.283 33.5503C167.001 33.8901 167.831 34.0601 168.775 34.0601C169.729 34.0601 170.56 33.8901 171.268 33.5503C171.985 33.2104 172.542 32.6912 172.938 31.9927C173.335 31.2941 173.533 30.4067 173.533 29.3306V15.3828ZM186.122 36H181.817L181.845 33.7769H186.122C187.594 33.7769 188.821 33.4701 189.803 32.8564C190.785 32.2334 191.521 31.3649 192.012 30.251C192.513 29.1276 192.763 27.8154 192.763 26.3145V25.0542C192.763 23.8742 192.621 22.8263 192.338 21.9106C192.055 20.9855 191.639 20.2067 191.092 19.5742C190.544 18.9323 189.874 18.4461 189.081 18.1157C188.298 17.7853 187.396 17.6201 186.376 17.6201H181.732V15.3828H186.376C187.726 15.3828 188.958 15.6094 190.072 16.0625C191.186 16.5062 192.144 17.1528 192.947 18.0024C193.759 18.8426 194.382 19.8621 194.816 21.061C195.25 22.2505 195.467 23.591 195.467 25.0825V26.3145C195.467 27.806 195.25 29.1512 194.816 30.3501C194.382 31.5396 193.754 32.5544 192.933 33.3945C192.121 34.2347 191.139 34.8813 189.987 35.3345C188.845 35.7782 187.556 36 186.122 36ZM183.275 15.3828V36H180.542V15.3828H183.275Z" fill="white"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.001 0C10.748 0 0 10.745 0 24.001C0 33.826 5.90999 42.271 14.369 45.982C14.301 44.308 14.357 42.293 14.784 40.47C15.246 38.522 17.106 27.5 17.106 27.5C17.106 27.5 17.106 25.861 17.106 23.595C17.106 20.039 19.434 21.819 22 21.819L25.5 23C32 23 42.5 23 42.5 23C42.5 23 32.943 15.5 26.5 15.5C19.221 15.5 18.5 15.5 18.5 15.5C18.5 17.594 13.5 18 13.5 18L11.5 15.5L9 14.5C9 7.684 13.52 8.069 24.922 8.069C34.086 8.069 48 14.5 42.5 23C42.5 23 33.219 23 25.5 23C22.912 23 28.336 31.09 27.5 29.5C27.5 29.5 28 33 22 37C21.492 38.85 18.111 45.575 17.2 47.015C19.359 47.653 21.64 48 24.001 48C37.255 48 48 37.255 48 24.001C48 10.745 37.255 0 24.001 0Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.6 KiB |
@@ -79,6 +79,10 @@ public class MonitorServiceImpl implements MonitorService {
|
|||||||
List<Configmap> configmaps = params.stream().map(param ->
|
List<Configmap> configmaps = params.stream().map(param ->
|
||||||
new Configmap(param.getField(), param.getValue(), param.getType())).collect(Collectors.toList());
|
new Configmap(param.getField(), param.getValue(), param.getType())).collect(Collectors.toList());
|
||||||
appDefine.setConfigmap(configmaps);
|
appDefine.setConfigmap(configmaps);
|
||||||
|
// 探测可用性只需要采集优先级为0的可用性指标集合
|
||||||
|
List<Metrics> availableMetrics = appDefine.getMetrics().stream()
|
||||||
|
.filter(item -> item.getPriority() == 0).collect(Collectors.toList());
|
||||||
|
appDefine.setMetrics(availableMetrics);
|
||||||
List<CollectRep.MetricsData> collectRep = collectJobService.collectSyncJobData(appDefine);
|
List<CollectRep.MetricsData> collectRep = collectJobService.collectSyncJobData(appDefine);
|
||||||
// 判断探测结果 失败则抛出探测异常
|
// 判断探测结果 失败则抛出探测异常
|
||||||
if (collectRep == null || collectRep.isEmpty()) {
|
if (collectRep == null || collectRep.isEmpty()) {
|
||||||
@@ -236,6 +240,9 @@ public class MonitorServiceImpl implements MonitorService {
|
|||||||
case "checkbox":
|
case "checkbox":
|
||||||
// todo checkbox校验
|
// todo checkbox校验
|
||||||
break;
|
break;
|
||||||
|
case "key-value":
|
||||||
|
// todo key-value校验
|
||||||
|
break;
|
||||||
// todo 更多参数定义与实际值格式校验
|
// todo 更多参数定义与实际值格式校验
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("ParamDefine type " + paramDefine.getType() + " is invalid.");
|
throw new IllegalArgumentException("ParamDefine type " + paramDefine.getType() + " is invalid.");
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ app: example
|
|||||||
name:
|
name:
|
||||||
zh-CN: 模拟应用类型
|
zh-CN: 模拟应用类型
|
||||||
en-US: EXAMPLE APP
|
en-US: EXAMPLE APP
|
||||||
# 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串
|
# 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串, 3-map映射的json串
|
||||||
# 强制固定必须参数 - host
|
# 强制固定必须参数 - host
|
||||||
configmap:
|
configmap:
|
||||||
- key: host
|
- key: host
|
||||||
@@ -16,6 +16,8 @@ configmap:
|
|||||||
type: 1
|
type: 1
|
||||||
- key: password
|
- key: password
|
||||||
type: 2
|
type: 2
|
||||||
|
- key: headers
|
||||||
|
type: 3
|
||||||
# 指标组列表
|
# 指标组列表
|
||||||
metrics:
|
metrics:
|
||||||
# 第一个监控指标组 cpu
|
# 第一个监控指标组 cpu
|
||||||
@@ -69,7 +71,7 @@ metrics:
|
|||||||
ssl: false
|
ssl: false
|
||||||
# 请求头内容
|
# 请求头内容
|
||||||
headers:
|
headers:
|
||||||
apiVersion: v1
|
^_^headers^_^: ^_^headers^_^
|
||||||
# 请求参数内容
|
# 请求参数内容
|
||||||
params:
|
params:
|
||||||
param1: param1
|
param1: param1
|
||||||
|
|||||||
@@ -26,6 +26,12 @@ configmap:
|
|||||||
type: 1
|
type: 1
|
||||||
- key: payload
|
- key: payload
|
||||||
type: 1
|
type: 1
|
||||||
|
- key: authType
|
||||||
|
type: 1
|
||||||
|
- key: headers
|
||||||
|
type: 3
|
||||||
|
- key: params
|
||||||
|
type: 3
|
||||||
# 指标组列表
|
# 指标组列表
|
||||||
metrics:
|
metrics:
|
||||||
# 第一个监控指标组 cpu
|
# 第一个监控指标组 cpu
|
||||||
@@ -58,12 +64,18 @@ metrics:
|
|||||||
# 请求头内容
|
# 请求头内容
|
||||||
headers:
|
headers:
|
||||||
content-type: ^_^contentType^_^
|
content-type: ^_^contentType^_^
|
||||||
|
^_^headers^_^: ^_^headers^_^
|
||||||
|
# 请求参数内容
|
||||||
|
params:
|
||||||
|
^_^params^_^: ^_^params^_^
|
||||||
# 认证
|
# 认证
|
||||||
authorization:
|
authorization:
|
||||||
# 认证方式: Basic Auth, Digest Auth, Bearer Token
|
# 认证方式: Basic Auth, Digest Auth, Bearer Token
|
||||||
type: Basic Auth
|
type: ^_^authType^_^
|
||||||
basicAuthUsername: ^_^username^_^
|
basicAuthUsername: ^_^username^_^
|
||||||
basicAuthPassword: ^_^password^_^
|
basicAuthPassword: ^_^password^_^
|
||||||
|
digestAuthUsername: ^_^username^_^
|
||||||
|
digestAuthPassword: ^_^password^_^
|
||||||
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-网站可用性指标监控
|
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-网站可用性指标监控
|
||||||
# todo xmlPath-xmlPath脚本,prometheus-Prometheus数据规则
|
# todo xmlPath-xmlPath脚本,prometheus-Prometheus数据规则
|
||||||
parseType: website
|
parseType: website
|
||||||
@@ -16,6 +16,8 @@ configmap:
|
|||||||
type: 1
|
type: 1
|
||||||
- key: password
|
- key: password
|
||||||
type: 2
|
type: 2
|
||||||
|
- key: timeout
|
||||||
|
type: 0
|
||||||
# 指标组列表
|
# 指标组列表
|
||||||
metrics:
|
metrics:
|
||||||
# 第一个监控指标组 basic
|
# 第一个监控指标组 basic
|
||||||
@@ -44,6 +46,7 @@ metrics:
|
|||||||
port: ^_^port^_^
|
port: ^_^port^_^
|
||||||
username: ^_^username^_^
|
username: ^_^username^_^
|
||||||
password: ^_^password^_^
|
password: ^_^password^_^
|
||||||
|
timeout: ^_^timeout^_^
|
||||||
script: (uname -r ; hostname ; uptime | awk -F "," '{print $1}' | sed "s/ //g") | sed ":a;N;s/\n/^/g;ta" | awk -F '^' 'BEGIN{print "version hostname uptime"} {print $1, $2, $3}'
|
script: (uname -r ; hostname ; uptime | awk -F "," '{print $1}' | sed "s/ //g") | sed ":a;N;s/\n/^/g;ta" | awk -F '^' 'BEGIN{print "version hostname uptime"} {print $1, $2, $3}'
|
||||||
# 响应数据解析方式:oneRow, multiRow
|
# 响应数据解析方式:oneRow, multiRow
|
||||||
parseType: multiRow
|
parseType: multiRow
|
||||||
@@ -75,6 +78,7 @@ metrics:
|
|||||||
port: ^_^port^_^
|
port: ^_^port^_^
|
||||||
username: ^_^username^_^
|
username: ^_^username^_^
|
||||||
password: ^_^password^_^
|
password: ^_^password^_^
|
||||||
|
timeout: ^_^timeout^_^
|
||||||
script: "LANG=C lscpu | awk -F: '/Model name/ {print $2}';awk '/processor/{core++} END{print core}' /proc/cpuinfo;uptime | sed 's/,/ /g' | awk '{for(i=NF-2;i<=NF;i++)print $i }' | xargs;vmstat 1 1 | awk 'NR==3{print $11}';vmstat 1 1 | awk 'NR==3{print $12}'"
|
script: "LANG=C lscpu | awk -F: '/Model name/ {print $2}';awk '/processor/{core++} END{print core}' /proc/cpuinfo;uptime | sed 's/,/ /g' | awk '{for(i=NF-2;i<=NF;i++)print $i }' | xargs;vmstat 1 1 | awk 'NR==3{print $11}';vmstat 1 1 | awk 'NR==3{print $12}'"
|
||||||
parseType: oneRow
|
parseType: oneRow
|
||||||
|
|
||||||
@@ -107,6 +111,7 @@ metrics:
|
|||||||
port: ^_^port^_^
|
port: ^_^port^_^
|
||||||
username: ^_^username^_^
|
username: ^_^username^_^
|
||||||
password: ^_^password^_^
|
password: ^_^password^_^
|
||||||
|
timeout: ^_^timeout^_^
|
||||||
script: free -m | grep Mem | awk 'BEGIN{print "total used free buff_cache available"} {print $2,$3,$4,$6,$7}'
|
script: free -m | grep Mem | awk 'BEGIN{print "total used free buff_cache available"} {print $2,$3,$4,$6,$7}'
|
||||||
parseType: multiRow
|
parseType: multiRow
|
||||||
|
|
||||||
@@ -139,6 +144,7 @@ metrics:
|
|||||||
port: ^_^port^_^
|
port: ^_^port^_^
|
||||||
username: ^_^username^_^
|
username: ^_^username^_^
|
||||||
password: ^_^password^_^
|
password: ^_^password^_^
|
||||||
|
timeout: ^_^timeout^_^
|
||||||
script: vmstat -D | awk 'NR==1{print $1}';vmstat -D | awk 'NR==2{print $1}';vmstat 1 1 | awk 'NR==3{print $10}';vmstat 1 1 | awk 'NR==3{print $9}';vmstat 1 1 | awk 'NR==3{print $16}'
|
script: vmstat -D | awk 'NR==1{print $1}';vmstat -D | awk 'NR==2{print $1}';vmstat 1 1 | awk 'NR==3{print $10}';vmstat 1 1 | awk 'NR==3{print $9}';vmstat 1 1 | awk 'NR==3{print $16}'
|
||||||
parseType: oneRow
|
parseType: oneRow
|
||||||
|
|
||||||
@@ -164,5 +170,6 @@ metrics:
|
|||||||
port: ^_^port^_^
|
port: ^_^port^_^
|
||||||
username: ^_^username^_^
|
username: ^_^username^_^
|
||||||
password: ^_^password^_^
|
password: ^_^password^_^
|
||||||
|
timeout: ^_^timeout^_^
|
||||||
script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {print $1,$2,$10}'
|
script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {print $1,$2,$10}'
|
||||||
parseType: multiRow
|
parseType: multiRow
|
||||||
@@ -29,11 +29,141 @@ metrics:
|
|||||||
# 指标组中的具体监控指标
|
# 指标组中的具体监控指标
|
||||||
fields:
|
fields:
|
||||||
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
||||||
- field: DST_PRIMARY_TT_VERSION
|
- field: database_version
|
||||||
type: 1
|
type: 1
|
||||||
instance: true
|
instance: true
|
||||||
- field: NLS_RDBMS_VERSION
|
- field: database_type
|
||||||
type: 1
|
type: 1
|
||||||
|
- field: hostname
|
||||||
|
type: 1
|
||||||
|
- field: instance_name
|
||||||
|
type: 1
|
||||||
|
- field: startup_time
|
||||||
|
type: 1
|
||||||
|
- field: status
|
||||||
|
type: 1
|
||||||
|
# (非必须)监控指标别名,与上面的指标名映射。用于采集接口数据字段不直接是最终指标名称,需要此别名做映射转换
|
||||||
|
aliasFields:
|
||||||
|
- VERSION
|
||||||
|
- DATABASE_TYPE
|
||||||
|
- HOST_NAME
|
||||||
|
- INSTANCE_NAME
|
||||||
|
- STARTUP_TIME
|
||||||
|
- STATUS
|
||||||
|
# (非必须)指标计算表达式,与上面的别名一起作用,计算出最终需要的指标值
|
||||||
|
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
|
||||||
|
calculates:
|
||||||
|
- database_version=VERSION
|
||||||
|
- database_type=DATABASE_TYPE
|
||||||
|
- hostname=HOST_NAME
|
||||||
|
- instance_name=INSTANCE_NAME
|
||||||
|
- startup_time=STARTUP_TIME
|
||||||
|
- status=STATUS
|
||||||
|
protocol: jdbc
|
||||||
|
jdbc:
|
||||||
|
# 主机host: ipv4 ipv6 域名
|
||||||
|
host: ^_^host^_^
|
||||||
|
# 端口
|
||||||
|
port: ^_^port^_^
|
||||||
|
platform: oracle
|
||||||
|
username: ^_^username^_^
|
||||||
|
password: ^_^password^_^
|
||||||
|
database: ^_^database^_^
|
||||||
|
timeout: ^_^timeout^_^
|
||||||
|
# SQL查询方式: oneRow, multiRow, columns
|
||||||
|
queryType: oneRow
|
||||||
|
# sql
|
||||||
|
sql: select * from sys.v_$instance
|
||||||
|
url: ^_^url^_^
|
||||||
|
|
||||||
|
- name: tablespace
|
||||||
|
priority: 1
|
||||||
|
# 指标组中的具体监控指标
|
||||||
|
fields:
|
||||||
|
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
||||||
|
- field: file_id
|
||||||
|
type: 1
|
||||||
|
instance: true
|
||||||
|
- field: file_name
|
||||||
|
type: 1
|
||||||
|
- field: tablespace_name
|
||||||
|
type: 1
|
||||||
|
- field: status
|
||||||
|
type: 1
|
||||||
|
- field: bytes
|
||||||
|
type: 0
|
||||||
|
unit: MB
|
||||||
|
- field: blocks
|
||||||
|
type: 0
|
||||||
|
unit: 块数
|
||||||
|
protocol: jdbc
|
||||||
|
jdbc:
|
||||||
|
# 主机host: ipv4 ipv6 域名
|
||||||
|
host: ^_^host^_^
|
||||||
|
# 端口
|
||||||
|
port: ^_^port^_^
|
||||||
|
platform: oracle
|
||||||
|
username: ^_^username^_^
|
||||||
|
password: ^_^password^_^
|
||||||
|
database: ^_^database^_^
|
||||||
|
timeout: ^_^timeout^_^
|
||||||
|
# SQL查询方式: oneRow, multiRow, columns
|
||||||
|
queryType: oneRow
|
||||||
|
# sql
|
||||||
|
sql: select file_id, file_name, tablespace_name, status, bytes / 1024 / 1024 as bytes, blocks from dba_data_files
|
||||||
|
url: ^_^url^_^
|
||||||
|
|
||||||
|
- name: user_connect
|
||||||
|
priority: 1
|
||||||
|
fields:
|
||||||
|
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
||||||
|
- field: username
|
||||||
|
type: 1
|
||||||
|
instance: true
|
||||||
|
- field: counts
|
||||||
|
type: 0
|
||||||
|
unit: 连接数
|
||||||
|
protocol: jdbc
|
||||||
|
jdbc:
|
||||||
|
# 主机host: ipv4 ipv6 域名
|
||||||
|
host: ^_^host^_^
|
||||||
|
# 端口
|
||||||
|
port: ^_^port^_^
|
||||||
|
platform: oracle
|
||||||
|
username: ^_^username^_^
|
||||||
|
password: ^_^password^_^
|
||||||
|
database: ^_^database^_^
|
||||||
|
timeout: ^_^timeout^_^
|
||||||
|
# SQL查询方式: oneRow, multiRow, columns
|
||||||
|
queryType: oneRow
|
||||||
|
# sql
|
||||||
|
sql: SELECT username, count( username ) as counts FROM v$session WHERE username IS NOT NULL GROUP BY username
|
||||||
|
url: ^_^url^_^
|
||||||
|
|
||||||
|
- name: performance
|
||||||
|
priority: 1
|
||||||
|
fields:
|
||||||
|
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
||||||
|
- field: qps
|
||||||
|
type: 0
|
||||||
|
unit: qps
|
||||||
|
- field: tps
|
||||||
|
type: 0
|
||||||
|
unit: tps
|
||||||
|
- field: mbps
|
||||||
|
type: 0
|
||||||
|
unit: mbps
|
||||||
|
# (非必须)监控指标别名,与上面的指标名映射。用于采集接口数据字段不直接是最终指标名称,需要此别名做映射转换
|
||||||
|
aliasFields:
|
||||||
|
- I/O Requests per Second
|
||||||
|
- User Transaction Per Sec
|
||||||
|
- I/O Megabytes per Second
|
||||||
|
# (非必须)指标计算表达式,与上面的别名一起作用,计算出最终需要的指标值
|
||||||
|
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
|
||||||
|
calculates:
|
||||||
|
- qps=I/O Requests per Second
|
||||||
|
- tps=User Transaction Per Sec
|
||||||
|
- mbps=I/O Megabytes per Second
|
||||||
protocol: jdbc
|
protocol: jdbc
|
||||||
jdbc:
|
jdbc:
|
||||||
# 主机host: ipv4 ipv6 域名
|
# 主机host: ipv4 ipv6 域名
|
||||||
@@ -48,5 +178,5 @@ metrics:
|
|||||||
# SQL查询方式: oneRow, multiRow, columns
|
# SQL查询方式: oneRow, multiRow, columns
|
||||||
queryType: columns
|
queryType: columns
|
||||||
# sql
|
# sql
|
||||||
sql: select * from sys.props$
|
sql: select metric_name, value from gv$sysmetric where metric_name = 'I/O Megabytes per Second' or metric_name = 'User Transaction Per Sec' or metric_name = 'I/O Requests per Second'
|
||||||
url: ^_^url^_^
|
url: ^_^url^_^
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
category: service
|
|
||||||
app: telnet
|
|
||||||
name:
|
|
||||||
zh-CN: TELNET端口可用性
|
|
||||||
en-US: PORT TELNET
|
|
||||||
configmap:
|
|
||||||
- key: host
|
|
||||||
type: 1
|
|
||||||
- key: port
|
|
||||||
type: 0
|
|
||||||
- key: timeout
|
|
||||||
type: 0
|
|
||||||
metrics:
|
|
||||||
- name: summary
|
|
||||||
priority: 0
|
|
||||||
fields:
|
|
||||||
- field: responseTime
|
|
||||||
type: 0
|
|
||||||
unit: ms
|
|
||||||
protocol: telnet
|
|
||||||
# 当protocol为telnet协议时具体的采集配置
|
|
||||||
telnet:
|
|
||||||
host: ^_^host^_^
|
|
||||||
port: ^_^port^_^
|
|
||||||
timeout: ^_^timeout^_^
|
|
||||||
@@ -12,6 +12,12 @@ configmap:
|
|||||||
type: 1
|
type: 1
|
||||||
- key: ssl
|
- key: ssl
|
||||||
type: 1
|
type: 1
|
||||||
|
- key: authType
|
||||||
|
type: 1
|
||||||
|
- key: username
|
||||||
|
type: 1
|
||||||
|
- key: password
|
||||||
|
type: 2
|
||||||
# 指标组列表
|
# 指标组列表
|
||||||
metrics:
|
metrics:
|
||||||
# 第一个监控指标组 cpu
|
# 第一个监控指标组 cpu
|
||||||
@@ -40,6 +46,13 @@ metrics:
|
|||||||
method: GET
|
method: GET
|
||||||
# 是否启用ssl/tls,即是http还是https,默认false
|
# 是否启用ssl/tls,即是http还是https,默认false
|
||||||
ssl: ^_^ssl^_^
|
ssl: ^_^ssl^_^
|
||||||
|
authorization:
|
||||||
|
# 认证方式: Basic Auth, Digest Auth, Bearer Token
|
||||||
|
type: ^_^authType^_^
|
||||||
|
basicAuthUsername: ^_^username^_^
|
||||||
|
basicAuthPassword: ^_^password^_^
|
||||||
|
digestAuthUsername: ^_^username^_^
|
||||||
|
digestAuthPassword: ^_^password^_^
|
||||||
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-网站可用性指标监控
|
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-网站可用性指标监控
|
||||||
# todo xmlPath-xmlPath脚本,prometheus-Prometheus数据规则
|
# todo xmlPath-xmlPath脚本,prometheus-Prometheus数据规则
|
||||||
parseType: website
|
parseType: website
|
||||||
@@ -26,10 +26,12 @@ param:
|
|||||||
# 当type为text时,用limit表示字符串限制大小
|
# 当type为text时,用limit表示字符串限制大小
|
||||||
limit: 20
|
limit: 20
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
- field: password
|
- field: password
|
||||||
name: 密码
|
name: 密码
|
||||||
type: password
|
type: password
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
- field: ssl
|
- field: ssl
|
||||||
name: 启动SSL
|
name: 启动SSL
|
||||||
# 当type为boolean时,前端用switch展示开关
|
# 当type为boolean时,前端用switch展示开关
|
||||||
@@ -48,4 +50,10 @@ param:
|
|||||||
- label: PUT请求
|
- label: PUT请求
|
||||||
value: PUT
|
value: PUT
|
||||||
- label: DELETE请求
|
- label: DELETE请求
|
||||||
value: DELETE
|
value: DELETE
|
||||||
|
- field: headers
|
||||||
|
name: 请求Headers
|
||||||
|
type: key-value
|
||||||
|
required: false
|
||||||
|
keyAlias: Header Name
|
||||||
|
valueAlias: Header Value
|
||||||
@@ -17,13 +17,6 @@ param:
|
|||||||
range: '[0,65535]'
|
range: '[0,65535]'
|
||||||
required: true
|
required: true
|
||||||
defaultValue: 80
|
defaultValue: 80
|
||||||
- field: uri
|
|
||||||
name: 相对路径
|
|
||||||
type: text
|
|
||||||
# 当type为text时,用limit表示字符串限制大小
|
|
||||||
limit: 200
|
|
||||||
required: false
|
|
||||||
placeholder: 'API地址除IP端口外的路径 例如:/v2/book/bar'
|
|
||||||
- field: method
|
- field: method
|
||||||
name: 请求方式
|
name: 请求方式
|
||||||
type: radio
|
type: radio
|
||||||
@@ -38,28 +31,62 @@ param:
|
|||||||
value: PUT
|
value: PUT
|
||||||
- label: DELETE请求
|
- label: DELETE请求
|
||||||
value: DELETE
|
value: DELETE
|
||||||
|
- field: uri
|
||||||
|
name: 相对路径
|
||||||
|
type: text
|
||||||
|
# 当type为text时,用limit表示字符串限制大小
|
||||||
|
limit: 200
|
||||||
|
required: false
|
||||||
|
placeholder: 'API地址除IP端口外的路径 例如:/v2/book/bar'
|
||||||
- field: ssl
|
- field: ssl
|
||||||
name: 启用HTTPS
|
name: 启用HTTPS
|
||||||
# 当type为boolean时,前端用switch展示开关
|
# 当type为boolean时,前端用switch展示开关
|
||||||
type: boolean
|
type: boolean
|
||||||
required: true
|
required: true
|
||||||
|
- field: headers
|
||||||
|
name: 请求Headers
|
||||||
|
type: key-value
|
||||||
|
required: false
|
||||||
|
keyAlias: Header Name
|
||||||
|
valueAlias: Header Value
|
||||||
|
- field: params
|
||||||
|
name: 查询Params
|
||||||
|
type: key-value
|
||||||
|
required: false
|
||||||
|
keyAlias: Param Key
|
||||||
|
valueAlias: Param Value
|
||||||
|
- field: contentType
|
||||||
|
name: Content-Type
|
||||||
|
type: text
|
||||||
|
placeholder: '请求BODY资源类型'
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
- field: payload
|
||||||
|
name: 请求BODY
|
||||||
|
type: textarea
|
||||||
|
placeholder: 'POST PUT请求时有效'
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
- field: authType
|
||||||
|
name: 认证方式
|
||||||
|
type: radio
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
# 当type为radio单选框,checkbox复选框时,option表示可选项值列表 {name1:value1,name2:value2}
|
||||||
|
options:
|
||||||
|
- label: Basic Auth
|
||||||
|
value: Basic Auth
|
||||||
|
- label: Digest Auth
|
||||||
|
value: Digest Auth
|
||||||
- field: username
|
- field: username
|
||||||
name: 用户名
|
name: 用户名
|
||||||
type: text
|
type: text
|
||||||
# 当type为text时,用limit表示字符串限制大小
|
# 当type为text时,用limit表示字符串限制大小
|
||||||
limit: 20
|
limit: 20
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
- field: password
|
- field: password
|
||||||
name: 密码
|
name: 密码
|
||||||
type: password
|
type: password
|
||||||
required: false
|
required: false
|
||||||
- field: contentType
|
hide: true
|
||||||
name: Content-Type
|
|
||||||
type: text
|
|
||||||
placeholder: '请求BODY资源类型'
|
|
||||||
required: false
|
|
||||||
- field: payload
|
|
||||||
name: 请求BODY
|
|
||||||
type: textarea
|
|
||||||
placeholder: 'POST PUT请求时有效'
|
|
||||||
required: false
|
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ param:
|
|||||||
required: true
|
required: true
|
||||||
defaultValue: 22
|
defaultValue: 22
|
||||||
placeholder: '请输入端口'
|
placeholder: '请输入端口'
|
||||||
|
- field: timeout
|
||||||
|
name: 超时时间
|
||||||
|
type: number
|
||||||
|
required: false
|
||||||
|
defaultValue: 6000
|
||||||
|
placeholder: '超时时间'
|
||||||
- field: username
|
- field: username
|
||||||
name: 用户名
|
name: 用户名
|
||||||
type: text
|
type: text
|
||||||
@@ -19,4 +25,4 @@ param:
|
|||||||
- field: password
|
- field: password
|
||||||
name: 密码
|
name: 密码
|
||||||
type: password
|
type: password
|
||||||
required: true
|
required: false
|
||||||
@@ -15,8 +15,9 @@ param:
|
|||||||
name: 查询超时时间
|
name: 查询超时时间
|
||||||
type: number
|
type: number
|
||||||
required: false
|
required: false
|
||||||
defaultValue: 3000
|
defaultValue: 6000
|
||||||
placeholder: '查询超时时间'
|
placeholder: '查询超时时间'
|
||||||
|
hide: true
|
||||||
- field: database
|
- field: database
|
||||||
name: 数据库名称
|
name: 数据库名称
|
||||||
type: text
|
type: text
|
||||||
@@ -33,4 +34,5 @@ param:
|
|||||||
- field: url
|
- field: url
|
||||||
name: URL
|
name: URL
|
||||||
type: text
|
type: text
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -15,7 +15,8 @@ param:
|
|||||||
name: 查询超时时间
|
name: 查询超时时间
|
||||||
type: number
|
type: number
|
||||||
required: false
|
required: false
|
||||||
defaultValue: 3000
|
hide: true
|
||||||
|
defaultValue: 6000
|
||||||
placeholder: '查询超时时间'
|
placeholder: '查询超时时间'
|
||||||
- field: database
|
- field: database
|
||||||
name: 数据库名称
|
name: 数据库名称
|
||||||
@@ -33,4 +34,5 @@ param:
|
|||||||
- field: url
|
- field: url
|
||||||
name: URL
|
name: URL
|
||||||
type: text
|
type: text
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -9,13 +9,14 @@ param:
|
|||||||
type: number
|
type: number
|
||||||
range: '[0,65535]'
|
range: '[0,65535]'
|
||||||
required: true
|
required: true
|
||||||
defaultValue: 3306
|
defaultValue: 1521
|
||||||
placeholder: '请输入端口'
|
placeholder: '请输入端口'
|
||||||
- field: timeout
|
- field: timeout
|
||||||
name: 查询超时时间
|
name: 查询超时时间
|
||||||
type: number
|
type: number
|
||||||
required: false
|
required: false
|
||||||
defaultValue: 3000
|
hide: true
|
||||||
|
defaultValue: 6000
|
||||||
placeholder: '查询超时时间'
|
placeholder: '查询超时时间'
|
||||||
- field: database
|
- field: database
|
||||||
name: 数据库名称
|
name: 数据库名称
|
||||||
@@ -33,4 +34,5 @@ param:
|
|||||||
- field: url
|
- field: url
|
||||||
name: URL
|
name: URL
|
||||||
type: text
|
type: text
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -17,4 +17,4 @@ param:
|
|||||||
range: '[0,100000]'
|
range: '[0,100000]'
|
||||||
required: true
|
required: true
|
||||||
placeholder: '请输入超时时间,单位毫秒'
|
placeholder: '请输入超时时间,单位毫秒'
|
||||||
defaultValue: 3000
|
defaultValue: 6000
|
||||||
@@ -24,4 +24,4 @@ param:
|
|||||||
range: '[0,100000]'
|
range: '[0,100000]'
|
||||||
required: true
|
required: true
|
||||||
placeholder: '请输入超时时间,单位毫秒'
|
placeholder: '请输入超时时间,单位毫秒'
|
||||||
defaultValue: 3000
|
defaultValue: 6000
|
||||||
@@ -15,7 +15,8 @@ param:
|
|||||||
name: 查询超时时间
|
name: 查询超时时间
|
||||||
type: number
|
type: number
|
||||||
required: false
|
required: false
|
||||||
defaultValue: 3000
|
hide: true
|
||||||
|
defaultValue: 6000
|
||||||
placeholder: '查询超时时间'
|
placeholder: '查询超时时间'
|
||||||
- field: database
|
- field: database
|
||||||
name: 数据库名称
|
name: 数据库名称
|
||||||
@@ -33,4 +34,5 @@ param:
|
|||||||
- field: url
|
- field: url
|
||||||
name: URL
|
name: URL
|
||||||
type: text
|
type: text
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -15,7 +15,8 @@ param:
|
|||||||
name: 查询超时时间
|
name: 查询超时时间
|
||||||
type: number
|
type: number
|
||||||
required: false
|
required: false
|
||||||
defaultValue: 3000
|
hide: true
|
||||||
|
defaultValue: 6000
|
||||||
placeholder: '查询超时时间'
|
placeholder: '查询超时时间'
|
||||||
- field: database
|
- field: database
|
||||||
name: 数据库名称
|
name: 数据库名称
|
||||||
@@ -33,4 +34,5 @@ param:
|
|||||||
- field: url
|
- field: url
|
||||||
name: URL
|
name: URL
|
||||||
type: text
|
type: text
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# 监控应用类型名称(与文件名保持一致) eg: linux windows tomcat mysql aws...
|
|
||||||
app: telnet
|
|
||||||
# 强制固定必须参数 - host(ipv4,ipv6,域名)
|
|
||||||
param:
|
|
||||||
# field-字段名称标识符
|
|
||||||
- field: host
|
|
||||||
# name-参数字段显示名称
|
|
||||||
name: 主机Host
|
|
||||||
# type-字段类型,样式(大部分映射input标签type属性)
|
|
||||||
type: host
|
|
||||||
# 是否是必输项 true-必填 false-可选
|
|
||||||
required: true
|
|
||||||
- field: port
|
|
||||||
name: 端口
|
|
||||||
type: number
|
|
||||||
# 当type为number时,用range表示范围
|
|
||||||
range: '[0,65535]'
|
|
||||||
required: true
|
|
||||||
defaultValue: 80
|
|
||||||
- field: timeout
|
|
||||||
name: Telnet超时时间
|
|
||||||
type: number
|
|
||||||
# 当type为number时,用range表示范围
|
|
||||||
range: '[0,100000]'
|
|
||||||
required: true
|
|
||||||
placeholder: '请输入超时时间,单位毫秒'
|
|
||||||
defaultValue: 3000
|
|
||||||
@@ -28,4 +28,27 @@ param:
|
|||||||
name: 启用HTTPS
|
name: 启用HTTPS
|
||||||
# 当type为boolean时,前端用switch展示开关
|
# 当type为boolean时,前端用switch展示开关
|
||||||
type: boolean
|
type: boolean
|
||||||
required: true
|
required: true
|
||||||
|
- field: authType
|
||||||
|
name: 认证方式
|
||||||
|
type: radio
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
# 当type为radio单选框,checkbox复选框时,option表示可选项值列表 {name1:value1,name2:value2}
|
||||||
|
options:
|
||||||
|
- label: Basic Auth
|
||||||
|
value: Basic Auth
|
||||||
|
- label: Digest Auth
|
||||||
|
value: Digest Auth
|
||||||
|
- field: username
|
||||||
|
name: 用户名
|
||||||
|
type: text
|
||||||
|
# 当type为text时,用limit表示字符串限制大小
|
||||||
|
limit: 20
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
- field: password
|
||||||
|
name: 密码
|
||||||
|
type: password
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
23
script/assembly/server/bin/shutdown.bat
Normal file
23
script/assembly/server/bin/shutdown.bat
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
@title HertzBeat
|
||||||
|
@echo off
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
rem 项目名称
|
||||||
|
set SERVER_NAME="${project.artifactId}"
|
||||||
|
|
||||||
|
|
||||||
|
rem 应用的端口号
|
||||||
|
set SERVER_PORT=1157
|
||||||
|
|
||||||
|
echo Start shutdown HertzBeat %SERVER_NAME%
|
||||||
|
|
||||||
|
for /f "tokens=1-5" %%i in ('netstat -ano^|findstr ":%SERVER_PORT%"') do (
|
||||||
|
echo kill the process %%m who use the port
|
||||||
|
taskkill /pid %%m -t -f
|
||||||
|
echo Shutdown HertzBeat %SERVER_NAME% Success!
|
||||||
|
goto q
|
||||||
|
)
|
||||||
|
echo Faild shutdown HertzBeat %SERVER_NAME%
|
||||||
|
|
||||||
|
:q
|
||||||
|
pause
|
||||||
56
script/assembly/server/bin/startup.bat
Normal file
56
script/assembly/server/bin/startup.bat
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
@title HertzBeat
|
||||||
|
@echo off
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
rem 项目名称
|
||||||
|
set SERVER_NAME=${project.artifactId}
|
||||||
|
|
||||||
|
rem jar名称
|
||||||
|
set JAR_NAME=${project.build.finalName}.jar
|
||||||
|
|
||||||
|
rem 进入bin目录
|
||||||
|
cd /d %~dp0
|
||||||
|
rem 返回到上一级项目根目录路径
|
||||||
|
cd ..
|
||||||
|
rem 打印项目安装根目录绝对路径
|
||||||
|
set DEPLOY_DIR=%~dp0..
|
||||||
|
echo %DEPLOY_DIR%
|
||||||
|
rem 外部配置文件绝对目录,如果是目录需要/结尾,也可以直接指定文件
|
||||||
|
rem 如果指定的是目录,spring则会读取目录中的所有配置文件
|
||||||
|
set CONF_DIR=%DEPLOY_DIR%\config
|
||||||
|
echo %CONF_DIR%
|
||||||
|
|
||||||
|
rem 应用的端口号
|
||||||
|
set SERVER_PORT=1157
|
||||||
|
|
||||||
|
for /f "tokens=1-5" %%i in ('netstat -ano^|findstr "0.0.0.0:%SERVER_PORT%"') do (
|
||||||
|
echo The HertzBeat %SERVER_NAME% port %SERVER_PORT% already used!
|
||||||
|
echo exit!
|
||||||
|
goto q
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rem 项目日志输出绝对路径
|
||||||
|
set LOGS_DIR=%DEPLOY_DIR%\logs
|
||||||
|
|
||||||
|
rem JVM Configuration
|
||||||
|
set JAVA_OPTS= -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Duser.timezone=Asia/Shanghai
|
||||||
|
|
||||||
|
set JAVA_MEM_OPTS= -server -Xms256m -Xmx1024m -XX:SurvivorRatio=2 -XX:+UseParallelGC
|
||||||
|
|
||||||
|
rem 加载外部log文件的配置
|
||||||
|
set LOGGING_CONFIG=-Dlogging.config=%CONF_DIR%\logback-spring.xml
|
||||||
|
rem 注意配置文件目录最后的后缀需为 / 而不是 windows \
|
||||||
|
set CONFIG_FILES= -Dlogging.path=%LOGS_DIR% %LOGGING_CONFIG% -Dspring.config.location=%CONF_DIR%/
|
||||||
|
echo Starting the %SERVER_NAME% ...
|
||||||
|
|
||||||
|
start javaw %JAVA_OPTS% %JAVA_MEM_OPTS% %CONFIG_FILES% -jar %DEPLOY_DIR%\%JAR_NAME%
|
||||||
|
|
||||||
|
echo "Service starting OK!"
|
||||||
|
for /f "tokens=1-5" %%i in ('netstat -ano^|findstr ":%SERVER_PORT%"') do (
|
||||||
|
echo Service PID: %%m , Port %SERVER_PORT%
|
||||||
|
goto q
|
||||||
|
)
|
||||||
|
|
||||||
|
:q
|
||||||
|
pause
|
||||||
@@ -34,7 +34,7 @@ CREATE TABLE param
|
|||||||
id bigint not null auto_increment comment '参数ID',
|
id bigint not null auto_increment comment '参数ID',
|
||||||
monitor_id bigint not null comment '监控ID',
|
monitor_id bigint not null comment '监控ID',
|
||||||
field varchar(100) not null comment '参数标识符',
|
field varchar(100) not null comment '参数标识符',
|
||||||
value varchar(255) comment '参数值,最大字符长度255',
|
value varchar(8126) comment '参数值,最大字符长度8126',
|
||||||
type tinyint not null default 0 comment '参数类型 0:数字 1:字符串 2:加密串',
|
type tinyint not null default 0 comment '参数类型 0:数字 1:字符串 2:加密串',
|
||||||
gmt_create timestamp default current_timestamp comment 'create time',
|
gmt_create timestamp default current_timestamp comment 'create time',
|
||||||
gmt_update datetime default current_timestamp on update current_timestamp comment 'update time',
|
gmt_update datetime default current_timestamp on update current_timestamp comment 'update time',
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ excludedResource:
|
|||||||
# eg: lili 拥有[role1,role2],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289
|
# eg: lili 拥有[role1,role2],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289
|
||||||
account:
|
account:
|
||||||
- appId: admin
|
- appId: admin
|
||||||
credential: admin@123.
|
credential: admin
|
||||||
role: [role1,role2]
|
role: [role1,role2]
|
||||||
- appId: tom
|
- appId: tom
|
||||||
credential: tom@123.
|
credential: tom
|
||||||
role: [role1,role2,role3]
|
role: [role1,role2,role3]
|
||||||
- appId: lili
|
- appId: lili
|
||||||
# 注意 Digest认证不支持加盐加密的密码账户
|
# 注意 Digest认证不支持加盐加密的密码账户
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ CREATE TABLE param
|
|||||||
id bigint not null auto_increment comment '参数ID',
|
id bigint not null auto_increment comment '参数ID',
|
||||||
monitor_id bigint not null comment '监控ID',
|
monitor_id bigint not null comment '监控ID',
|
||||||
field varchar(100) not null comment '参数标识符',
|
field varchar(100) not null comment '参数标识符',
|
||||||
value varchar(255) comment '参数值,最大字符长度255',
|
value varchar(8126) comment '参数值,最大字符长度8126',
|
||||||
type tinyint not null default 0 comment '参数类型 0:数字 1:字符串 2:加密串',
|
type tinyint not null default 0 comment '参数类型 0:数字 1:字符串 2:加密串',
|
||||||
gmt_create timestamp default current_timestamp comment 'create time',
|
gmt_create timestamp default current_timestamp comment 'create time',
|
||||||
gmt_update datetime default current_timestamp on update current_timestamp comment 'update time',
|
gmt_update datetime default current_timestamp on update current_timestamp comment 'update time',
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ excludedResource:
|
|||||||
- /**/*.ttf===get
|
- /**/*.ttf===get
|
||||||
- /**/*.png===get
|
- /**/*.png===get
|
||||||
- /**/*.gif===get
|
- /**/*.gif===get
|
||||||
- /**/*.png===*
|
- /**/*.png===*
|
||||||
# swagger ui 资源
|
# swagger ui 资源
|
||||||
- /swagger-resources/**===get
|
- /swagger-resources/**===get
|
||||||
- /v2/api-docs===get
|
- /v2/api-docs===get
|
||||||
|
|||||||
@@ -61,11 +61,11 @@ public class TdEngineDataStorage implements DisposableBean {
|
|||||||
log.error("init error, please config Warehouse TdEngine props in application.yml");
|
log.error("init error, please config Warehouse TdEngine props in application.yml");
|
||||||
throw new IllegalArgumentException("please config Warehouse TdEngine props");
|
throw new IllegalArgumentException("please config Warehouse TdEngine props");
|
||||||
}
|
}
|
||||||
initTdEngineDatasource(properties.getStore().getTdEngine());
|
boolean success = initTdEngineDatasource(properties.getStore().getTdEngine());
|
||||||
startStorageData();
|
startStorageData(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initTdEngineDatasource(WarehouseProperties.StoreProperties.TdEngineProperties tdEngineProperties) {
|
private boolean initTdEngineDatasource(WarehouseProperties.StoreProperties.TdEngineProperties tdEngineProperties) {
|
||||||
HikariConfig config = new HikariConfig();
|
HikariConfig config = new HikariConfig();
|
||||||
// jdbc properties
|
// jdbc properties
|
||||||
config.setJdbcUrl(tdEngineProperties.getUrl());
|
config.setJdbcUrl(tdEngineProperties.getUrl());
|
||||||
@@ -84,16 +84,28 @@ public class TdEngineDataStorage implements DisposableBean {
|
|||||||
config.setIdleTimeout(0);
|
config.setIdleTimeout(0);
|
||||||
//validation query
|
//validation query
|
||||||
config.setConnectionTestQuery("select server_status()");
|
config.setConnectionTestQuery("select server_status()");
|
||||||
this.hikariDataSource = new HikariDataSource(config);
|
try {
|
||||||
|
this.hikariDataSource = new HikariDataSource(config);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("\n\t------------------WARN WARN WARN------------------\n" +
|
||||||
|
"\t---------------Init TdEngine Failed---------------\n" +
|
||||||
|
"\t---------------Init TdEngine Failed---------------\n" +
|
||||||
|
"\t--------------Please Config Tdengine--------------\n" +
|
||||||
|
"\t----------Can Not Use Metric History Now----------\n" +
|
||||||
|
"\t----------Can Not Use Metric History Now----------\n" +
|
||||||
|
"\t----------Can Not Use Metric History Now----------\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startStorageData() {
|
private void startStorageData(boolean consume) {
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
Thread.currentThread().setName("warehouse-tdEngine-data-storage");
|
Thread.currentThread().setName("warehouse-tdEngine-data-storage");
|
||||||
while (!Thread.currentThread().isInterrupted()) {
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
try {
|
try {
|
||||||
CollectRep.MetricsData metricsData = dataExporter.pollPersistentStorageMetricsData();
|
CollectRep.MetricsData metricsData = dataExporter.pollPersistentStorageMetricsData();
|
||||||
if (metricsData != null) {
|
if (consume && metricsData != null) {
|
||||||
saveData(metricsData);
|
saveData(metricsData);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@@ -232,6 +244,12 @@ public class TdEngineDataStorage implements DisposableBean {
|
|||||||
Connection connection = null;
|
Connection connection = null;
|
||||||
Map<String, List<Value>> instanceValuesMap = new HashMap<>(8);
|
Map<String, List<Value>> instanceValuesMap = new HashMap<>(8);
|
||||||
try {
|
try {
|
||||||
|
if (hikariDataSource == null) {
|
||||||
|
log.error("\n\t---------------TdEngine Init Failed---------------\n" +
|
||||||
|
"\t--------------Please Config Tdengine--------------\n" +
|
||||||
|
"\t----------Can Not Use Metric History Now----------\n");
|
||||||
|
return instanceValuesMap;
|
||||||
|
}
|
||||||
connection = hikariDataSource.getConnection();
|
connection = hikariDataSource.getConnection();
|
||||||
Statement statement = connection.createStatement();
|
Statement statement = connection.createStatement();
|
||||||
ResultSet resultSet = statement.executeQuery(selectSql);
|
ResultSet resultSet = statement.executeQuery(selectSql);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<global-footer [links]="links">
|
<global-footer [links]="links">
|
||||||
Copyright
|
Copyright
|
||||||
<i nz-icon nzType="copyright" nzTheme="outline"></i>
|
<i nz-icon nzType="copyright" nzTheme="outline"></i>
|
||||||
2021
|
2022
|
||||||
<a href="https://tancloud.cn" target="_blank">探云 tancloud.cn | </a>
|
<a href="https://tancloud.cn" target="_blank">探云 tancloud.cn | </a>
|
||||||
<a href="https://hertzbeat.com" target="_blank">赫兹跳动 hertzbeat.com</a>
|
<a href="https://hertzbeat.com" target="_blank">赫兹跳动 hertzbeat.com</a>
|
||||||
</global-footer>
|
</global-footer>
|
||||||
|
|||||||
@@ -9,4 +9,9 @@ export class ParamDefine {
|
|||||||
limit: number | undefined;
|
limit: number | undefined;
|
||||||
//'[{"label":"GET请求","value":"GET"},{"label":"PUT请求","value":"PUT"}]'
|
//'[{"label":"GET请求","value":"GET"},{"label":"PUT请求","value":"PUT"}]'
|
||||||
options!: any[];
|
options!: any[];
|
||||||
|
// 当type为key-value时有效,表示别名描述
|
||||||
|
keyAlias!: string;
|
||||||
|
valueAlias!: string;
|
||||||
|
// 此参数是否隐藏 即默认不显示, 在高级设置区显示
|
||||||
|
hide: boolean = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
>{{ paramDefine.name }}
|
>{{ paramDefine.name }}
|
||||||
</nz-form-label>
|
</nz-form-label>
|
||||||
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
<nz-input-group [nzSuffix]="suffixTemplate">
|
<nz-input-group [nzSuffix]="suffixTemplate" style="width: 100%">
|
||||||
<input
|
<input
|
||||||
[type]="passwordVisible ? 'text' : 'password'"
|
[type]="passwordVisible ? 'text' : 'password'"
|
||||||
nz-input
|
nz-input
|
||||||
@@ -125,6 +125,7 @@
|
|||||||
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
<nz-switch
|
<nz-switch
|
||||||
[(ngModel)]="params[i].value"
|
[(ngModel)]="params[i].value"
|
||||||
|
(ngModelChange)="onParamBooleanChanged($event, paramDefine.field)"
|
||||||
[required]="paramDefine.required"
|
[required]="paramDefine.required"
|
||||||
[name]="paramDefine.field"
|
[name]="paramDefine.field"
|
||||||
[id]="paramDefine.field"
|
[id]="paramDefine.field"
|
||||||
@@ -147,13 +148,165 @@
|
|||||||
</label>
|
</label>
|
||||||
</nz-radio-group>
|
</nz-radio-group>
|
||||||
</nz-form-control>
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'key-value'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'key-value'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<app-key-value-input
|
||||||
|
[(value)]="params[i].value"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
keyAlias="Header Name"
|
||||||
|
valueAlias="Header Value"
|
||||||
|
></app-key-value-input>
|
||||||
|
</nz-form-control>
|
||||||
</nz-form-item>
|
</nz-form-item>
|
||||||
|
|
||||||
|
<nz-collapse [nzGhost]="true">
|
||||||
|
<nz-collapse-panel nzHeader="高级" [nzHeader]="extraColHeader" [nzShowArrow]="false">
|
||||||
|
<nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index">
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control
|
||||||
|
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
|
||||||
|
nzSpan="8"
|
||||||
|
[nzErrorTip]="'validation.required' | i18n"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
nz-input
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[type]="paramDefine.type"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
/>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'textarea'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'textarea'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<textarea
|
||||||
|
nz-input
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
rows="3"
|
||||||
|
></textarea>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'password'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-input-group [nzSuffix]="suffixTemplate" style="width: 100%">
|
||||||
|
<input
|
||||||
|
[type]="passwordVisible ? 'text' : 'password'"
|
||||||
|
nz-input
|
||||||
|
placeholder="input password"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
/>
|
||||||
|
</nz-input-group>
|
||||||
|
<ng-template #suffixTemplate>
|
||||||
|
<i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" (click)="passwordVisible = !passwordVisible"></i>
|
||||||
|
</ng-template>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'number'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-input-number
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[nzMin]="-1000"
|
||||||
|
[nzMax]="65535"
|
||||||
|
[nzStep]="1"
|
||||||
|
[nzPlaceHolder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
></nz-input-number>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'boolean'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-switch
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
></nz-switch>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'radio'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'radio'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-radio-group
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
nzButtonStyle="solid"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
>
|
||||||
|
<label nz-radio-button [nzValue]="optionItem.value" *ngFor="let optionItem of paramDefine.options">
|
||||||
|
{{ optionItem.label }}
|
||||||
|
</label>
|
||||||
|
</nz-radio-group>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'key-value'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'key-value'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<app-key-value-input
|
||||||
|
[(value)]="advancedParams[i].value"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
keyAlias="Header Name"
|
||||||
|
valueAlias="Header Value"
|
||||||
|
></app-key-value-input>
|
||||||
|
</nz-form-control>
|
||||||
|
</nz-form-item>
|
||||||
|
</nz-collapse-panel>
|
||||||
|
</nz-collapse>
|
||||||
|
<ng-template #extraColHeader>
|
||||||
|
<button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip nzTooltipTitle="设置高级可选参数">
|
||||||
|
<span>高级设置</span>
|
||||||
|
<i nz-icon nzType="down-circle" nzTheme="outline"></i>
|
||||||
|
</button>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
<nz-divider></nz-divider>
|
<nz-divider></nz-divider>
|
||||||
|
|
||||||
<nz-form-item>
|
<nz-form-item>
|
||||||
<nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
|
<nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
|
||||||
<nz-form-control nzSpan="10">
|
<nz-form-control nzSpan="8">
|
||||||
<nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="604800" [nzStep]="60" name="intervals" id="intervals">
|
<nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="604800" [nzStep]="60" name="intervals" id="intervals">
|
||||||
</nz-input-number>
|
</nz-input-number>
|
||||||
</nz-form-control>
|
</nz-form-control>
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
.dynamic-button {
|
||||||
|
font-size: 20px;
|
||||||
|
margin-left: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-button:hover {
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ import { MonitorService } from '../../../service/monitor.service';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-monitor-modify',
|
selector: 'app-monitor-modify',
|
||||||
templateUrl: './monitor-edit.component.html',
|
templateUrl: './monitor-edit.component.html',
|
||||||
styles: []
|
styleUrls: ['./monitor-edit.component.less']
|
||||||
})
|
})
|
||||||
export class MonitorEditComponent implements OnInit {
|
export class MonitorEditComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -30,6 +30,8 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
|
|
||||||
paramDefines!: ParamDefine[];
|
paramDefines!: ParamDefine[];
|
||||||
params!: Param[];
|
params!: Param[];
|
||||||
|
advancedParamDefines!: ParamDefine[];
|
||||||
|
advancedParams!: Param[];
|
||||||
paramValueMap = new Map<String, Param>();
|
paramValueMap = new Map<String, Param>();
|
||||||
monitor = new Monitor();
|
monitor = new Monitor();
|
||||||
profileForm: FormGroup = new FormGroup({});
|
profileForm: FormGroup = new FormGroup({});
|
||||||
@@ -59,7 +61,6 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
this.paramValueMap.set(item.field, item);
|
this.paramValueMap.set(item.field, item);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.params = message.data.params;
|
|
||||||
this.detected = message.data.detected ? message.data.detected : true;
|
this.detected = message.data.detected ? message.data.detected : true;
|
||||||
} else {
|
} else {
|
||||||
console.warn(message.msg);
|
console.warn(message.msg);
|
||||||
@@ -73,12 +74,21 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
if (message.code === 0) {
|
if (message.code === 0) {
|
||||||
this.paramDefines = message.data;
|
this.paramDefines = message.data;
|
||||||
this.params = [];
|
this.params = [];
|
||||||
this.paramDefines.forEach(define => {
|
this.advancedParams = [];
|
||||||
|
this.paramDefines = [];
|
||||||
|
this.advancedParamDefines = [];
|
||||||
|
message.data.forEach(define => {
|
||||||
let param = this.paramValueMap.get(define.field);
|
let param = this.paramValueMap.get(define.field);
|
||||||
if (param === undefined) {
|
if (param === undefined) {
|
||||||
param = new Param();
|
param = new Param();
|
||||||
param.field = define.field;
|
param.field = define.field;
|
||||||
param.type = define.type === 'number' ? 0 : 1;
|
if (define.type === 'number') {
|
||||||
|
param.type = 0;
|
||||||
|
} else if (define.type === 'key-value') {
|
||||||
|
param.type = 3;
|
||||||
|
} else {
|
||||||
|
param.type = 1;
|
||||||
|
}
|
||||||
if (define.type === 'boolean') {
|
if (define.type === 'boolean') {
|
||||||
param.value = false;
|
param.value = false;
|
||||||
}
|
}
|
||||||
@@ -94,7 +104,13 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.params.push(param);
|
if (define.hide) {
|
||||||
|
this.advancedParams.push(param);
|
||||||
|
this.advancedParamDefines.push(define);
|
||||||
|
} else {
|
||||||
|
this.params.push(param);
|
||||||
|
this.paramDefines.push(define);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.warn(message.msg);
|
console.warn(message.msg);
|
||||||
@@ -102,6 +118,21 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onParamBooleanChanged(booleanValue: boolean, field: string) {
|
||||||
|
// 对SSL的端口联动处理, 不开启SSL默认80端口,开启SSL默认443
|
||||||
|
if (field === 'ssl') {
|
||||||
|
this.params.forEach(param => {
|
||||||
|
if (param.field === 'port') {
|
||||||
|
if (booleanValue) {
|
||||||
|
param.value = '443';
|
||||||
|
} else {
|
||||||
|
param.value = '80';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit(formGroup: FormGroup) {
|
onSubmit(formGroup: FormGroup) {
|
||||||
if (formGroup.invalid) {
|
if (formGroup.invalid) {
|
||||||
Object.values(formGroup.controls).forEach(control => {
|
Object.values(formGroup.controls).forEach(control => {
|
||||||
@@ -123,10 +154,15 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
param.value = (param.value as string).trim();
|
param.value = (param.value as string).trim();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.advancedParams.forEach(param => {
|
||||||
|
if (param.value != null && typeof param.value == 'string') {
|
||||||
|
param.value = (param.value as string).trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
let addMonitor = {
|
let addMonitor = {
|
||||||
detected: this.detected,
|
detected: this.detected,
|
||||||
monitor: this.monitor,
|
monitor: this.monitor,
|
||||||
params: this.params
|
params: this.params.concat(this.advancedParams)
|
||||||
};
|
};
|
||||||
this.isSpinning = true;
|
this.isSpinning = true;
|
||||||
this.monitorSvc.editMonitor(addMonitor).subscribe(
|
this.monitorSvc.editMonitor(addMonitor).subscribe(
|
||||||
@@ -167,10 +203,15 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
param.value = (param.value as string).trim();
|
param.value = (param.value as string).trim();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.advancedParams.forEach(param => {
|
||||||
|
if (param.value != null && typeof param.value == 'string') {
|
||||||
|
param.value = (param.value as string).trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
let detectMonitor = {
|
let detectMonitor = {
|
||||||
detected: this.detected,
|
detected: this.detected,
|
||||||
monitor: this.monitor,
|
monitor: this.monitor,
|
||||||
params: this.params
|
params: this.params.concat(this.advancedParams)
|
||||||
};
|
};
|
||||||
this.isSpinning = true;
|
this.isSpinning = true;
|
||||||
this.monitorSvc.detectMonitor(detectMonitor).subscribe(
|
this.monitorSvc.detectMonitor(detectMonitor).subscribe(
|
||||||
|
|||||||
@@ -95,7 +95,7 @@
|
|||||||
>{{ paramDefine.name }}
|
>{{ paramDefine.name }}
|
||||||
</nz-form-label>
|
</nz-form-label>
|
||||||
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
<nz-input-group [nzSuffix]="suffixTemplate">
|
<nz-input-group [nzSuffix]="suffixTemplate" style="width: 100%">
|
||||||
<input
|
<input
|
||||||
[type]="passwordVisible ? 'text' : 'password'"
|
[type]="passwordVisible ? 'text' : 'password'"
|
||||||
nz-input
|
nz-input
|
||||||
@@ -134,6 +134,7 @@
|
|||||||
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
<nz-switch
|
<nz-switch
|
||||||
[(ngModel)]="params[i].value"
|
[(ngModel)]="params[i].value"
|
||||||
|
(ngModelChange)="onParamBooleanChanged($event, paramDefine.field)"
|
||||||
[required]="paramDefine.required"
|
[required]="paramDefine.required"
|
||||||
[name]="paramDefine.field"
|
[name]="paramDefine.field"
|
||||||
[id]="paramDefine.field"
|
[id]="paramDefine.field"
|
||||||
@@ -156,8 +157,160 @@
|
|||||||
</label>
|
</label>
|
||||||
</nz-radio-group>
|
</nz-radio-group>
|
||||||
</nz-form-control>
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'key-value'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'key-value'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<app-key-value-input
|
||||||
|
[(value)]="params[i].value"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[keyAlias]="paramDefine.keyAlias ? paramDefine.keyAlias : 'Name'"
|
||||||
|
[valueAlias]="paramDefine.valueAlias ? paramDefine.valueAlias : 'Value'"
|
||||||
|
></app-key-value-input>
|
||||||
|
</nz-form-control>
|
||||||
</nz-form-item>
|
</nz-form-item>
|
||||||
|
|
||||||
|
<nz-collapse [nzGhost]="true">
|
||||||
|
<nz-collapse-panel nzHeader="高级" [nzHeader]="extraColHeader" [nzShowArrow]="false">
|
||||||
|
<nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index">
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control
|
||||||
|
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
|
||||||
|
nzSpan="8"
|
||||||
|
[nzErrorTip]="'validation.required' | i18n"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
nz-input
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[type]="paramDefine.type"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
/>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'textarea'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'textarea'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<textarea
|
||||||
|
nz-input
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
rows="3"
|
||||||
|
></textarea>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'password'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-input-group [nzSuffix]="suffixTemplate" style="width: 100%">
|
||||||
|
<input
|
||||||
|
[type]="passwordVisible ? 'text' : 'password'"
|
||||||
|
nz-input
|
||||||
|
placeholder="input password"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
/>
|
||||||
|
</nz-input-group>
|
||||||
|
<ng-template #suffixTemplate>
|
||||||
|
<i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" (click)="passwordVisible = !passwordVisible"></i>
|
||||||
|
</ng-template>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'number'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-input-number
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[nzMin]="-1000"
|
||||||
|
[nzMax]="65535"
|
||||||
|
[nzStep]="1"
|
||||||
|
[nzPlaceHolder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
></nz-input-number>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'boolean'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-switch
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
></nz-switch>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'radio'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'radio'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-radio-group
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
nzButtonStyle="solid"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
>
|
||||||
|
<label nz-radio-button [nzValue]="optionItem.value" *ngFor="let optionItem of paramDefine.options">
|
||||||
|
{{ optionItem.label }}
|
||||||
|
</label>
|
||||||
|
</nz-radio-group>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'key-value'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'key-value'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<app-key-value-input
|
||||||
|
[(value)]="advancedParams[i].value"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
keyAlias="Header Name"
|
||||||
|
valueAlias="Header Value"
|
||||||
|
></app-key-value-input>
|
||||||
|
</nz-form-control>
|
||||||
|
</nz-form-item>
|
||||||
|
</nz-collapse-panel>
|
||||||
|
</nz-collapse>
|
||||||
|
<ng-template #extraColHeader>
|
||||||
|
<button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip nzTooltipTitle="设置高级可选参数">
|
||||||
|
<span>高级设置</span>
|
||||||
|
<i nz-icon nzType="down-circle" nzTheme="outline"></i>
|
||||||
|
</button>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
<nz-divider></nz-divider>
|
<nz-divider></nz-divider>
|
||||||
|
|
||||||
<nz-form-item>
|
<nz-form-item>
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import { MonitorService } from '../../../service/monitor.service';
|
|||||||
export class MonitorNewComponent implements OnInit {
|
export class MonitorNewComponent implements OnInit {
|
||||||
paramDefines!: ParamDefine[];
|
paramDefines!: ParamDefine[];
|
||||||
params!: Param[];
|
params!: Param[];
|
||||||
|
advancedParamDefines!: ParamDefine[];
|
||||||
|
advancedParams!: Param[];
|
||||||
monitor!: Monitor;
|
monitor!: Monitor;
|
||||||
detected: boolean = true;
|
detected: boolean = true;
|
||||||
passwordVisible: boolean = false;
|
passwordVisible: boolean = false;
|
||||||
@@ -53,12 +55,20 @@ export class MonitorNewComponent implements OnInit {
|
|||||||
)
|
)
|
||||||
.subscribe(message => {
|
.subscribe(message => {
|
||||||
if (message.code === 0) {
|
if (message.code === 0) {
|
||||||
this.paramDefines = message.data;
|
|
||||||
this.params = [];
|
this.params = [];
|
||||||
this.paramDefines.forEach(define => {
|
this.advancedParams = [];
|
||||||
|
this.paramDefines = [];
|
||||||
|
this.advancedParamDefines = [];
|
||||||
|
message.data.forEach(define => {
|
||||||
let param = new Param();
|
let param = new Param();
|
||||||
param.field = define.field;
|
param.field = define.field;
|
||||||
param.type = define.type === 'number' ? 0 : 1;
|
if (define.type === 'number') {
|
||||||
|
param.type = 0;
|
||||||
|
} else if (define.type === 'key-value') {
|
||||||
|
param.type = 3;
|
||||||
|
} else {
|
||||||
|
param.type = 1;
|
||||||
|
}
|
||||||
if (define.type === 'boolean') {
|
if (define.type === 'boolean') {
|
||||||
param.value = false;
|
param.value = false;
|
||||||
}
|
}
|
||||||
@@ -71,7 +81,13 @@ export class MonitorNewComponent implements OnInit {
|
|||||||
param.value = define.defaultValue;
|
param.value = define.defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.params.push(param);
|
if (define.hide) {
|
||||||
|
this.advancedParams.push(param);
|
||||||
|
this.advancedParamDefines.push(define);
|
||||||
|
} else {
|
||||||
|
this.params.push(param);
|
||||||
|
this.paramDefines.push(define);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.warn(message.msg);
|
console.warn(message.msg);
|
||||||
@@ -83,6 +99,21 @@ export class MonitorNewComponent implements OnInit {
|
|||||||
this.monitor.name = `${this.monitor.app.toUpperCase()}_${hostValue}`;
|
this.monitor.name = `${this.monitor.app.toUpperCase()}_${hostValue}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onParamBooleanChanged(booleanValue: boolean, field: string) {
|
||||||
|
// 对SSL的端口联动处理, 不开启SSL默认80端口,开启SSL默认443
|
||||||
|
if (field === 'ssl') {
|
||||||
|
this.params.forEach(param => {
|
||||||
|
if (param.field === 'port') {
|
||||||
|
if (booleanValue) {
|
||||||
|
param.value = '443';
|
||||||
|
} else {
|
||||||
|
param.value = '80';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit(formGroup: FormGroup) {
|
onSubmit(formGroup: FormGroup) {
|
||||||
if (formGroup.invalid) {
|
if (formGroup.invalid) {
|
||||||
Object.values(formGroup.controls).forEach(control => {
|
Object.values(formGroup.controls).forEach(control => {
|
||||||
@@ -104,10 +135,15 @@ export class MonitorNewComponent implements OnInit {
|
|||||||
param.value = (param.value as string).trim();
|
param.value = (param.value as string).trim();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.advancedParams.forEach(param => {
|
||||||
|
if (param.value != null && typeof param.value == 'string') {
|
||||||
|
param.value = (param.value as string).trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
let addMonitor = {
|
let addMonitor = {
|
||||||
detected: this.detected,
|
detected: this.detected,
|
||||||
monitor: this.monitor,
|
monitor: this.monitor,
|
||||||
params: this.params
|
params: this.params.concat(this.advancedParams)
|
||||||
};
|
};
|
||||||
this.isSpinning = true;
|
this.isSpinning = true;
|
||||||
this.monitorSvc.newMonitor(addMonitor).subscribe(
|
this.monitorSvc.newMonitor(addMonitor).subscribe(
|
||||||
@@ -148,10 +184,15 @@ export class MonitorNewComponent implements OnInit {
|
|||||||
param.value = (param.value as string).trim();
|
param.value = (param.value as string).trim();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.advancedParams.forEach(param => {
|
||||||
|
if (param.value != null && typeof param.value == 'string') {
|
||||||
|
param.value = (param.value as string).trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
let detectMonitor = {
|
let detectMonitor = {
|
||||||
detected: true,
|
detected: true,
|
||||||
monitor: this.monitor,
|
monitor: this.monitor,
|
||||||
params: this.params
|
params: this.params.concat(this.advancedParams)
|
||||||
};
|
};
|
||||||
this.isSpinning = true;
|
this.isSpinning = true;
|
||||||
this.monitorSvc.detectMonitor(detectMonitor).subscribe(
|
this.monitorSvc.detectMonitor(detectMonitor).subscribe(
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { MonitorEditComponent } from './monitor-edit/monitor-edit.component';
|
|||||||
import { MonitorListComponent } from './monitor-list/monitor-list.component';
|
import { MonitorListComponent } from './monitor-list/monitor-list.component';
|
||||||
import { MonitorNewComponent } from './monitor-new/monitor-new.component';
|
import { MonitorNewComponent } from './monitor-new/monitor-new.component';
|
||||||
import { MonitorRoutingModule } from './monitor-routing.module';
|
import { MonitorRoutingModule } from './monitor-routing.module';
|
||||||
|
import { NzCollapseModule } from 'ng-zorro-antd/collapse';
|
||||||
|
|
||||||
const COMPONENTS: Array<Type<void>> = [
|
const COMPONENTS: Array<Type<void>> = [
|
||||||
MonitorNewComponent,
|
MonitorNewComponent,
|
||||||
@@ -37,7 +38,8 @@ const COMPONENTS: Array<Type<void>> = [
|
|||||||
NzRadioModule,
|
NzRadioModule,
|
||||||
NgxEchartsModule,
|
NgxEchartsModule,
|
||||||
NzLayoutModule,
|
NzLayoutModule,
|
||||||
NzSpaceModule
|
NzSpaceModule,
|
||||||
|
NzCollapseModule
|
||||||
],
|
],
|
||||||
declarations: COMPONENTS
|
declarations: COMPONENTS
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
### 公共通用小组件
|
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<div *ngFor="let item of keyValues; let i = index" nz-row>
|
||||||
|
<div nz-col nzSpan="10">
|
||||||
|
<input nz-input [placeholder]="keyAlias" [(ngModel)]="item.key" (ngModelChange)="onChange()" />
|
||||||
|
</div>
|
||||||
|
<div nz-col nzSpan="11">
|
||||||
|
<input nz-input [placeholder]="valueAlias" [(ngModel)]="item.value" (ngModelChange)="onChange()" />
|
||||||
|
</div>
|
||||||
|
<div nz-col nzSpan="3">
|
||||||
|
<i nz-icon nzType="plus-circle" class="dynamic-button" *ngIf="i === 0" (click)="addNew($event)"></i>
|
||||||
|
<i nz-icon nzType="minus-circle" class="dynamic-button" (click)="removeCurrent(i, $event)"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
.dynamic-button {
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
top: 20%;
|
||||||
|
font-size: 15px;
|
||||||
|
transition: all 0.3s;
|
||||||
|
margin-left: 12%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-button:hover {
|
||||||
|
font-size: 26px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { KeyValueInputComponent } from './key-value-input.component';
|
||||||
|
|
||||||
|
describe('KeyValueInputComponent', () => {
|
||||||
|
let component: KeyValueInputComponent;
|
||||||
|
let fixture: ComponentFixture<KeyValueInputComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ KeyValueInputComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(KeyValueInputComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-key-value-input',
|
||||||
|
templateUrl: './key-value-input.component.html',
|
||||||
|
styleUrls: ['./key-value-input.component.less']
|
||||||
|
})
|
||||||
|
export class KeyValueInputComponent implements OnInit {
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
@Input() value!: any;
|
||||||
|
@Output() readonly valueChange = new EventEmitter<string>();
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
keyAlias: string = 'Key';
|
||||||
|
@Input()
|
||||||
|
valueAlias: string = 'Value';
|
||||||
|
|
||||||
|
keyValues: any[] = [];
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
if (this.value == undefined) {
|
||||||
|
this.value = {
|
||||||
|
'': ''
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.value = JSON.parse(this.value);
|
||||||
|
}
|
||||||
|
Object.keys(this.value).map(item => {
|
||||||
|
this.keyValues.push({
|
||||||
|
key: item,
|
||||||
|
value: this.value[item]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addNew(e?: MouseEvent) {
|
||||||
|
if (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
this.keyValues.push({
|
||||||
|
key: '',
|
||||||
|
value: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
removeCurrent(index: number, e?: MouseEvent) {
|
||||||
|
if (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
if (this.keyValues.length > 1) {
|
||||||
|
this.keyValues.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onChange() {
|
||||||
|
this.value = {};
|
||||||
|
this.keyValues.forEach(item => {
|
||||||
|
if (item != null && item.key != null) {
|
||||||
|
this.value[item.key] = item.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.valueChange.emit(JSON.stringify(this.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import { DelonACLModule } from '@delon/acl';
|
|||||||
import { DelonFormModule } from '@delon/form';
|
import { DelonFormModule } from '@delon/form';
|
||||||
import { AlainThemeModule } from '@delon/theme';
|
import { AlainThemeModule } from '@delon/theme';
|
||||||
|
|
||||||
|
import { KeyValueInputComponent } from './components/key-value-input/key-value-input.component';
|
||||||
import { TimezonePipe } from './pipe/timezone.pipe';
|
import { TimezonePipe } from './pipe/timezone.pipe';
|
||||||
import { SHARED_DELON_MODULES } from './shared-delon.module';
|
import { SHARED_DELON_MODULES } from './shared-delon.module';
|
||||||
import { SHARED_ZORRO_MODULES } from './shared-zorro.module';
|
import { SHARED_ZORRO_MODULES } from './shared-zorro.module';
|
||||||
@@ -18,7 +19,7 @@ const THIRDMODULES: Array<Type<void>> = [];
|
|||||||
|
|
||||||
// #region your components & directives
|
// #region your components & directives
|
||||||
|
|
||||||
const COMPONENTS: Array<Type<void>> = [];
|
const COMPONENTS: Array<Type<void>> = [KeyValueInputComponent];
|
||||||
const DIRECTIVES: Array<Type<void>> = [TimezonePipe];
|
const DIRECTIVES: Array<Type<void>> = [TimezonePipe];
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"name": "TANCLOUD",
|
"name": "HertzBeat",
|
||||||
"description": "易用友好的高性能监控云"
|
"description": "易用友好的高性能监控云"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 8.9 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 8.9 KiB |
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>TanCloud</title>
|
<title>HertzBeat</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
|||||||
Reference in New Issue
Block a user