Compare commits

..

15 Commits

Author SHA1 Message Date
tomsun28
e4e9b0d187 [home]适配支持Linux操作系统监控帮助文档 2022-03-12 14:06:13 +08:00
tomsun28
ffa3194113 [web-app]前端放开操作系统 2022-03-12 10:57:25 +08:00
tomsun28
f52247df67 [collector,manager]linux监控类型新增内存,磁盘,网络监控指标 2022-03-12 10:51:22 +08:00
tomsun28
25d692cf37 [collector,manager]支持Linux操作系统监控类型 2022-03-11 23:57:55 +08:00
tomsun28
0f5a0c0cfc [home]v1.0.beat5发布文档 2022-03-11 09:19:11 +08:00
Peng Guo
4404d2347b [script]!12 从源码中同步“认证鉴权”相关配置信息到“快速入门”指南相应内容
* 从源码中同步“认证鉴权”相关配置信息到“快速入门”指南相应内容
2022-03-10 12:39:44 +00:00
tomsun28
49660ff03f [manager]fix国际化异常 放开hierarchy接口认证保护 2022-03-09 17:31:24 +08:00
tomsun28
b2558d641d [web-app]隐藏操作系统菜单 2022-03-09 17:11:51 +08:00
tomsun28
a6038d1feb [script]版本1.0-beta.4修改为1.0-beta.5 2022-03-09 15:21:00 +08:00
会编程的王学长
eca634bd55 Merge pull request #17 from dromara/new-branch
feat: 模拟浏览器设置为chrome浏览器 #Issues 14
2022-03-09 14:49:42 +08:00
chenghua
c99cfaf2b7 feat: 模拟浏览器设置为chrome浏览器 #Issues 14 2022-03-09 10:20:23 +08:00
tomsun28
daa505ce20 [web-app]监控详情添加帮助链接 2022-03-09 08:54:36 +08:00
tomsun28
c2e60bebdd [home]新增postgresql帮助文档 2022-03-09 07:50:56 +08:00
tomsun28
8b97d0a2ca [collector,manager]feature 支持postgresql数据库的监控 (#16) 2022-03-08 17:17:24 +08:00
tomsun28
7c12eda30e [alerter,webapp]feature 告警配置支持多指标集合 !10
* [alerter,webapp]feature 告警配置支持多指标集合
2022-03-08 02:57:49 +00:00
32 changed files with 921 additions and 29 deletions

View File

@@ -91,6 +91,18 @@
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.3</version>
</dependency>
<!-- linux ssh -->
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
</project>

View File

@@ -21,9 +21,9 @@ import java.util.concurrent.TimeUnit;
public class CommonCache {
/**
* 默认缓存时间 30minute
* 默认缓存时间 10minute
*/
private static final long DEFAULT_CACHE_TIMEOUT = 30 * 60 * 1000L;
private static final long DEFAULT_CACHE_TIMEOUT = 10 * 60 * 1000L;
/**
* 默认最大缓存数量
@@ -155,6 +155,15 @@ public class CommonCache {
});
}
/**
* 新增或更新cache
* @param key 存储对象key
* @param value 存储对象
*/
public void addCache(Object key, Object value) {
addCache(key, value, DEFAULT_CACHE_TIMEOUT);
}
/**
* 根据缓存key获取缓存对象
* @param key key

View File

@@ -0,0 +1,25 @@
package com.usthe.collector.collect.common.ssh;
import lombok.extern.slf4j.Slf4j;
import org.apache.sshd.client.SshClient;
/**
* ssh公共client
* @author tom
* @date 2022/3/11 15:58
*/
@Slf4j
public class CommonSshClient {
private static SshClient sshClient;
static {
sshClient = SshClient.setUpDefaultClient();
sshClient.start();
}
public static SshClient getSshClient() {
return sshClient;
}
}

View File

@@ -11,6 +11,7 @@ import com.usthe.common.entity.job.protocol.JdbcProtocol;
import com.usthe.common.entity.message.CollectRep;
import com.usthe.common.util.CommonConstants;
import lombok.extern.slf4j.Slf4j;
import org.postgresql.util.PSQLException;
import java.sql.Connection;
import java.sql.DriverManager;
@@ -72,7 +73,16 @@ public class JdbcCommonCollect extends AbstractCollect {
} catch (CommunicationsException communicationsException) {
log.warn("Jdbc sql error: {}, code: {}.", communicationsException.getMessage(), communicationsException.getErrorCode());
builder.setCode(CollectRep.Code.UN_REACHABLE);
builder.setMsg("Query Error: " + communicationsException.getMessage() + " Code: " + communicationsException.getErrorCode());
builder.setMsg("Error: " + communicationsException.getMessage() + " Code: " + communicationsException.getErrorCode());
} catch (PSQLException psqlException) {
// for PostgreSQL 08001
if (CollectorConstants.POSTGRESQL_UN_REACHABLE_CODE.equals(psqlException.getSQLState())) {
// 对端链接失败 不可达
builder.setCode(CollectRep.Code.UN_REACHABLE);
} else {
builder.setCode(CollectRep.Code.FAIL);
}
builder.setMsg("Error: " + psqlException.getMessage() + " Code: " + psqlException.getSQLState());
} catch (SQLException sqlException) {
log.warn("Jdbc sql error: {}, code: {}.", sqlException.getMessage(), sqlException.getErrorCode());
builder.setCode(CollectRep.Code.FAIL);
@@ -253,6 +263,10 @@ public class JdbcCommonCollect extends AbstractCollect {
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase())
+ "?useUnicode=true&characterEncoding=utf-8&useSSL=false";
break;
case "postgresql":
url = "jdbc:postgresql://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase());
break;
default:
throw new IllegalArgumentException("Not support database platform: " + jdbcProtocol.getPlatform());

View File

@@ -406,7 +406,11 @@ public class HttpCollectImpl extends AbstractCollect {
}
}
}
// headers
// The default request header can be overridden if customized
// keep-alive
requestBuilder.addHeader(HttpHeaders.CONNECTION, "keep-alive");
requestBuilder.addHeader(HttpHeaders.USER_AGENT,"Mozilla/5.0 (Windows NT 6.1; WOW64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36");
// headers The custom request header is overwritten here
Map<String, String> headers = httpProtocol.getHeaders();
if (headers != null && !headers.isEmpty()) {
for (Map.Entry<String, String> header : headers.entrySet()) {
@@ -415,8 +419,6 @@ public class HttpCollectImpl extends AbstractCollect {
}
}
}
// keep-alive
requestBuilder.addHeader(HttpHeaders.CONNECTION, "keep-alive");
// add accept
if (DispatchConstants.PARSE_DEFAULT.equals(httpProtocol.getParseType())
|| DispatchConstants.PARSE_JSON_PATH.equals(httpProtocol.getParseType())) {

View File

@@ -0,0 +1,202 @@
package com.usthe.collector.collect.ssh;
import com.usthe.collector.collect.AbstractCollect;
import com.usthe.collector.collect.common.cache.CacheIdentifier;
import com.usthe.collector.collect.common.cache.CommonCache;
import com.usthe.collector.collect.common.ssh.CommonSshClient;
import com.usthe.collector.util.CollectorConstants;
import com.usthe.common.entity.job.Metrics;
import com.usthe.common.entity.job.protocol.SshProtocol;
import com.usthe.common.entity.message.CollectRep;
import com.usthe.common.util.CommonConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.springframework.util.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
/**
* ssh协议采集实现
* @author tom
* @date 2022/03/11 15:10
*/
@Slf4j
public class SshCollectImpl extends AbstractCollect {
private static final String PARSE_TYPE_ONE_ROW = "oneRow";
private static final String PARSE_TYPE_MULTI_ROW = "multiRow";
private SshCollectImpl(){}
public static SshCollectImpl getInstance() {
return SshCollectImpl.Singleton.INSTANCE;
}
@Override
public void collect(CollectRep.MetricsData.Builder builder, long appId, String app, Metrics metrics) {
long startTime = System.currentTimeMillis();
// 校验参数
try {
validateParams(metrics);
} catch (Exception e) {
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(e.getMessage());
return;
}
SshProtocol sshProtocol = metrics.getSsh();
// 超时时间默认300毫秒
int timeout = 3000;
try {
timeout = Integer.parseInt(sshProtocol.getTimeout());
} catch (Exception e) {
log.warn(e.getMessage());
}
try {
ClientSession clientSession = getConnectSession(sshProtocol, timeout);
ClientChannel channel = clientSession.createExecChannel(sshProtocol.getScript());
ByteArrayOutputStream response = new ByteArrayOutputStream();
channel.setOut(response);
if (!channel.open().verify(timeout).isOpened()) {
throw new Exception("open failed");
}
List<ClientChannelEvent> list = new ArrayList<>();
list.add(ClientChannelEvent.CLOSED);
channel.waitFor(list, timeout);
Long responseTime = System.currentTimeMillis() - startTime;
channel.close();
String result = response.toString();
if (!StringUtils.hasText(result)) {
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("采集数据失败");
}
switch (sshProtocol.getParseType()) {
case PARSE_TYPE_ONE_ROW:
parseResponseDataByOne(result, metrics.getAliasFields(), builder, responseTime);
break;
default: parseResponseDataByMulti(result, metrics.getAliasFields(), builder, responseTime);
break;
}
} catch (ConnectException connectException) {
log.debug(connectException.getMessage());
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg("对端拒绝连接:服务未启动端口监听或防火墙");
} catch (IOException ioException) {
log.debug(ioException.getMessage());
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg("对端连接失败 " + ioException.getMessage());
} catch (Exception exception) {
log.debug(exception.getMessage());
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(exception.getMessage());
}
}
private void parseResponseDataByOne(String result, List<String> aliasFields, CollectRep.MetricsData.Builder builder, Long responseTime) {
String[] lines = result.split("\n");
if (lines.length + 1 < aliasFields.size()) {
log.error("ssh response data not enough: {}", result);
}
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
int aliasIndex = 0;
int lineIndex = 0;
while (aliasIndex < aliasFields.size()) {
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(aliasFields.get(aliasIndex))) {
valueRowBuilder.addColumns(responseTime.toString());
} else {
valueRowBuilder.addColumns(lines[lineIndex].trim());
lineIndex++;
}
aliasIndex++;
}
builder.addValues(valueRowBuilder.build());
}
private void parseResponseDataByMulti(String result, List<String> aliasFields,
CollectRep.MetricsData.Builder builder, Long responseTime) {
String[] lines = result.split("\n");
if (lines.length <= 1) {
log.error("ssh response data only has header: {}", result);
}
String[] fields = lines[0].split(" ");
Map<String, Integer> fieldMapping = new HashMap<>(fields.length);
for (int i = 0; i < fields.length; i++) {
fieldMapping.put(fields[i].trim().toLowerCase(), i);
}
for (int i = 1; i < lines.length; i++) {
String[] values = lines[i].split(" ");
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String alias : aliasFields) {
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(responseTime.toString());
} else {
Integer index = fieldMapping.get(alias.toLowerCase());
if (index != null && index < values.length) {
valueRowBuilder.addColumns(values[index]);
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
}
}
builder.addValues(valueRowBuilder.build());
}
}
private ClientSession getConnectSession(SshProtocol sshProtocol, int timeout) throws IOException {
CacheIdentifier identifier = CacheIdentifier.builder()
.ip(sshProtocol.getHost()).port(sshProtocol.getPort())
.username(sshProtocol.getUsername()).password(sshProtocol.getPassword())
.build();
Optional<Object> cacheOption = CommonCache.getInstance().getCache(identifier, true);
ClientSession clientSession = null;
if (cacheOption.isPresent()) {
clientSession = (ClientSession) cacheOption.get();
try {
if (clientSession.isClosed() || clientSession.isClosing()) {
clientSession = null;
CommonCache.getInstance().removeCache(identifier);
}
} catch (Exception e) {
log.warn(e.getMessage());
clientSession = null;
CommonCache.getInstance().removeCache(identifier);
}
}
if (clientSession != null) {
return clientSession;
}
SshClient sshClient = CommonSshClient.getSshClient();
clientSession = sshClient.connect(sshProtocol.getUsername(), sshProtocol.getHost(), Integer.parseInt(sshProtocol.getPort()))
.verify(timeout, TimeUnit.MILLISECONDS).getSession();
if (StringUtils.hasText(sshProtocol.getPassword())) {
clientSession.addPasswordIdentity(sshProtocol.getPassword());
}
// 进行认证
if (!clientSession.auth().verify(timeout, TimeUnit.MILLISECONDS).isSuccess()) {
throw new IllegalArgumentException("认证失败");
}
CommonCache.getInstance().addCache(identifier, clientSession);
return clientSession;
}
private void validateParams(Metrics metrics) throws Exception {
if (metrics == null || metrics.getSsh() == null) {
throw new Exception("Ssh collect must has ssh params");
}
}
private static class Singleton {
private static final SshCollectImpl INSTANCE = new SshCollectImpl();
}
}

