Compare commits

..

3 Commits

Author SHA1 Message Date
tomsun28
02ebca02cc [docs]api tags i18n, update readme (#103) 2022-04-21 22:04:15 +08:00
会编程的王学长
1c31b3ff0c feat: [manager]feature:App/Account Controller compatible with Chinese and English #wqh (#90) 2022-04-21 21:44:54 +08:00
tomsun28
0b82096ff7 [doc,manager,webapp]support deploy with osrc.com 2022-04-19 20:18:01 +08:00
28 changed files with 183 additions and 187 deletions

122
OSRC.md
View File

@@ -1,122 +0,0 @@
## HertzBeat 赫兹跳动在开源运行时OSRC部署流程
### HertzBeat介绍
> 易用友好的监控告警系统。
![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/web-monitor.svg)
![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/ping-connect.svg)
![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/port-available.svg)
![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/database-monitor.svg)
![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/os-monitor.svg)
![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/custom-monitor.svg)
![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/threshold.svg)
![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/alert.svg)
**官网: [hertzbeat.com](https://hertzbeat.com) | [tancloud.cn](https://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`的多类型支持,易扩展,低耦合,希望能帮助开发者和中小团队快速搭建自有监控系统。
----
### 在开源运行时社区的部署过程
1. 注册开源运行时社区账户 osrc.com
进入网站 osrc.com 登录注册购买需要的云服务器或Serverless
2. 本地安装osrc开发者工具
```
# clone maplecloudy-osrc-tools to local
git clone https://github.com/maplecloudy/maplecloudy-osrt-tools.git
# 下载后通过maven在本地安装
mvn clean install
# 进入osrc-cli目录安装cli
npm install
npm link
# 支持 osrc 看cli是否安装成功
osrc
```
4. 部署依赖服务-MYSQL和TDengine
> HertzBeat最少依赖于 关系型数据库[MYSQL5+](https://www.mysql.com/) 和 时序性数据库[TDengine2+](https://www.taosdata.com/getting-started)
> 我们需要将依赖服务部署到公有云上,即数据存储自己保存,计算运行在开源运行时社区,保证数据安全性。
###### 部署MYSQL
- docker安装MYSQl
`docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7`
- 创建名称为hertzbeat的数据库
- 执行位于项目仓库/script/sql/目录下的数据库脚本 [schema.sql](https://gitee.com/dromara/hertzbeat/raw/master/script/sql/schema.sql)
详细步骤参考 [依赖服务MYSQL安装初始化](https://hertzbeat.com/docs/start/mysql-init)
###### 部署TDengine
- docker安装TDengine
`docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/udp --name tdengine tdengine/tdengine:2.4.0.12`
- 创建名称为hertzbeat的数据库
详细步骤参考 [依赖服务TDengine安装初始化](https://hertzbeat.com/docs/start/tdengine-init)
2. 拉取hertzbeat项目代码git切换到`osrc`分支
[github仓库](https://github.com/dromara/hertzbeat) [gitee仓库](https://github.com/dromara/hertzbeat)
```
git clone https://github.com/dromara/hertzbeat.git
git checkout osrc
```
3. 配置MYSQL-TDengine服务连接
修改位于 `hertzbeat/manager/resources/application.yml` 的配置文件
需要替换里面的MYSQL服务和TDengine服务参数IP端口账户密码
具体替换参数如下:
```
spring.datasource.url
spring.datasource.username
spring.datasource.password
warehouse.store.td-engine.url
warehouse.store.td-engine.username
warehouse.store.td-engine.password
```
4. 注册OSRC账户上传部署hertzbeat后端服务
进入网站 https://osrc.com , 注册用户
在本地hertzbeat项目下执行 `mvn clean intall` 部署上传到osrc
注意交互控制台会提示输入账户密码登录。
5. 启动hertzbeat后端服务
进入网站 https://osrc.com, 个人中心 -> 我的应用 -> 启动服务
<img alt="tan-cloud" src="https://tancloud.gd2.qingstor.com/tmp/%E6%88%AA%E5%B1%8F2022-04-19%2017.59.20.png" width="1000"/>
6. 构建前端项目
在本地hertzbeat项目下 `web-app` 目录下执行 `yarn build`
7. 上传部署hertzbeat前端服务
在本地hertzbeat项目下 `web-app` 目录下执行 `osrc deploy`
8. 配置前端代理
进入网站 https://osrc.com, 个人中心 -> 我的pages -> 代理配置
配置前端调用接口流量走刚刚部署的后台服务
<img alt="tan-cloud" src="https://tancloud.gd2.qingstor.com/tmp/cc.png" width="1000"/>
9. 部署完成,发布应用
部署OK点击page页面连接即可使用服务

View File

@@ -8,7 +8,7 @@
## HertzBeat 赫兹跳动 | [English Documentation](README_EN.md) ## HertzBeat 赫兹跳动 | [English Documentation](README_EN.md)
> 易用友好的监控告警系统。 > 易用友好的监控系统无需Agent强大自定义监控能力
![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/web-monitor.svg) ![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/web-monitor.svg)
![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/ping-connect.svg) ![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/ping-connect.svg)
@@ -28,7 +28,7 @@
> [HertzBeat赫兹跳动](https://github.com/dromara/hertzbeat) 是由[Dromara](https://dromara.org)孵化,[TanCloud](https://tancloud.cn)开源的一个支持网站APIPING端口数据库操作系统等监控类型拥有易用友好的可视化操作界面的开源监控告警项目。 > [HertzBeat赫兹跳动](https://github.com/dromara/hertzbeat) 是由[Dromara](https://dromara.org)孵化,[TanCloud](https://tancloud.cn)开源的一个支持网站APIPING端口数据库操作系统等监控类型拥有易用友好的可视化操作界面的开源监控告警项目。
> 我们也提供了对应的 **[SAAS版本监控云](https://console.tancloud.cn)**,中小团队和个人无需再为了监控自己的网站资源,而去部署一套繁琐的监控系统,**[登录即可免费开始](https://console.tancloud.cn)**。 > 我们也提供了对应的 **[SAAS版本监控云](https://console.tancloud.cn)**,中小团队和个人无需再为了监控自己的网站资源,而去部署一套繁琐的监控系统,**[登录即可免费开始](https://console.tancloud.cn)**。
> HertzBeat 支持[自定义监控](https://hertzbeat.com/docs/advanced/extend-point) ,只用通过配置YML文件我们就可以自定义需要的监控类型和指标来满足常见的个性化需求。 > HertzBeat 支持[自定义监控](https://hertzbeat.com/docs/advanced/extend-point) ,只用通过配置YML文件我们就可以自定义需要的监控类型和指标来满足常见的个性化需求。
> HertzBeat 模块化,`manager, collector, scheduler, warehouse, alerter` 各个模块解耦合,方便理解与定制开发。 > HertzBeat 模块化,`manager, collector, warehouse, alerter` 各个模块解耦合,方便理解与定制开发。
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模版,邮件钉钉微信飞书等及时通知送达 > HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模版,邮件钉钉微信飞书等及时通知送达
> 欢迎登录 HertzBeat 的 [云环境TanCloud](https://console.tancloud.cn) 试用发现更多。 > 欢迎登录 HertzBeat 的 [云环境TanCloud](https://console.tancloud.cn) 试用发现更多。
> 我们正在快速迭代中,欢迎参与加入一起共建项目开源生态。 > 我们正在快速迭代中,欢迎参与加入一起共建项目开源生态。
@@ -47,8 +47,6 @@
> 提供对监控的管理,监控应用配置的管理,系统用户租户后台管理等。 > 提供对监控的管理,监控应用配置的管理,系统用户租户后台管理等。
- **[collector](https://github.com/dromara/hertzbeat/tree/master/collector)** 提供监控数据采集服务 - **[collector](https://github.com/dromara/hertzbeat/tree/master/collector)** 提供监控数据采集服务
> 使用通用协议远程采集获取对端指标数据。 > 使用通用协议远程采集获取对端指标数据。
- **[scheduler](https://github.com/dromara/hertzbeat/tree/master/scheduler)** 提供监控任务调度服务
> 采集任务管理,一次性任务和周期性任务的调度分发。
- **[warehouse](https://github.com/dromara/hertzbeat/tree/master/warehouse)** 提供监控数据仓储服务 - **[warehouse](https://github.com/dromara/hertzbeat/tree/master/warehouse)** 提供监控数据仓储服务
> 采集指标结果数据管理,数据落盘,查询,计算统计。 > 采集指标结果数据管理,数据落盘,查询,计算统计。
- **[alerter](https://github.com/dromara/hertzbeat/tree/master/alerter)** 提供告警服务 - **[alerter](https://github.com/dromara/hertzbeat/tree/master/alerter)** 提供告警服务

View File

@@ -22,6 +22,8 @@
**Home: [hertzbeat.com](https://hertzbeat.com) | [tancloud.cn](https://tancloud.cn)** **Home: [hertzbeat.com](https://hertzbeat.com) | [tancloud.cn](https://tancloud.cn)**
Running HertzBeat in [OSCR.COM](https://osrc.com) Open Source Runtime Community - [Doc](https://osrc.com/user/articles/wiki_776513931985080320)
## 🎡 <font color="green">Introduction</font> ## 🎡 <font color="green">Introduction</font>
> [HertzBeat](https://github.com/dromara/hertzbeat) is an opensource monitoring and alarm project incubated by [Dromara](https://dromara.org) and open sourced by [TanCloud](https://tancloud.cn), which supports Website, API, PING, Port, Database, OS Monitor etc. > [HertzBeat](https://github.com/dromara/hertzbeat) is an opensource monitoring and alarm project incubated by [Dromara](https://dromara.org) and open sourced by [TanCloud](https://tancloud.cn), which supports Website, API, PING, Port, Database, OS Monitor etc.
@@ -46,8 +48,6 @@
> Provides monitoring management, monitoring configuration management, system user management, etc. > Provides monitoring management, monitoring configuration management, system user management, etc.
- **[collector](https://github.com/dromara/hertzbeat/tree/master/collector)** Provide metrics data collection services. - **[collector](https://github.com/dromara/hertzbeat/tree/master/collector)** Provide metrics data collection services.
> Use common protocols to remotely collect and obtain peer-to-peer metrics data. > Use common protocols to remotely collect and obtain peer-to-peer metrics data.
- **[scheduler](https://github.com/dromara/hertzbeat/tree/master/scheduler)** Provide monitoring task scheduling service.
> Collection task management, scheduling and distribution of one-time tasks and periodic tasks.
- **[warehouse](https://github.com/dromara/hertzbeat/tree/master/warehouse)** Provide monitoring data warehousing services. - **[warehouse](https://github.com/dromara/hertzbeat/tree/master/warehouse)** Provide monitoring data warehousing services.
> Metrics data management, data query, calculation and statistics. > Metrics data management, data query, calculation and statistics.
- **[alerter](https://github.com/dromara/hertzbeat/tree/master/alerter)** Provide alert service. - **[alerter](https://github.com/dromara/hertzbeat/tree/master/alerter)** Provide alert service.

View File

@@ -31,7 +31,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
* @author tom * @author tom
* @date 2021/12/9 10:32 * @date 2021/12/9 10:32
*/ */
@Api(tags = "告警定义管理API") @Api(tags = "Alert Define API | 告警定义管理API")
@RestController @RestController
@RequestMapping(path = "/alert/define", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/alert/define", produces = {APPLICATION_JSON_VALUE})
public class AlertDefineController { public class AlertDefineController {

View File

@@ -31,7 +31,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
* @author tom * @author tom
* @date 2021/12/9 10:32 * @date 2021/12/9 10:32
*/ */
@Api(tags = "告警定义管理API") @Api(tags = "Alert Define Batch API | 告警定义管理API")
@RestController @RestController
@RequestMapping(path = "/alert/defines", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/alert/defines", produces = {APPLICATION_JSON_VALUE})
public class AlertDefinesController { public class AlertDefinesController {

View File

@@ -35,7 +35,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
* @author tom * @author tom
* @date 2021/12/9 10:32 * @date 2021/12/9 10:32
*/ */
@Api(tags = "en: Alarm batch management API, zh:告警批量管理API") @Api(tags = "Alarm Manage Batch API | 告警批量管理API")
@RestController @RestController
@RequestMapping(path = "/alerts", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/alerts", produces = {APPLICATION_JSON_VALUE})
public class AlertsController { public class AlertsController {

View File

@@ -22,7 +22,9 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
/** /**
* todo 字段默认值 * todo 字段默认值
* Monitoring parameter definitions
* 监控参数定义 * 监控参数定义
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/13 21:49 * @date 2021/11/13 21:49
*/ */
@@ -32,57 +34,68 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(description = "参数结构定义实体") @ApiModel(description = "en: Parameter structure definition entity,zh: 参数结构定义实体")
public class ParamDefine { public class ParamDefine {
/**
* Parameter Structure ID
*/
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "参数结构ID", example = "87584674384", accessMode = READ_ONLY, position = 0) @ApiModelProperty(value = "参数结构ID", example = "87584674384", accessMode = READ_ONLY, position = 0)
private Long id; private Long id;
/** /**
* Monitoring application type name
* 监控应用类型名称 * 监控应用类型名称
*/ */
@ApiModelProperty(value = "监控类型", example = "TanCloud", accessMode = READ_WRITE, position = 1) @ApiModelProperty(value = "监控类型", example = "TanCloud", accessMode = READ_WRITE, position = 1)
private String app; private String app;
/** /**
* Parameter field external display name
* 参数字段对外显示名称 * 参数字段对外显示名称
*/ */
@ApiModelProperty(value = "参数字段显示名称", example = "端口", accessMode = READ_WRITE, position = 2) @ApiModelProperty(value = "参数字段显示名称", example = "端口", accessMode = READ_WRITE, position = 2)
private String name; private String name;
/** /**
* Parameter Field Identifier
* 参数字段标识符 * 参数字段标识符
*/ */
@ApiModelProperty(value = "参数字段标识符", example = "port", accessMode = READ_WRITE, position = 3) @ApiModelProperty(value = "参数字段标识符", example = "port", accessMode = READ_WRITE, position = 3)
private String field; private String field;
/** /**
* Field type, style (mostly map the input tag type attribute)
* 字段类型,样式(大部分映射input标签type属性) * 字段类型,样式(大部分映射input标签type属性)
*/ */
@ApiModelProperty(value = "字段类型,样式(大部分映射input标签type属性)", example = "number", accessMode = READ_WRITE, position = 4) @ApiModelProperty(value = "字段类型,样式(大部分映射input标签type属性)", example = "number", accessMode = READ_WRITE, position = 4)
private String type; private String type;
/** /**
* Is it mandatory true-required false-optional
* 是否是必输项 true-必填 false-可选 * 是否是必输项 true-必填 false-可选
*/ */
@ApiModelProperty(value = "是否是必输项 true-必填 false-可选", example = "true", accessMode = READ_WRITE, position = 5) @ApiModelProperty(value = "是否是必输项 true-必填 false-可选", example = "true", accessMode = READ_WRITE, position = 5)
private boolean required = false; private boolean required = false;
/** /**
* Parameter Default Value
* 参数默认值 * 参数默认值
*/ */
@ApiModelProperty(value = "参数默认值", example = "12", accessMode = READ_WRITE, position = 6) @ApiModelProperty(value = "参数默认值", example = "12", accessMode = READ_WRITE, position = 6)
private String defaultValue; private String defaultValue;
/** /**
* Parameter input box prompt information
* 参数输入框提示信息 * 参数输入框提示信息
*/ */
@ApiModelProperty(value = "参数输入框提示信息", example = "请输入密码", accessMode = READ_WRITE, position = 7) @ApiModelProperty(value = "参数输入框提示信息", example = "请输入密码", accessMode = READ_WRITE, position = 7)
private String placeholder; private String placeholder;
/** /**
* When type is number, use range to represent the range eg: 0-233
* 当type为number时,用range表示范围 eg: 0-233 * 当type为number时,用range表示范围 eg: 0-233
*/ */
@ApiModelProperty(value = "当type为number时,用range区间表示范围", example = "[0,233]", accessMode = READ_WRITE, position = 6) @ApiModelProperty(value = "当type为number时,用range区间表示范围", example = "[0,233]", accessMode = READ_WRITE, position = 6)
@@ -90,6 +103,7 @@ public class ParamDefine {
private String range; private String range;
/** /**
* When type is text, use limit to indicate the limit size of the string. The maximum is 255
* 当type为text时,用limit表示字符串限制大小.最大255 * 当type为text时,用limit表示字符串限制大小.最大255
*/ */
@ApiModelProperty(value = "当type为text时,用limit表示字符串限制大小.最大255", example = "30", accessMode = READ_WRITE, position = 7) @ApiModelProperty(value = "当type为text时,用limit表示字符串限制大小.最大255", example = "30", accessMode = READ_WRITE, position = 7)
@@ -97,6 +111,7 @@ public class ParamDefine {
private Short limit; private Short limit;
/** /**
* When the type is radio radio box, checkbox checkbox, options represents a list of optional values
* 当type为radio单选框,checkbox复选框时,options表示可选项值列表 * 当type为radio单选框,checkbox复选框时,options表示可选项值列表
* eg: { * eg: {
* "key1":"value1", * "key1":"value1",
@@ -111,36 +126,42 @@ public class ParamDefine {
private List<Option> options; private List<Option> options;
/** /**
* Valid when type is key-value, indicating the alias description of the key
* 当type为key-value时有效,表示key的别名描述 * 当type为key-value时有效,表示key的别名描述
*/ */
@ApiModelProperty(value = "当type为key-value时有效,表示key的别名描述", example = "Name", accessMode = READ_WRITE, position = 9) @ApiModelProperty(value = "当type为key-value时有效,表示key的别名描述", example = "Name", accessMode = READ_WRITE, position = 9)
private String keyAlias; private String keyAlias;
/** /**
* Valid when type is key-value, indicating the alias description of value type
* 当type为key-value时有效,表示value的别名描述 * 当type为key-value时有效,表示value的别名描述
*/ */
@ApiModelProperty(value = "当type为key-value时有效,表示value的别名描述", example = "Value", accessMode = READ_WRITE, position = 10) @ApiModelProperty(value = "当type为key-value时有效,表示value的别名描述", example = "Value", accessMode = READ_WRITE, position = 10)
private String valueAlias; private String valueAlias;
/** /**
* Is it an advanced hidden parameter true-yes false-no
* 是否是高级隐藏参数 true-是 false-否 * 是否是高级隐藏参数 true-是 false-否
*/ */
@ApiModelProperty(value = "是否是高级隐藏参数 true-是 false-否", example = "true", accessMode = READ_WRITE, position = 11) @ApiModelProperty(value = "是否是高级隐藏参数 true-是 false-否", example = "true", accessMode = READ_WRITE, position = 11)
private boolean hide = false; private boolean hide = false;
/** /**
* The creator of this record
* 此条记录创建者 * 此条记录创建者
*/ */
@ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 11) @ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 11)
private String creator; private String creator;
/** /**
* This record was last modified by
* 此条记录最新修改者 * 此条记录最新修改者
*/ */
@ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 12) @ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 12)
private String modifier; private String modifier;
/** /**
* record creation time
* 记录创建时间 * 记录创建时间
*/ */
@ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 13) @ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 13)
@@ -148,6 +169,7 @@ public class ParamDefine {
private LocalDateTime gmtCreate; private LocalDateTime gmtCreate;
/** /**
* Record the latest modification time
* 记录最新修改时间 * 记录最新修改时间
*/ */
@ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 14) @ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 14)
@@ -159,10 +181,12 @@ public class ParamDefine {
@NoArgsConstructor @NoArgsConstructor
public static final class Option { public static final class Option {
/** /**
* value display label
* 值显示标签 * 值显示标签
*/ */
private String label; private String label;
/** /**
* optional value
* 可选值 * 可选值
*/ */
private String value; private String value;

View File

@@ -52,12 +52,12 @@ Detailed steps refer to [Install HertzBeat via package](https://hertzbeat.com/do
3. Webneed `nodejs npm angular-cli` environment, Run `ng serve --open` in `web-app` directory after backend startup. 3. Webneed `nodejs npm angular-cli` environment, Run `ng serve --open` in `web-app` directory after backend startup.
4. Access `localhost:4200` to start, default account: `admin/admin` 4. Access `localhost:4200` to start, default account: `admin/admin`
Detailed steps refer to [CONTRIBUTING](CONTRIBUTING.md) Detailed steps refer to [CONTRIBUTING](../others/contributing)
##### 4Install All(mysql+tdengine+hertzbeat) via Docker-compose ##### 4Install All(mysql+tdengine+hertzbeat) via Docker-compose
Install and deploy the mysql database, tdengine database and hertzbeat at one time through [docker-compose deployment script](script/docker-compose). Install and deploy the mysql database, tdengine database and hertzbeat at one time through [docker-compose deployment script](https://github.com/dromara/hertzbeat/tree/master/script/docker-compose).
Detailed steps refer to [docker-compose install](script/docker-compose/README.md) Detailed steps refer to [docker-compose install](https://github.com/dromara/hertzbeat/tree/master/script/docker-compose)
**HAVE FUN** **HAVE FUN**

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -107,17 +107,64 @@
</dependencies> </dependencies>
<build> <build>
<finalName>hertzbeat</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>application.yml</include>
<include>sureness.yml</include>
<include>banner.txt</include>
<include>define/**</include>
<include>**/*.html</include>
</includes>
</resource>
</resources>
<plugins> <plugins>
<plugin> <plugin>
<groupId>com.maplecloudy.osrt</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maplecloudy-osrt-maven-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>1.0.0-RELEASE</version> <version>3.2.0</version>
<configuration>
<classesDirectory>target/classes/</classesDirectory>
<archive>
<!--生成的jar包不包含maven描述相关文件-->
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<!--项目启动类-->
<mainClass>com.usthe.manager.Manager</mainClass>
<useUniqueVersions>false</useUniqueVersions>
<!--第三方JAR加入类构建的路径maven-dependency-plugin-->
<addClasspath>true</addClasspath>
<!--外部依赖jar包的位置-->
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>. config</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<!--关键插件,maven提供的assembly插件,需要放在最后-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions> <executions>
<execution> <execution>
<id>make-zip</id>
<!--绑定的maven操作-->
<phase>package</phase>
<!--运行一次-->
<goals> <goals>
<goal>repackage</goal> <goal>single</goal>
<goal>install-osrt-app</goal>
</goals> </goals>
<configuration>
<descriptors>
<descriptor>../script/assembly/server/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution> </execution>
</executions> </executions>
</plugin> </plugin>

View File

@@ -26,7 +26,7 @@ public class SwaggerConfig {
return new Docket(DocumentationType.OAS_30) return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo()) .apiInfo(apiInfo())
.enable(true) .enable(true)
.groupName("TanCloud") .groupName("HertzBeat")
.select() .select()
.apis(RequestHandlerSelectors.any()) .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("(?!/error.*).*")) .paths(PathSelectors.regex("(?!/error.*).*"))
@@ -35,7 +35,7 @@ public class SwaggerConfig {
private ApiInfo apiInfo(){ private ApiInfo apiInfo(){
return new ApiInfo( return new ApiInfo(
"TanCloud", "HertzBeat",
null, null,
"v1.0", "v1.0",
null, null,

View File

@@ -29,17 +29,20 @@ import static com.usthe.common.util.CommonConstants.MONITOR_LOGIN_FAILED_CODE;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/** /**
* Authentication registration TOKEN management API
* 认证注册TOKEN管理API * 认证注册TOKEN管理API
*
* @author tomsun28 * @author tomsun28
* @date 13:11 2019-05-26 * @date 13:11 2019-05-26
*/ */
@Api(tags = "认证注册TOKEN管理API") @Api(tags = "Auth Manage API | 认证注册TOKEN管理API")
@RestController() @RestController()
@RequestMapping(value = "/account/auth", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(value = "/account/auth", produces = {APPLICATION_JSON_VALUE})
@Slf4j @Slf4j
public class AccountController { public class AccountController {
/** /**
* Token validity time in seconds
* TOKEN有效期时间 单位秒 * TOKEN有效期时间 单位秒
*/ */
private static final long PERIOD_TIME = 3600L; private static final long PERIOD_TIME = 3600L;
@@ -50,7 +53,7 @@ public class AccountController {
private SurenessAccountProvider accountProvider = new DocumentAccountProvider(); private SurenessAccountProvider accountProvider = new DocumentAccountProvider();
@PostMapping("/form") @PostMapping("/form")
@ApiOperation(value = "账户登录", notes = "账户密码登录获取关联用户信息") @ApiOperation(value = "Account password login to obtain associated user information", notes = "账户密码登录获取关联用户信息")
public ResponseEntity<Message<Map<String, String>>> authGetToken(@RequestBody LoginDto loginDto) { public ResponseEntity<Message<Map<String, String>>> authGetToken(@RequestBody LoginDto loginDto) {
SurenessAccount account = accountProvider.loadAccount(loginDto.getIdentifier()); SurenessAccount account = accountProvider.loadAccount(loginDto.getIdentifier());
@@ -76,7 +79,7 @@ public class AccountController {
} }
// Get the roles the user has - rbac // Get the roles the user has - rbac
List<String> roles = account.getOwnRoles(); List<String> roles = account.getOwnRoles();
// 签发TOKEN // Issue TOKEN 签发TOKEN
String issueToken = JsonWebTokenUtil.issueJwt(loginDto.getIdentifier(), PERIOD_TIME, roles); String issueToken = JsonWebTokenUtil.issueJwt(loginDto.getIdentifier(), PERIOD_TIME, roles);
Map<String, Object> customClaimMap = new HashMap<>(1); Map<String, Object> customClaimMap = new HashMap<>(1);
customClaimMap.put("refresh", true); customClaimMap.put("refresh", true);
@@ -88,9 +91,9 @@ public class AccountController {
} }
@GetMapping("/refresh/{refreshToken}") @GetMapping("/refresh/{refreshToken}")
@ApiOperation(value = "TOKEN刷新", notes = "使用刷新TOKEN重新获取TOKEN") @ApiOperation(value = "Use refresh TOKEN to re-acquire TOKEN", notes = "使用刷新TOKEN重新获取TOKEN")
public ResponseEntity<Message<Map<String, String>>> refreshToken( public ResponseEntity<Message<Map<String, String>>> refreshToken(
@ApiParam(value = "刷新TOKEN", example = "xxx") @ApiParam(value = "en: Refresh TOKEN,zh: 刷新TOKEN", example = "xxx")
@PathVariable("refreshToken") @NotNull final String refreshToken) { @PathVariable("refreshToken") @NotNull final String refreshToken) {
String userId; String userId;
boolean isRefresh; boolean isRefresh;
@@ -116,7 +119,7 @@ public class AccountController {
return ResponseEntity.ok(message); return ResponseEntity.ok(message);
} }
List<String> roles = account.getOwnRoles(); List<String> roles = account.getOwnRoles();
// 签发TOKEN // Issue TOKEN 签发TOKEN
String issueToken = JsonWebTokenUtil.issueJwt(userId, PERIOD_TIME, roles); String issueToken = JsonWebTokenUtil.issueJwt(userId, PERIOD_TIME, roles);
Map<String, Object> customClaimMap = new HashMap<>(1); Map<String, Object> customClaimMap = new HashMap<>(1);
customClaimMap.put("refresh", true); customClaimMap.put("refresh", true);

View File

@@ -21,11 +21,13 @@ import java.util.List;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/** /**
* Monitoring Type Management API
* 监控类型管理API * 监控类型管理API
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 16:47 * @date 2021/11/14 16:47
*/ */
@Api(tags = "监控类型管理API") @Api(tags = "Monitor Type Manage API | 监控类型管理API")
@RestController @RestController
@RequestMapping(path = "/apps", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/apps", produces = {APPLICATION_JSON_VALUE})
public class AppController { public class AppController {
@@ -34,25 +36,26 @@ public class AppController {
private AppService appService; private AppService appService;
@GetMapping(path = "/{app}/params") @GetMapping(path = "/{app}/params")
@ApiOperation(value = "查询监控类型的参数结构", notes = "根据app查询指定监控类型的需要输入参数的结构") @ApiOperation(value = "The structure of the input parameters required to specify the monitoring type according to the app query", notes = "根据app查询指定监控类型的需要输入参数的结构")
public ResponseEntity<Message<List<ParamDefine>>> queryAppParamDefines( public ResponseEntity<Message<List<ParamDefine>>> queryAppParamDefines(
@ApiParam(value = "监控类型名称", example = "api") @PathVariable("app") final String app) { @ApiParam(value = "en: Monitoring type name,zh: 监控类型名称", example = "api") @PathVariable("app") final String app) {
List<ParamDefine> paramDefines = appService.getAppParamDefines(app.toLowerCase()); List<ParamDefine> paramDefines = appService.getAppParamDefines(app.toLowerCase());
return ResponseEntity.ok(new Message<>(paramDefines)); return ResponseEntity.ok(new Message<>(paramDefines));
} }
@GetMapping(path = "/{app}/define") @GetMapping(path = "/{app}/define")
@ApiOperation(value = "查询监控类型的结构定义", notes = "根据app查询指定监控类型的定义结构") @ApiOperation(value = "The definition structure of the specified monitoring type according to the app query", notes = "根据app查询指定监控类型的定义结构")
public ResponseEntity<Message<Job>> queryAppDefine( public ResponseEntity<Message<Job>> queryAppDefine(
@ApiParam(value = "监控类型名称", example = "api") @PathVariable("app") final String app) { @ApiParam(value = "en: Monitoring type name,zh: 监控类型名称", example = "api") @PathVariable("app") final String app) {
Job define = appService.getAppDefine(app.toLowerCase()); Job define = appService.getAppDefine(app.toLowerCase());
return ResponseEntity.ok(new Message<>(define)); return ResponseEntity.ok(new Message<>(define));
} }
@GetMapping(path = "/hierarchy") @GetMapping(path = "/hierarchy")
@ApiOperation(value = "查询全部监控指标层级", notes = "查询所有监控的类型-指标组-指标层级,以层级结构输出") @ApiOperation(value = "Query all monitored types-indicator group-indicator level, output in a hierarchical structure", notes = "查询所有监控的类型-指标组-指标层级,以层级结构输出")
public ResponseEntity<Message<List<Hierarchy>>> queryAppsHierarchy( public ResponseEntity<Message<List<Hierarchy>>> queryAppsHierarchy(
@ApiParam(value = "语言类型", example = "zh-CN", defaultValue = "zh-CN") @ApiParam(value = "en: language type,zh: 语言类型",
example = "zh-CN", defaultValue = "zh-CN")
@RequestParam(name = "lang", required = false) String lang) { @RequestParam(name = "lang", required = false) String lang) {
if (lang == null || "".equals(lang)) { if (lang == null || "".equals(lang)) {
lang = "zh-CN"; lang = "zh-CN";

View File

@@ -21,7 +21,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
* @author tom * @author tom
* @date 2021/12/4 21:40 * @date 2021/12/4 21:40
*/ */
@Api(tags = "I18N国际化资源API") @Api(tags = "I18N API | I18N国际化资源API")
@RestController @RestController
@RequestMapping(path = "/i18n", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/i18n", produces = {APPLICATION_JSON_VALUE})
public class I18nController { public class I18nController {

View File

@@ -30,7 +30,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 10:57 * @date 2021/11/14 10:57
*/ */
@Api(tags = "en: Monitoring management API,zh: 监控管理API") @Api(tags = "Monitor Manage API | 监控管理API")
@RestController @RestController
@RequestMapping(path = "/monitor", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/monitor", produces = {APPLICATION_JSON_VALUE})
public class MonitorController { public class MonitorController {

View File

@@ -35,7 +35,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
* @author tom * @author tom
* @date 2021/12/1 20:43 * @date 2021/12/1 20:43
*/ */
@Api(tags = "en: Monitor and manage batch API,zh: 监控列表API") @Api(tags = "Monitor Manage Batch API | 监控列表API")
@RestController @RestController
@RequestMapping(path = "/monitors", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/monitors", produces = {APPLICATION_JSON_VALUE})
public class MonitorsController { public class MonitorsController {

View File

@@ -34,7 +34,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
* @author tom * @author tom
* @date 2021/12/16 16:18 * @date 2021/12/16 16:18
*/ */
@Api(tags = "en: Message Notification Configuration API,zh: 消息通知配置API") @Api(tags = "Notification Config API | 消息通知配置API")
@RestController() @RestController()
@RequestMapping(value = "/notice", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(value = "/notice", produces = {APPLICATION_JSON_VALUE})
public class NoticeConfigController { public class NoticeConfigController {

View File

@@ -24,7 +24,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
* @author tom * @author tom
* @date 2021/12/7 15:57 * @date 2021/12/7 15:57
*/ */
@Api(tags = "en: System Summary Statistics API,zh: 系统摘要统计API") @Api(tags = "Summary Statistics API | 系统摘要统计API")
@RestController @RestController
@RequestMapping(path = "/summary", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/summary", produces = {APPLICATION_JSON_VALUE})
public class SummaryController { public class SummaryController {

View File

@@ -6,16 +6,20 @@ import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;
/** /**
* Param Define Database Operations
* ParamDefine数据库操作 * ParamDefine数据库操作
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 11:27 * @date 2021/11/14 11:27
*/ */
public interface ParamDefineDao extends JpaRepository<ParamDefine, Long> { public interface ParamDefineDao extends JpaRepository<ParamDefine, Long> {
/** /**
* Query the parameter definitions under it according to the monitoring type
* 根据监控类型查询其下的参数定义 * 根据监控类型查询其下的参数定义
* @param app 监控类型 *
* @return 参数定义列表 * @param app Monitoring type 监控类型
* @return parameter definition list 参数定义列表
*/ */
List<ParamDefine> findParamDefinesByApp(String app); List<ParamDefine> findParamDefinesByApp(String app);
} }

View File

@@ -11,8 +11,11 @@ import java.util.List;
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE; import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
/** /**
* Hierarchical structure
* 层级关系结构 * 层级关系结构
* eg: Monitoring Type Indicator Group Indicator Information Hierarchy Relationship
* eg: 监控类型指标组指标信息层级关系 * eg: 监控类型指标组指标信息层级关系
*
* @author tom * @author tom
* @date 2021/12/12 16:23 * @date 2021/12/12 16:23
*/ */
@@ -21,18 +24,33 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
@Data @Data
public class Hierarchy { public class Hierarchy {
/**
* Category value
*/
@ApiModelProperty(value = "类别值", example = "os", accessMode = READ_WRITE, position = 0) @ApiModelProperty(value = "类别值", example = "os", accessMode = READ_WRITE, position = 0)
String category; String category;
/**
* Attribute value
*/
@ApiModelProperty(value = "属性值", example = "linux", accessMode = READ_WRITE, position = 1) @ApiModelProperty(value = "属性值", example = "linux", accessMode = READ_WRITE, position = 1)
String value; String value;
/**
* Attribute internationalization tag
*/
@ApiModelProperty(value = "属性国际化标签", example = "Linux系统", accessMode = READ_WRITE, position = 2) @ApiModelProperty(value = "属性国际化标签", example = "Linux系统", accessMode = READ_WRITE, position = 2)
String label; String label;
/**
* Is it a leaf node
*/
@ApiModelProperty(value = "是否是叶子节点", example = "true", accessMode = READ_WRITE, position = 3) @ApiModelProperty(value = "是否是叶子节点", example = "true", accessMode = READ_WRITE, position = 3)
Boolean isLeaf = false; Boolean isLeaf = false;
/**
* Next level of association
*/
@ApiModelProperty(value = "下一关联层级", accessMode = READ_WRITE, position = 4) @ApiModelProperty(value = "下一关联层级", accessMode = READ_WRITE, position = 4)
private List<Hierarchy> children; private List<Hierarchy> children;
} }

View File

@@ -13,7 +13,9 @@ import javax.validation.constraints.NotBlank;
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY; import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
/** /**
* Login registered account information transfer body username phone email
* 登录注册账户信息传输体 username phone email * 登录注册账户信息传输体 username phone email
*
* @author tomsun28 * @author tomsun28
* @date 20:36 2019-08-01 * @date 20:36 2019-08-01
*/ */
@@ -21,17 +23,27 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(description = "账户信息传输体") @ApiModel(description = "en: Account information transfer body,zh: 账户信息传输体")
public class LoginDto { public class LoginDto {
/**
* type
* 1. Account (email username and mobile phone number) password login 2. github login 3. WeChat login
*/
@ApiModelProperty(value = "类型", example = "1", accessMode = READ_ONLY, position = 0) @ApiModelProperty(value = "类型", example = "1", accessMode = READ_ONLY, position = 0)
@Range(min = 0, max = 4, message = "1.账户(邮箱用户名手机号)密码登录 2.github登录 3.微信登录") @Range(min = 0, max = 4, message = "1.账户(邮箱用户名手机号)密码登录 2.github登录 3.微信登录")
private Byte type; private Byte type;
/**
* User ID
*/
@ApiModelProperty(value = "用户标识", example = "1", accessMode = READ_ONLY, position = 0) @ApiModelProperty(value = "用户标识", example = "1", accessMode = READ_ONLY, position = 0)
@NotBlank(message = "Identifier can not null") @NotBlank(message = "Identifier can not null")
private String identifier; private String identifier;
/**
* key
*/
@ApiModelProperty(value = "密钥", example = "1", accessMode = READ_ONLY, position = 0) @ApiModelProperty(value = "密钥", example = "1", accessMode = READ_ONLY, position = 0)
@NotBlank(message = "Credential can not null") @NotBlank(message = "Credential can not null")
private String credential; private String credential;

View File

@@ -8,6 +8,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* Monitoring Type Management Interface
* 监控类型管理接口 * 监控类型管理接口
* *
* @author tomsun28 * @author tomsun28
@@ -16,10 +17,11 @@ import java.util.Map;
public interface AppService { public interface AppService {
/** /**
* Query the defined parameter structure based on the monitoring type
* 根据监控类型查询定义的参数结构 * 根据监控类型查询定义的参数结构
* *
* @param app 监控类型 * @param app Monitoring type 监控类型
* @return 参数结构列表 * @return list of parameter structures 参数结构列表
*/ */
List<ParamDefine> getAppParamDefines(String app); List<ParamDefine> getAppParamDefines(String app);
@@ -35,18 +37,20 @@ public interface AppService {
Job getAppDefine(String app) throws IllegalArgumentException; Job getAppDefine(String app) throws IllegalArgumentException;
/** /**
* Get defined monitoring I 18 N resources
* 获取定义的监控I18N资源 * 获取定义的监控I18N资源
* *
* @param lang 语言类型 * @param lang Language type 语言类型
* @return I18N资源 * @return I18N Resources I18N资源
*/ */
Map<String, String> getI18nResources(String lang); Map<String, String> getI18nResources(String lang);
/** /**
* Query all types of monitoring - indicator group - indicator level
* 查询所有监控的类型-指标组-指标层级 * 查询所有监控的类型-指标组-指标层级
* *
* @param lang 语言 * @param lang language 语言
* @return 层级信息 * @return level information 层级信息
*/ */
List<Hierarchy> getAllAppHierarchy(String lang); List<Hierarchy> getAllAppHierarchy(String lang);

View File

@@ -22,7 +22,12 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.*; import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**

View File

@@ -29,7 +29,7 @@ spring:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
username: root username: root
password: 123456 password: 123456
url: jdbc:mysql://103.20.220.86:3306/hertzbeat?useUnicode=true&characterEncoding=utf-8&useSSL=false url: jdbc:mysql://localhost:3306/hertzbeat?useUnicode=true&characterEncoding=utf-8&useSSL=false
platform: mysql platform: mysql
hikari: hikari:
max-lifetime: 120000 max-lifetime: 120000
@@ -66,7 +66,7 @@ warehouse:
td-engine: td-engine:
enabled: true enabled: true
driver-class-name: com.taosdata.jdbc.rs.RestfulDriver driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
url: jdbc:TAOS-RS://103.20.220.86:6041/hertzbeat url: jdbc:TAOS-RS://localhost:6041/hertzbeat
username: root username: root
password: taosdata password: taosdata

View File

@@ -34,7 +34,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
*/ */
@RestController @RestController
@RequestMapping(produces = {APPLICATION_JSON_VALUE}) @RequestMapping(produces = {APPLICATION_JSON_VALUE})
@Api(tags = "监控指标数据API") @Api(tags = "Metrics Data API | 监控指标数据API")
public class MetricsDataController { public class MetricsDataController {
private static final Integer METRIC_FULL_LENGTH = 3; private static final Integer METRIC_FULL_LENGTH = 3;

View File

@@ -4,7 +4,7 @@ export const environment = {
production: true, production: true,
useHash: false, useHash: false,
api: { api: {
baseUrl: '/api/', baseUrl: '/',
refreshTokenEnabled: true refreshTokenEnabled: true
} }
} as Environment; } as Environment;