View File

@@ -13,7 +13,7 @@ import java.io.IOException;
import java.net.ConnectException;
/**
* icmp协议采集实现 - ping
* telnet协议采集实现
* @author tom
* @date 2021/12/4 12:32
*/

View File

@@ -24,6 +24,10 @@ public interface DispatchConstants {
* 协议 jdbc
*/
String PROTOCOL_JDBC = "jdbc";
/**
* 协议 ssh
*/
String PROTOCOL_SSH = "ssh";
// 协议类型相关 - end //
// http协议相关 - start 需尽可能先复用 HttpHeaders //

View File

@@ -6,6 +6,7 @@ import com.usthe.collector.collect.AbstractCollect;
import com.usthe.collector.collect.database.JdbcCommonCollect;
import com.usthe.collector.collect.http.HttpCollectImpl;
import com.usthe.collector.collect.icmp.IcmpCollectImpl;
import com.usthe.collector.collect.ssh.SshCollectImpl;
import com.usthe.collector.collect.telnet.TelnetCollectImpl;
import com.usthe.collector.dispatch.timer.Timeout;
import com.usthe.collector.dispatch.timer.WheelTimerTask;
@@ -111,6 +112,9 @@ public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
case DispatchConstants.PROTOCOL_JDBC:
abstractCollect = JdbcCommonCollect.getInstance();
break;
case DispatchConstants.PROTOCOL_SSH:
abstractCollect = SshCollectImpl.getInstance();
break;
// todo
default: break;
}

View File

@@ -14,4 +14,9 @@ public interface CollectorConstants {
String ERROR_MSG = "errorMsg";
String URL = "url";
/**
* POSTGRESQL状态码 不可达
*/
String POSTGRESQL_UN_REACHABLE_CODE = "08001";
}

View File

@@ -3,6 +3,7 @@ package com.usthe.common.entity.job;
import com.usthe.common.entity.job.protocol.HttpProtocol;
import com.usthe.common.entity.job.protocol.IcmpProtocol;
import com.usthe.common.entity.job.protocol.JdbcProtocol;
import com.usthe.common.entity.job.protocol.SshProtocol;
import com.usthe.common.entity.job.protocol.TcpUdpProtocol;
import com.usthe.common.entity.job.protocol.TelnetProtocol;
import lombok.AllArgsConstructor;
@@ -73,6 +74,10 @@ public class Metrics {
* 使用公共的jdbc规范实现的数据库配置信息
*/
private JdbcProtocol jdbc;
/**
* 使用公共的ssh协议的监控配置信息
*/
private SshProtocol ssh;
@Override
public boolean equals(Object o) {

View File

@@ -0,0 +1,58 @@
package com.usthe.common.entity.job.protocol;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* ssh 协议参数配置
* @author tom
* @date 2022/3/11 15:20
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SshProtocol {
/**
* 对端主机ip或域名
*/
private String host;
/**
* 对端主机端口
*/
private String port;
/**
* 超时时间
*/
private String timeout = "3000";
/**
* 用户名
*/
private String username;
/**
* 密码(可选)
*/
private String password;
/**
* 公钥(可选)
*/
private String publicKey;
/**
* SSH执行脚本
*/
private String script;
/**
* 响应数据解析方式oneRow, multiRow
*/
private String parseType;
}

View File

@@ -1,5 +1,5 @@
---
title: HertzBeat赫兹节拍 v1.0.beta.4 发布,易用友好的高性能监控告警系统
title: HertzBeat赫兹节拍 v1.0.beta.4 发布,易用友好的监控告警系统
author: tom
author_title: tom
author_url: https://github.com/tomsun28

View File

@@ -0,0 +1,71 @@
---
title: HertzBeat赫兹节拍 v1.0.beta.5 发布,易用友好的监控告警系统
author: tom
author_title: tom
author_url: https://github.com/tomsun28
author_image_url: https://avatars.githubusercontent.com/u/24788200?s=400&v=4
tags: [opensource]
---
HertzBeat赫兹跳动是由Dromara孵化TanCloud开源的一个支持网站APIPING端口数据库全站等监控类型支持阈值告警告警通知(邮箱webhook钉钉企业微信飞书机器人),拥有易用友好的可视化操作界面的开源监控告警项目。
官网:hertzbeat.com | tancloud.cn
此升级版本包含了dashboard仪表盘重新设计阈值表达式支持多指标丰富了数据库监控类型新增mariaDB和postgreSQL数据库的监控控制台页面新增帮助文档等欢迎使用。
版本特性:
1. feature 支持mariadb监控类型 (#11)
2. feature dashboard仪表盘重构 (#13)
3. feature 告警配置支持多指标集合 !10 由 @pengliren 提出 thanks
4. feature 支持postgresql数据库的监控 (#16)
5. 新增监控默认开启探测.
6. 新增mysql采集指标.
7. 新增监控大类别,支持自定义监控页面菜单自动渲染
8. 操作页面新增帮助链接,完善自定义和阈值帮助文档
9. feat: 模拟浏览器设置为chrome浏览器 #Issues 14 由@learning-code 贡献 thanks
BUG修复
1. 登陆改登录,傻傻分不清.
2. 文档新增常见问题采集器http参数优化校验.
3. 采集器调度第0优先级失败则取消后续的优化.
4. bugfix website monitor path Illegal character in path at index
5. bugfix深色主题适配问题 (#10)
6. fix国际化异常 放开hierarchy接口认证保护
欢迎在线试用 https://console.tancloud.cn
-----------------------
> [HertzBeat赫兹跳动](https://github.com/dromara/hertzbeat) 是由[Dromara](https://dromara.org)孵化,[TanCloud](https://tancloud.cn)开源的一个支持网站APIPING端口数据库等监控类型拥有易用友好的可视化操作界面的开源监控告警项目。
> 我们也提供了对应的 **[SAAS版本监控云](https://console.tancloud.cn)**,中小团队和个人无需再为了监控自己的网站资源,而去部署一套繁琐的监控系统,**[登录即可免费开始](https://console.tancloud.cn)**。
> HertzBeat 支持[自定义监控](https://hertzbeat.com/docs/advanced/extend-point) ,只用通过配置YML文件我们就可以自定义需要的监控类型和指标来满足常见的个性化需求。
> HertzBeat 模块化,`manager, collector, scheduler, warehouse, alerter` 各个模块解耦合,方便理解与定制开发。
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模版,邮件钉钉微信飞书等及时通知送达
> 欢迎登录 HertzBeat 的 [云环境TanCloud](https://console.tancloud.cn) 试用发现更多。
> 我们正在快速迭代中,欢迎参与加入一起共建项目开源生态。
> `HertzBeat`的多类型支持,易扩展,低耦合,希望能帮助开发者和中小团队快速搭建自有监控系统。
老铁们可以通过演示视频来直观了解功能: https://www.bilibili.com/video/BV1Vi4y1f7i8
##### 欢迎联系交流哦
**微信交流群**
加微信号 tan-cloud 或 扫描下面账号二维码拉进微信群。
<img alt="tan-cloud" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/docs/help/tan-cloud-wechat.jpg" width="200"/>
**QQ交流群**
加QQ群号 718618151 或 扫描下面的群二维码进群, 验证信息: tancloud
<img alt="tan-cloud" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/docs/help/qq-qr.jpg" width="200"/>
**仓库地址**
[Github](https://github.com/dromara/hertzbeat) https://github.com/dromara/hertzbeat
[Gitee](https://gitee.com/dromara/hertzbeat) https://gitee.com/dromara/hertzbeat
看到这里不妨给个Star哦灰常感谢弯腰!!

View File

@@ -1,15 +1,15 @@
---
id: extend-mysql
title: MYSQL协议自定义监控
sidebar_label: MYSQL协议自定义监控
id: extend-jdbc
title: JDBC协议自定义监控
sidebar_label: JDBC协议自定义监控
---
> 从[自定义监控](extend-point)了解熟悉了怎么自定义类型,指标,协议等,这里我们来详细介绍下用MYSQL协议自定义指标监控。
> mysql协议自定义监控可以让我们很方便的通过写SQL查询语句就能监控到我们想监控的指标
> 从[自定义监控](extend-point)了解熟悉了怎么自定义类型,指标,协议等,这里我们来详细介绍下用JDBC(目前支持mysql,mariadb,postgresql)自定义指标监控。
> JDBC协议自定义监控可以让我们很方便的通过写SQL查询语句就能监控到我们想监控的指标
### MYSQL协议采集流程
### JDBC协议采集流程
【**系统直连MYSQL**】->【**运行SQL查询语句**】->【**响应数据解析:oneRow, multiRow, columns**】->【**指标数据提取**】
由流程可见,我们自定义一个MYSQL协议的监控类型,需要配置MYSQL请求参数配置获取哪些指标配置查询SQL语句。
由流程可见,我们自定义一个JDBC协议的监控类型,需要配置JDBC请求参数配置获取哪些指标配置查询SQL语句。
### 数据解析方式
SQL查询回来的数据字段和我们需要的指标映射就能获取对应的指标数据目前映射解析方式有三种oneRow, multiRow, columns

View File

@@ -4,7 +4,7 @@ title: 自定义监控
sidebar_label: 自定义监控
---
> HertzBeat拥有自定义监控能力您只需配置两个YML文件就能适配一款自定义的监控类型。
> 目前自定义监控支持[HTTP协议](extend-http)MYSQL协议,后续会支持更多通用协议(ssh telnet wmi snmp)。
> 目前自定义监控支持[HTTP协议](extend-http)[JDBC](extend-jdbc)(mysql,mariadb,postgresql..)协议,后续会支持更多通用协议(ssh telnet wmi snmp)。
### 自定义步骤

View File

@@ -18,7 +18,11 @@ sidebar_label: 帮助入门
### 数据库监控
[MYSQL数据库监控](mysql) &emsp;&emsp;&emsp;&emsp; [MariaDB数据库监控](mariadb)
[MYSQL数据库监控](mysql) &emsp;&emsp;&emsp;&emsp; [MariaDB数据库监控](mariadb) &emsp;&emsp;&emsp;&emsp; [PostgreSQL数据库监控](postgresql)
### 操作系统监控
[Linux操作系统监控](linux) &emsp;&emsp;&emsp;&emsp;
## 💡 告警服务

View File

@@ -10,7 +10,7 @@ sidebar_label: 常见问题
> 如信息所示输入的监控Host须是ipv4,ipv6或域名不能携带协议头例如协议头http
2. ** 网站API等监控反馈statusCode:403或401但对端服务本身无需认证浏览器直接访问是OK **
> 请排查是否是被防火墙拦截如宝塔等默认设置了对请求header中`User-Agent=Apache-HttpClient`的拦截,若被拦截请删除此拦截规则。
> 请排查是否是被防火墙拦截如宝塔等默认设置了对请求header中`User-Agent=Apache-HttpClient`的拦截,若被拦截请删除此拦截规则。(v1.0.beat5版本已将user-agent模拟成浏览器此问题不存在)
### Docker部署常见问题

70
home/docs/help/linux.md Normal file
View File

@@ -0,0 +1,70 @@
---
id: linux
title: 监控Linux操作系统监控
sidebar_label: Linux操作系统
---
> 对Linux操作系统的通用性能指标进行采集监控。
### 配置参数
| 参数名称 | 参数帮助描述 |
| ----------- | ----------- |
| 监控Host | 被监控的对端IPV4IPV6或域名。注意⚠不带协议头(eg: https://, http://)。 |
| 监控名称 | 标识此监控的名称,名称需要保证唯一性。 |
| 端口 | Linux SSH对外提供的端口默认为22。 |
| 用户名 | SSH连接用户名可选 |
| 密码 | SSH连接密码可选 |
| 采集间隔 | 监控周期性采集数据间隔时间单位秒可设置的最小间隔为10秒 |
| 是否探测 | 新增监控前是否先探测检查监控可用性,探测成功才会继续新增修改操作 |
| 描述备注 | 更多标识和描述此监控的备注信息,用户可以在这里备注信息 |
### 采集指标
#### 指标集合basic
| 指标名称 | 指标单位 | 指标帮助描述 |
| ----------- | ----------- | ----------- |
| hostname | 无 | 主机名称 |
| version | 无 | 操作系统版本 |
| uptime | 无 | 系统运行时间 |
#### 指标集合cpu
| 指标名称 | 指标单位 | 指标帮助描述 |
| ----------- | ----------- | ----------- |
| info | 无 | CPU型号 |
| cores | 核数 | CPU内核数量 |
| interrupt | 个数 | CPU中断数量 |
| load | 无 | CPU最近1/5/15分钟的平均负载 |
| context_switch | 个数 | 当前上下文切换数量 |
#### 指标集合memory
| 指标名称 | 指标单位 | 指标帮助描述 |
| ----------- | ----------- | ----------- |
| total | Mb | 总内存容量 |
| used | Mb | 用户程序内存量 |
| free | Mb | 空闲内存容量 |
| buff_cache | Mb | 缓存占用内存 |
| available | Mb | 剩余可用内存容 |
#### 指标集合disk
| 指标名称 | 指标单位 | 指标帮助描述 |
| ----------- | ----------- | ----------- |
| disk_num | 块数 | 磁盘总数 |
| partition_num | 分区数 | 分区总数 |
| block_write | 块数 | 写入磁盘的总块数 |
| block_read | 块数 | 从磁盘读出的块数 |
| write_rate | iops | 每秒写磁盘块的速率 |
#### 指标集合interface
| 指标名称 | 指标单位 | 指标帮助描述 |
| ----------- | ----------- | ----------- |
| interface_name | 无 | 网卡名称 |
| receive_bytes | byte | 入站数据流量(bytes) |
| transmit_bytes | byte | 出站数据流量(bytes) |

View File

@@ -12,7 +12,7 @@ sidebar_label: MariaDB数据库
| ----------- | ----------- |
| 监控Host | 被监控的对端IPV4IPV6或域名。注意⚠不带协议头(eg: https://, http://)。 |
| 监控名称 | 标识此监控的名称,名称需要保证唯一性。 |
| 端口 | 网站对外提供的端口,http一般默认为80https一般默认为443。 |
| 端口 | 数据库对外提供的端口,默认为3306。 |
| 数据库名称 | 数据库实例名称,可选。 |
| 用户名 | 数据库连接用户名,可选 |
| 密码 | 数据库连接密码,可选 |
@@ -40,8 +40,6 @@ sidebar_label: MariaDB数据库
| threads_connected | 无 | MariaDB已经连接的连接数 |
| threads_cached | 无 | MariaDB当前缓存的连接数 |
| threads_running | 无 | MariaDB当前活跃的连接数 |
| qps | 无 | 每秒请求查询次数。`QPS = questions/uptimes` |
| tps | 无 | 每秒事务数据 `TPS= (commit+rollback)/seconds`|
#### 指标集合innodb

View File

@@ -12,7 +12,7 @@ sidebar_label: MYSQL数据库
| ----------- | ----------- |
| 监控Host | 被监控的对端IPV4IPV6或域名。注意⚠不带协议头(eg: https://, http://)。 |
| 监控名称 | 标识此监控的名称,名称需要保证唯一性。 |
| 端口 | 网站对外提供的端口,http一般默认为80https一般默认为443。 |
| 端口 | 数据库对外提供的端口,默认为3306。 |
| 数据库名称 | 数据库实例名称,可选。 |
| 用户名 | 数据库连接用户名,可选 |
| 密码 | 数据库连接密码,可选 |
@@ -40,8 +40,6 @@ sidebar_label: MYSQL数据库
| threads_connected | 无 | MySql已经连接的连接数 |
| threads_cached | 无 | MySql当前缓存的连接数 |
| threads_running | 无 | MySql当前活跃的连接数 |
| qps | 无 | 每秒请求查询次数。`QPS = questions/uptimes` |
| tps | 无 | 每秒事务数据 `TPS= (commit+rollback)/seconds`|
#### 指标集合innodb

View File

@@ -0,0 +1,56 @@
---
id: postgresql
title: 监控PostgreSQL数据库监控
sidebar_label: PostgreSQL数据库
---
> 对PostgreSQL数据库的通用性能指标进行采集监控。支持PostgreSQL 10+。
### 配置参数
| 参数名称 | 参数帮助描述 |
| ----------- | ----------- |
| 监控Host | 被监控的对端IPV4IPV6或域名。注意⚠不带协议头(eg: https://, http://)。 |
| 监控名称 | 标识此监控的名称,名称需要保证唯一性。 |
| 端口 | 数据库对外提供的端口默认为5432。 |
| 数据库名称 | 数据库实例名称,可选。 |
| 用户名 | 数据库连接用户名,可选 |
| 密码 | 数据库连接密码,可选 |
| URL | 数据库连接URL可选若配置则URL里面的数据库名称用户名密码等参数会覆盖上面配置的参数 |
| 采集间隔 | 监控周期性采集数据间隔时间单位秒可设置的最小间隔为10秒 |
| 是否探测 | 新增监控前是否先探测检查监控可用性,探测成功才会继续新增修改操作 |
| 描述备注 | 更多标识和描述此监控的备注信息,用户可以在这里备注信息 |
### 采集指标
#### 指标集合basic
| 指标名称 | 指标单位 | 指标帮助描述 |
| ----------- | ----------- | ----------- |
| server_version | 无 | 数据库服务器的版本号 |
| port | 无 | 数据库服务器端暴露服务端口 |
| server_encoding | 无 | 数据库服务器端的字符集编码 |
| data_directory | 无 | 数据库存储数据盘地址 |
| max_connections | 连接数 | 数据库最大连接数 |
#### 指标集合state
| 指标名称 | 指标单位 | 指标帮助描述 |
| ----------- | ----------- | ----------- |
| name | 无 | 数据库名称或share-object为共享对象。 |
| conflicts | 次数 | 由于与恢复冲突而在这个数据库中被取消的查询的数目 |
| deadlocks | 个数 | 在这个数据库中被检测到的死锁数 |
| blks_read | 次数 | 在这个数据库中被读取的磁盘块的数量 |
| blks_hit | 次数 | 磁盘块被发现已经在缓冲区中的次数,这样不需要一次读取(这只包括 PostgreSQL 缓冲区中的命中,而不包括在操作系统文件系统缓冲区中的命中) |
| blk_read_time | ms | 在这个数据库中后端花费在读取数据文件块的时间 |
| blk_write_time | ms | 在这个数据库中后端花费在写数据文件块的时间 |
| stats_reset | 无 | 这些统计信息上次被重置的时间 |
#### 指标集合activity
| 指标名称 | 指标单位 | 指标帮助描述 |
| ----------- | ----------- | ----------- |
| running | 连接数 | 当前客户端连接数 |

View File

@@ -28,9 +28,9 @@
},
{
"type": "category",
"label": "MYSQL协议",
"label": "JDBC协议",
"items": [
"advanced/extend-mysql"
"advanced/extend-jdbc"
]
}
]
@@ -56,7 +56,15 @@
"label": "数据库监控",
"items": [
"help/mysql",
"help/mariadb"
"help/mariadb",
"help/postgresql"
]
},
{
"type": "category",
"label": "操作系统",
"items": [
"help/linux"
]
},
{

View File

@@ -0,0 +1,168 @@
# 此监控类型所属类别service-应用服务监控 db-数据库监控 custom-自定义监控 os-操作系统监控
category: os
# 监控应用类型(与文件名保持一致) eg: linux windows tomcat mysql aws...
app: linux
name:
zh-CN: Linux操作系统
en-US: OS Linux
# 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串
# 强制固定必须参数 - host
configmap:
- key: host
type: 1
- key: port
type: 0
- key: username
type: 1
- key: password
type: 2
# 指标组列表
metrics:
# 第一个监控指标组 basic
# 注意:内置监控指标有 (responseTime - 响应时间)
- name: basic
# 指标组调度优先级(0-127)越小优先级越高,优先级低的指标组会等优先级高的指标组采集完成后才会被调度,相同优先级的指标组会并行调度采集
# 优先级为0的指标组为可用性指标组,即它会被首先调度,采集成功才会继续调度其它指标组,采集失败则中断调度
priority: 0
# 指标组中的具体监控指标
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: hostname
type: 1
instance: true
- field: version
type: 1
- field: uptime
type: 1
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
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
parseType: multiRow
- name: cpu
priority: 1
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: info
type: 1
- field: cores
type: 0
unit: 核数
- field: interrupt
type: 0
unit: 个数
- field: load
type: 1
- field: context_switch
type: 0
unit: 个数
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
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
- name: memory
priority: 2
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: total
type: 0
unit: Mb
- field: used
type: 0
unit: Mb
- field: free
type: 0
unit: Mb
- field: buff_cache
type: 0
unit: Mb
- field: available
type: 0
unit: Mb
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
script: free -m | grep Mem | awk 'BEGIN{print "total used free buff_cache available"} {print $2,$3,$4,$6,$7}'
parseType: multiRow
- name: disk
priority: 3
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: disk_num
type: 0
unit: 块数
- field: partition_num
type: 0
unit: 分区数
- field: block_write
type: 0
unit: 块数
- field: block_read
type: 0
unit: 块数
- field: write_rate
type: 0
unit: iops
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
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
- name: interface
priority: 4
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: interface_name
type: 1
- field: receive_bytes
type: 0
unit: byte
- field: transmit_bytes
type: 0
unit: byte
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {print $1,$2,$10}'
parseType: multiRow

View File

@@ -0,0 +1,121 @@
category: db
app: postgresql
name:
zh-CN: PostgreSQL数据库
en-US: PostgreSQL DB
# 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串
# 强制固定必须参数 - host
configmap:
- key: host
type: 1
- key: port
type: 0
- key: username
type: 1
- key: password
type: 2
- key: database
type: 1
- key: url
type: 1
# 指标组列表
metrics:
- name: basic
# 指标组调度优先级(0-127)越小优先级越高,优先级低的指标组会等优先级高的指标组采集完成后才会被调度,相同优先级的指标组会并行调度采集
# 优先级为0的指标组为可用性指标组,即它会被首先调度,采集成功才会继续调度其它指标组,采集失败则中断调度
priority: 0
# 指标组中的具体监控指标
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: server_version
type: 1
instance: true
- field: port
type: 1
- field: server_encoding
type: 1
- field: data_directory
type: 1
- field: max_connections
type: 0
unit: 连接数
protocol: jdbc
jdbc:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
platform: postgresql
username: ^_^username^_^
password: ^_^password^_^
database: ^_^database^_^
# SQL查询方式 oneRow, multiRow, columns
queryType: columns
# sql
sql: select name, setting as value from pg_settings where name = 'max_connections' or name = 'server_version' or name = 'server_encoding' or name = 'port' or name = 'data_directory';
url: ^_^url^_^
- name: state
priority: 1
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: name
type: 1
- field: conflicts
type: 0
unit: 次数
- field: deadlocks
type: 0
unit: 个数
- field: blks_read
type: 0
unit: 次数
- field: blks_hit
type: 0
unit: 次数
- field: blk_read_time
type: 0
unit: ms
- field: blk_write_time
type: 0
unit: ms
- field: stats_reset
type: 1
protocol: jdbc
jdbc:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
platform: postgresql
username: ^_^username^_^
password: ^_^password^_^
database: ^_^database^_^
# SQL查询方式 oneRow, multiRow, columns
queryType: multiRow
# sql
sql: SELECT COALESCE(datname,'shared-object') as name, conflicts, deadlocks, blks_read, blks_hit, blk_read_time, blk_write_time, stats_reset from pg_stat_database where (datname != 'template1' and datname != 'template0') or datname is null;
url: ^_^url^_^
- name: activity
priority: 2
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: running
type: 0
unit: 连接数
protocol: jdbc
jdbc:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
platform: postgresql
username: ^_^username^_^
password: ^_^password^_^
database: ^_^database^_^
# SQL查询方式 oneRow, multiRow, columns
queryType: oneRow
# sql
sql: SELECT count(*) as running FROM pg_stat_activity WHERE NOT pid=pg_backend_pid();
url: ^_^url^_^

View File

@@ -0,0 +1,22 @@
app: linux
param:
- field: host
name: 主机Host
type: host
required: true
- field: port
name: 端口
type: number
range: '[0,65535]'
required: true
defaultValue: 22
placeholder: '请输入端口'
- field: username
name: 用户名
type: text
limit: 20
required: true
- field: password
name: 密码
type: password
required: true

View File

@@ -0,0 +1,30 @@
app: postgresql
param:
- field: host
name: 主机Host
type: host
required: true
- field: port
name: 端口
type: number
range: '[0,65535]'
required: true
defaultValue: 5432
placeholder: '请输入端口'
- field: database
name: 数据库名称
type: text
required: false
- field: username
name: 用户名
type: text
limit: 20
required: false
- field: password
name: 密码
type: password
required: false
- field: url
name: URL
type: text
required: false

View File

@@ -13,6 +13,7 @@ excludedResource:
- /account/auth/**===*
- /===get
- /i18n/**===get
- /apps/hierarchy===get
# web ui 静态资源
- /console/**===get
- /**/*.html===get

View File

@@ -3,7 +3,7 @@
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd
http://maven.apache.org/ASSEMBLY/2.0.0 ">
<!--必填,会追加到打包文件名称的末尾-->
<id>1.0-beta.4</id>
<id>1.0-beta.5</id>
<!--打包类型,可以设置多种类型,打包的时候不同的类型都会打包打出来-->
<formats>
<format>tar</format>

View File

@@ -2,7 +2,7 @@ FROM openjdk:8-alpine
MAINTAINER tomsun28 "tomsun28@outlook.com"
ADD hertzbeat-1.0-beta.4.tar /opt/
ADD hertzbeat-1.0-beta.5.tar /opt/
EXPOSE 1157

View File

@@ -13,6 +13,7 @@ excludedResource:
- /account/auth/**===*
- /===get
- /i18n/**===get
- /apps/hierarchy===get
# web ui 静态资源
- /console/**===get
- /**/*.html===get

View File

@@ -15,6 +15,10 @@
<nz-breadcrumb-item>
<i nz-icon nzType="pie-chart"></i>
<span>{{ 'monitor.app.' + app | i18n }} 监控详情</span>
<a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%">
<span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a>
</nz-breadcrumb-item>
</nz-breadcrumb>
<nz-divider></nz-divider>