Compare commits

..

1 Commits

Author SHA1 Message Date
tomsun28
0e6bf1618a [collector]bugfix: non-supported character set when monitor GBK oracle 2022-04-11 16:20:32 +08:00
70 changed files with 789 additions and 2258 deletions

View File

@@ -6,7 +6,7 @@
[comment]: <> (<img alt="sureness" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat/home/static/img/hertzbeat-brand.svg" width="300">) [comment]: <> (<img alt="sureness" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat/home/static/img/hertzbeat-brand.svg" width="300">)
## HertzBeat 赫兹跳动 | [English Documentation](README_EN.md) ## HertzBeat 赫兹跳动
> 易用友好的监控告警系统。 > 易用友好的监控告警系统。

View File

@@ -1,148 +0,0 @@
<p align="center">
<a href="https://hertzbeat.com">
<img alt="hertzbeat" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat/home/static/img/hertzbeat-brand.svg" width="260">
</a>
</p>
[comment]: <> (<img alt="sureness" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat/home/static/img/hertzbeat-brand.svg" width="300">)
## HertzBeat | [中文文档](README.md)
> Friendly cloud monitoring system.
![tan-cloud](https://img.shields.io/badge/web-monitor-4EB1BA)
![tan-cloud](https://img.shields.io/badge/api-monitor-lightgrey)
![tan-cloud](https://img.shields.io/badge/ping-connect-brightgreen)
![tan-cloud](https://img.shields.io/badge/port-available-green)
![tan-cloud](https://img.shields.io/badge/database-monitor-yellowgreen)
![tan-cloud](https://img.shields.io/badge/os-monitor-yellow)
![tan-cloud](https://img.shields.io/badge/custom-monitor-orange)
![tan-cloud](https://img.shields.io/badge/threshold-red)
![tan-cloud](https://img.shields.io/badge/alert-bule)
**Home: [hertzbeat.com](https://hertzbeat.com) | [tancloud.cn](https://tancloud.cn)**
## 🎡 <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.
> We also provide **[Monitoring Cloud For Saas](https://console.tancloud.cn)**, people no longer need to deploy a cumbersome monitoring system in order to monitor their website resources. **[Sign in to get started for free](https://console.tancloud.cn)**.
> HertzBeat supports more liberal threshold alarm configuration (calculation expression), supports alarm notification, alarm template, email, DingDing, WeChat FeiShu and WebHook.
> Most important is HertzBeat supports [Custom Monitoring](https://hertzbeat.com/docs/advanced/extend-point), just by configuring the YML file, we can customize the monitoring types and metrics what we need.
> HertzBeat is modular, `manager, collector, scheduler, warehouse, alerter` modules are decoupled for easy understanding and custom development.
> Welcome to HertzBeat's [Cloud Environment TanCloud](https://console.tancloud.cn) to try and discover more.
> Welcome to join us to build hertzbeat together.
> `HertzBeat`'s multi-type support, easy expansion, low coupling, hope to help developers and micro teams to quickly build their own monitoring system.
----
[![tancloud](tancloud.gif)](https://www.bilibili.com/video/BV1DY4y1i7ts)
----
## 🥐 Architecture
- **[manager](https://github.com/dromara/hertzbeat/tree/master/manager)** Provide monitoring management, system management basic services.
> Provides monitoring management, monitoring configuration management, system user management, etc.
- **[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.
- **[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.
> Metrics data management, data query, calculation and statistics.
- **[alerter](https://github.com/dromara/hertzbeat/tree/master/alerter)** Provide alert service.
> Alarm calculation trigger, monitoring status linkage, alarm configuration, and alarm notification.
- **[web-app](https://github.com/dromara/hertzbeat/tree/master/web-app)** Provide web ui.
> Angular Web UI.
![hertzBeat](home/static/img/docs/hertzbeat-stru-en.svg)
## 🐕 Quick Start
- If you dont want to deploy but use it directly, we provide [SAAS Monitoring Cloud-TanCloud](https://console.tancloud.cn), **[Log In And Register For Free](https://console.tancloud.cn) **.
- If you want to deploy HertzBeat local, please refer to the following [Deployment Documentation](https://hertzbeat.com/docs/start/quickstart) for operation.
### 🐵 Dependency Service Deployment
> HertzBeat depends at least on relational database [MYSQL5+](https://www.mysql.com/) and time series database [TDengine2+](https://www.taosdata.com/getting-started)
##### Install MYSQL
1. Install mysql with docker
`docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7`
2. Create database names `hertzbeat`
3. Run the database sql script [schema.sql](https://gitee.com/dromara/hertzbeat/raw/master/script/sql/schema.sql) located in the project repository `/script/sql/` directory.
For detailed steps, refer to [MYSQL Installation And Initialization](https://hertzbeat.com/docs/start/mysql-init)
##### Install TDengine
1. Install TDengine with docker
`docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/udp --name tdengine tdengine/tdengine:2.4.0.12`
2. Create database names `hertzbeat`
For detailed steps, refer to [TDengine Installation And Initialization](https://hertzbeat.com/docs/start/tdengine-init).
### 🍞 Install HertzBeat
> HertzBeat supports installation through source code, docker or package.
##### 1Install quickly via docker
`docker run -d -p 1157:1157 -v /opt/application.yml:/opt/hertzbeat/config/application.yml --name hertzbeat tancloud/hertzbeat:[版本tag]`
Detailed steps refer to [Install HertzBeat via Docker](https://hertzbeat.com/docs/start/docker-deploy)
##### 2Install via package
1. Download the installation package [GITEE Release](https://gitee.com/dromara/hertzbeat/releases) [GITHUB Release](https://github.com/dromara/hertzbeat/releases)
2. Configure the HertzBeat configuration yml file `hertzbeat/config/application.yml`
3. Run shell `$ ./startup.sh `
4. Access `localhost:1157` to start, default account: `admin/admin`
Detailed steps refer to [Install HertzBeat via package](https://hertzbeat.com/docs/start/package-deploy)
##### 3Start via source code
1. Local source code debugging needs to start the back-end project manager and the front-end project web-app.
2. Backendneed `maven3+`, `java8+`, start the manager service.
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`
Detailed steps refer to [CONTRIBUTING](CONTRIBUTING.md)
##### 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).
Detailed steps refer to [docker-compose install](script/docker-compose/README.md)
**HAVE FUN**
## 💬 Join discussion
HertzBeat is an incubation project of [Dromara Open Source Community](https://dromara.org/).
##### WeChat Group
Add WeChat account `tan-cloud` or scan the QR code below to pull you into the WeChat group.
<img alt="tan-cloud" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/docs/help/tan-cloud-wechat.jpg" width="200"/>
##### QQ Group
QQ group number `718618151` or scan the group QR code below, verify code: `tancloud`
<img alt="tan-cloud" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/docs/help/qq-qr.jpg" width="200"/>
##### Github Discussion
Welcome to Discuss in [Github Discussion](https://github.com/dromara/hertzbeat/discussions)
##### Public WeChat
<img alt="tan-cloud" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat/home/static/img/wechat.png" width="400"/>
##### Sponsor
Thanks [吉实信息(构建全新的微波+光交易网络)](https://www.flarespeed.com) sponsored server node.
Thanks [天上云计算(全新智慧上云)](https://www.tsyvps.com/aff/BZBEGYLX) sponsored server node.
## 🛡️ License
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)

View File

@@ -1,12 +1,10 @@
package com.usthe.alert; package com.usthe.alert;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* 数据仓储配置属性 * 数据仓储配置属性
*
* @author tom * @author tom
* @date 2021/11/24 10:38 * @date 2021/11/24 10:38
*/ */
@@ -14,22 +12,11 @@ import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "alerter") @ConfigurationProperties(prefix = "alerter")
public class AlerterProperties { public class AlerterProperties {
private String consoleUrl = "https://console.tancloud.cn";
public String getConsoleUrl() {
return consoleUrl;
}
public void setConsoleUrl(String url) {
this.consoleUrl = url;
}
/** /**
* 数据入口配置属性 * 数据入口配置属性
*/ */
private EntranceProperties entrance; private EntranceProperties entrance;
public EntranceProperties getEntrance() { public EntranceProperties getEntrance() {
return entrance; return entrance;
} }
@@ -38,7 +25,6 @@ public class AlerterProperties {
this.entrance = entrance; this.entrance = entrance;
} }
/** /**
* 数据入口配置属性 * 数据入口配置属性
* 入口可以是从kafka rabbitmq rocketmq等消息中间件获取数据 * 入口可以是从kafka rabbitmq rocketmq等消息中间件获取数据
@@ -112,5 +98,4 @@ public class AlerterProperties {
} }
} }

View File

@@ -7,43 +7,34 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List; import java.util.List;
/** /**
* AlertDefineBind database operations 数据库操作 * AlertDefineBind 数据库操作
*
* @author tom * @author tom
* @date 2021/12/9 10:03 * @date 2021/12/9 10:03
*/ */
public interface AlertDefineBindDao extends JpaRepository<AlertDefineMonitorBind, Long>, JpaSpecificationExecutor<AlertDefineMonitorBind> { public interface AlertDefineBindDao extends JpaRepository<AlertDefineMonitorBind, Long>, JpaSpecificationExecutor<AlertDefineMonitorBind> {
/** /**
* Delete the alarm definition and monitor association based on the alarm definition ID
* 根据告警定义ID删除告警定义与监控关联 * 根据告警定义ID删除告警定义与监控关联
* * @param alertDefineId 告警定义ID
* @param alertDefineId Alarm Definition ID 告警定义ID
*/ */
void deleteAlertDefineBindsByAlertDefineIdEquals(Long alertDefineId); void deleteAlertDefineBindsByAlertDefineIdEquals(Long alertDefineId);
/** /**
* Deleting alarms based on monitoring IDs defines monitoring associations
* 根据监控ID删除告警定义监控关联 * 根据监控ID删除告警定义监控关联
* * @param monitorId 监控ID
* @param monitorId Monitor Id 监控ID
*/ */
void deleteAlertDefineMonitorBindsByMonitorIdEquals(Long monitorId); void deleteAlertDefineMonitorBindsByMonitorIdEquals(Long monitorId);
/** /**
* Delete alarm definition monitoring association based on monitoring ID list
* 根据监控ID列表删除告警定义监控关联 * 根据监控ID列表删除告警定义监控关联
* * @param monitorIds 监控ID列表
* @param monitorIds Monitoring ID List 监控ID列表
*/ */
void deleteAlertDefineMonitorBindsByMonitorIdIn(List<Long> monitorIds); void deleteAlertDefineMonitorBindsByMonitorIdIn(List<Long> monitorIds);
/** /**
* Query monitoring related information based on alarm definition ID
* 根据告警定义ID查询监控关联信息 * 根据告警定义ID查询监控关联信息
* * @param alertDefineId 告警定义ID
* @param alertDefineId Alarm Definition ID 告警定义ID * @return 关联监控信息
* @return Associated monitoring information 关联监控信息
*/ */
List<AlertDefineMonitorBind> getAlertDefineBindsByAlertDefineIdEquals(Long alertDefineId); List<AlertDefineMonitorBind> getAlertDefineBindsByAlertDefineIdEquals(Long alertDefineId);
} }

View File

@@ -15,7 +15,6 @@ import java.util.concurrent.TimeUnit;
/** /**
* 采集job管理提供api接口 * 采集job管理提供api接口
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/6 13:58 * @date 2021/11/6 13:58
*/ */
@@ -27,11 +26,9 @@ public class CollectJobService {
private TimerDispatch timerDispatch; private TimerDispatch timerDispatch;
/** /**
* Execute a one-time collection task and get the collected data response
* 执行一次性采集任务,获取采集数据响应 * 执行一次性采集任务,获取采集数据响应
* * @param job 采集任务详情
* @param job Collect task details 采集任务详情 * @return 采集结果
* @return Collection results 采集结果
*/ */
public List<CollectRep.MetricsData> collectSyncJobData(Job job) { public List<CollectRep.MetricsData> collectSyncJobData(Job job) {
final List<CollectRep.MetricsData> metricsData = new LinkedList<>(); final List<CollectRep.MetricsData> metricsData = new LinkedList<>();
@@ -55,11 +52,9 @@ public class CollectJobService {
} }
/** /**
* Issue periodic asynchronous collection tasks
* 下发周期性异步采集任务 * 下发周期性异步采集任务
* * @param job 采集任务详情
* @param job Collect task details 采集任务详情 * @return long 任务ID
* @return long Job ID 任务ID
*/ */
public long addAsyncCollectJob(Job job) { public long addAsyncCollectJob(Job job) {
if (job.getId() == 0L) { if (job.getId() == 0L) {
@@ -71,10 +66,8 @@ public class CollectJobService {
} }
/** /**
* Update the periodic asynchronous collection tasks that have been delivered
* 更新已经下发的周期性异步采集任务 * 更新已经下发的周期性异步采集任务
* * @param modifyJob 采集任务详情
* @param modifyJob Collect task details 采集任务详情
*/ */
public void updateAsyncCollectJob(Job modifyJob) { public void updateAsyncCollectJob(Job modifyJob) {
timerDispatch.deleteJob(modifyJob.getId(), true); timerDispatch.deleteJob(modifyJob.getId(), true);
@@ -82,10 +75,8 @@ public class CollectJobService {
} }
/** /**
* Cancel periodic asynchronous collection tasks
* 取消周期性异步采集任务 * 取消周期性异步采集任务
* * @param jobId 任务ID
* @param jobId Job ID 任务ID
*/ */
public void cancelAsyncCollectJob(Long jobId) { public void cancelAsyncCollectJob(Long jobId) {
timerDispatch.deleteJob(jobId, true); timerDispatch.deleteJob(jobId, true);

View File

@@ -10,44 +10,36 @@ import java.util.concurrent.TimeUnit;
/** /**
* 时间轮调度接口 * 时间轮调度接口
*
* @author tomsun28 * @author tomsun28
* @date 2021/10/17 22:14 * @date 2021/10/17 22:14
*/ */
public interface TimerDispatch { public interface TimerDispatch {
/** /**
* Add new job
* 增加新的job * 增加新的job
* * @param addJob job
* @param addJob job * @param eventListener 一次性同步任务监听器异步任务不需要listener
* @param eventListener One-time synchronous task listener, asynchronous task does not need listener一次性同步任务监听器异步任务不需要listener
*/ */
void addJob(Job addJob, CollectResponseEventListener eventListener); void addJob(Job addJob, CollectResponseEventListener eventListener);
/** /**
* 调度循环周期性job * 调度循环周期性job
*
* @param timerTask timerTask * @param timerTask timerTask
* @param interval 开始调度的间隔时间 * @param interval 开始调度的间隔时间
* @param timeUnit 时间单位 * @param timeUnit 时间单位
*/ */
void cyclicJob(WheelTimerTask timerTask, long interval, TimeUnit timeUnit); void cyclicJob(WheelTimerTask timerTask, long interval, TimeUnit timeUnit);
/** /**
* Delete existing job
* 删除存在的job * 删除存在的job
* * @param jobId jobId
* @param jobId jobId * @param isCyclic 是否是周期性任务,true是, false为临时性任务
* @param isCyclic Whether it is a periodic task, true is, false is a temporary task
* 是否是周期性任务,true是, false为临时性任务
*/ */
void deleteJob(long jobId, boolean isCyclic); void deleteJob(long jobId, boolean isCyclic);
/** /**
* 一次性同步采集任务采集结果通知监听器 * 一次性同步采集任务采集结果通知监听器
* * @param jobId jobId
* @param jobId jobId
* @param metricsDataTemps 采集结果数据 * @param metricsDataTemps 采集结果数据
*/ */
void responseSyncJobData(long jobId, List<CollectRep.MetricsData> metricsDataTemps); void responseSyncJobData(long jobId, List<CollectRep.MetricsData> metricsDataTemps);

View File

@@ -18,22 +18,18 @@ import java.util.concurrent.TimeUnit;
public class TimerDispatcher implements TimerDispatch { public class TimerDispatcher implements TimerDispatch {
/** /**
* time round schedule
* 时间轮调度 * 时间轮调度
*/ */
private Timer wheelTimer; private Timer wheelTimer;
/** /**
* Existing periodic scheduled tasks
* 已存在的周期性调度任务 * 已存在的周期性调度任务
*/ */
private Map<Long, Timeout> currentCyclicTaskMap; private Map<Long, Timeout> currentCyclicTaskMap;
/** /**
* Existing temporary scheduled tasks
* 已存在的临时性调度任务 * 已存在的临时性调度任务
*/ */
private Map<Long, Timeout> currentTempTaskMap; private Map<Long, Timeout> currentTempTaskMap;
/** /**
* One-time task response listener holds
* 一次性任务响应监听器持有 * 一次性任务响应监听器持有
* jobId - listener * jobId - listener
*/ */

View File

@@ -22,9 +22,7 @@ import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* Timer Task implementation
* TimerTask实现 * TimerTask实现
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/1 17:18 * @date 2021/11/1 17:18
*/ */
@@ -38,15 +36,12 @@ public class WheelTimerTask implements TimerTask {
public WheelTimerTask(Job job) { public WheelTimerTask(Job job) {
this.metricsTaskDispatch = SpringContextHolder.getBean(MetricsTaskDispatch.class); this.metricsTaskDispatch = SpringContextHolder.getBean(MetricsTaskDispatch.class);
this.job = job; this.job = job;
// The initialization job will monitor the actual parameter value and replace the collection field
// 初始化job 将监控实际参数值对采集字段进行替换 // 初始化job 将监控实际参数值对采集字段进行替换
initJobMetrics(job); initJobMetrics(job);
} }
/** /**
* Initialize job fill information
* 初始化job填充信息 * 初始化job填充信息
*
* @param job job * @param job job
*/ */
private void initJobMetrics(Job job) { private void initJobMetrics(Job job) {
@@ -78,10 +73,9 @@ public class WheelTimerTask implements TimerTask {
} }
/** /**
* json parameter replacement json参数替换 * json参数替换
*
* @param jsonElement json * @param jsonElement json
* @param configmap parameter map 参数map * @param configmap 参数map
* @return json * @return json
*/ */
private JsonElement replaceSpecialValue(JsonElement jsonElement, Map<String, Configmap> configmap) { private JsonElement replaceSpecialValue(JsonElement jsonElement, Map<String, Configmap> configmap) {
@@ -92,29 +86,26 @@ public class WheelTimerTask implements TimerTask {
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(); String key = entry.getKey();
// Replace the attributes of the KEY-VALUE case such as http headers params
// 替换KEY-VALUE情况的属性 比如http headers params // 替换KEY-VALUE情况的属性 比如http headers params
if (key != null && key.startsWith("^_^") && key.endsWith("^_^")) { if (key != null && key.startsWith("^_^") && key.endsWith("^_^")) {
key = key.replaceAll("\\^_\\^", ""); key = key.replaceAll("\\^_\\^", "");
Configmap param = configmap.get(key); Configmap param = configmap.get(key);
if (param != null && param.getType() == (byte) 3) { if (param != null && param.getType() == (byte) 3) {
String jsonValue = (String) param.getValue(); String jsonValue = (String) param.getValue();
Map<String, String> map = GsonUtil.fromJson(jsonValue, Map.class); Map<String, String> map = GsonUtil.fromJson(jsonValue, Map.class);
if (map != null) { if (map != null) {
map.forEach((name, value) -> { map.forEach((name, value) -> {
if (name != null && !"".equals(name.trim())) { if (name != null && !"".equals(name.trim())) {
jsonObject.addProperty(name, value); jsonObject.addProperty(name, value);
} }
}); });
} }
} }
iterator.remove(); iterator.remove();
continue; continue;
} }
// Replace normal VALUE value
// 替换正常的VALUE值 // 替换正常的VALUE值
if (element.isJsonPrimitive()) { if (element.isJsonPrimitive()) {
// Check if there are special characters Replace
// 判断是否含有特殊字符 替换 // 判断是否含有特殊字符 替换
String value = element.getAsString(); String value = element.getAsString();
if (value.startsWith("^_^") && value.endsWith("^_^")) { if (value.startsWith("^_^") && value.endsWith("^_^")) {
@@ -138,7 +129,6 @@ public class WheelTimerTask implements TimerTask {
while (iterator.hasNext()) { while (iterator.hasNext()) {
JsonElement element = iterator.next(); JsonElement element = iterator.next();
if (element.isJsonPrimitive()) { if (element.isJsonPrimitive()) {
// Check if there are special characters Replace
// 判断是否含有特殊字符 替换 // 判断是否含有特殊字符 替换
String value = element.getAsString(); String value = element.getAsString();
if (value.startsWith("^_^") && value.endsWith("^_^")) { if (value.startsWith("^_^") && value.endsWith("^_^")) {

View File

@@ -6,12 +6,8 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
/** /**
* Monitoring configuration parameter properties and values
* 监控配置参数属性及值 * 监控配置参数属性及值
* During the process, you need to replace the content with the identifier ^_^key^_^
* in the protocol configuration parameter with the real value in the configuration parameter
* 过程中需要将协议配置参数里面的标识符为^_^key^_^的内容替换为配置参数里的真实值 * 过程中需要将协议配置参数里面的标识符为^_^key^_^的内容替换为配置参数里的真实值
*
* @author tomsun28 * @author tomsun28
* @date 2021/10/29 22:04 * @date 2021/10/29 22:04
*/ */
@@ -22,20 +18,16 @@ import lombok.NoArgsConstructor;
public class Configmap { public class Configmap {
/** /**
* Parameter key, replace the content with the identifier ^^_key_^^ in the protocol
* configuration parameter with the real value in the configuration parameter
* <p>
* 参数key,将协议配置参数里面的标识符为^^_key_^^的内容替换为配置参数里的真实值 * 参数key,将协议配置参数里面的标识符为^^_key_^^的内容替换为配置参数里的真实值
*/ */
private String key; private String key;
/** /**
* parameter value 参数value * 参数value
*/ */
private Object value; private Object value;
/** /**
* Parameter type 0: number 1: string 2: encrypted string 3: json string mapped by map
* 参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串 * 参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串
* number,string,secret * number,string,secret
* 数字,非加密字符串,加密字符串 * 数字,非加密字符串,加密字符串

View File

@@ -21,9 +21,7 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* Collect task details
* 采集任务详情 * 采集任务详情
*
* @author tomsun28 * @author tomsun28
* @date 2021/10/17 21:19 * @date 2021/10/17 21:19
*/ */
@@ -37,72 +35,61 @@ public class Job {
private static final String AVAILABILITY = "availability"; private static final String AVAILABILITY = "availability";
/** /**
* Task id 任务ID * 任务ID
*/ */
private long id; private long id;
/** /**
* Monitoring ID Application ID
* 监控ID 应用ID * 监控ID 应用ID
*/ */
private long monitorId; private long monitorId;
/** /**
* Large categories of monitoring 监控的大类别 * 监控的大类别
* service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
* service-应用服务监控 db-数据库监控 custom-自定义监控 os-操作系统监控 * service-应用服务监控 db-数据库监控 custom-自定义监控 os-操作系统监控
*/ */
private String category; private String category;
/** /**
* Type of monitoring eg: linux | mysql | jvm
* 监控的类型 eg: linux | mysql | jvm * 监控的类型 eg: linux | mysql | jvm
*/ */
private String app; private String app;
/** /**
* The internationalized name of the monitoring type 监控类型的国际化名称 * 监控类型的国际化名称
* zh-CN: PING连通性 * zh-CN: PING连通性
* en-US: PING CONNECT * en-US: PING CONNECT
*/ */
private Map<String, String> name; private Map<String, String> name;
/** /**
* Task dispatch start timestamp
* 任务派发开始时间戳 * 任务派发开始时间戳
*/ */
private long timestamp; private long timestamp;
/** /**
* Task collection time interval (unit: second) eg: 30,60,600
* 任务采集时间间隔(单位秒) eg: 30,60,600 * 任务采集时间间隔(单位秒) eg: 30,60,600
*/ */
private long interval = 600L; private long interval = 600L;
/** /**
* Whether it is a recurring periodic task true is yes, false is no
* 是否是循环周期性任务 true为是,false为否 * 是否是循环周期性任务 true为是,false为否
*/ */
private boolean isCyclic = false; private boolean isCyclic = false;
/** /**
* Indicator group configuration eg: cpu memory
* 指标组配置 eg: cpu memory * 指标组配置 eg: cpu memory
*/ */
private List<Metrics> metrics; private List<Metrics> metrics;
/** /**
* Monitoring configuration parameter properties and values eg: username password timeout host
* 监控配置参数属性及值 eg: username password timeout host * 监控配置参数属性及值 eg: username password timeout host
*/ */
private List<Configmap> configmap; private List<Configmap> configmap;
/** /**
* collector use - timestamp when the task was scheduled by the time wheel
* collector使用 - 任务被时间轮开始调度的时间戳 * collector使用 - 任务被时间轮开始调度的时间戳
*/ */
@JsonIgnore @JsonIgnore
private transient long dispatchTime; private transient long dispatchTime;
/** /**
* collector use - task version, this field is not stored in etcd
* collector使用 - 任务版本,此字段不存储于etcd * collector使用 - 任务版本,此字段不存储于etcd
*/ */
@JsonIgnore @JsonIgnore
private transient long version; private transient long version;
/** /**
* collector usage - metric group task execution priority view
* collector使用 - 指标组任务执行优先级视图 * collector使用 - 指标组任务执行优先级视图
* 0 - availability * 0 - availability
* 1 - cpu | memory * 1 - cpu | memory
@@ -116,32 +103,27 @@ public class Job {
private transient List<Set<Metrics>> priorMetrics; private transient List<Set<Metrics>> priorMetrics;
/** /**
* collector use - Temporarily store one-time task indicator group response data
* collector使用 - 临时存储一次性任务指标组响应数据 * collector使用 - 临时存储一次性任务指标组响应数据
*/ */
@JsonIgnore @JsonIgnore
private transient List<CollectRep.MetricsData> responseDataTemp; private transient List<CollectRep.MetricsData> responseDataTemp;
/** /**
* collector uses - construct to initialize metrics group execution view
* collector使用 - 构造初始化指标组执行视图 * collector使用 - 构造初始化指标组执行视图
*/ */
public synchronized void constructPriorMetrics() { public synchronized void constructPriorMetrics() {
Map<Byte, List<Metrics>> map = metrics.stream() Map<Byte, List<Metrics>> map = metrics.stream()
.peek(metric -> { .peek(metric -> {
// Determine whether to configure aliasFields If not, configure the default
// 判断是否配置aliasFields 没有则配置默认 // 判断是否配置aliasFields 没有则配置默认
if (metric.getAliasFields() == null || metric.getAliasFields().isEmpty()) { if (metric.getAliasFields() == null || metric.getAliasFields().isEmpty()) {
metric.setAliasFields(metric.getFields().stream().map(Metrics.Field::getField).collect(Collectors.toList())); metric.setAliasFields(metric.getFields().stream().map(Metrics.Field::getField).collect(Collectors.toList()));
} }
// Set the default indicator group execution priority, if not filled, the default last priority
// 设置默认的指标组执行优先级,不填则默认最后优先级 // 设置默认的指标组执行优先级,不填则默认最后优先级
if (metric.getPriority() == null) { if (metric.getPriority() == null) {
metric.setPriority(Byte.MAX_VALUE); metric.setPriority(Byte.MAX_VALUE);
} }
}) })
.collect(Collectors.groupingBy(Metrics::getPriority)); .collect(Collectors.groupingBy(Metrics::getPriority));
// Construct a linked list of task execution order of the indicator group
// 构造指标组任务执行顺序链表 // 构造指标组任务执行顺序链表
priorMetrics = new LinkedList<>(); priorMetrics = new LinkedList<>();
map.values().forEach(metric -> { map.values().forEach(metric -> {
@@ -159,18 +141,12 @@ public class Job {
} }
/** /**
* collector use - to get the next set of priority metric group tasks
* collector使用 - 获取下一组优先级的指标组任务 * collector使用 - 获取下一组优先级的指标组任务
* * @param metrics 当前指标组
* @param metrics Current indicator group 当前指标组 * @param first 是否是第一次获取
* @param first Is it the first time to get 是否是第一次获取 * @return 指标组任务
* @return Metric Group Tasks 指标组任务
* Returning null means: the job has been completed, and the collection of all indicator groups has ended
* 返回null表示job已完成,所有指标组采集结束 * 返回null表示job已完成,所有指标组采集结束
* Returning the empty set indicates that there are still indicator group collection tasks at the current
* level that have not been completed,and the next level indicator group task collection cannot be performed.
* 返回empty的集合表示当前级别下还有指标组采集任务未结束,无法进行下一级别的指标组任务采集 * 返回empty的集合表示当前级别下还有指标组采集任务未结束,无法进行下一级别的指标组任务采集
* Returns a set of data representation: get the next set of priority index group tasks
* 返回有数据集合表示:获取到下一组优先级的指标组任务 * 返回有数据集合表示:获取到下一组优先级的指标组任务
*/ */
public synchronized Set<Metrics> getNextCollectMetrics(Metrics metrics, boolean first) { public synchronized Set<Metrics> getNextCollectMetrics(Metrics metrics, boolean first) {
@@ -213,7 +189,7 @@ public class Job {
@Override @Override
public Job clone() { public Job clone() {
// deep clone 深度克隆 // 深度克隆
return GsonUtil.fromJson(GsonUtil.toJson(this), Job.class); return GsonUtil.fromJson(GsonUtil.toJson(this), Job.class);
} }
} }

View File

@@ -15,10 +15,7 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
/** /**
* Details of the collection of indicators collected by monitoring
* eg: cpu | memory | health
* 监控采集的指标集合详情 eg: cpu | memory | health * 监控采集的指标集合详情 eg: cpu | memory | health
*
* @author tomsun28 * @author tomsun28
* @date 2021/10/17 21:24 * @date 2021/10/17 21:24
*/ */
@@ -29,7 +26,6 @@ import java.util.Objects;
public class Metrics { public class Metrics {
/** /**
* public property-name eg: cpu | memory | health
* 公共属性-名称 eg: cpu | memory | health * 公共属性-名称 eg: cpu | memory | health
*/ */
private String name; private String name;
@@ -38,27 +34,20 @@ public class Metrics {
*/ */
private String protocol; private String protocol;
/** /**
* Range (0-127) indicator group scheduling priority, the smaller the value, the higher the priority
* The collection task of the next priority indicator group will be scheduled only after the scheduled collection with the higher priority is completed.
* The default priority of the availability indicator group is 0, and the range of other common indicator groups is 1-127, that is,
* the subsequent indicator group tasks will only be scheduled after the availability is collected successfully.
* 范围(0-127)指标组调度优先级,数值越小优先级越高 * 范围(0-127)指标组调度优先级,数值越小优先级越高
* 优先级高的调度采集完成后才会调度下一优先级的指标组采集任务 * 优先级高的调度采集完成后才会调度下一优先级的指标组采集任务
* 可用性指标组(availability)默认优先级为0,其它普通指标组范围为1-127,即需要等availability采集成功后才会调度后面的指标组任务 * 可用性指标组(availability)默认优先级为0,其它普通指标组范围为1-127,即需要等availability采集成功后才会调度后面的指标组任务
*/ */
private Byte priority; private Byte priority;
/** /**
* Public attribute - collection and monitoring final result attribute set eg: speed | times | size
* 公共属性-采集监控的最终结果属性集合 eg: speed | times | size * 公共属性-采集监控的最终结果属性集合 eg: speed | times | size
*/ */
private List<Field> fields; private List<Field> fields;
/** /**
* Public attribute - collection and monitoring pre-query attribute set eg: size1 | size2 | speedSize
* 公共属性-采集监控的前置查询属性集合 eg: size1 | size2 | speedSize * 公共属性-采集监控的前置查询属性集合 eg: size1 | size2 | speedSize
*/ */
private List<String> aliasFields; private List<String> aliasFields;
/** /**
* Public attribute - expression calculation, map the pre-query attribute (pre Fields) with the final attribute (fields), and calculate the final attribute (fields) value
* 公共属性-表达式计算,将前置查询属性(preFields)与最终属性(fields)映射,计算出最终属性(fields)值 * 公共属性-表达式计算,将前置查询属性(preFields)与最终属性(fields)映射,计算出最终属性(fields)值
* eg: size = size1 + size2, speed = speedSize * eg: size = size1 + size2, speed = speedSize
* https://www.yuque.com/boyan-avfmj/aviatorscript/ban32m * https://www.yuque.com/boyan-avfmj/aviatorscript/ban32m
@@ -66,32 +55,26 @@ public class Metrics {
private List<String> calculates; private List<String> calculates;
/** /**
* Monitoring configuration information using the http protocol
* 使用http协议的监控配置信息 * 使用http协议的监控配置信息
*/ */
private HttpProtocol http; private HttpProtocol http;
/** /**
* Monitoring configuration information for ping using the icmp protocol
* 使用icmp协议进行ping的监控配置信息 * 使用icmp协议进行ping的监控配置信息
*/ */
private IcmpProtocol icmp; private IcmpProtocol icmp;
/** /**
* Monitoring configuration information using the telnet protocol
* 使用telnet协议的监控配置信息 * 使用telnet协议的监控配置信息
*/ */
private TelnetProtocol telnet; private TelnetProtocol telnet;
/** /**
* Use tcp or ucp implemented by socket for service port detection configuration information
* 使用socket实现的tcp或ucp进行服务端口探测配置信息 * 使用socket实现的tcp或ucp进行服务端口探测配置信息
*/ */
private TcpUdpProtocol tcpUdp; private TcpUdpProtocol tcpUdp;
/** /**
* Database configuration information implemented using the public jdbc specification
* 使用公共的jdbc规范实现的数据库配置信息 * 使用公共的jdbc规范实现的数据库配置信息
*/ */
private JdbcProtocol jdbc; private JdbcProtocol jdbc;
/** /**
* Monitoring configuration information using the public ssh protocol
* 使用公共的ssh协议的监控配置信息 * 使用公共的ssh协议的监控配置信息
*/ */
private SshProtocol ssh; private SshProtocol ssh;
@@ -118,22 +101,18 @@ public class Metrics {
@NoArgsConstructor @NoArgsConstructor
public static class Field { public static class Field {
/** /**
* Indicator name
* 指标名称 * 指标名称
*/ */
private String field; private String field;
/** /**
* Indicator type 0-number: number 1-string: string
* 指标类型 0-number:数字 1-string:字符串 * 指标类型 0-number:数字 1-string:字符串
*/ */
private byte type = 1; private byte type = 1;
/** /**
* Whether this field is the instance primary key
* 此字段是否为实例主键 * 此字段是否为实例主键
*/ */
private boolean instance = false; private boolean instance = false;
/** /**
* Indicator unit
* 指标单位 * 指标单位
*/ */
private String unit; private String unit;

View File

@@ -22,9 +22,7 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE; import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
/** /**
* Monitor Entity
* 监控实体 * 监控实体
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 9:53 * @date 2021/11/14 9:53
*/ */
@@ -34,11 +32,10 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(description = "en: Monitor Entity,zh: 监控实体") @ApiModel(description = "监控实体")
public class Monitor { public class Monitor {
/** /**
* Monitor ID
* 主键ID * 主键ID
*/ */
@Id @Id
@@ -46,14 +43,12 @@ public class Monitor {
private Long id; private Long id;
/** /**
* Job ID
* 监控对应下发的任务ID * 监控对应下发的任务ID
*/ */
@ApiModelProperty(value = "任务ID", example = "43243543543", accessMode = READ_ONLY, position = 1) @ApiModelProperty(value = "任务ID", example = "43243543543", accessMode = READ_ONLY, position = 1)
private Long jobId; private Long jobId;
/** /**
* Monitor Name
* 监控的名称 * 监控的名称
*/ */
@ApiModelProperty(value = "监控名称", example = "Api-TanCloud.cn", accessMode = READ_WRITE, position = 2) @ApiModelProperty(value = "监控名称", example = "Api-TanCloud.cn", accessMode = READ_WRITE, position = 2)
@@ -61,7 +56,6 @@ public class Monitor {
private String name; private String name;
/** /**
* Type of monitoring: linux, mysql, jvm...
* 监控的类型:linux,mysql,jvm... * 监控的类型:linux,mysql,jvm...
*/ */
@ApiModelProperty(value = "监控类型", example = "TanCloud", accessMode = READ_WRITE, position = 3) @ApiModelProperty(value = "监控类型", example = "TanCloud", accessMode = READ_WRITE, position = 3)
@@ -69,7 +63,6 @@ public class Monitor {
private String app; private String app;
/** /**
* Monitored peer host: ipv4, ipv6, domain name
* 监控的对端host:ipv4,ipv6,域名 * 监控的对端host:ipv4,ipv6,域名
*/ */
@ApiModelProperty(value = "监控的对端host", example = "192.167.25.11", accessMode = READ_WRITE, position = 4) @ApiModelProperty(value = "监控的对端host", example = "192.167.25.11", accessMode = READ_WRITE, position = 4)
@@ -78,7 +71,6 @@ public class Monitor {
private String host; private String host;
/** /**
* Monitoring collection interval time, in seconds
* 监控的采集间隔时间,单位秒 * 监控的采集间隔时间,单位秒
*/ */
@ApiModelProperty(value = "监控的采集间隔时间,单位秒", example = "600", accessMode = READ_WRITE, position = 5) @ApiModelProperty(value = "监控的采集间隔时间,单位秒", example = "600", accessMode = READ_WRITE, position = 5)
@@ -86,7 +78,6 @@ public class Monitor {
private Integer intervals; private Integer intervals;
/** /**
* Monitoring status 0: Unmonitored, 1: Available, 2: Unavailable, 3: Unreachable, 4: Suspended
* 监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起 * 监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起
*/ */
@ApiModelProperty(value = "监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起", accessMode = READ_WRITE, position = 6) @ApiModelProperty(value = "监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起", accessMode = READ_WRITE, position = 6)
@@ -95,7 +86,6 @@ public class Monitor {
private byte status; private byte status;
/** /**
* Monitoring note description
* 监控备注描述 * 监控备注描述
*/ */
@ApiModelProperty(value = "监控备注描述", example = "对SAAS网站TanCloud的可用性监控", accessMode = READ_WRITE, position = 7) @ApiModelProperty(value = "监控备注描述", example = "对SAAS网站TanCloud的可用性监控", accessMode = READ_WRITE, position = 7)
@@ -103,21 +93,18 @@ public class Monitor {
private String description; private String description;
/** /**
* The creator of this record
* 此条记录创建者 * 此条记录创建者
*/ */
@ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 8) @ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 8)
private String creator; private String creator;
/** /**
* This record was last modified by
* 此条记录最新修改者 * 此条记录最新修改者
*/ */
@ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 9) @ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 9)
private String modifier; private String modifier;
/** /**
* record creation time (millisecond timestamp)
* 记录创建时间 * 记录创建时间
*/ */
@ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 10) @ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 10)
@@ -125,7 +112,6 @@ public class Monitor {
private LocalDateTime gmtCreate; private LocalDateTime gmtCreate;
/** /**
* Record the latest modification time (timestamp in milliseconds)
* 记录最新修改时间 * 记录最新修改时间
*/ */
@ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 11) @ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 11)

View File

@@ -23,9 +23,7 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE; import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
/** /**
* Monitor parameter values
* 监控参数值 * 监控参数值
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/13 22:19 * @date 2021/11/13 22:19
*/ */
@@ -35,26 +33,21 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(description = "嗯: Parameter Entity,zh: 参数实体") @ApiModel(description = "参数实体")
public class Param { public class Param {
/**
* Parameter primary key index 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;
/** /**
* Monitor ID
* 监控ID * 监控ID
*/ */
@ApiModelProperty(value = "监控ID", example = "875846754543", accessMode = READ_WRITE, position = 1) @ApiModelProperty(value = "监控ID", example = "875846754543", accessMode = READ_WRITE, position = 1)
private Long monitorId; private Long monitorId;
/** /**
* Parameter Field Identifier
* 参数字段标识符 * 参数字段标识符
*/ */
@ApiModelProperty(value = "参数标识符字段", example = "port", accessMode = READ_WRITE, position = 2) @ApiModelProperty(value = "参数标识符字段", example = "port", accessMode = READ_WRITE, position = 2)
@@ -63,7 +56,6 @@ public class Param {
private String field; private String field;
/** /**
* Param Value
* 参数值 * 参数值
*/ */
@ApiModelProperty(value = "参数值", example = "8080", accessMode = READ_WRITE, position = 3) @ApiModelProperty(value = "参数值", example = "8080", accessMode = READ_WRITE, position = 3)
@@ -71,7 +63,6 @@ public class Param {
private String value; private String value;
/** /**
* Parameter type 0: number 1: string 2: encrypted string 3: json string mapped by map
* 参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串 * 参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串
*/ */
@ApiModelProperty(value = "参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串", accessMode = READ_WRITE, position = 4) @ApiModelProperty(value = "参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串", accessMode = READ_WRITE, position = 4)
@@ -80,7 +71,6 @@ public class Param {
private byte type; private byte type;
/** /**
* Record Creation Time
* 记录创建时间 * 记录创建时间
*/ */
@ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 5) @ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 5)
@@ -88,7 +78,6 @@ public class Param {
private LocalDateTime gmtCreate; private LocalDateTime gmtCreate;
/** /**
* Record the latest modification time
* 记录最新修改时间 * 记录最新修改时间
*/ */
@ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 6) @ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 6)

View File

@@ -1,208 +1,175 @@
package com.usthe.common.util; package com.usthe.common.util;
/** /**
* Public Constant
* 公共常量 * 公共常量
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 12:06 * @date 2021/11/14 12:06
*/ */
public interface CommonConstants { public interface CommonConstants {
/** /**
* Response status code: generic success
* 响应状态码: 通用成功 * 响应状态码: 通用成功
*/ */
byte SUCCESS_CODE = 0x00; byte SUCCESS_CODE = 0x00;
/** /**
* Response status code: generic failure
* 响应状态码: 通用失败 * 响应状态码: 通用失败
*/ */
byte FAIL_CODE = 0x0F; byte FAIL_CODE = 0x0F;
/** /**
* Response status code: Parameter verification failed
* 响应状态码: 参数校验失败 * 响应状态码: 参数校验失败
*/ */
byte PARAM_INVALID_CODE = 0x01; byte PARAM_INVALID_CODE = 0x01;
/** /**
* Response Status Code: Probe Failed
* 响应状态码: 探测失败 * 响应状态码: 探测失败
*/ */
byte DETECT_FAILED_CODE = 0x02; byte DETECT_FAILED_CODE = 0x02;
/** /**
* Response status code: monitoring does not exist
* 响应状态码: 监控不存在 * 响应状态码: 监控不存在
*/ */
byte MONITOR_NOT_EXIST_CODE = 0x03; byte MONITOR_NOT_EXIST_CODE = 0x03;
/** /**
* Response Status Code: Monitor Service Conflict
* 响应状态码: 监控服务冲突 * 响应状态码: 监控服务冲突
*/ */
byte MONITOR_CONFLICT_CODE = 0x04; byte MONITOR_CONFLICT_CODE = 0x04;
/** /**
* Response status code: Incorrect login account password
* 响应状态码: 登录账户密码错误 * 响应状态码: 登录账户密码错误
*/ */
byte MONITOR_LOGIN_FAILED_CODE = 0x05; byte MONITOR_LOGIN_FAILED_CODE = 0x05;
/** /**
* Response status code: Registration failed exception
* 响应状态码: 注册失败异常 * 响应状态码: 注册失败异常
*/ */
byte MONITOR_REGISTER_FAILED_CODE = 0x06; byte MONITOR_REGISTER_FAILED_CODE = 0x06;
/** /**
* Monitoring Status Code: Unmanaged
* 监控状态码: 未管理 * 监控状态码: 未管理
*/ */
byte UN_MANAGE_CODE = 0x00; byte UN_MANAGE_CODE = 0x00;
/** /**
* Monitoring Status Code: Available
* 监控状态码: 可用 * 监控状态码: 可用
*/ */
byte AVAILABLE_CODE = 0x01; byte AVAILABLE_CODE = 0x01;
/** /**
* Monitoring Status Code: Not Available
* 监控状态码: 不可用 * 监控状态码: 不可用
*/ */
byte UN_AVAILABLE_CODE = 0x02; byte UN_AVAILABLE_CODE = 0x02;
/** /**
* Monitoring Status Code: Unreachable
* 监控状态码: 不可达 * 监控状态码: 不可达
*/ */
byte UN_REACHABLE_CODE = 0x03; byte UN_REACHABLE_CODE = 0x03;
/** /**
* Monitoring Status Code: Pending
* 监控状态码: 挂起 * 监控状态码: 挂起
*/ */
byte SUSPENDING_CODE = 0x04; byte SUSPENDING_CODE = 0x04;
/** /**
* Alarm status: 0 - normal alarm (to be processed)
* 告警状态: 0-正常告警(待处理) * 告警状态: 0-正常告警(待处理)
*/ */
byte ALERT_STATUS_CODE_PENDING = 0x00; byte ALERT_STATUS_CODE_PENDING = 0x00;
/** /**
* Alarm Status: 1 - Threshold triggered but not reached the number of alarms
* 告警状态: 1-阈值触发但未达到告警次数 * 告警状态: 1-阈值触发但未达到告警次数
*/ */
byte ALERT_STATUS_CODE_NOT_REACH = 0x01; byte ALERT_STATUS_CODE_NOT_REACH = 0x01;
/** /**
* Alarm Status: 2-Restore Alarm
* 告警状态: 2-恢复告警 * 告警状态: 2-恢复告警
*/ */
byte ALERT_STATUS_CODE_RESTORED = 0x02; byte ALERT_STATUS_CODE_RESTORED = 0x02;
/** /**
* Alert Status: 3-Handled
* 告警状态: 3-已处理 * 告警状态: 3-已处理
*/ */
byte ALERT_STATUS_CODE_SOLVED = 0x03; byte ALERT_STATUS_CODE_SOLVED = 0x03;
/** /**
* Alarm level: 0: high-emergency-emergency-red
* 告警级别: 0:高-emergency-紧急告警-红色 * 告警级别: 0:高-emergency-紧急告警-红色
*/ */
byte ALERT_PRIORITY_CODE_EMERGENCY = 0x00; byte ALERT_PRIORITY_CODE_EMERGENCY = 0x00;
/** /**
* Alarm severity: 1: medium-critical-critical alarm-orange
* 告警级别: 1:中-critical-严重告警-橙色 * 告警级别: 1:中-critical-严重告警-橙色
*/ */
byte ALERT_PRIORITY_CODE_CRITICAL = 0x01; byte ALERT_PRIORITY_CODE_CRITICAL = 0x01;
/** /**
* Warning level: 2: low-warning-warning warning-yellow
* 告警级别: 2:低-warning-警告告警-黄色 * 告警级别: 2:低-warning-警告告警-黄色
*/ */
byte ALERT_PRIORITY_CODE_WARNING = 0x02; byte ALERT_PRIORITY_CODE_WARNING = 0x02;
/** /**
* Field parameter type: number
* 字段参数类型: 数字 * 字段参数类型: 数字
*/ */
byte TYPE_NUMBER = 0; byte TYPE_NUMBER = 0;
/** /**
* Field parameter type: String
* 字段参数类型: 字符串 * 字段参数类型: 字符串
*/ */
byte TYPE_STRING = 1; byte TYPE_STRING = 1;
/** /**
* Field parameter type: encrypted string
* 字段参数类型: 加密字符串 * 字段参数类型: 加密字符串
*/ */
byte TYPE_SECRET = 2; byte TYPE_SECRET = 2;
/** /**
* Collection indicator value: null placeholder for empty value
* 采集指标值null空值占位符 * 采集指标值null空值占位符
*/ */
String NULL_VALUE = "&nbsp;"; String NULL_VALUE = "&nbsp;";
/** /**
* Availability Object
* 可用性对象 * 可用性对象
*/ */
String AVAILABLE = "available"; String AVAILABLE = "available";
/** /**
* Reachability Object可达性对象 * 可达性对象
*/ */
String REACHABLE = "reachable"; String REACHABLE = "reachable";
/** /**
* Parameter Type Number
* 参数类型 数字 * 参数类型 数字
*/ */
byte PARAM_TYPE_NUMBER = 0; byte PARAM_TYPE_NUMBER = 0;
/** /**
* Parameter Type String
* 参数类型 字符串 * 参数类型 字符串
*/ */
byte PARAM_TYPE_STRING = 1; byte PARAM_TYPE_STRING = 1;
/** /**
* Parameter Type Password
* 参数类型 密码 * 参数类型 密码
*/ */
byte PARAM_TYPE_PASSWORD = 2; byte PARAM_TYPE_PASSWORD = 2;
/** /**
* Authentication type Account password
* 认证类型 账户密码 * 认证类型 账户密码
*/ */
byte AUTH_TYPE_PASSWORD = 1; byte AUTH_TYPE_PASSWORD = 1;
/** /**
* Authentication type GITHUB three-party login
* 认证类型 GITHUB三方登录 * 认证类型 GITHUB三方登录
*/ */
byte AUTH_TYPE_GITHUB = 2; byte AUTH_TYPE_GITHUB = 2;
/** /**
* Authentication type WeChat three-party login
* 认证类型 微信三方登录 * 认证类型 微信三方登录
*/ */
byte AUTH_TYPE_WEIXIN = 3; byte AUTH_TYPE_WEIXIN = 3;
/** /**
* Authentication type GITEE three-party login
* 认证类型 GITEE三方登录 * 认证类型 GITEE三方登录
*/ */
byte AUTH_TYPE_GITEE = 5; byte AUTH_TYPE_GITEE = 5;

View File

@@ -1,9 +1,7 @@
package com.usthe.common.util; package com.usthe.common.util;
/** /**
* Snowflake Algorithm Generator Tool
* 雪花算法生成器工具 * 雪花算法生成器工具
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/10 11:04 * @date 2021/11/10 11:04
*/ */

View File

@@ -1,18 +0,0 @@
---
id: alert_console
title: 告警模板中自定义的控制台地址
sidebar_label: 告警模板登录台地址
---
> 阈值触发后发送告警信息,通过钉钉/企业微信/飞书机器人通知或者使用邮箱通知的时候,告警内容中有登录控制台的详情链接
### 自定义设置
在我们的启动配置文件application.yml中找到下面的配置
```yml
alerter:
console-url: #这里就是我们的自定义控制台地址
```
默认值是赫兹跳动的官方控制台地址

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -1,7 +1,6 @@
package com.usthe.manager.component.alerter; package com.usthe.manager.component.alerter;
import com.usthe.alert.AlerterDataQueue; import com.usthe.alert.AlerterDataQueue;
import com.usthe.alert.AlerterProperties;
import com.usthe.alert.AlerterWorkerPool; import com.usthe.alert.AlerterWorkerPool;
import com.usthe.common.util.CommonUtil; import com.usthe.common.util.CommonUtil;
import com.usthe.common.entity.alerter.Alert; import com.usthe.common.entity.alerter.Alert;
@@ -25,7 +24,6 @@ import org.springframework.stereotype.Component;
import org.springframework.web.client.ResourceAccessException; import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@@ -50,8 +48,6 @@ public class DispatchAlarm {
private JavaMailSender javaMailSender; private JavaMailSender javaMailSender;
private RestTemplate restTemplate; private RestTemplate restTemplate;
private MailService mailService; private MailService mailService;
@Resource
private AlerterProperties alerterProperties;
@Value("${spring.mail.username}") @Value("${spring.mail.username}")
private String emailFromUser; private String emailFromUser;
@@ -181,13 +177,13 @@ public class DispatchAlarm {
"\n所属监控ID :" + alert.getMonitorId() + "\n所属监控ID :" + alert.getMonitorId() +
"\n所属监控名称 :" + alert.getMonitorName() + "\n所属监控名称 :" + alert.getMonitorName() +
"\n告警级别 :" + CommonUtil.transferAlertPriority(alert.getPriority()) + "\n告警级别 :" + CommonUtil.transferAlertPriority(alert.getPriority()) +
"\n内容详情 : " + alert.getContent() + "\n"; "\n内容详情 : " + alert.getContent();
flyBookContent.setText(text); flyBookContent.setText(text);
contents1.add(flyBookContent); contents1.add(flyBookContent);
FlyBookWebHookDto.FlyBookContent bookContent = new FlyBookWebHookDto.FlyBookContent(); FlyBookWebHookDto.FlyBookContent bookContent = new FlyBookWebHookDto.FlyBookContent();
bookContent.setTag("a"); bookContent.setTag("a");
bookContent.setText("登入控制台"); bookContent.setText("登入控制台");
bookContent.setHref(alerterProperties.getConsoleUrl()); bookContent.setHref("https://www.tancloud.cn");
contents1.add(bookContent); contents1.add(bookContent);
contents.add(contents1); contents.add(contents1);
zhCn.setTitle("[TanCloud探云告警通知]"); zhCn.setTitle("[TanCloud探云告警通知]");
@@ -218,16 +214,14 @@ public class DispatchAlarm {
private void sendDingTalkRobotAlert(NoticeReceiver receiver, Alert alert) { private void sendDingTalkRobotAlert(NoticeReceiver receiver, Alert alert) {
DingTalkWebHookDto dingTalkWebHookDto = new DingTalkWebHookDto(); DingTalkWebHookDto dingTalkWebHookDto = new DingTalkWebHookDto();
DingTalkWebHookDto.MarkdownDTO markdownDTO = new DingTalkWebHookDto.MarkdownDTO(); DingTalkWebHookDto.MarkdownDTO markdownDTO = new DingTalkWebHookDto.MarkdownDTO();
StringBuilder content = new StringBuilder(); String content = "#### [TanCloud探云告警通知]\n##### **告警目标对象** : " +
content.append("#### [TanCloud探云告警通知]\n##### **告警目标对象** : " +
alert.getTarget() + "\n " + alert.getTarget() + "\n " +
"##### **所属监控ID** : " + alert.getMonitorId() + "\n " + "##### **所属监控ID** : " + alert.getMonitorId() + "\n " +
"##### **所属监控名称** : " + alert.getMonitorName() + "\n " + "##### **所属监控名称** : " + alert.getMonitorName() + "\n " +
"##### **告警级别** : " + "##### **告警级别** : " +
CommonUtil.transferAlertPriority(alert.getPriority()) + "\n " + CommonUtil.transferAlertPriority(alert.getPriority()) + "\n " +
"##### **内容详情** : " + alert.getContent()); "##### **内容详情** : " + alert.getContent();
content.append("[点击跳转查看详情](" + alerterProperties.getConsoleUrl() + ")"); markdownDTO.setText(content);
markdownDTO.setText(content.toString());
markdownDTO.setTitle("TanCloud探云告警通知"); markdownDTO.setTitle("TanCloud探云告警通知");
dingTalkWebHookDto.setMarkdown(markdownDTO); dingTalkWebHookDto.setMarkdown(markdownDTO);
String webHookUrl = DingTalkWebHookDto.WEBHOOK_URL + receiver.getAccessToken(); String webHookUrl = DingTalkWebHookDto.WEBHOOK_URL + receiver.getAccessToken();
@@ -267,10 +261,8 @@ public class DispatchAlarm {
content.append("告警级别 : <font color=\"comment\">") content.append("告警级别 : <font color=\"comment\">")
.append(CommonUtil.transferAlertPriority(alert.getPriority())).append("</font>\n"); .append(CommonUtil.transferAlertPriority(alert.getPriority())).append("</font>\n");
} }
content.append("内容详情 : ").append(alert.getContent() + "\n"); content.append("内容详情 : ").append(alert.getContent());
content.append("[点击跳转查看详情](" + alerterProperties.getConsoleUrl() + ")");
markdownDTO.setContent(content.toString()); markdownDTO.setContent(content.toString());
//TODO 增加控制台地址登录可控制
weWorkWebHookDTO.setMarkdown(markdownDTO); weWorkWebHookDTO.setMarkdown(markdownDTO);
String webHookUrl = WeWorkWebHookDto.WEBHOOK_URL + receiver.getWechatId(); String webHookUrl = WeWorkWebHookDto.WEBHOOK_URL + receiver.getWechatId();
try { try {

View File

@@ -1,7 +1,6 @@
package com.usthe.manager.controller; package com.usthe.manager.controller;
import com.usthe.common.entity.dto.Message; import com.usthe.common.entity.dto.Message;
import com.usthe.common.entity.manager.Monitor;
import com.usthe.manager.pojo.dto.MonitorDto; import com.usthe.manager.pojo.dto.MonitorDto;
import com.usthe.manager.service.MonitorService; import com.usthe.manager.service.MonitorService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@@ -24,13 +23,11 @@ import static com.usthe.common.util.CommonConstants.MONITOR_NOT_EXIST_CODE;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/** /**
* Monitoring management API
* 监控管理API * 监控管理API
*
* @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 = "监控管理API")
@RestController @RestController
@RequestMapping(path = "/monitor", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/monitor", produces = {APPLICATION_JSON_VALUE})
public class MonitorController { public class MonitorController {
@@ -39,12 +36,12 @@ public class MonitorController {
private MonitorService monitorService; private MonitorService monitorService;
@PostMapping @PostMapping
@ApiOperation(value = "Add a monitoring application", notes = "新增一个监控应用") @ApiOperation(value = "新增监控", notes = "新增一个监控应用")
public ResponseEntity<Message<Void>> addNewMonitor(@Valid @RequestBody MonitorDto monitorDto) { public ResponseEntity<Message<Void>> addNewMonitor(@Valid @RequestBody MonitorDto monitorDto) {
// Verify request data 校验请求数据 // 校验请求数据
monitorService.validate(monitorDto, false); monitorService.validate(monitorDto, false);
if (monitorDto.isDetected()) { if (monitorDto.isDetected()) {
// Probe 进行探测 // 进行探测
monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams()); monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams());
} }
monitorService.addMonitor(monitorDto.getMonitor(), monitorDto.getParams()); monitorService.addMonitor(monitorDto.getMonitor(), monitorDto.getParams());
@@ -52,12 +49,12 @@ public class MonitorController {
} }
@PutMapping @PutMapping
@ApiOperation(value = "Modify an existing monitoring application", notes = "修改一个已存在监控应用") @ApiOperation(value = "修改监控", notes = "修改一个已存在监控应用")
public ResponseEntity<Message<Void>> modifyMonitor(@Valid @RequestBody MonitorDto monitorDto) { public ResponseEntity<Message<Void>> modifyMonitor(@Valid @RequestBody MonitorDto monitorDto) {
// Verify request data 校验请求数据 // 校验请求数据
monitorService.validate(monitorDto, true); monitorService.validate(monitorDto, true);
if (monitorDto.isDetected()) { if (monitorDto.isDetected()) {
// Probe 进行探测 // 进行探测
monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams()); monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams());
} }
monitorService.modifyMonitor(monitorDto.getMonitor(), monitorDto.getParams()); monitorService.modifyMonitor(monitorDto.getMonitor(), monitorDto.getParams());
@@ -65,10 +62,9 @@ public class MonitorController {
} }
@GetMapping(path = "/{id}") @GetMapping(path = "/{id}")
@ApiOperation(value = "Obtain monitoring information based on monitoring ID", notes = "根据监控ID获取监控信息") @ApiOperation(value = "查询监控", notes = "根据监控ID获取监控信息")
public ResponseEntity<Message<MonitorDto>> getMonitor( public ResponseEntity<Message<MonitorDto>> getMonitor(
@ApiParam(value = "监控ID", example = "6565463543") @PathVariable("id") final long id) { @ApiParam(value = "监控ID", example = "6565463543") @PathVariable("id") final long id) {
// Get monitoring information
// 获取监控信息 // 获取监控信息
MonitorDto monitorDto = monitorService.getMonitorDto(id); MonitorDto monitorDto = monitorService.getMonitorDto(id);
Message.MessageBuilder<MonitorDto> messageBuilder = Message.builder(); Message.MessageBuilder<MonitorDto> messageBuilder = Message.builder();
@@ -81,20 +77,16 @@ public class MonitorController {
} }
@DeleteMapping(path = "/{id}") @DeleteMapping(path = "/{id}")
@ApiOperation(value = "Delete monitoring application based on monitoring ID", notes = "根据监控ID删除监控应用") @ApiOperation(value = "删除监控", notes = "根据监控ID删除监控应用,监控不存在也是删除成功")
public ResponseEntity<Message<Void>> deleteMonitor( public ResponseEntity<Message<Void>> deleteMonitor(
@ApiParam(value = "en: Monitor ID,zh: 监控ID", example = "6565463543") @PathVariable("id") final long id) { @ApiParam(value = "监控ID", example = "6565463543") @PathVariable("id") final long id) {
// delete monitor 删除监控 // 删除监控,监控不存在或删除成功都返回成功
Monitor monitor = monitorService.getMonitor(id);
if (monitor == null) {
return ResponseEntity.ok(new Message<>("The specified monitoring was not queried, please check whether the parameters are correct"));
}
monitorService.deleteMonitor(id); monitorService.deleteMonitor(id);
return ResponseEntity.ok(new Message<>("Delete success")); return ResponseEntity.ok(new Message<>("Delete success"));
} }
@PostMapping(path = "/detect") @PostMapping(path = "/detect")
@ApiOperation(value = "Perform availability detection on this monitoring based on monitoring information", notes = "根据监控信息去对此监控进行可用性探测") @ApiOperation(value = "探测监控", notes = "根据监控信息去对此监控进行可用性探测")
public ResponseEntity<Message<Void>> detectMonitor(@Valid @RequestBody MonitorDto monitorDto) { public ResponseEntity<Message<Void>> detectMonitor(@Valid @RequestBody MonitorDto monitorDto) {
monitorService.validate(monitorDto, null); monitorService.validate(monitorDto, null);
monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams()); monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams());

View File

@@ -29,13 +29,11 @@ import java.util.List;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/** /**
* Monitor and manage batch API
* 监控管理批量API * 监控管理批量API
*
* @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 = "监控列表API")
@RestController @RestController
@RequestMapping(path = "/monitors", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/monitors", produces = {APPLICATION_JSON_VALUE})
public class MonitorsController { public class MonitorsController {
@@ -46,23 +44,22 @@ public class MonitorsController {
private MonitorService monitorService; private MonitorService monitorService;
@GetMapping @GetMapping
@ApiOperation(value = "Obtain a list of monitoring information based on query filter items", @ApiOperation(value = "查询监控列表", notes = "根据查询过滤项获取监控信息列表")
notes = "根据查询过滤项获取监控信息列表")
public ResponseEntity<Message<Page<Monitor>>> getMonitors( public ResponseEntity<Message<Page<Monitor>>> getMonitors(
@ApiParam(value = "en: Monitor ID,zh: 监控ID", example = "6565463543") @RequestParam(required = false) final List<Long> ids, @ApiParam(value = "监控ID", example = "6565463543") @RequestParam(required = false) final List<Long> ids,
@ApiParam(value = "en: Monitor Type,zh: 监控类型", example = "linux") @RequestParam(required = false) final String app, @ApiParam(value = "监控类型", example = "linux") @RequestParam(required = false) final String app,
@ApiParam(value = "en: Monitor Name,zh: 监控名称,模糊查询", example = "linux-127.0.0.1") @RequestParam(required = false) final String name, @ApiParam(value = "监控名称,模糊查询", example = "linux-127.0.0.1") @RequestParam(required = false) final String name,
@ApiParam(value = "en: Monitor Host,zh: 监控Host模糊查询", example = "127.0.0.1") @RequestParam(required = false) final String host, @ApiParam(value = "监控Host模糊查询", example = "127.0.0.1") @RequestParam(required = false) final String host,
@ApiParam(value = "en: Monitor Status,zh: 监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起,9:全部状态", example = "1") @RequestParam(required = false) final Byte status, @ApiParam(value = "监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起,9:全部状态", example = "1") @RequestParam(required = false) final Byte status,
@ApiParam(value = "en: Sort Field,default id,zh: 排序字段默认id", example = "name") @RequestParam(defaultValue = "id") final String sort, @ApiParam(value = "排序字段默认id", example = "name") @RequestParam(defaultValue = "id") final String sort,
@ApiParam(value = "en: Sort by,zh: 排序方式asc:升序desc:降序", example = "desc") @RequestParam(defaultValue = "desc") final String order, @ApiParam(value = "排序方式asc:升序desc:降序", example = "desc") @RequestParam(defaultValue = "desc") final String order,
@ApiParam(value = "en: List current page,zh: 列表当前分页", example = "0") @RequestParam(defaultValue = "0") int pageIndex, @ApiParam(value = "列表当前分页", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
@ApiParam(value = "en: Number of list pagination,zh: 列表分页数量", example = "8") @RequestParam(defaultValue = "8") int pageSize) { @ApiParam(value = "列表分页数量", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
Specification<Monitor> specification = (root, query, criteriaBuilder) -> { Specification<Monitor> specification = (root, query, criteriaBuilder) -> {
List<Predicate> andList = new ArrayList<>(); List<Predicate> andList = new ArrayList<>();
if (ids != null && !ids.isEmpty()) { if (ids != null && !ids.isEmpty()) {
CriteriaBuilder.In<Long> inPredicate = criteriaBuilder.in(root.get("id")); CriteriaBuilder.In<Long> inPredicate= criteriaBuilder.in(root.get("id"));
for (long id : ids) { for (long id : ids) {
inPredicate.value(id); inPredicate.value(id);
} }
@@ -98,10 +95,10 @@ public class MonitorsController {
} else if (orPredicate.getExpressions().isEmpty()) { } else if (orPredicate.getExpressions().isEmpty()) {
return query.where(andPredicate).getRestriction(); return query.where(andPredicate).getRestriction();
} else { } else {
return query.where(andPredicate, orPredicate).getRestriction(); return query.where(andPredicate,orPredicate).getRestriction();
} }
}; };
// Pagination is a must 分页是必须的 // 分页是必须的
Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort)); Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort));
PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp); PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp);
Page<Monitor> monitorPage = monitorService.getMonitors(specification, pageRequest); Page<Monitor> monitorPage = monitorService.getMonitors(specification, pageRequest);
@@ -110,20 +107,18 @@ public class MonitorsController {
} }
@GetMapping(path = "/{app}") @GetMapping(path = "/{app}")
@ApiOperation(value = "Filter all acquired monitoring information lists of the specified monitoring type according to the query", @ApiOperation(value = "查询指定监控类型的监控列表", notes = "根据查询过滤指定监控类型的所有获取监控信息列表")
notes = "根据查询过滤指定监控类型的所有获取监控信息列表")
public ResponseEntity<Message<List<Monitor>>> getAppMonitors( public ResponseEntity<Message<List<Monitor>>> getAppMonitors(
@ApiParam(value = "en: Monitoring type,zh: 监控类型", example = "linux") @PathVariable(required = false) final String app) { @ApiParam(value = "监控类型", example = "linux") @PathVariable(required = false) final String app) {
List<Monitor> monitors = monitorService.getAppMonitors(app); List<Monitor> monitors = monitorService.getAppMonitors(app);
Message<List<Monitor>> message = new Message<>(monitors); Message<List<Monitor>> message = new Message<>(monitors);
return ResponseEntity.ok(message); return ResponseEntity.ok(message);
} }
@DeleteMapping @DeleteMapping
@ApiOperation(value = "Delete monitoring items in batches according to the monitoring ID list", @ApiOperation(value = "批量删除监控", notes = "根据监控ID列表批量删除监控项")
notes = "根据监控ID列表批量删除监控项")
public ResponseEntity<Message<Void>> deleteMonitors( public ResponseEntity<Message<Void>> deleteMonitors(
@ApiParam(value = "en: Monitoring ID List,zh: 监控ID列表", example = "6565463543") @RequestParam(required = false) List<Long> ids @ApiParam(value = "监控IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
) { ) {
if (ids != null && !ids.isEmpty()) { if (ids != null && !ids.isEmpty()) {
monitorService.deleteMonitors(new HashSet<>(ids)); monitorService.deleteMonitors(new HashSet<>(ids));
@@ -133,10 +128,9 @@ public class MonitorsController {
} }
@DeleteMapping("manage") @DeleteMapping("manage")
@ApiOperation(value = "Unmanaged monitoring items in batches according to the monitoring ID list", @ApiOperation(value = "批量取消纳管监控", notes = "根据监控ID列表批量取消纳管监控项")
notes = "根据监控ID列表批量取消纳管监控项")
public ResponseEntity<Message<Void>> cancelManageMonitors( public ResponseEntity<Message<Void>> cancelManageMonitors(
@ApiParam(value = "en: Monitoring ID List,zh: 监控ID列表", example = "6565463543") @RequestParam(required = false) List<Long> ids @ApiParam(value = "监控IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
) { ) {
if (ids != null && !ids.isEmpty()) { if (ids != null && !ids.isEmpty()) {
monitorService.cancelManageMonitors(new HashSet<>(ids)); monitorService.cancelManageMonitors(new HashSet<>(ids));
@@ -146,10 +140,9 @@ public class MonitorsController {
} }
@GetMapping("manage") @GetMapping("manage")
@ApiOperation(value = "Start the managed monitoring items in batches according to the monitoring ID list", @ApiOperation(value = "批量启动纳管监控", notes = "根据监控ID列表批量启动纳管监控项")
notes = "根据监控ID列表批量启动纳管监控项")
public ResponseEntity<Message<Void>> enableManageMonitors( public ResponseEntity<Message<Void>> enableManageMonitors(
@ApiParam(value = "en: Monitor ID List,zh: 监控ID列表", example = "6565463543") @RequestParam(required = false) List<Long> ids @ApiParam(value = "监控IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
) { ) {
if (ids != null && !ids.isEmpty()) { if (ids != null && !ids.isEmpty()) {
monitorService.enableManageMonitors(new HashSet<>(ids)); monitorService.enableManageMonitors(new HashSet<>(ids));

View File

@@ -60,10 +60,8 @@ public class NoticeConfigController {
@ApiOperation(value = "Delete existing recipient information", notes = "删除已存在的接收人信息") @ApiOperation(value = "Delete existing recipient information", notes = "删除已存在的接收人信息")
public ResponseEntity<Message<Void>> deleteNoticeReceiver( public ResponseEntity<Message<Void>> deleteNoticeReceiver(
@ApiParam(value = "en: Recipient ID,zh: 接收人ID", example = "6565463543") @PathVariable("id") final Long receiverId) { @ApiParam(value = "en: Recipient ID,zh: 接收人ID", example = "6565463543") @PathVariable("id") final Long receiverId) {
NoticeReceiver noticeReceiver = noticeConfigService.getReceiverById(receiverId); // Returns success if it does not exist or if the deletion is successful
if (noticeReceiver == null) { // todo 不存在或删除成功都返回成功
return ResponseEntity.ok(new Message<>("The relevant information of the recipient could not be found, please check whether the parameters are correct"));
}
noticeConfigService.deleteReceiver(receiverId); noticeConfigService.deleteReceiver(receiverId);
return ResponseEntity.ok(new Message<>("Delete success")); return ResponseEntity.ok(new Message<>("Delete success"));
} }
@@ -74,6 +72,7 @@ public class NoticeConfigController {
public ResponseEntity<Message<List<NoticeReceiver>>> getReceivers( public ResponseEntity<Message<List<NoticeReceiver>>> getReceivers(
@ApiParam(value = "en: Recipient name,zh: 接收人名称,模糊查询", example = "tom") @RequestParam(required = false) final String name) { @ApiParam(value = "en: Recipient name,zh: 接收人名称,模糊查询", example = "tom") @RequestParam(required = false) final String name) {
//todo Writing can be optimized 写法可优化
Specification<NoticeReceiver> specification = (root, query, criteriaBuilder) -> { Specification<NoticeReceiver> specification = (root, query, criteriaBuilder) -> {
Predicate predicate = criteriaBuilder.conjunction(); Predicate predicate = criteriaBuilder.conjunction();
if (name != null && !"".equals(name)) { if (name != null && !"".equals(name)) {
@@ -108,10 +107,6 @@ public class NoticeConfigController {
@ApiParam(value = "en: Notification Policy ID,zh: 通知策略ID", example = "6565463543") @PathVariable("id") final Long ruleId) { @ApiParam(value = "en: Notification Policy ID,zh: 通知策略ID", example = "6565463543") @PathVariable("id") final Long ruleId) {
// Returns success if it does not exist or if the deletion is successful // Returns success if it does not exist or if the deletion is successful
// todo 不存在或删除成功都返回成功 // todo 不存在或删除成功都返回成功
NoticeRule noticeRule = noticeConfigService.getNoticeRulesById(ruleId);
if (noticeRule == null) {
return ResponseEntity.ok(new Message<>("The specified notification rule could not be queried, please check whether the parameters are correct"));
}
noticeConfigService.deleteNoticeRule(ruleId); noticeConfigService.deleteNoticeRule(ruleId);
return ResponseEntity.ok(new Message<>("Delete success")); return ResponseEntity.ok(new Message<>("Delete success"));
} }

View File

@@ -22,37 +22,33 @@ public interface MonitorDao extends JpaRepository<Monitor, Long>, JpaSpecificati
/** /**
* Delete monitor based on monitor ID list
* 根据监控ID列表删除监控 * 根据监控ID列表删除监控
* *
* @param monitorIds Monitoring ID List 监控ID列表 * @param monitorIds 监控ID列表
*/ */
void deleteAllByIdIn(Set<Long> monitorIds); void deleteAllByIdIn(Set<Long> monitorIds);
/** /**
* Query monitoring based on monitoring ID list
* 根据监控ID列表查询监控 * 根据监控ID列表查询监控
* *
* @param monitorIds Monitoring ID List 监控ID列表 * @param monitorIds 监控ID列表
* @return Monitor List 监控列表 * @return 监控列表
*/ */
List<Monitor> findMonitorsByIdIn(Set<Long> monitorIds); List<Monitor> findMonitorsByIdIn(Set<Long> monitorIds);
/** /**
* Query monitoring by monitoring type
* 根据监控类型查询监控 * 根据监控类型查询监控
* *
* @param app Monitor Type 监控类型 * @param app 监控类型
* @return Monitor List 监控列表 * @return 监控列表
*/ */
List<Monitor> findMonitorsByAppEquals(String app); List<Monitor> findMonitorsByAppEquals(String app);
/** /**
* Querying Monitoring of Sent Collection Tasks
* 查询已下发采集任务的监控 * 查询已下发采集任务的监控
* *
* @param status Monitor Status 监控状态 * @param status 监控状态
* @return Monitor List 监控列表 * @return 监控列表
*/ */
List<Monitor> findMonitorsByStatusNotInAndAndJobIdNotNull(List<Byte> status); List<Monitor> findMonitorsByStatusNotInAndAndJobIdNotNull(List<Byte> status);

View File

@@ -8,34 +8,27 @@ import java.util.Set;
/** /**
* ParamDao 数据库操作 * ParamDao 数据库操作
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 11:26 * @date 2021/11/14 11:26
*/ */
public interface ParamDao extends JpaRepository<Param, Long> { public interface ParamDao extends JpaRepository<Param, Long> {
/** /**
* Query the list of parameters associated with the monitoring ID'
* 根据监控ID查询与之关联的参数列表 * 根据监控ID查询与之关联的参数列表
* * @param monitorId 监控ID
* @param monitorId Monitor ID 监控ID * @return 参数值列表
* @return list of parameter values 参数值列表
*/ */
List<Param> findParamsByMonitorId(long monitorId); List<Param> findParamsByMonitorId(long monitorId);
/** /**
* Remove the parameter list associated with the monitoring ID based on it
* 根据监控ID删除与之关联的参数列表 * 根据监控ID删除与之关联的参数列表
* * @param monitorId 监控ID
* @param monitorId Monitor Id 监控ID
*/ */
void deleteParamsByMonitorId(long monitorId); void deleteParamsByMonitorId(long monitorId);
/** /**
* Remove the parameter list associated with the monitoring ID list based on it
* 根据监控ID列表删除与之关联的参数列表 * 根据监控ID列表删除与之关联的参数列表
* * @param monitorIds 监控ID列表
* @param monitorIds Monitoring ID List 监控ID列表
*/ */
void deleteParamsByMonitorIdIn(Set<Long> monitorIds); void deleteParamsByMonitorIdIn(Set<Long> monitorIds);
} }

View File

@@ -14,18 +14,15 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE; import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
/** /**
* Monitoring Information External Interaction Entities
* 监控信息对外交互实体 * 监控信息对外交互实体
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 10:13 * @date 2021/11/14 10:13
*/ */
@Data @Data
@ApiModel(description = "en: Monitoring information entities,zh: 监控信息实体") @ApiModel(description = "监控信息实体")
public class MonitorDto { public class MonitorDto {
/** /**
* Monitoring entity
* 监控实体 * 监控实体
*/ */
@ApiModelProperty(value = "监控实体", accessMode = READ_WRITE, position = 0) @ApiModelProperty(value = "监控实体", accessMode = READ_WRITE, position = 0)
@@ -34,22 +31,17 @@ public class MonitorDto {
private Monitor monitor; private Monitor monitor;
/** /**
* Params 参数 * 参数
*/ */
@ApiModelProperty(value = "监控参数", accessMode = READ_WRITE, position = 1) @ApiModelProperty(value = "监控参数", accessMode = READ_WRITE, position = 1)
@NotNull @NotNull
@Valid @Valid
private List<Param> params; private List<Param> params;
/**
* List of indicator groups
* 指标组列表
*/
@ApiModelProperty(value = "指标组列表", accessMode = READ_ONLY, position = 2) @ApiModelProperty(value = "指标组列表", accessMode = READ_ONLY, position = 2)
private List<String> metrics; private List<String> metrics;
/** /**
* Whether to detect
* 是否探测 * 是否探测
*/ */
@ApiModelProperty(value = "是否进行探测", accessMode = READ_WRITE, position = 3) @ApiModelProperty(value = "是否进行探测", accessMode = READ_WRITE, position = 3)

View File

@@ -9,7 +9,6 @@ import java.util.Map;
/** /**
* 监控类型管理接口 * 监控类型管理接口
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 17:12 * @date 2021/11/14 17:12
*/ */
@@ -17,26 +16,21 @@ public interface AppService {
/** /**
* 根据监控类型查询定义的参数结构 * 根据监控类型查询定义的参数结构
*
* @param app 监控类型 * @param app 监控类型
* @return 参数结构列表 * @return 参数结构列表
*/ */
List<ParamDefine> getAppParamDefines(String app); List<ParamDefine> getAppParamDefines(String app);
/** /**
* Get monitor structure definition based on monitor type name
* 根据监控类型名称获取监控结构定义 * 根据监控类型名称获取监控结构定义
* * @param app 监控类型名称
* @param app Monitoring type name 监控类型名称 * @return 监控结构定义
* @return Monitoring Structure Definition 监控结构定义 * @throws IllegalArgumentException 当不存在即不支持对应名称的监控类型时抛出
* @throws IllegalArgumentException Thrown when there is no monitoring type with the corresponding name that is not supported
* 当不存在即不支持对应名称的监控类型时抛出
*/ */
Job getAppDefine(String app) throws IllegalArgumentException; Job getAppDefine(String app) throws IllegalArgumentException;
/** /**
* 获取定义的监控I18N资源 * 获取定义的监控I18N资源
*
* @param lang 语言类型 * @param lang 语言类型
* @return I18N资源 * @return I18N资源
*/ */
@@ -44,7 +38,6 @@ public interface AppService {
/** /**
* 查询所有监控的类型-指标组-指标层级 * 查询所有监控的类型-指标组-指标层级
*
* @param lang 语言 * @param lang 语言
* @return 层级信息 * @return 层级信息
*/ */

View File

@@ -23,103 +23,93 @@ public interface MonitorService {
/** /**
* Monitoring Availability Probes
* 监控可用性探测 * 监控可用性探测
* *
* @param monitor Monitoring entity information 监控实体信息 * @param monitor 监控实体信息
* @param params Parameter information 参数信息 * @param params 参数信息
* @throws MonitorDetectException Probe failure throws 探测失败抛出 * @throws MonitorDetectException 探测失败抛出
*/ */
void detectMonitor(Monitor monitor, List<Param> params) throws MonitorDetectException; void detectMonitor(Monitor monitor, List<Param> params) throws MonitorDetectException;
/** /**
* Add monitoring 新增监控 * 新增监控
* *
* @param monitor Monitoring Entity 监控实体 * @param monitor 监控实体
* @param params Parameter information 参数信息 * @param params 参数信息
* @throws RuntimeException Add process exception throw 新增过程异常抛出 * @throws RuntimeException 新增过程异常抛出
*/ */
void addMonitor(Monitor monitor, List<Param> params) throws RuntimeException; void addMonitor(Monitor monitor, List<Param> params) throws RuntimeException;
/** /**
* Verify the correctness of request data parameters
* 校验请求数据参数正确性 * 校验请求数据参数正确性
* *
* @param monitorDto monitorDto * @param monitorDto monitorDto
* @param isModify Whether it is a modification monitoring 是否是修改监控 * @param isModify 是否是修改监控
* @throws IllegalArgumentException Validation parameter error thrown 校验参数错误抛出 * @throws IllegalArgumentException 校验参数错误抛出
*/ */
void validate(MonitorDto monitorDto, Boolean isModify) throws IllegalArgumentException; void validate(MonitorDto monitorDto, Boolean isModify) throws IllegalArgumentException;
/** /**
* Modify update monitoring
* 修改更新监控 * 修改更新监控
* *
* @param monitor Monitor Entity 监控实体 * @param monitor 监控实体
* @param params Parameter information 参数信息 * @param params 参数信息
* @throws RuntimeException Exception thrown during modification 修改过程中异常抛出 * @throws RuntimeException 修改过程中异常抛出
*/ */
void modifyMonitor(Monitor monitor, List<Param> params) throws RuntimeException; void modifyMonitor(Monitor monitor, List<Param> params) throws RuntimeException;
/** /**
* Delete Monitor
* 删除监控 * 删除监控
* *
* @param id Monitor ID 监控ID * @param id 监控ID
* @throws RuntimeException Exception thrown during deletion 删除过程中异常抛出 * @throws RuntimeException 删除过程中异常抛出
*/ */
void deleteMonitor(long id) throws RuntimeException; void deleteMonitor(long id) throws RuntimeException;
/** /**
* Batch delete monitoring
* 批量删除监控 * 批量删除监控
* *
* @param ids Monitoring ID List 监控ID列表 * @param ids 监控ID
* @throws RuntimeException Exception thrown during deletion 删除过程中异常抛出 * @throws RuntimeException 删除过程中异常抛出
*/ */
void deleteMonitors(Set<Long> ids) throws RuntimeException; void deleteMonitors(Set<Long> ids) throws RuntimeException;
/** /**
* Get monitoring information
* 获取监控信息 * 获取监控信息
* *
* @param id Monitor ID 监控ID * @param id 监控ID
* @return MonitorDto Monitor Entity 監控实体 * @return MonitorDto
* @throws RuntimeException Exception thrown during query 查询过程中异常抛出 * @throws RuntimeException 查询过程中异常抛出
*/ */
MonitorDto getMonitorDto(long id) throws RuntimeException; MonitorDto getMonitorDto(long id) throws RuntimeException;
/** /**
* Dynamic conditional query
* 动态条件查询 * 动态条件查询
* *
* @param specification Query conditions 查询条件 * @param specification 查询条件
* @param pageRequest Pagination parameters 分页参数 * @param pageRequest 分页参数
* @return Search Result 查询结果 * @return 查询结果
*/ */
Page<Monitor> getMonitors(Specification<Monitor> specification, PageRequest pageRequest); Page<Monitor> getMonitors(Specification<Monitor> specification, PageRequest pageRequest);
/** /**
* Unmanaged monitoring items in batches according to the monitoring ID list
* 根据监控ID列表批量取消纳管监控项 * 根据监控ID列表批量取消纳管监控项
* *
* @param ids Monitoring ID List 监控ID列表 * @param ids 监控IDs
*/ */
void cancelManageMonitors(HashSet<Long> ids); void cancelManageMonitors(HashSet<Long> ids);
/** /**
* Start the managed monitoring items in batches according to the monitoring ID list
* 根据监控ID列表批量启动纳管监控项 * 根据监控ID列表批量启动纳管监控项
* *
* @param ids Monitoring ID List 监控ID列表 * @param ids 监控IDs
*/ */
void enableManageMonitors(HashSet<Long> ids); void enableManageMonitors(HashSet<Long> ids);
/** /**
* Query the monitoring category and its corresponding monitoring quantity
* 查询监控类别及其对应的监控数量 * 查询监控类别及其对应的监控数量
* *
* @return Monitoring Category and Monitoring Quantity Mapping 监控类别与监控数量映射 * @return 监控类别与监控数量映射
*/ */
List<AppCount> getAllAppMonitorsCount(); List<AppCount> getAllAppMonitorsCount();
@@ -142,11 +132,10 @@ public interface MonitorService {
void updateMonitorStatus(Long monitorId, byte status); void updateMonitorStatus(Long monitorId, byte status);
/** /**
* Query the list of all monitoring information under the specified monitoring type
* 查询指定监控类型下的所有监控信息列表 * 查询指定监控类型下的所有监控信息列表
* *
* @param app Monitor Type 监控类型 * @param app 监控类型
* @return Monitor Entity List 监控列表 * @return 监控列表
*/ */
List<Monitor> getAppMonitors(String app); List<Monitor> getAppMonitors(String app);
} }

View File

@@ -90,22 +90,4 @@ public interface NoticeConfigService {
* @return Receiver 接收人 * @return Receiver 接收人
*/ */
List<NoticeReceiver> getReceiverFilterRule(Alert alert); List<NoticeReceiver> getReceiverFilterRule(Alert alert);
/**
* Query recipient information based on recipient ID (primary key Id)
* 根据接收人ID(主键Id)查询接收人信息
*
* @param receiverId Receiver ID (primary key ID) 接收人ID(主键ID)
* @return Recipient Entity 接收人实体
*/
NoticeReceiver getReceiverById(Long receiverId);
/**
* Query specific notification rules according to the rule ID (primary key ID)
* 根据规则ID(主键ID)查询具体通知规则
*
* @param ruleId Rule ID 规则ID(主键ID)
* @return Notification Rule Entity 通知规则实体
*/
NoticeRule getNoticeRulesById(Long ruleId);
} }

View File

@@ -1,6 +1,5 @@
package com.usthe.manager.service.impl; package com.usthe.manager.service.impl;
import com.usthe.alert.AlerterProperties;
import com.usthe.common.entity.alerter.Alert; import com.usthe.common.entity.alerter.Alert;
import com.usthe.common.util.CommonUtil; import com.usthe.common.util.CommonUtil;
import com.usthe.manager.service.MailService; import com.usthe.manager.service.MailService;
@@ -12,7 +11,6 @@ import org.thymeleaf.context.Context;
import javax.annotation.Resource; import javax.annotation.Resource;
/** /**
* Mailbox sending service interface implementation class
* 邮箱发送服务接口实现类 * 邮箱发送服务接口实现类
* *
* @author 花城 * @author 花城
@@ -25,20 +23,16 @@ public class MailServiceImpl implements MailService {
@Resource @Resource
private TemplateEngine templateEngine; private TemplateEngine templateEngine;
@Resource
private AlerterProperties alerterProperties;
@Override @Override
public String buildAlertHtmlTemplate(final Alert alert) { public String buildAlertHtmlTemplate(final Alert alert) {
// Introduce thymeleaf context parameters to render pages
// 引入thymeleaf上下文参数渲染页面 // 引入thymeleaf上下文参数渲染页面
Context context = new Context(); Context context = new Context();
context.setVariable("target", alert.getTarget()); context.setVariable("target",alert.getTarget());
context.setVariable("monitorId", alert.getMonitorId()); context.setVariable("monitorId",alert.getMonitorId());
context.setVariable("monitorName", alert.getMonitorName()); context.setVariable("monitorName",alert.getMonitorName());
context.setVariable("priority", CommonUtil.transferAlertPriority(alert.getPriority())); context.setVariable("priority", CommonUtil.transferAlertPriority(alert.getPriority()));
context.setVariable("content", alert.getContent()); context.setVariable("content",alert.getContent());
context.setVariable("consoleUrl", alerterProperties.getConsoleUrl());
return templateEngine.process("mailAlarm", context); return templateEngine.process("mailAlarm", context);
} }
} }

View File

@@ -80,13 +80,11 @@ 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);
// To detect availability, you only need to collect the set of availability indicators with a priority of 0.
// 探测可用性只需要采集优先级为0的可用性指标集合 // 探测可用性只需要采集优先级为0的可用性指标集合
List<Metrics> availableMetrics = appDefine.getMetrics().stream() List<Metrics> availableMetrics = appDefine.getMetrics().stream()
.filter(item -> item.getPriority() == 0).collect(Collectors.toList()); .filter(item -> item.getPriority() == 0).collect(Collectors.toList());
appDefine.setMetrics(availableMetrics); appDefine.setMetrics(availableMetrics);
List<CollectRep.MetricsData> collectRep = collectJobService.collectSyncJobData(appDefine); List<CollectRep.MetricsData> collectRep = collectJobService.collectSyncJobData(appDefine);
// If the detection result fails, a detection exception is thrown
// 判断探测结果 失败则抛出探测异常 // 判断探测结果 失败则抛出探测异常
if (collectRep == null || collectRep.isEmpty()) { if (collectRep == null || collectRep.isEmpty()) {
throw new MonitorDetectException("No collector response"); throw new MonitorDetectException("No collector response");
@@ -99,9 +97,9 @@ public class MonitorServiceImpl implements MonitorService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void addMonitor(Monitor monitor, List<Param> params) throws RuntimeException { public void addMonitor(Monitor monitor, List<Param> params) throws RuntimeException {
// Apply for monitor id 申请 monitor id // 申请 monitor id
long monitorId = SnowFlakeIdGenerator.generateId(); long monitorId = SnowFlakeIdGenerator.generateId();
// Construct the collection task Job entity 构造采集任务Job实体 // 构造采集任务Job实体
Job appDefine = appService.getAppDefine(monitor.getApp()); Job appDefine = appService.getAppDefine(monitor.getApp());
appDefine.setMonitorId(monitorId); appDefine.setMonitorId(monitorId);
appDefine.setInterval(monitor.getIntervals()); appDefine.setInterval(monitor.getIntervals());
@@ -112,10 +110,8 @@ public class MonitorServiceImpl implements MonitorService {
return new Configmap(param.getField(), param.getValue(), param.getType()); return new Configmap(param.getField(), param.getValue(), param.getType());
}).collect(Collectors.toList()); }).collect(Collectors.toList());
appDefine.setConfigmap(configmaps); appDefine.setConfigmap(configmaps);
// Send the collection task to get the job ID
// 下发采集任务得到jobId // 下发采集任务得到jobId
long jobId = collectJobService.addAsyncCollectJob(appDefine); long jobId = collectJobService.addAsyncCollectJob(appDefine);
// Brush the library after the download is successful
// 下发成功后刷库 // 下发成功后刷库
try { try {
monitor.setId(monitorId); monitor.setId(monitorId);
@@ -125,7 +121,6 @@ public class MonitorServiceImpl implements MonitorService {
paramDao.saveAll(params); paramDao.saveAll(params);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
// Repository brushing abnormally cancels the previously delivered task
// 刷库异常取消之前的下发任务 // 刷库异常取消之前的下发任务
collectJobService.cancelAsyncCollectJob(jobId); collectJobService.cancelAsyncCollectJob(jobId);
throw new MonitorDatabaseException(e.getMessage()); throw new MonitorDatabaseException(e.getMessage());
@@ -135,7 +130,6 @@ public class MonitorServiceImpl implements MonitorService {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public void validate(MonitorDto monitorDto, Boolean isModify) throws IllegalArgumentException { public void validate(MonitorDto monitorDto, Boolean isModify) throws IllegalArgumentException {
// The request monitoring parameter matches the monitoring parameter definition mapping check
// 请求监控参数与监控参数定义映射校验匹配 // 请求监控参数与监控参数定义映射校验匹配
Monitor monitor = monitorDto.getMonitor(); Monitor monitor = monitorDto.getMonitor();
monitor.setHost(monitor.getHost().trim()); monitor.setHost(monitor.getHost().trim());
@@ -148,7 +142,7 @@ public class MonitorServiceImpl implements MonitorService {
param.setValue(value); param.setValue(value);
}) })
.collect(Collectors.toMap(Param::getField, param -> param)); .collect(Collectors.toMap(Param::getField, param -> param));
// Check name uniqueness 校验名称唯一性 // 校验名称唯一性
if (isModify != null) { if (isModify != null) {
Optional<Monitor> monitorOptional = monitorDao.findMonitorByNameEquals(monitor.getName()); Optional<Monitor> monitorOptional = monitorDao.findMonitorByNameEquals(monitor.getName());
if (monitorOptional.isPresent()) { if (monitorOptional.isPresent()) {
@@ -163,7 +157,7 @@ public class MonitorServiceImpl implements MonitorService {
} }
} }
// Parameter definition structure verification 参数定义结构校验 // 参数定义结构校验
List<ParamDefine> paramDefines = appService.getAppParamDefines(monitorDto.getMonitor().getApp()); List<ParamDefine> paramDefines = appService.getAppParamDefines(monitorDto.getMonitor().getApp());
if (paramDefines != null) { if (paramDefines != null) {
for (ParamDefine paramDefine : paramDefines) { for (ParamDefine paramDefine : paramDefines) {
@@ -209,7 +203,6 @@ public class MonitorServiceImpl implements MonitorService {
} }
break; break;
case "password": case "password":
// The plaintext password needs to be encrypted for transmission and storage
// 明文密码需加密传输存储 // 明文密码需加密传输存储
String passwordValue = param.getValue(); String passwordValue = param.getValue();
if (!AesUtil.isCiphertext(passwordValue)) { if (!AesUtil.isCiphertext(passwordValue)) {
@@ -219,7 +212,7 @@ public class MonitorServiceImpl implements MonitorService {
param.setType(CommonConstants.PARAM_TYPE_PASSWORD); param.setType(CommonConstants.PARAM_TYPE_PASSWORD);
break; break;
case "boolean": case "boolean":
// boolean check // boolean校验
String booleanValue = param.getValue(); String booleanValue = param.getValue();
try { try {
Boolean.parseBoolean(booleanValue); Boolean.parseBoolean(booleanValue);
@@ -229,7 +222,7 @@ public class MonitorServiceImpl implements MonitorService {
} }
break; break;
case "radio": case "radio":
// radio single value check radio单选值校验 // radio单选值校验
List<ParamDefine.Option> options = paramDefine.getOptions(); List<ParamDefine.Option> options = paramDefine.getOptions();
boolean invalid = true; boolean invalid = true;
if (options != null) { if (options != null) {
@@ -251,8 +244,7 @@ public class MonitorServiceImpl implements MonitorService {
case "key-value": case "key-value":
// todo key-value校验 // todo key-value校验
break; break;
// todo More parameter definitions and actual value format verification // todo 更多参数定义与实际值格式校验
// 更多参数定义与实际值格式校验
default: default:
throw new IllegalArgumentException("ParamDefine type " + paramDefine.getType() + " is invalid."); throw new IllegalArgumentException("ParamDefine type " + paramDefine.getType() + " is invalid.");
} }
@@ -262,10 +254,8 @@ public class MonitorServiceImpl implements MonitorService {
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void modifyMonitor(Monitor monitor, List<Param> params) throws RuntimeException { public void modifyMonitor(Monitor monitor, List<Param> params) throws RuntimeException {
long monitorId = monitor.getId(); long monitorId = monitor.getId();
// Check to determine whether the monitor corresponding to the monitor Id exists
// 查判断monitorId对应的此监控是否存在 // 查判断monitorId对应的此监控是否存在
Optional<Monitor> queryOption = monitorDao.findById(monitorId); Optional<Monitor> queryOption = monitorDao.findById(monitorId);
if (!queryOption.isPresent()) { if (!queryOption.isPresent()) {
@@ -273,11 +263,9 @@ public class MonitorServiceImpl implements MonitorService {
} }
Monitor preMonitor = queryOption.get(); Monitor preMonitor = queryOption.get();
if (!preMonitor.getApp().equals(monitor.getApp())) { if (!preMonitor.getApp().equals(monitor.getApp())) {
// The type of monitoring cannot be modified
// 监控的类型不能修改 // 监控的类型不能修改
throw new IllegalArgumentException("Can not modify monitor's app type"); throw new IllegalArgumentException("Can not modify monitor's app type");
} }
// Construct the collection task Job entity
// 构造采集任务Job实体 // 构造采集任务Job实体
Job appDefine = appService.getAppDefine(monitor.getApp()); Job appDefine = appService.getAppDefine(monitor.getApp());
appDefine.setId(preMonitor.getJobId()); appDefine.setId(preMonitor.getJobId());
@@ -288,16 +276,14 @@ 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);
// After the update is successfully released, refresh the library // 更新采集任务
collectJobService.updateAsyncCollectJob(appDefine);
// 下发更新成功后刷库 // 下发更新成功后刷库
try { try {
monitor.setJobId(preMonitor.getJobId()); monitor.setJobId(preMonitor.getJobId());
monitor.setStatus(preMonitor.getStatus()); monitor.setStatus(preMonitor.getStatus());
monitorDao.save(monitor); monitorDao.save(monitor);
paramDao.saveAll(params); paramDao.saveAll(params);
// Update the collection task after the storage is completed
// 入库完成后更新采集任务
collectJobService.updateAsyncCollectJob(appDefine);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
throw new MonitorDatabaseException(e.getMessage()); throw new MonitorDatabaseException(e.getMessage());
@@ -358,9 +344,7 @@ public class MonitorServiceImpl implements MonitorService {
@Override @Override
public void cancelManageMonitors(HashSet<Long> ids) { public void cancelManageMonitors(HashSet<Long> ids) {
// Update monitoring status Delete corresponding monitoring periodic task
// 更新监控状态 删除对应的监控周期性任务 // 更新监控状态 删除对应的监控周期性任务
// The jobId is not deleted, and the jobId is reused again after the management is started.
// jobId不删除 待启动纳管之后再次复用jobId // jobId不删除 待启动纳管之后再次复用jobId
List<Monitor> managedMonitors = monitorDao.findMonitorsByIdIn(ids) List<Monitor> managedMonitors = monitorDao.findMonitorsByIdIn(ids)
.stream().filter(monitor -> .stream().filter(monitor ->
@@ -377,7 +361,6 @@ public class MonitorServiceImpl implements MonitorService {
@Override @Override
public void enableManageMonitors(HashSet<Long> ids) { public void enableManageMonitors(HashSet<Long> ids) {
// Update monitoring status Add corresponding monitoring periodic task
// 更新监控状态 新增对应的监控周期性任务 // 更新监控状态 新增对应的监控周期性任务
List<Monitor> unManagedMonitors = monitorDao.findMonitorsByIdIn(ids) List<Monitor> unManagedMonitors = monitorDao.findMonitorsByIdIn(ids)
.stream().filter(monitor -> .stream().filter(monitor ->
@@ -387,7 +370,6 @@ public class MonitorServiceImpl implements MonitorService {
if (!unManagedMonitors.isEmpty()) { if (!unManagedMonitors.isEmpty()) {
monitorDao.saveAll(unManagedMonitors); monitorDao.saveAll(unManagedMonitors);
for (Monitor monitor : unManagedMonitors) { for (Monitor monitor : unManagedMonitors) {
// Construct the collection task Job entity
// 构造采集任务Job实体 // 构造采集任务Job实体
Job appDefine = appService.getAppDefine(monitor.getApp()); Job appDefine = appService.getAppDefine(monitor.getApp());
appDefine.setMonitorId(monitor.getId()); appDefine.setMonitorId(monitor.getId());
@@ -398,7 +380,7 @@ 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);
// Issue collection tasks 下发采集任务 // 下发采集任务
collectJobService.addAsyncCollectJob(appDefine); collectJobService.addAsyncCollectJob(appDefine);
} }
} }

View File

@@ -18,7 +18,6 @@ import java.util.stream.Collectors;
/** /**
* 消息通知配置实现 * 消息通知配置实现
*
* @author tom * @author tom
* @date 2021/12/16 16:16 * @date 2021/12/16 16:16
*/ */
@@ -75,24 +74,13 @@ public class NoticeConfigServiceImpl implements NoticeConfigService {
@Override @Override
public List<NoticeReceiver> getReceiverFilterRule(Alert alert) { public List<NoticeReceiver> getReceiverFilterRule(Alert alert) {
// todo use cache 使用缓存 // todo 使用缓存
List<NoticeRule> rules = noticeRuleDao.findNoticeRulesByEnableTrue(); List<NoticeRule> rules = noticeRuleDao.findNoticeRulesByEnableTrue();
// todo The temporary rule is to forward all, and then implement more matching rules: alarm status selection, monitoring type selection, etc. // todo 暂时规则是全部转发 后面实现更多匹配规则:告警状态选择 监控类型选择等
// 暂时规则是全部转发 后面实现更多匹配规则:告警状态选择 监控类型选择等
Set<Long> receiverIds = rules.stream() Set<Long> receiverIds = rules.stream()
.filter(NoticeRule::isFilterAll) .filter(NoticeRule::isFilterAll)
.map(NoticeRule::getReceiverId) .map(NoticeRule::getReceiverId)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
return noticeReceiverDao.findAllById(receiverIds); return noticeReceiverDao.findAllById(receiverIds);
} }
@Override
public NoticeReceiver getReceiverById(Long receiverId) {
return noticeReceiverDao.getOne(receiverId);
}
@Override
public NoticeRule getNoticeRulesById(Long ruleId) {
return noticeRuleDao.getOne(ruleId);
}
} }

View File

@@ -69,8 +69,3 @@ warehouse:
url: jdbc:TAOS-RS://localhost:6041/hertzbeat url: jdbc:TAOS-RS://localhost:6041/hertzbeat
username: root username: root
password: taosdata password: taosdata
#自定义告警控制台地址
alerter:
#这里就是我们的自定义控制台地址
console-url: https://console.tancloud.cn

View File

@@ -4,7 +4,7 @@ category: custom
app: example app: example
name: name:
zh-CN: 模拟应用类型 zh-CN: 模拟应用类型
en-US: EXAMPLE en-US: EXAMPLE APP
# 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串, 3-map映射的json串 # 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串, 3-map映射的json串
# 强制固定必须参数 - host # 强制固定必须参数 - host
configmap: configmap:

View File

@@ -1,247 +0,0 @@
# 此监控类型所属类别service-应用服务监控 db-数据库监控 custom-自定义监控 os-操作系统监控
category: os
# 监控应用类型(与文件名保持一致) eg: linux windows tomcat mysql aws...
app: centos
name:
zh-CN: Centos Linux
en-US: Centos 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
- key: timeout
type: 0
# 指标组列表
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^_^
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}'
# 响应数据解析方式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: 个数
- field: usage
type: 0
unit: '%'
# (非必须)监控指标别名,与上面的指标名映射。用于采集接口数据字段不直接是最终指标名称,需要此别名做映射转换
aliasFields:
- info
- cores
- interrupt
- load
- context_switch
- idle
# (非必须)指标计算表达式,与上面的别名一起作用,计算出最终需要的指标值
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
calculates:
- info=info
- cores=cores
- interrupt=interrupt
- load=load
- context_switch=context_switch
- usage=100-idle
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
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}';vmstat 1 1 | awk 'NR==3{print $15}'"
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
- field: usage
type: 0
unit: '%'
# (非必须)监控指标别名,与上面的指标名映射。用于采集接口数据字段不直接是最终指标名称,需要此别名做映射转换
aliasFields:
- total
- used
- free
- buff_cache
- available
# (非必须)指标计算表达式,与上面的别名一起作用,计算出最终需要的指标值
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
calculates:
- total=total
- used=used
- free=free
- buff_cache=buff_cache
- available=available
- usage=(used / total) * 100
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
timeout: ^_^timeout^_^
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^_^
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}'
parseType: oneRow
- name: interface
priority: 4
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: interface_name
type: 1
instance: true
- 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^_^
timeout: ^_^timeout^_^
script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {print $1,$2,$10}'
parseType: multiRow
- name: disk_free
priority: 5
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: filesystem
type: 1
- field: used
type: 0
unit: Mb
- field: available
type: 0
unit: Mb
- field: usage
type: 0
unit: '%'
- field: mounted
type: 1
instance: true
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
timeout: ^_^timeout^_^
script: df -m | tail -n +2 | awk 'BEGIN{ print "filesystem used available usage mounted"} {print $1,$3,$4,$5,$6}'
parseType: multiRow

View File

@@ -2,7 +2,7 @@ category: service
app: fullsite app: fullsite
name: name:
zh-CN: 全站监控 zh-CN: 全站监控
en-US: SITE MAP en-US: FULL WEBSITE MONITOR
configmap: configmap:
- key: host - key: host
type: 1 type: 1

View File

@@ -1,247 +0,0 @@
# 此监控类型所属类别service-应用服务监控 db-数据库监控 custom-自定义监控 os-操作系统监控
category: os
# 监控应用类型(与文件名保持一致) eg: linux windows tomcat mysql aws...
app: ubuntu
name:
zh-CN: Ubuntu Linux
en-US: Ubuntu 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
- key: timeout
type: 0
# 指标组列表
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^_^
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}'
# 响应数据解析方式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: 个数
- field: usage
type: 0
unit: '%'
# (非必须)监控指标别名,与上面的指标名映射。用于采集接口数据字段不直接是最终指标名称,需要此别名做映射转换
aliasFields:
- info
- cores
- interrupt
- load
- context_switch
- idle
# (非必须)指标计算表达式,与上面的别名一起作用,计算出最终需要的指标值
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
calculates:
- info=info
- cores=cores
- interrupt=interrupt
- load=load
- context_switch=context_switch
- usage=100-idle
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
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}';vmstat 1 1 | awk 'NR==3{print $15}'"
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
- field: usage
type: 0
unit: '%'
# (非必须)监控指标别名,与上面的指标名映射。用于采集接口数据字段不直接是最终指标名称,需要此别名做映射转换
aliasFields:
- total
- used
- free
- buff_cache
- available
# (非必须)指标计算表达式,与上面的别名一起作用,计算出最终需要的指标值
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
calculates:
- total=total
- used=used
- free=free
- buff_cache=buff_cache
- available=available
- usage=(used / total) * 100
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
timeout: ^_^timeout^_^
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^_^
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}'
parseType: oneRow
- name: interface
priority: 4
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: interface_name
type: 1
instance: true
- 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^_^
timeout: ^_^timeout^_^
script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {print $1,$2,$10}'
parseType: multiRow
- name: disk_free
priority: 5
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: filesystem
type: 1
- field: used
type: 0
unit: Mb
- field: available
type: 0
unit: Mb
- field: usage
type: 0
unit: '%'
- field: mounted
type: 1
instance: true
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
timeout: ^_^timeout^_^
script: df -m | tail -n +2 | awk 'BEGIN{ print "filesystem used available usage mounted"} {print $1,$3,$4,$5,$6}'
parseType: multiRow

View File

@@ -2,7 +2,7 @@ category: service
app: website app: website
name: name:
zh-CN: 网站监测 zh-CN: 网站监测
en-US: WEBSITE en-US: WEBSITE MONITOR
configmap: configmap:
- key: host - key: host
type: 1 type: 1

View File

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

View File

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

View File

@@ -700,7 +700,7 @@
<span style="font-family:Arial, Verdana; font-size:14px;color:#FFFFFF;"><a <span style="font-family:Arial, Verdana; font-size:14px;color:#FFFFFF;"><a
target="_blank" target="_blank"
style="color:#FFFFFF;text-decoration:none;" style="color:#FFFFFF;text-decoration:none;"
th:href="${consoleUrl}" href="https://console.tancloud.cn"
data-link-type="web">登入控制台</a></span> data-link-type="web">登入控制台</a></span>
</td> </td>
</tr> </tr>

View File

@@ -2,9 +2,11 @@
@echo off @echo off
setlocal enabledelayedexpansion setlocal enabledelayedexpansion
rem 项目名称
set SERVER_NAME="${project.artifactId}" set SERVER_NAME="${project.artifactId}"
rem 应用的端口号
set SERVER_PORT=1157 set SERVER_PORT=1157
echo Start shutdown HertzBeat %SERVER_NAME% echo Start shutdown HertzBeat %SERVER_NAME%

View File

@@ -2,21 +2,25 @@
@echo off @echo off
setlocal enabledelayedexpansion setlocal enabledelayedexpansion
rem 项目名称
set SERVER_NAME=${project.artifactId} set SERVER_NAME=${project.artifactId}
rem jar名称
set JAR_NAME=${project.build.finalName}.jar set JAR_NAME=${project.build.finalName}.jar
rem enter the bin directory rem 进入bin目录
cd /d %~dp0 cd /d %~dp0
rem 返回到上一级项目根目录路径
cd .. cd ..
rem 打印项目安装根目录绝对路径
set DEPLOY_DIR=%~dp0.. set DEPLOY_DIR=%~dp0..
echo %DEPLOY_DIR% echo %DEPLOY_DIR%
rem 外部配置文件绝对目录,如果是目录需要/结尾,也可以直接指定文件
rem 如果指定的是目录,spring则会读取目录中的所有配置文件
set CONF_DIR=%DEPLOY_DIR%\config set CONF_DIR=%DEPLOY_DIR%\config
echo %CONF_DIR% echo %CONF_DIR%
rem 应用的端口号
set SERVER_PORT=1157 set SERVER_PORT=1157
for /f "tokens=1-5" %%i in ('netstat -ano^|findstr "0.0.0.0:%SERVER_PORT%"') do ( for /f "tokens=1-5" %%i in ('netstat -ano^|findstr "0.0.0.0:%SERVER_PORT%"') do (
@@ -25,6 +29,8 @@ for /f "tokens=1-5" %%i in ('netstat -ano^|findstr "0.0.0.0:%SERVER_PORT%"') do
goto q goto q
) )
rem 项目日志输出绝对路径
set LOGS_DIR=%DEPLOY_DIR%\logs set LOGS_DIR=%DEPLOY_DIR%\logs
rem JVM Configuration rem JVM Configuration
@@ -32,9 +38,9 @@ set JAVA_OPTS= -Duser.timezone=Asia/Shanghai
set JAVA_MEM_OPTS= -server -XX:SurvivorRatio=6 -XX:+UseParallelGC set JAVA_MEM_OPTS= -server -XX:SurvivorRatio=6 -XX:+UseParallelGC
rem 加载外部log文件的配置
set LOGGING_CONFIG=-Dlogging.config=%CONF_DIR%\logback-spring.xml 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%/ set CONFIG_FILES= -Dlogging.path=%LOGS_DIR% %LOGGING_CONFIG% -Dspring.config.location=%CONF_DIR%/
echo Starting the %SERVER_NAME% ... echo Starting the %SERVER_NAME% ...

View File

@@ -71,9 +71,9 @@ import { environment } from '@env/environment';
<setting-drawer *ngIf="showSettingDrawer"></setting-drawer> <setting-drawer *ngIf="showSettingDrawer"></setting-drawer>
<theme-btn <theme-btn
[types]="[ [types]="[
{ key: 'default', text: 'app.theme.default' | i18n }, { key: 'default', text: '浅色主题' },
{ key: 'dark', text: 'app.theme.dark' | i18n }, { key: 'dark', text: '深色主题' },
{ key: 'compact', text: 'app.theme.compact' | i18n } { key: 'compact', text: '紧凑主题' }
]" ]"
></theme-btn> ></theme-btn>
` `

View File

@@ -1,6 +1,4 @@
import { ChangeDetectionStrategy, Component, HostListener, Inject } from '@angular/core'; import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzMessageService } from 'ng-zorro-antd/message'; import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal'; import { NzModalService } from 'ng-zorro-antd/modal';
@@ -16,19 +14,15 @@ import { NzModalService } from 'ng-zorro-antd/modal';
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class HeaderClearStorageComponent { export class HeaderClearStorageComponent {
constructor( constructor(private modalSrv: NzModalService, private messageSrv: NzMessageService) {}
private modalSrv: NzModalService,
private messageSrv: NzMessageService,
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {}
@HostListener('click') @HostListener('click')
_click(): void { _click(): void {
this.modalSrv.confirm({ this.modalSrv.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.clear-cache'), nzTitle: '请确认是否清理缓存?',
nzOnOk: () => { nzOnOk: () => {
localStorage.clear(); localStorage.clear();
this.messageSrv.success(this.i18nSvc.fanyi('common.notify.clear-success')); this.messageSrv.success('清理成功!');
} }
}); });
} }

View File

@@ -26,11 +26,11 @@ import { AlertService } from '../../../service/alert.service';
export class HeaderNotifyComponent implements OnInit { export class HeaderNotifyComponent implements OnInit {
data: NoticeItem[] = [ data: NoticeItem[] = [
{ {
title: this.i18nSvc.fanyi('dashboard.alerts.title-no'), title: '近期未处理告警',
list: [], list: [],
emptyText: this.i18nSvc.fanyi('dashboard.alerts.no'), emptyText: '暂无未处理告警',
emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg', emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
clearText: this.i18nSvc.fanyi('dashboard.alerts.enter') clearText: '进入告警中心'
} }
]; ];
count = 0; count = 0;
@@ -69,10 +69,10 @@ export class HeaderNotifyComponent implements OnInit {
let item = { let item = {
id: alert.id, id: alert.id,
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
title: `${alert.monitorName}--${this.i18nSvc.fanyi(`alert.priority.${alert.priority}`)}`, title: `监控-${alert.monitorName}-发出${this.i18nSvc.fanyi(`alert.priority.${alert.priority}`)}`,
datetime: alert.gmtCreate, datetime: alert.gmtCreate,
color: 'blue', color: 'blue',
type: this.i18nSvc.fanyi('dashboard.alerts.title-no') type: '近期未处理告警'
}; };
this.data[0].list.push(item); this.data[0].list.push(item);
}); });

View File

@@ -40,8 +40,8 @@ import { MonitorService } from '../../../service/monitor.service';
<nz-autocomplete nzBackfill="false" nzDefaultActiveFirstOption #auto> <nz-autocomplete nzBackfill="false" nzDefaultActiveFirstOption #auto>
<nz-auto-option *ngFor="let option of options" [nzValue]="option.id" [nzLabel]="option.name"> <nz-auto-option *ngFor="let option of options" [nzValue]="option.id" [nzLabel]="option.name">
<a [routerLink]="['/monitors/' + option.id]"> <a [routerLink]="['/monitors/' + option.id]">
{{ 'monitor.name' | i18n }} : {{ option.name }} 监控名称: {{ option.name }}
<span style="left:50% ; position: absolute;">{{ 'monitor.host' | i18n }} : {{ option.host }}</span> <span style="left:50% ; position: absolute;">监控Host: {{ option.host }}</span>
<span style="right: 10px; position: absolute;"><i nz-icon nzType="arrow-right" nzTheme="outline"></i></span> <span style="right: 10px; position: absolute;"><i nz-icon nzType="arrow-right" nzTheme="outline"></i></span>
</a> </a>
</nz-auto-option> </nz-auto-option>

View File

@@ -6,15 +6,15 @@
<img class="logo" src="./assets/logo.svg" alt="" /> <img class="logo" src="./assets/logo.svg" alt="" />
<span class="title">HertzBeat</span> <span class="title">HertzBeat</span>
</div> </div>
<div class="desc">{{ 'app.passport.desc' | i18n }}</div> <div class="desc">TanCloud-易用友好的高性能监控云服务</div>
</div> </div>
<router-outlet></router-outlet> <router-outlet></router-outlet>
<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>
2022 2022
<a href="https://tancloud.cn" target="_blank">TanCloud tancloud.cn | </a> <a href="https://tancloud.cn" target="_blank">探云 tancloud.cn | </a>
<a href="https://hertzbeat.com" target="_blank">HertzBeat hertzbeat.com</a> <a href="https://hertzbeat.com" target="_blank">赫兹跳动 hertzbeat.com</a>
</global-footer> </global-footer>
</div> </div>
</div> </div>

View File

@@ -1,7 +1,5 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, Inject, OnInit } from '@angular/core';
import { I18NService } from '@core';
import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
@Component({ @Component({
selector: 'layout-passport', selector: 'layout-passport',
@@ -11,12 +9,12 @@ import { ALAIN_I18N_TOKEN } from '@delon/theme';
export class LayoutPassportComponent implements OnInit { export class LayoutPassportComponent implements OnInit {
links = [ links = [
{ {
title: this.i18nSvc.fanyi('app.passport.welcome'), title: '欢迎使用TanCloud探云-监控云服务-tancloud.cn',
href: 'https://tancloud.cn' href: 'https://tancloud.cn'
} }
]; ];
constructor(@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService, @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService) {} constructor(@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService) {}
ngOnInit(): void { ngOnInit(): void {
this.tokenService.clear(); this.tokenService.clear();

View File

@@ -3,12 +3,12 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="alert"></i> <i nz-icon nzType="alert"></i>
<span>{{ 'menu.alert.center' | i18n }}</span> <span>告警中心</span>
</nz-breadcrumb-item> </nz-breadcrumb-item>
</nz-breadcrumb> </nz-breadcrumb>
<nz-divider></nz-divider> <nz-divider></nz-divider>
@@ -16,28 +16,26 @@
<div> <div>
<button nz-button nzType="primary" (click)="onDeleteAlerts()"> <button nz-button nzType="primary" (click)="onDeleteAlerts()">
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
{{ 'alert.center.delete' | i18n }} 删除告警
</button> </button>
<button nz-button nzType="primary" (click)="onMarkReadAlerts()"> <button nz-button nzType="primary" (click)="onMarkReadAlerts()">
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
{{ 'alert.center.deal' | i18n }} 标记已处理
</button> </button>
<button nz-button nzType="primary" (click)="onMarkUnReadAlerts()"> <button nz-button nzType="primary" (click)="onMarkUnReadAlerts()">
<i nz-icon nzType="up-circle" nzTheme="outline"></i> <i nz-icon nzType="up-circle" nzTheme="outline"></i>
{{ 'alert.center.no-deal' | i18n }} 标记未处理
</button> </button>
<button nz-button nzType="primary" (click)="sync()" nz-tooltip [nzTooltipTitle]="'common.refresh' | i18n"> <button nz-button nzType="primary" (click)="sync()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="onFilterSearchAlerts()"> <button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="onFilterSearchAlerts()"> 搜索 </button>
{{ 'common.search' | i18n }}
</button>
<input <input
style="margin-right: 5px; float: right; width: 150px; border-radius: 9px; text-align: center" style="margin-right: 5px; float: right; width: 150px; border-radius: 9px; text-align: center"
nz-input nz-input
type="text" type="text"
[placeholder]="'alert.center.search' | i18n" placeholder="搜索告警内容"
nzSize="default" nzSize="default"
(keyup.enter)="onFilterSearchAlerts()" (keyup.enter)="onFilterSearchAlerts()"
[(ngModel)]="filterContent" [(ngModel)]="filterContent"
@@ -45,24 +43,23 @@
<nz-select <nz-select
style="margin-right: 10px; float: right; width: 120px" style="margin-right: 10px; float: right; width: 120px"
nzAllowClear nzAllowClear
[nzPlaceHolder]="'alert.center.filter-status' | i18n" [nzPlaceHolder]="'告警状态过滤'"
[(ngModel)]="filterStatus" [(ngModel)]="filterStatus"
> >
<nz-option [nzLabel]="'alert.status.all' | i18n" nzValue="9"></nz-option> <nz-option nzLabel="全部状态" nzValue="9"></nz-option>
<nz-option [nzLabel]="'alert.status.0' | i18n" nzValue="0"></nz-option> <nz-option nzLabel="未处理" nzValue="0"></nz-option>
<nz-option [nzLabel]="'alert.status.2' | i18n" nzValue="2"></nz-option> <nz-option nzLabel="已处理" nzValue="3"></nz-option>
<nz-option [nzLabel]="'alert.status.3' | i18n" nzValue="3"></nz-option>
</nz-select> </nz-select>
<nz-select <nz-select
style="margin-right: 10px; float: right; width: 120px" style="margin-right: 10px; float: right; width: 120px"
nzAllowClear nzAllowClear
[nzPlaceHolder]="'alert.center.filter-priority' | i18n" [nzPlaceHolder]="'告警级别过滤'"
[(ngModel)]="filterPriority" [(ngModel)]="filterPriority"
> >
<nz-option [nzLabel]="'alert.priority.all' | i18n" nzValue="9"></nz-option> <nz-option nzLabel="全部级别" nzValue="9"></nz-option>
<nz-option [nzLabel]="'alert.priority.2' | i18n" nzValue="2"></nz-option> <nz-option nzLabel="警告级别" nzValue="2"></nz-option>
<nz-option [nzLabel]="'alert.priority.1' | i18n" nzValue="1"></nz-option> <nz-option nzLabel="严重级别" nzValue="1"></nz-option>
<nz-option [nzLabel]="'alert.priority.0' | i18n" nzValue="0"></nz-option> <nz-option nzLabel="紧急级别" nzValue="0"></nz-option>
</nz-select> </nz-select>
</div> </div>
@@ -84,13 +81,13 @@
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th> <th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th>
<th nzAlign="center" nzLeft>{{ 'alert.center.target' | i18n }}</th> <th nzAlign="center" nzLeft>告警指标</th>
<th nzAlign="center">{{ 'alert.center.monitor' | i18n }}</th> <th nzAlign="center">所属监控</th>
<th nzAlign="center">{{ 'alert.center.priority' | i18n }}</th> <th nzAlign="center">级别</th>
<th nzAlign="center">{{ 'alert.center.content' | i18n }}</th> <th nzAlign="center">告警内容</th>
<th nzAlign="center">{{ 'alert.center.status' | i18n }}</th> <th nzAlign="center">状态</th>
<th nzAlign="center">{{ 'alert.center.time' | i18n }}</th> <th nzAlign="center">告警时间</th>
<th nzAlign="center">{{ 'common.edit' | i18n }}</th> <th nzAlign="center">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -105,36 +102,30 @@
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.priority == 0" nzColor="red"> <nz-tag *ngIf="data.priority == 0" nzColor="red">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.0' | i18n }}</span> <span>紧急告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.priority == 1" nzColor="orange"> <nz-tag *ngIf="data.priority == 1" nzColor="orange">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.1' | i18n }}</span> <span>严重告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.priority == 2" nzColor="yellow"> <nz-tag *ngIf="data.priority == 2" nzColor="yellow">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.2' | i18n }}</span> <span>警告告警</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ data.content }}</td> <td nzAlign="center">{{ data.content }}</td>
<td nzAlign="center"> <td nzAlign="center">
{{ 'alert.status.' + data.status | i18n }} {{ data.status === 0 ? '未处理' : '已处理' }}
</td> </td>
<td nzAlign="center">{{ data.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss' }}</td> <td nzAlign="center">{{ data.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center"> <td nzAlign="center">
<button nz-button nzType="primary" (click)="onDeleteOneAlert(data.id)" nz-tooltip [nzTooltipTitle]="'alert.center.delete' | i18n"> <button nz-button nzType="primary" (click)="onDeleteOneAlert(data.id)" nz-tooltip nzTooltipTitle="删除告警">
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
</button> </button>
<button nz-button nzType="primary" (click)="onMarkReadOneAlert(data.id)" nz-tooltip [nzTooltipTitle]="'alert.center.deal' | i18n"> <button nz-button nzType="primary" (click)="onMarkReadOneAlert(data.id)" nz-tooltip nzTooltipTitle="标记已处理">
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onMarkUnReadOneAlert(data.id)" nz-tooltip nzTooltipTitle="标记未处理">
nz-button
nzType="primary"
(click)="onMarkUnReadOneAlert(data.id)"
nz-tooltip
[nzTooltipTitle]="'alert.center.no-deal' | i18n"
>
<i nz-icon nzType="up-circle" nzTheme="outline"></i> <i nz-icon nzType="up-circle" nzTheme="outline"></i>
</button> </button>
</td> </td>
@@ -142,4 +133,4 @@
</tbody> </tbody>
</nz-table> </nz-table>
<ng-template #rangeTemplate> {{ 'common.total' | i18n }} {{ total }} </ng-template> <ng-template #rangeTemplate> 总量 {{ total }} </ng-template>

View File

@@ -1,6 +1,4 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzModalService } from 'ng-zorro-antd/modal'; import { NzModalService } from 'ng-zorro-antd/modal';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { NzTableQueryParams } from 'ng-zorro-antd/table'; import { NzTableQueryParams } from 'ng-zorro-antd/table';
@@ -14,12 +12,7 @@ import { AlertService } from '../../../service/alert.service';
styles: [] styles: []
}) })
export class AlertCenterComponent implements OnInit { export class AlertCenterComponent implements OnInit {
constructor( constructor(private notifySvc: NzNotificationService, private modal: NzModalService, private alertSvc: AlertService) {}
private notifySvc: NzNotificationService,
private modal: NzModalService,
private alertSvc: AlertService,
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {}
pageIndex: number = 1; pageIndex: number = 1;
pageSize: number = 8; pageSize: number = 8;
@@ -94,13 +87,13 @@ export class AlertCenterComponent implements OnInit {
onDeleteAlerts() { onDeleteAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) { if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('alert.center.notify.no-delete'), ''); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('alert.center.confirm.delete-batch'), nzTitle: '请确认是否批量删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteAlerts(this.checkedAlertIds) nzOnOk: () => this.deleteAlerts(this.checkedAlertIds)
@@ -109,13 +102,13 @@ export class AlertCenterComponent implements OnInit {
onMarkReadAlerts() { onMarkReadAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) { if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('alert.center.notify.no-mark'), ''); this.notifySvc.warning('未选中任何待标记项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('alert.center.confirm.mark-done-batch'), nzTitle: '请确认是否批量标记已处理!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 3) nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 3)
@@ -123,13 +116,13 @@ export class AlertCenterComponent implements OnInit {
} }
onMarkUnReadAlerts() { onMarkUnReadAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) { if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('alert.center.notify.no-mark'), ''); this.notifySvc.warning('未选中任何待标记项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('alert.center.confirm.mark-no-batch'), nzTitle: '请确认是否批量标记未处理!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 0) nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 0)
@@ -140,9 +133,9 @@ export class AlertCenterComponent implements OnInit {
let alerts = new Set<number>(); let alerts = new Set<number>();
alerts.add(alertId); alerts.add(alertId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), nzTitle: '请确认是否删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteAlerts(alerts) nzOnOk: () => this.deleteAlerts(alerts)
@@ -153,9 +146,9 @@ export class AlertCenterComponent implements OnInit {
let alerts = new Set<number>(); let alerts = new Set<number>();
alerts.add(alertId); alerts.add(alertId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('alert.center.confirm.mark-done'), nzTitle: '请确认是否标记已处理!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(alerts, 3) nzOnOk: () => this.updateAlertsStatus(alerts, 3)
@@ -166,9 +159,9 @@ export class AlertCenterComponent implements OnInit {
let alerts = new Set<number>(); let alerts = new Set<number>();
alerts.add(alertId); alerts.add(alertId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('alert.center.confirm.mark-no'), nzTitle: '请确认是否标记未处理!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(alerts, 0) nzOnOk: () => this.updateAlertsStatus(alerts, 0)
@@ -181,17 +174,17 @@ export class AlertCenterComponent implements OnInit {
message => { message => {
deleteAlerts$.unsubscribe(); deleteAlerts$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); this.notifySvc.success('删除成功!', '');
this.loadAlertsTable(); this.loadAlertsTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
deleteAlerts$.unsubscribe(); deleteAlerts$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
@@ -202,17 +195,17 @@ export class AlertCenterComponent implements OnInit {
message => { message => {
markAlertsStatus$.unsubscribe(); markAlertsStatus$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.mark-success'), ''); this.notifySvc.success('标记成功!', '');
this.loadAlertsTable(); this.loadAlertsTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.mark-fail'), message.msg); this.notifySvc.error('标记失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
markAlertsStatus$.unsubscribe(); markAlertsStatus$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.mark-fail'), error.msg); this.notifySvc.error('标记失败!', error.msg);
} }
); );
} }

View File

@@ -3,14 +3,14 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="alert"></i> <i nz-icon nzType="alert"></i>
<span>{{ 'menu.alert.dispatch' | i18n }}</span> <span>告警通知配置</span>
<a href="https://tancloud.cn/docs/help/alert_email" target="_blank" style="float: right; margin-right: 5%"> <a href="https://tancloud.cn/docs/help/alert_email" target="_blank" style="float: right; margin-right: 5%">
<span>{{ 'common.button.help' | i18n }}&nbsp;</span> <span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i> <i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
@@ -18,12 +18,12 @@
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-tabset nzSize="large"> <nz-tabset nzSize="large">
<nz-tab [nzTitle]="'alert.notice.receiver' | i18n"> <nz-tab nzTitle="告警接收人">
<button nz-button nzType="primary" (click)="onNewNoticeReceiver()"> <button nz-button nzType="primary" (click)="onNewNoticeReceiver()">
<i nz-icon nzType="appstore-add" nzTheme="outline"></i> <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
{{ 'alert.notice.receiver.new' | i18n }} 新增接收人
</button> </button>
<button nz-button nzType="primary" (click)="syncReceiver()" nz-tooltip [nzTooltipTitle]="'common.refresh' | i18n"> <button nz-button nzType="primary" (click)="syncReceiver()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<nz-table <nz-table
@@ -35,11 +35,11 @@
> >
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzWidth="10%">{{ 'alert.notice.receiver.people' | i18n }}</th> <th nzAlign="center" nzWidth="10%">接收人</th>
<th nzAlign="center" nzWidth="20%">{{ 'alert.notice.receiver.type' | i18n }}</th> <th nzAlign="center" nzWidth="20%">通知方式</th>
<th nzAlign="center" nzWidth="20%">{{ 'alert.notice.receiver.setting' | i18n }}</th> <th nzAlign="center" nzWidth="20%">配置</th>
<th nzAlign="center" nzWidth="20%">{{ 'common.edit-time' | i18n }}</th> <th nzAlign="center" nzWidth="20%">最新修改时间</th>
<th nzAlign="center" nzWidth="30%">{{ 'common.edit' | i18n }}</th> <th nzAlign="center" nzWidth="30%">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -50,11 +50,11 @@
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.type == 0" nzColor="orange"> <nz-tag *ngIf="data.type == 0" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.sms' | i18n }}</span> <span>短信</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 1" nzColor="orange"> <nz-tag *ngIf="data.type == 1" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.email' | i18n }}</span> <span>邮件</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 2" nzColor="orange"> <nz-tag *ngIf="data.type == 2" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
@@ -62,19 +62,19 @@
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 3" nzColor="orange"> <nz-tag *ngIf="data.type == 3" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.wechat' | i18n }}</span> <span>微信公众号</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 4" nzColor="orange"> <nz-tag *ngIf="data.type == 4" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.wework' | i18n }}</span> <span>企业微信机器人</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 5" nzColor="orange"> <nz-tag *ngIf="data.type == 5" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.ding' | i18n }}</span> <span>钉钉机器人</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 6" nzColor="orange"> <nz-tag *ngIf="data.type == 6" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.fei-shu' | i18n }}</span> <span>飞书机器人</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
@@ -88,22 +88,10 @@
</td> </td>
<td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td> <td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center"> <td nzAlign="center">
<button <button nz-button nzType="primary" (click)="onEditOneNoticeReceiver(data)" nz-tooltip nzTooltipTitle="修改接收人">
nz-button
nzType="primary"
(click)="onEditOneNoticeReceiver(data)"
nz-tooltip
[nzTooltipTitle]="'alert.notice.receiver.edit' | i18n"
>
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onDeleteOneNoticeReceiver(data.id)" nz-tooltip nzTooltipTitle="删除接收人">
nz-button
nzType="primary"
(click)="onDeleteOneNoticeReceiver(data.id)"
nz-tooltip
[nzTooltipTitle]="'alert.notice.receiver.delete' | i18n"
>
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
</button> </button>
</td> </td>
@@ -111,12 +99,12 @@
</tbody> </tbody>
</nz-table> </nz-table>
</nz-tab> </nz-tab>
<nz-tab [nzTitle]="'alert.notice.rule' | i18n"> <nz-tab nzTitle="告警通知策略">
<button nz-button nzType="primary" (click)="onNewNoticeRule()"> <button nz-button nzType="primary" (click)="onNewNoticeRule()">
<i nz-icon nzType="appstore-add" nzTheme="outline"></i> <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
{{ 'alert.notice.rule.new' | i18n }} 新增通知策略
</button> </button>
<button nz-button nzType="primary" (click)="syncRule()" nz-tooltip [nzTooltipTitle]="'common.refresh' | i18n"> <button nz-button nzType="primary" (click)="syncRule()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<nz-table <nz-table
@@ -128,12 +116,12 @@
> >
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzWidth="15%">{{ 'alert.notice.rule.name' | i18n }}</th> <th nzAlign="center" nzWidth="15%">策略名称</th>
<th nzAlign="center" nzWidth="12%">{{ 'alert.notice.receiver.people' | i18n }}</th> <th nzAlign="center" nzWidth="12%">接收人</th>
<th nzAlign="center" nzWidth="12%">{{ 'alert.notice.rule.all' | i18n }}</th> <th nzAlign="center" nzWidth="12%">转发所有</th>
<th nzAlign="center" nzWidth="15%">{{ 'alert.notice.rule.enable' | i18n }}</th> <th nzAlign="center" nzWidth="15%">是否启用</th>
<th nzAlign="center" nzWidth="15%">{{ 'common.edit-time' | i18n }}</th> <th nzAlign="center" nzWidth="15%">最新修改时间</th>
<th nzAlign="center" nzWidth="25%">{{ 'common.edit' | i18n }}</th> <th nzAlign="center" nzWidth="25%">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -146,38 +134,26 @@
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.filterAll" nzColor="green"> <nz-tag *ngIf="data.filterAll" nzColor="green">
<span>{{ 'common.yes' | i18n }}</span> <span></span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="!data.filterAll" nzColor="orange"> <nz-tag *ngIf="!data.filterAll" nzColor="orange">
<span>{{ 'common.no' | i18n }}</span> <span></span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.enable" nzColor="green"> <nz-tag *ngIf="data.enable" nzColor="green">
<span>{{ 'common.enable' | i18n }}</span> <span>开启</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="!data.enable" nzColor="orange"> <nz-tag *ngIf="!data.enable" nzColor="orange">
<span>{{ 'common.disable' | i18n }}</span> <span>关闭</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td> <td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center"> <td nzAlign="center">
<button <button nz-button nzType="primary" (click)="onEditOneNoticeRule(data)" nz-tooltip nzTooltipTitle="修改告警策略">
nz-button
nzType="primary"
(click)="onEditOneNoticeRule(data)"
nz-tooltip
[nzTooltipTitle]="'alert.notice.rule.edit' | i18n"
>
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onDeleteOneNoticeRule(data.id)" nz-tooltip nzTooltipTitle="删除告警策略">
nz-button
nzType="primary"
(click)="onDeleteOneNoticeRule(data.id)"
nz-tooltip
[nzTooltipTitle]="'alert.notice.rule.delete' | i18n"
>
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
</button> </button>
</td> </td>
@@ -190,7 +166,7 @@
<!-- 新增或修改通知接收人弹出框 --> <!-- 新增或修改通知接收人弹出框 -->
<nz-modal <nz-modal
[(nzVisible)]="isManageReceiverModalVisible" [(nzVisible)]="isManageReceiverModalVisible"
[nzTitle]="isManageReceiverModalAdd ? ('alert.notice.receiver.new' | i18n) : ('alert.notice.receiver.edit' | i18n)" [nzTitle]="isManageReceiverModalAdd ? '新增接收人' : '修改接收人'"
(nzOnCancel)="onManageReceiverModalCancel()" (nzOnCancel)="onManageReceiverModalCancel()"
(nzOnOk)="onManageReceiverModalOk()" (nzOnOk)="onManageReceiverModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
@@ -200,27 +176,27 @@
<div *nzModalContent class="-inner-content"> <div *nzModalContent class="-inner-content">
<form nz-form #receiverForm="ngForm"> <form nz-form #receiverForm="ngForm">
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true">{{ 'alert.notice.receiver.people.name' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true">接收人名称</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.name" nz-input required name="name" type="text" id="name" /> <input [(ngModel)]="receiver.name" nz-input required name="name" type="text" id="name" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="type">{{ 'alert.notice.receiver.type' | i18n }} </nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="type">通知方式 </nz-form-label>
<nz-form-control nzSpan="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control nzSpan="12" [nzErrorTip]="'validation.required' | i18n">
<nz-select [(ngModel)]="receiver.type" nzPlaceHolder="Choose" required name="type" id="type"> <nz-select [(ngModel)]="receiver.type" nzPlaceHolder="Choose" required name="type" id="type">
<nz-option [nzValue]="0" nzDisabled [nzLabel]="'alert.notice.type.sms' | i18n"></nz-option> <nz-option [nzValue]="0" nzDisabled nzLabel="短信"></nz-option>
<nz-option [nzValue]="1" [nzLabel]="'alert.notice.type.email' | i18n"></nz-option> <nz-option [nzValue]="1" nzLabel="邮箱"></nz-option>
<nz-option [nzValue]="2" nzLabel="WebHook"></nz-option> <nz-option [nzValue]="2" nzLabel="WebHook"></nz-option>
<nz-option [nzValue]="3" nzDisabled [nzLabel]="'alert.notice.type.wechat' | i18n"></nz-option> <nz-option [nzValue]="3" nzDisabled nzLabel="微信公众号"></nz-option>
<nz-option [nzValue]="4" [nzLabel]="'alert.notice.type.wework' | i18n"></nz-option> <nz-option [nzValue]="4" nzLabel="企业微信机器人"></nz-option>
<nz-option [nzValue]="5" [nzLabel]="'alert.notice.type.ding' | i18n"></nz-option> <nz-option [nzValue]="5" nzLabel="钉钉机器人"></nz-option>
<nz-option [nzValue]="6" [nzLabel]="'alert.notice.type.fei-shu' | i18n"></nz-option> <nz-option [nzValue]="6" nzLabel="飞书机器人"></nz-option>
</nz-select> </nz-select>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 0"> <nz-form-item *ngIf="receiver.type === 0">
<nz-form-label [nzSpan]="7" nzFor="phone" [nzRequired]="receiver.type === 0">{{ 'alert.notice.type.phone' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="phone" [nzRequired]="receiver.type === 0">手机号</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.phone.invalid' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.phone.invalid' | i18n">
<input <input
[(ngModel)]="receiver.phone" [(ngModel)]="receiver.phone"
@@ -234,45 +210,37 @@
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 1"> <nz-form-item *ngIf="receiver.type === 1">
<nz-form-label [nzSpan]="7" nzFor="email" [nzRequired]="receiver.type === 1">{{ 'alert.notice.type.email' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="email" [nzRequired]="receiver.type === 1">邮箱</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.email.invalid' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.email.invalid' | i18n">
<input [(ngModel)]="receiver.email" nz-input [required]="receiver.type === 1" email name="email" type="email" id="email" /> <input [(ngModel)]="receiver.email" nz-input [required]="receiver.type === 1" email name="email" type="email" id="email" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 2"> <nz-form-item *ngIf="receiver.type === 2">
<nz-form-label [nzSpan]="7" nzFor="hookUrl" [nzRequired]="receiver.type === 2">{{ 'alert.notice.type.url' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="hookUrl" [nzRequired]="receiver.type === 2">URL地址</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.hookUrl" nz-input [required]="receiver.type === 2" name="hookUrl" type="url" id="hookUrl" /> <input [(ngModel)]="receiver.hookUrl" nz-input [required]="receiver.type === 2" name="hookUrl" type="url" id="hookUrl" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 3"> <nz-form-item *ngIf="receiver.type === 3">
<nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 3">{{ <nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 3">微信OPENID</nz-form-label>
'alert.notice.type.wechat-id' | i18n
}}</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 3" name="wechatId" type="text" /> <input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 3" name="wechatId" type="text" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 4"> <nz-form-item *ngIf="receiver.type === 4">
<nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 4">{{ <nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 4">企业微信机器人KEY</nz-form-label>
'alert.notice.type.wework-key' | i18n
}}</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 4" name="wechatId" type="text" /> <input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 4" name="wechatId" type="text" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 5"> <nz-form-item *ngIf="receiver.type === 5">
<nz-form-label [nzSpan]="7" nzFor="accessToken" [nzRequired]="receiver.type === 5">{{ <nz-form-label [nzSpan]="7" nzFor="accessToken" [nzRequired]="receiver.type === 5">机器人ACCESS_TOKEN</nz-form-label>
'alert.notice.type.access-token' | i18n
}}</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.accessToken" nz-input [required]="receiver.type === 5" name="accessToken" type="text" /> <input [(ngModel)]="receiver.accessToken" nz-input [required]="receiver.type === 5" name="accessToken" type="text" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 6"> <nz-form-item *ngIf="receiver.type === 6">
<nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 6">{{ <nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 6">飞书机器人KEY</nz-form-label>
'alert.notice.type.fei-shu-key' | i18n
}}</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 6" name="wechatId" type="text" /> <input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 6" name="wechatId" type="text" />
</nz-form-control> </nz-form-control>
@@ -284,7 +252,7 @@
<!-- 新增或修改通知策略弹出框 --> <!-- 新增或修改通知策略弹出框 -->
<nz-modal <nz-modal
[(nzVisible)]="isManageRuleModalVisible" [(nzVisible)]="isManageRuleModalVisible"
[nzTitle]="isManageRuleModalAdd ? ('alert.notice.rule.new' | i18n) : ('alert.notice.rule.edit' | i18n)" [nzTitle]="isManageRuleModalAdd ? '新增策略' : '修改策略'"
(nzOnCancel)="onManageRuleModalCancel()" (nzOnCancel)="onManageRuleModalCancel()"
(nzOnOk)="onManageRuleModalOk()" (nzOnOk)="onManageRuleModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
@@ -294,19 +262,19 @@
<div *nzModalContent class="-inner-content"> <div *nzModalContent class="-inner-content">
<form nz-form #ruleForm="ngForm"> <form nz-form #ruleForm="ngForm">
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="rule_name" nzRequired="true">{{ 'alert.notice.rule.name' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="rule_name" nzRequired="true">策略名称</nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="rule.name" nz-input required name="rule_name" type="text" id="rule_name" /> <input [(ngModel)]="rule.name" nz-input required name="rule_name" type="text" id="rule_name" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="filterAll">{{ 'alert.notice.rule.all' | i18n }}</nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="filterAll">转发所有</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="rule.filterAll" disabled name="filterAll" id="filterAll"></nz-switch> <nz-switch [(ngModel)]="rule.filterAll" disabled name="filterAll" id="filterAll"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="receiver">{{ 'alert.notice.receiver.people' | i18n }}</nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="receiver">接收人</nz-form-label>
<nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-select <nz-select
[(ngModel)]="rule.receiverId" [(ngModel)]="rule.receiverId"
@@ -323,7 +291,7 @@
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="enable">{{ 'alert.notice.rule.enable' | i18n }}</nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="enable">是否启用</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="rule.enable" name="enable" id="enable"></nz-switch> <nz-switch [(ngModel)]="rule.enable" name="enable" id="enable"></nz-switch>
</nz-form-control> </nz-form-control>

View File

@@ -1,6 +1,4 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzModalService } from 'ng-zorro-antd/modal'; import { NzModalService } from 'ng-zorro-antd/modal';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
@@ -20,8 +18,7 @@ export class AlertNoticeComponent implements OnInit {
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private noticeReceiverSvc: NoticeReceiverService, private noticeReceiverSvc: NoticeReceiverService,
private modal: NzModalService, private modal: NzModalService,
private noticeRuleSvc: NoticeRuleService, private noticeRuleSvc: NoticeRuleService
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {} ) {}
receivers!: NoticeReceiver[]; receivers!: NoticeReceiver[];
@@ -81,9 +78,9 @@ export class AlertNoticeComponent implements OnInit {
onDeleteOneNoticeReceiver(receiveId: number) { onDeleteOneNoticeReceiver(receiveId: number) {
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), nzTitle: '请确认是否删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteOneNoticeReceiver(receiveId) nzOnOk: () => this.deleteOneNoticeReceiver(receiveId)
@@ -101,23 +98,23 @@ export class AlertNoticeComponent implements OnInit {
.subscribe( .subscribe(
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); this.notifySvc.success('删除成功!', '');
this.loadReceiversTable(); this.loadReceiversTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
onDeleteOneNoticeRule(ruleId: number) { onDeleteOneNoticeRule(ruleId: number) {
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), nzTitle: '请确认是否删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteOneNoticeRule(ruleId) nzOnOk: () => this.deleteOneNoticeRule(ruleId)
@@ -135,14 +132,14 @@ export class AlertNoticeComponent implements OnInit {
.subscribe( .subscribe(
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); this.notifySvc.success('删除成功!', '');
this.loadRulesTable(); this.loadRulesTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
@@ -182,14 +179,14 @@ export class AlertNoticeComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageReceiverModalVisible = false; this.isManageReceiverModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.new-success'), ''); this.notifySvc.success('新增成功!', '');
this.loadReceiversTable(); this.loadReceiversTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), message.msg); this.notifySvc.error('新增失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), error.msg); this.notifySvc.error('新增失败!', error.msg);
} }
); );
} else { } else {
@@ -205,14 +202,14 @@ export class AlertNoticeComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageReceiverModalVisible = false; this.isManageReceiverModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.edit-success'), ''); this.notifySvc.success('修改成功!', '');
this.loadReceiversTable(); this.loadReceiversTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), message.msg); this.notifySvc.error('修改失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), error.msg); this.notifySvc.error('修改失败!', error.msg);
} }
); );
} }
@@ -313,14 +310,14 @@ export class AlertNoticeComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageRuleModalVisible = false; this.isManageRuleModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.new-success'), ''); this.notifySvc.success('新增成功!', '');
this.loadRulesTable(); this.loadRulesTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), message.msg); this.notifySvc.error('新增失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), error.msg); this.notifySvc.error('新增失败!', error.msg);
} }
); );
} else { } else {
@@ -336,14 +333,14 @@ export class AlertNoticeComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageRuleModalVisible = false; this.isManageRuleModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.edit-success'), ''); this.notifySvc.success('修改成功!', '');
this.loadRulesTable(); this.loadRulesTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), message.msg); this.notifySvc.error('修改失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), error.msg); this.notifySvc.error('修改失败!', error.msg);
} }
); );
} }

View File

@@ -3,14 +3,14 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="alert"></i> <i nz-icon nzType="alert"></i>
<span>{{ 'menu.alert.setting' | i18n }}</span> <span>告警阈值配置</span>
<a href="https://tancloud.cn/docs/help/alert_threshold" target="_blank" style="float: right; margin-right: 5%"> <a href="https://tancloud.cn/docs/help/alert_threshold" target="_blank" style="float: right; margin-right: 5%">
<span>{{ 'common.button.help' | i18n }}&nbsp;</span> <span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i> <i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
@@ -19,17 +19,17 @@
<button nz-button nzType="primary" (click)="onNewAlertDefine()"> <button nz-button nzType="primary" (click)="onNewAlertDefine()">
<i nz-icon nzType="appstore-add" nzTheme="outline"></i> <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
{{ 'alert.setting.new' | i18n }} 新增阈值
</button> </button>
<button nz-button nzType="primary" (click)="onEditAlertDefine()"> <button nz-button nzType="primary" (click)="onEditAlertDefine()">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
{{ 'common.button.edit' | i18n }} 编辑
</button> </button>
<button nz-button nzType="primary" (click)="onDeleteAlertDefines()"> <button nz-button nzType="primary" (click)="onDeleteAlertDefines()">
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
{{ 'common.button.delete' | i18n }} 删除
</button> </button>
<button nz-button nzType="primary" (click)="sync()" nz-tooltip [nzTooltipTitle]="'common.refresh' | i18n"> <button nz-button nzType="primary" (click)="sync()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
@@ -51,14 +51,14 @@
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th> <th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th>
<th nzAlign="center" nzLeft>{{ 'alert.setting.target' | i18n }}</th> <th nzAlign="center" nzLeft>指标对象</th>
<th nzAlign="center">{{ 'alert.setting.expr' | i18n }}</th> <th nzAlign="center">阈值触发表达式</th>
<th nzAlign="center">{{ 'alert.priority' | i18n }}</th> <th nzAlign="center">告警级别</th>
<th nzAlign="center">{{ 'alert.setting.times' | i18n }}</th> <th nzAlign="center">触发次数</th>
<th nzAlign="center">{{ 'alert.setting.template' | i18n }}</th> <th nzAlign="center">通知模版</th>
<th nzAlign="center">{{ 'alert.setting.default' | i18n }}</th> <th nzAlign="center">全局默认</th>
<th nzAlign="center">{{ 'common.edit-time' | i18n }}</th> <th nzAlign="center">最新修改时间</th>
<th nzAlign="center">{{ 'common.edit' | i18n }}</th> <th nzAlign="center">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -73,54 +73,36 @@
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.priority == 0" nzColor="red"> <nz-tag *ngIf="data.priority == 0" nzColor="red">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.0' | i18n }}</span> <span>紧急告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.priority == 1" nzColor="orange"> <nz-tag *ngIf="data.priority == 1" nzColor="orange">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.1' | i18n }}</span> <span>严重告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.priority == 2" nzColor="yellow"> <nz-tag *ngIf="data.priority == 2" nzColor="yellow">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.2' | i18n }}</span> <span>警告告警</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ data.times }}</td> <td nzAlign="center">{{ data.times }}</td>
<td nzAlign="center">{{ data.template }}</td> <td nzAlign="center">{{ data.template }}</td>
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.preset" nzColor="green"> <nz-tag *ngIf="data.preset" nzColor="green">
<span>{{ 'common.yes' | i18n }}</span> <span></span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="!data.preset" nzColor="orange"> <nz-tag *ngIf="!data.preset" nzColor="orange">
<span>{{ 'common.no' | i18n }}</span> <span></span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td> <td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center"> <td nzAlign="center">
<button <button nz-button nzType="primary" (click)="onOpenConnectModal(data.id, data.app)" nz-tooltip nzTooltipTitle="配置关联监控">
nz-button
nzType="primary"
(click)="onOpenConnectModal(data.id, data.app)"
nz-tooltip
[nzTooltipTitle]="'alert.setting.connect' | i18n"
>
<i nz-icon nzType="link" nzTheme="outline"></i> <i nz-icon nzType="link" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onEditOneAlertDefine(data.id)" nz-tooltip nzTooltipTitle="修改告警配置">
nz-button
nzType="primary"
(click)="onEditOneAlertDefine(data.id)"
nz-tooltip
[nzTooltipTitle]="'alert.setting.edit' | i18n"
>
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onDeleteOneAlertDefine(data.id)" nz-tooltip nzTooltipTitle="删除告警配置">
nz-button
nzType="primary"
(click)="onDeleteOneAlertDefine(data.id)"
nz-tooltip
[nzTooltipTitle]="'alert.setting.delete' | i18n"
>
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
</button> </button>
</td> </td>
@@ -128,12 +110,12 @@
</tbody> </tbody>
</nz-table> </nz-table>
<ng-template #rangeTemplate> {{ 'common.total' | i18n }} {{ total }} </ng-template> <ng-template #rangeTemplate> 总量 {{ total }} </ng-template>
<!-- 新增或修改告警定义弹出框 --> <!-- 新增或修改告警定义弹出框 -->
<nz-modal <nz-modal
[(nzVisible)]="isManageModalVisible" [(nzVisible)]="isManageModalVisible"
[nzTitle]="isManageModalAdd ? ('alert.setting.new' | i18n) : ('alert.setting.edit' | i18n)" [nzTitle]="isManageModalAdd ? '新增告警阈值' : '修改告警阈值'"
(nzOnCancel)="onManageModalCancel()" (nzOnCancel)="onManageModalCancel()"
(nzOnOk)="onManageModalOk()" (nzOnOk)="onManageModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
@@ -143,7 +125,7 @@
<div *nzModalContent class="-inner-content"> <div *nzModalContent class="-inner-content">
<form nz-form #defineForm="ngForm"> <form nz-form #defineForm="ngForm">
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="target" nzRequired="true">{{ 'alert.setting.target' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="target" nzRequired="true">指标对象</nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<nz-cascader <nz-cascader
required required
@@ -158,19 +140,19 @@
<nz-form-item> <nz-form-item>
<nz-col [nzSpan]="8" nzOffset="7"> <nz-col [nzSpan]="8" nzOffset="7">
<nz-collapse> <nz-collapse>
<nz-collapse-panel [nzActive]="isManageModalAdd" [nzHeader]="'alert.setting.expr.tip' | i18n"> <nz-collapse-panel [nzActive]="isManageModalAdd" nzHeader="支持的阈值触发表达式环境变量与操作符">
<nz-list nzSize="small" nzSplit="false"> <nz-list nzSize="small" nzSplit="false">
<nz-list-item *ngIf="cascadeValues.length == 3"> <nz-list-item *ngIf="cascadeValues.length == 3">
<code>{{ cascadeValues[2] }} : {{ 'alert.setting.target.tip' | i18n }}</code> <code>{{ cascadeValues[2] }} : 选中的指标对象</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngFor="let item of otherMetrics"> <nz-list-item *ngFor="let item of otherMetrics">
<code>{{ item }} : {{ 'alert.setting.target.other' | i18n }}</code> <code>{{ item }} : 所属行其它指标对象</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngIf="otherMetrics.length != 0"> <nz-list-item *ngIf="otherMetrics.length != 0">
<code>instance : {{ 'alert.setting.target.instance' | i18n }}</code> <code>instance : 所属行实例</code>
</nz-list-item> </nz-list-item>
<nz-list-item> <nz-list-item>
<code>{{ 'alert.setting.operator' | i18n }} : equals(str1,str2), ==, <, <=, >, >=, !=, ( ), +, -, &&, ||</code> <code>支持操作符函数 : equals(str1,str2), ==, <, <=, >, >=, !=, ( ), +, -, &&, ||</code>
</nz-list-item> </nz-list-item>
</nz-list> </nz-list>
</nz-collapse-panel> </nz-collapse-panel>
@@ -178,8 +160,13 @@
</nz-col> </nz-col>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="expr" nzRequired="true" [nzTooltipTitle]="'alert.setting.expr.label' | i18n"> <nz-form-label
{{ 'alert.setting.expr' | i18n }} [nzSpan]="7"
nzFor="expr"
nzRequired="true"
nzTooltipTitle="根据此表达式来计算判断是否触发阈值,表达式环境变量和操作符见上方"
>
阈值触发表达式
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<nz-textarea-count [nzMaxCharacterCount]="100"> <nz-textarea-count [nzMaxCharacterCount]="100">
@@ -190,27 +177,32 @@
nz-input nz-input
name="expr" name="expr"
id="expr" id="expr"
[placeholder]="('alert.setting.expr.example' | i18n) + ': responseTime&gt;40'" placeholder="根据此表达式计算判断是否触发阈值.&#10;示例: responseTime&gt;40"
> >
</textarea> </textarea>
</nz-textarea-count> </nz-textarea-count>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="priority" [nzTooltipTitle]="'alert.setting.priority.tip' | i18n"> <nz-form-label
{{ 'alert.priority' | i18n }} nzSpan="7"
nzRequired="true"
nzFor="priority"
nzTooltipTitle="触发阈值的告警级别,从低到高依次为:警告-warning严重-critical紧急-emergency"
>
告警级别
</nz-form-label> </nz-form-label>
<nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-select [(ngModel)]="define.priority" nzPlaceHolder="Choose" name="priority" id="priority"> <nz-select [(ngModel)]="define.priority" nzPlaceHolder="Choose" name="priority" id="priority">
<nz-option [nzValue]="0" [nzLabel]="'alert.priority.0' | i18n"></nz-option> <nz-option [nzValue]="0" nzLabel="紧急告警"></nz-option>
<nz-option [nzValue]="1" [nzLabel]="'alert.priority.1' | i18n"></nz-option> <nz-option [nzValue]="1" nzLabel="严重告警"></nz-option>
<nz-option [nzValue]="2" [nzLabel]="'alert.priority.2' | i18n"></nz-option> <nz-option [nzValue]="2" nzLabel="警告告警"></nz-option>
</nz-select> </nz-select>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="duration" [nzTooltipTitle]="'alert.setting.times.tip' | i18n"> <nz-form-label nzSpan="7" nzRequired="true" nzFor="duration" nzTooltipTitle="设置触发阈值多少次之后才会发送告警">
{{ 'alert.setting.times' | i18n }} 触发次数
</nz-form-label> </nz-form-label>
<nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-input-number [(ngModel)]="define.times" [nzMin]="1" [nzMax]="10" [nzStep]="1" required name="duration" id="duration"> <nz-input-number [(ngModel)]="define.times" [nzMin]="1" [nzMax]="10" [nzStep]="1" required name="duration" id="duration">
@@ -220,25 +212,25 @@
<nz-form-item> <nz-form-item>
<nz-col [nzSpan]="8" nzOffset="7"> <nz-col [nzSpan]="8" nzOffset="7">
<nz-collapse> <nz-collapse>
<nz-collapse-panel [nzActive]="isManageModalAdd" [nzHeader]="'alert.setting.template.tip' | i18n"> <nz-collapse-panel [nzActive]="isManageModalAdd" nzHeader="支持的通知模版环境变量">
<nz-list nzSize="small" nzSplit="false"> <nz-list nzSize="small" nzSplit="false">
<nz-list-item> <nz-list-item>
<code>&#36;&#123;app&#125; : {{ 'alert.setting.template.monitor-type' | i18n }}</code> <code>&#36;&#123;app&#125; : 监控类型名称</code>
</nz-list-item> </nz-list-item>
<nz-list-item> <nz-list-item>
<code>&#36;&#123;metrics&#125; : {{ 'alert.setting.template.metrics-name' | i18n }}</code> <code>&#36;&#123;metrics&#125; : 监控指标集合名称</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngIf="cascadeValues.length == 3"> <nz-list-item *ngIf="cascadeValues.length == 3">
<code>&#36;&#123;metric&#125; : {{ 'alert.setting.template.metric-name' | i18n }}</code> <code>&#36;&#123;metric&#125; : 监控指标名称</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngIf="cascadeValues.length == 3"> <nz-list-item *ngIf="cascadeValues.length == 3">
<code>&#36;{{ '{' + cascadeValues[2] + '}' }} : {{ 'alert.setting.template.metric-value' | i18n }}</code> <code>&#36;{{ '{' + cascadeValues[2] + '}' }} : 监控指标对象值</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngFor="let item of otherMetrics"> <nz-list-item *ngFor="let item of otherMetrics">
<code>&#36;{{ '{' + item + '}' }} : {{ 'alert.setting.template.other-value' | i18n }}</code> <code>&#36;{{ '{' + item + '}' }} : 所属行其它指标值</code>
</nz-list-item> </nz-list-item>
<nz-list-item> <nz-list-item>
<code>&#36;&#123;instance&#125; : {{ 'alert.setting.template.instance-value' | i18n }}</code> <code>&#36;&#123;instance&#125; : 所属行实例值</code>
</nz-list-item> </nz-list-item>
</nz-list> </nz-list>
</nz-collapse-panel> </nz-collapse-panel>
@@ -246,8 +238,8 @@
</nz-col> </nz-col>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="template" nzRequired="true" [nzTooltipTitle]="'alert.setting.template.label' | i18n"> <nz-form-label [nzSpan]="7" nzFor="template" nzRequired="true" nzTooltipTitle="告警触发后发送的通知信息模版,模版环境变量见上方">
{{ 'alert.setting.template' | i18n }} 通知模版
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<nz-textarea-count [nzMaxCharacterCount]="200"> <nz-textarea-count [nzMaxCharacterCount]="200">
@@ -258,24 +250,20 @@
required required
name="template" name="template"
id="template" id="template"
[placeholder]="'alert.setting.template.example' | i18n" placeholder="请输入告警的通知模版.&#10;示例: ${app}.${metrics}.${metric}'s value is too high"
> >
</textarea> </textarea>
</nz-textarea-count> </nz-textarea-count>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor="preset" [nzTooltipTitle]="'alert.setting.default.tip' | i18n"> <nz-form-label nzSpan="7" nzFor="preset" nzTooltipTitle="此告警阈值配置是否应用于全局所有此类型监控"> 全局默认 </nz-form-label>
{{ 'alert.setting.default' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="define.preset" name="preset" id="preset"></nz-switch> <nz-switch [(ngModel)]="define.preset" name="preset" id="preset"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="enable" [nzTooltipTitle]="'alert.setting.enable.tip' | i18n"> <nz-form-label nzSpan="7" nzRequired="true" nzFor="enable" nzTooltipTitle="此告警阈值配置开启生效或关闭"> 启用告警 </nz-form-label>
{{ 'alert.setting.enable' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="define.enable" [ngModelOptions]="{ standalone: true }" name="enable" id="enable"></nz-switch> <nz-switch [(ngModel)]="define.enable" [ngModelOptions]="{ standalone: true }" name="enable" id="enable"></nz-switch>
</nz-form-control> </nz-form-control>
@@ -288,7 +276,7 @@
<nz-modal <nz-modal
[(nzVisible)]="isConnectModalVisible" [(nzVisible)]="isConnectModalVisible"
[nzTitle]="'alert.setting.connect' | i18n" nzTitle="告警定义关联监控"
(nzOnCancel)="onConnectModalCancel()" (nzOnCancel)="onConnectModalCancel()"
(nzOnOk)="onConnectModalOk()" (nzOnOk)="onConnectModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
@@ -315,8 +303,8 @@
<thead> <thead>
<tr> <tr>
<th [nzChecked]="stat.checkAll" [nzIndeterminate]="stat.checkHalf" (nzCheckedChange)="onItemSelectAll($event)"></th> <th [nzChecked]="stat.checkAll" [nzIndeterminate]="stat.checkHalf" (nzCheckedChange)="onItemSelectAll($event)"></th>
<th *ngIf="direction == 'left'">{{ 'alert.setting.connect.left' | i18n }}</th> <th *ngIf="direction == 'left'">未关联监控</th>
<th *ngIf="direction == 'right'">{{ 'alert.setting.connect.right' | i18n }}</th> <th *ngIf="direction == 'right'">已关联监控</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@@ -1,6 +1,4 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzModalService } from 'ng-zorro-antd/modal'; import { NzModalService } from 'ng-zorro-antd/modal';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { NzTableQueryParams } from 'ng-zorro-antd/table'; import { NzTableQueryParams } from 'ng-zorro-antd/table';
@@ -27,8 +25,7 @@ export class AlertSettingComponent implements OnInit {
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private appDefineSvc: AppDefineService, private appDefineSvc: AppDefineService,
private monitorSvc: MonitorService, private monitorSvc: MonitorService,
private alertDefineSvc: AlertDefineService, private alertDefineSvc: AlertDefineService
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {} ) {}
pageIndex: number = 1; pageIndex: number = 1;
@@ -101,7 +98,7 @@ export class AlertSettingComponent implements OnInit {
onEditOneAlertDefine(alertDefineId: number) { onEditOneAlertDefine(alertDefineId: number) {
if (alertDefineId == null) { if (alertDefineId == null) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-edit'), ''); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
this.editAlertDefine(alertDefineId); this.editAlertDefine(alertDefineId);
@@ -110,11 +107,11 @@ export class AlertSettingComponent implements OnInit {
onEditAlertDefine() { onEditAlertDefine() {
// 编辑时只能选中一个 // 编辑时只能选中一个
if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) { if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-edit'), ''); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
if (this.checkedDefineIds.size > 1) { if (this.checkedDefineIds.size > 1) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.one-select-edit'), ''); this.notifySvc.warning('只能对一个选中项进行编辑!', '');
return; return;
} }
let alertDefineId = 0; let alertDefineId = 0;
@@ -141,24 +138,24 @@ export class AlertSettingComponent implements OnInit {
this.cascadeValues = [this.define.app, this.define.metric, this.define.field]; this.cascadeValues = [this.define.app, this.define.metric, this.define.field];
this.cascadeOnChange(this.cascadeValues); this.cascadeOnChange(this.cascadeValues);
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.monitor-fail'), message.msg); this.notifySvc.error('查询此监控定义详情失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.monitor-fail'), error.msg); this.notifySvc.error('查询此监控定义详情失败!', error.msg);
} }
); );
} }
onDeleteAlertDefines() { onDeleteAlertDefines() {
if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) { if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-delete'), ''); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete-batch'), nzTitle: '请确认是否批量删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteAlertDefines(this.checkedDefineIds) nzOnOk: () => this.deleteAlertDefines(this.checkedDefineIds)
@@ -169,9 +166,9 @@ export class AlertSettingComponent implements OnInit {
let defineIds = new Set<number>(); let defineIds = new Set<number>();
defineIds.add(alertDefineId); defineIds.add(alertDefineId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), nzTitle: '请确认是否删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteAlertDefines(defineIds) nzOnOk: () => this.deleteAlertDefines(defineIds)
@@ -180,7 +177,7 @@ export class AlertSettingComponent implements OnInit {
deleteAlertDefines(defineIds: Set<number>) { deleteAlertDefines(defineIds: Set<number>) {
if (defineIds == null || defineIds.size == 0) { if (defineIds == null || defineIds.size == 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-delete'), ''); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.tableLoading = true; this.tableLoading = true;
@@ -188,17 +185,17 @@ export class AlertSettingComponent implements OnInit {
message => { message => {
deleteDefines$.unsubscribe(); deleteDefines$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); this.notifySvc.success('删除成功!', '');
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
deleteDefines$.unsubscribe(); deleteDefines$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
@@ -245,7 +242,7 @@ export class AlertSettingComponent implements OnInit {
} }
this.appHierarchies.forEach(hierarchy => { this.appHierarchies.forEach(hierarchy => {
if (hierarchy.value == values[0]) { if (hierarchy.value == values[0]) {
hierarchy.children.forEach((metrics: { value: string; children: any[] }) => { hierarchy.children.forEach((metrics: { value: string; children: any[]}) => {
if (metrics.value == values[1]) { if (metrics.value == values[1]) {
this.otherMetrics = []; this.otherMetrics = [];
metrics.children.forEach(item => { metrics.children.forEach(item => {
@@ -279,14 +276,14 @@ export class AlertSettingComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageModalVisible = false; this.isManageModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.new-success'), ''); this.notifySvc.success('新增成功!', '');
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), message.msg); this.notifySvc.error('新增失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), error.msg); this.notifySvc.error('新增失败!', error.msg);
} }
); );
} else { } else {
@@ -302,14 +299,14 @@ export class AlertSettingComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageModalVisible = false; this.isManageModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.edit-success'), ''); this.notifySvc.success('修改成功!', '');
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), message.msg); this.notifySvc.error('修改失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), error.msg); this.notifySvc.error('修改失败!', error.msg);
} }
); );
} }
@@ -376,16 +373,16 @@ export class AlertSettingComponent implements OnInit {
message => { message => {
this.isConnectModalOkLoading = false; this.isConnectModalOkLoading = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.apply-success'), ''); this.notifySvc.success('应用成功!', '');
this.isConnectModalVisible = false; this.isConnectModalVisible = false;
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.apply-fail'), message.msg); this.notifySvc.error('应用失败!', message.msg);
} }
}, },
error => { error => {
this.isConnectModalOkLoading = false; this.isConnectModalOkLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.apply-fail'), error.msg); this.notifySvc.error('应用失败!', error.msg);
} }
); );
} }

View File

@@ -10,19 +10,16 @@
</div> </div>
<div nz-col nzSpan="14" class="p-md text-white"> <div nz-col nzSpan="14" class="p-md text-white">
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.available' | i18n }} </span <span>正常 </span><span style="font-weight: bolder">{{ appCountService.availableSize }}</span>
><span style="font-weight: bolder">{{ appCountService.availableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unavailable' | i18n }} </span <span>不可用 </span><span style="font-weight: bolder">{{ appCountService.unAvailableSize }}</span>
><span style="font-weight: bolder">{{ appCountService.unAvailableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unreachable' | i18n }} </span <span>不可达 </span><span style="font-weight: bolder">{{ appCountService.unReachableSize }}</span>
><span style="font-weight: bolder">{{ appCountService.unReachableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.un-manage' | i18n }} </span><span style="font-weight: bolder">{{ appCountService.unManageSize }}</span> <span>未监控 </span><span style="font-weight: bolder">{{ appCountService.unManageSize }}</span>
</nz-tag> </nz-tag>
</div> </div>
</div> </div>
@@ -38,16 +35,16 @@
</div> </div>
<div nz-col nzSpan="14"> <div nz-col nzSpan="14">
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.available' | i18n }} </span><span style="font-weight: bolder">{{ appCountDb.availableSize }}</span> <span>正常 </span><span style="font-weight: bolder">{{ appCountDb.availableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unavailable' | i18n }} </span><span style="font-weight: bolder">{{ appCountDb.unAvailableSize }}</span> <span>不可用 </span><span style="font-weight: bolder">{{ appCountDb.unAvailableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unreachable' | i18n }} </span><span style="font-weight: bolder">{{ appCountDb.unReachableSize }}</span> <span>不可达 </span><span style="font-weight: bolder">{{ appCountDb.unReachableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.un-manage' | i18n }} </span><span style="font-weight: bolder">{{ appCountDb.unManageSize }}</span> <span>未监控 </span><span style="font-weight: bolder">{{ appCountDb.unManageSize }}</span>
</nz-tag> </nz-tag>
</div> </div>
</div> </div>
@@ -63,16 +60,16 @@
</div> </div>
<div nz-col nzSpan="14"> <div nz-col nzSpan="14">
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.available' | i18n }} </span><span style="font-weight: bolder">{{ appCountOs.availableSize }}</span> <span>正常 </span><span style="font-weight: bolder">{{ appCountOs.availableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unavailable' | i18n }} </span><span style="font-weight: bolder">{{ appCountOs.unAvailableSize }}</span> <span>不可用 </span><span style="font-weight: bolder">{{ appCountOs.unAvailableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unreachable' | i18n }} </span><span style="font-weight: bolder">{{ appCountOs.unReachableSize }}</span> <span>不可达 </span><span style="font-weight: bolder">{{ appCountOs.unReachableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.un-manage' | i18n }} </span><span style="font-weight: bolder">{{ appCountOs.unManageSize }}</span> <span>未监控 </span><span style="font-weight: bolder">{{ appCountOs.unManageSize }}</span>
</nz-tag> </nz-tag>
</div> </div>
</div> </div>
@@ -88,16 +85,16 @@
</div> </div>
<div nz-col nzSpan="14"> <div nz-col nzSpan="14">
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.available' | i18n }} </span><span style="font-weight: bolder">{{ appCountCustom.availableSize }}</span> <span>正常 </span><span style="font-weight: bolder">{{ appCountCustom.availableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unavailable' | i18n }} </span><span style="font-weight: bolder">{{ appCountCustom.unAvailableSize }}</span> <span>不可用 </span><span style="font-weight: bolder">{{ appCountCustom.unAvailableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unreachable' | i18n }} </span><span style="font-weight: bolder">{{ appCountCustom.unReachableSize }}</span> <span>不可达 </span><span style="font-weight: bolder">{{ appCountCustom.unReachableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.un-manage' | i18n }} </span><span style="font-weight: bolder">{{ appCountCustom.unManageSize }}</span> <span>未监控 </span><span style="font-weight: bolder">{{ appCountCustom.unManageSize }}</span>
</nz-tag> </nz-tag>
</div> </div>
</div> </div>
@@ -117,21 +114,21 @@
<div nz-row nzGutter="16" style="margin-top: 10px"> <div nz-row nzGutter="16" style="margin-top: 10px">
<div nz-col nzXs="24" nzSm="24" nzMd="12" class="mb-md"> <div nz-col nzXs="24" nzSm="24" nzMd="12" class="mb-md">
<nz-card nzHoverable [nzTitle]="'dashboard.alerts.title' | i18n" [nzExtra]="extraTemplate"> <nz-card nzHoverable nzTitle="最近告警列表" [nzExtra]="extraTemplate">
<nz-timeline nzMode="left"> <nz-timeline nzMode="left">
<nz-timeline-item *ngFor="let alert of alerts; let i = index" [nzLabel]="(alert.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss')?.trim()"> <nz-timeline-item *ngFor="let alert of alerts; let i = index" [nzLabel]="(alert.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss')?.trim()">
<p style="font-weight: 400"> <p style="font-weight: 400">
<nz-tag *ngIf="alert.priority == 0" nzColor="red"> <nz-tag *ngIf="alert.priority == 0" nzColor="red">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.0' | i18n }}</span> <span>紧急告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="alert.priority == 1" nzColor="orange"> <nz-tag *ngIf="alert.priority == 1" nzColor="orange">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.1' | i18n }}</span> <span>严重告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="alert.priority == 2" nzColor="yellow"> <nz-tag *ngIf="alert.priority == 2" nzColor="yellow">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.2' | i18n }}</span> <span>警告告警</span>
</nz-tag> </nz-tag>
<span>[{{ alert.monitorName }}] </span> <span>[{{ alert.monitorName }}] </span>
{{ alert.content }} {{ alert.content }}
@@ -165,5 +162,5 @@
</div> </div>
<ng-template #extraTemplate> <ng-template #extraTemplate>
<a [routerLink]="['/alert/center']">{{ 'dashboard.alerts.enter' | i18n }}</a> <a [routerLink]="['/alert/center']">进入告警中心</a>
</ng-template> </ng-template>

View File

@@ -48,13 +48,13 @@ export class DashboardComponent implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
this.appsCountTheme = { this.appsCountTheme = {
title: { title: {
text: this.i18nSvc.fanyi('dashboard.monitors.title'), text: '监控总览',
subtext: this.i18nSvc.fanyi('dashboard.monitors.sub-title'), subtext: '监控类型纳管数量分布',
left: 'center' left: 'center'
}, },
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
formatter: `{a} <br/>{b} : {c}${this.i18nSvc.fanyi('dashboard.monitors.formatter')}({d}%)` formatter: '{a} <br/>{b} : {c}个监控 占比({d}%)'
}, },
legend: { legend: {
show: false, show: false,
@@ -66,7 +66,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
calculable: true, calculable: true,
series: [ series: [
{ {
name: this.i18nSvc.fanyi('dashboard.monitors.total'), name: '总量',
type: 'pie', type: 'pie',
selectedMode: 'single', selectedMode: 'single',
color: '#722ED1', color: '#722ED1',
@@ -81,10 +81,10 @@ export class DashboardComponent implements OnInit, OnDestroy {
labelLine: { labelLine: {
show: false show: false
}, },
data: [{ value: 0, name: this.i18nSvc.fanyi('dashboard.monitors.total') }] data: [{ value: 0, name: '监控总量' }]
}, },
{ {
name: this.i18nSvc.fanyi('dashboard.monitors.distribute'), name: '纳管数量分布',
type: 'pie', type: 'pie',
radius: ['45%', '65%'], radius: ['45%', '65%'],
labelLine: { labelLine: {
@@ -127,7 +127,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
}; };
this.alertsTheme = { this.alertsTheme = {
title: { title: {
subtext: this.i18nSvc.fanyi('dashboard.alerts.distribute'), subtext: '告警分布',
left: 'center' left: 'center'
}, },
tooltip: { tooltip: {
@@ -138,14 +138,14 @@ export class DashboardComponent implements OnInit, OnDestroy {
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
data: [this.i18nSvc.fanyi('alert.priority.2'), this.i18nSvc.fanyi('alert.priority.1'), this.i18nSvc.fanyi('alert.priority.0')] data: ['警告告警', '严重告警', '紧急告警']
}, },
yAxis: { yAxis: {
type: 'value' type: 'value'
}, },
series: [ series: [
{ {
name: this.i18nSvc.fanyi('dashboard.alerts.num'), name: '告警数量',
type: 'bar', type: 'bar',
data: [ data: [
{ {
@@ -176,7 +176,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
}; };
this.alertsDealTheme = { this.alertsDealTheme = {
title: { title: {
subtext: this.i18nSvc.fanyi('dashboard.alerts.deal'), subtext: '告警处理',
left: 'center' left: 'center'
}, },
tooltip: { tooltip: {
@@ -184,7 +184,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
}, },
series: [ series: [
{ {
name: this.i18nSvc.fanyi('dashboard.alerts.deal-percent'), name: '告警处理率',
type: 'gauge', type: 'gauge',
progress: { progress: {
show: true show: true
@@ -196,7 +196,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
data: [ data: [
{ {
value: 100, value: 100,
name: this.i18nSvc.fanyi('dashboard.alerts.deal-percent') name: '告警处理率'
} }
] ]
} }
@@ -279,7 +279,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
} }
}); });
// @ts-ignore // @ts-ignore
this.appsCountTheme.series[0].data = [{ value: total, name: this.i18nSvc.fanyi('dashboard.monitors.total') }]; this.appsCountTheme.series[0].data = [{ value: total, name: '监控总量' }];
// @ts-ignore // @ts-ignore
this.appsCountTheme.series[1].data = this.appsCountTableData; this.appsCountTheme.series[1].data = this.appsCountTableData;
this.appsCountEChartOption = this.appsCountTheme; this.appsCountEChartOption = this.appsCountTheme;
@@ -397,7 +397,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
this.alertsDealTheme.series[0].data = [ this.alertsDealTheme.series[0].data = [
{ {
value: summary.rate, value: summary.rate,
name: this.i18nSvc.fanyi('dashboard.alerts.deal-percent') name: '告警处理率'
} }
]; ];
this.alertsEChartOption = this.alertsTheme; this.alertsEChartOption = this.alertsTheme;

View File

@@ -1,6 +1,4 @@
import { Component, Inject, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { EChartsOption } from 'echarts'; import { EChartsOption } from 'echarts';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
@@ -34,7 +32,7 @@ export class MonitorDataChartComponent implements OnInit {
echartsInstance!: any; echartsInstance!: any;
// 查询历史数据时间段 默认最近6小时 // 查询历史数据时间段 默认最近6小时
timePeriod: string = '6h'; timePeriod: string = '6h';
constructor(private monitorSvc: MonitorService, @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService) {} constructor(private monitorSvc: MonitorService) {}
ngOnInit(): void { ngOnInit(): void {
this.lineHistoryTheme = { this.lineHistoryTheme = {
@@ -53,8 +51,8 @@ export class MonitorDataChartComponent implements OnInit {
dataZoom: { dataZoom: {
yAxisIndex: 'none', yAxisIndex: 'none',
title: { title: {
zoom: this.i18nSvc.fanyi('monitors.detail.chart.zoom'), zoom: '区域缩放',
back: this.i18nSvc.fanyi('monitors.detail.chart.back') back: '缩放还原'
}, },
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -63,7 +61,7 @@ export class MonitorDataChartComponent implements OnInit {
} }
}, },
saveAsImage: { saveAsImage: {
title: this.i18nSvc.fanyi('monitors.detail.chart.save'), title: '保存图片',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
textPosition: 'left' textPosition: 'left'
@@ -72,7 +70,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myPeriod1h: { myPeriod1h: {
show: true, show: true,
title: this.i18nSvc.fanyi('monitors.detail.chart.query-1h'), title: '查询近1小时',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z', icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -85,7 +83,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myPeriod6h: { myPeriod6h: {
show: true, show: true,
title: this.i18nSvc.fanyi('monitors.detail.chart.query-6h'), title: '查询近6小时',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z', icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -98,7 +96,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myPeriod1d: { myPeriod1d: {
show: true, show: true,
title: this.i18nSvc.fanyi('monitors.detail.chart.query-1d'), title: '查询近1天',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z', icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -111,7 +109,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myPeriod1w: { myPeriod1w: {
show: true, show: true,
title: this.i18nSvc.fanyi('monitors.detail.chart.query-1w'), title: '查询近1周',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z', icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -124,7 +122,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myPeriod4w: { myPeriod4w: {
show: true, show: true,
title: this.i18nSvc.fanyi('monitors.detail.chart.query-1m'), title: '查询近1月',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z', icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -137,7 +135,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myRefresh: { myRefresh: {
show: true, show: true,
title: this.i18nSvc.fanyi('common.refresh'), title: '刷新',
icon: 'path://M663.881 339.763l274.021-0.742 0.058-13.271 0.699 0c-0.204-0.48-0.495-0.945-0.699-1.426L938.658 65l-23.776 0.044L914.3 280.41C835.9 151.374 694.321 65 532.342 65c-246.869 0-447 200.132-447 447 0 246.84 200.131 447 447 447 180.343 0 335.657-106.919 406.316-260.75l-33.176 0C836.948 835.027 695.456 929.2 532.342 929.2c-230.048 0-417.2-187.152-417.2-417.2s187.152-417.2 417.2-417.2c158.895 0 297.068 89.487 367.466 220.547l-235.868 0.64L663.881 339.763z', icon: 'path://M663.881 339.763l274.021-0.742 0.058-13.271 0.699 0c-0.204-0.48-0.495-0.945-0.699-1.426L938.658 65l-23.776 0.044L914.3 280.41C835.9 151.374 694.321 65 532.342 65c-246.869 0-447 200.132-447 447 0 246.84 200.131 447 447 447 180.343 0 335.657-106.919 406.316-260.75l-33.176 0C836.948 835.027 695.456 929.2 532.342 929.2c-230.048 0-417.2-187.152-417.2-417.2s187.152-417.2 417.2-417.2c158.895 0 297.068 89.487 367.466 220.547l-235.868 0.64L663.881 339.763z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -185,7 +183,7 @@ export class MonitorDataChartComponent implements OnInit {
}; };
if (this.unit != undefined || this.unit != null) { if (this.unit != undefined || this.unit != null) {
// @ts-ignore // @ts-ignore
this.lineHistoryTheme.title?.subtext = `${this.i18nSvc.fanyi('monitors.detail.chart.unit')} ${this.unit}`; this.lineHistoryTheme.title?.subtext = `单位 ${this.unit}`;
} }
this.loadData(); this.loadData();
} }
@@ -253,7 +251,7 @@ export class MonitorDataChartComponent implements OnInit {
} else { } else {
this.eChartOption = this.lineHistoryTheme; this.eChartOption = this.lineHistoryTheme;
this.eChartOption.title = { this.eChartOption.title = {
text: `${`${this.metrics}.${this.metric}` + '\n\n\n'}${this.i18nSvc.fanyi('monitors.detail.chart.no-data')}`, text: `${this.metrics}.${this.metric}` + '\n\n\n' + '暂无数据',
textStyle: { textStyle: {
fontSize: 16, fontSize: 16,
fontFamily: 'monospace', fontFamily: 'monospace',

View File

@@ -17,8 +17,8 @@
<nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows"> <nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows">
<thead> <thead>
<tr> <tr>
<th style="text-align: center">{{ 'common.name' | i18n }}</th> <th style="text-align: center">属性</th>
<th style="text-align: center">{{ 'common.value' | i18n }}</th> <th style="text-align: center"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -33,11 +33,17 @@
<ng-template #monitor_metrics_card_title> <ng-template #monitor_metrics_card_title>
<p style="font-size: small; text-align: center; margin-bottom: 3px">{{ metrics }}</p> <p style="font-size: small; text-align: center; margin-bottom: 3px">{{ metrics }}</p>
<div> <div>
<a nz-popover [nzPopoverContent]="'Last Collect Time ' + (time | _date: 'yyyy-MM-dd HH:mm:ss')"> <a nz-popover [nzPopoverContent]="'最近采集时间 ' + (time | _date: 'yyyy-MM-dd HH:mm:ss')">
<i nz-icon nzType="field-time" nzTheme="outline"></i <i nz-icon nzType="field-time" nzTheme="outline"></i
></a> ></a>
<i style="font-size: 0.3px; font-weight: normal; color: rgba(112, 112, 112, 0.89)"> <i style="font-size: 0.3px; font-weight: normal; color: rgba(112,112,112,0.89)">采集时间:{{ time | _date: 'HH:mm:ss' }}</i>
{{ 'monitors.collect.time' | i18n }}:{{ time | _date: 'HH:mm:ss' }}
</i>
</div> </div>
</ng-template> </ng-template>
<!--<nz-card *ngIf="!isTable" nzHoverable style="height:auto;margin-left: 14px;" [nzBordered]="true"-->
<!-- [nzTitle]="monitor_metrics_card_title" >-->
<!-- <div *ngFor="let field of fields;let i = index;" nz-row nzGutter="16">-->
<!-- <div nz-col nzSpan="10"><p style="text-align: right">{{field.name}}</p></div>-->
<!-- <div nz-col nzSpan="14"><p style="text-align: left">{{rowValues[i].origin}}</p></div>-->
<!-- </div>-->
<!--</nz-card>-->

View File

@@ -3,20 +3,20 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/monitors']" [queryParams]="{ app: app ? app : '' }"> <a [routerLink]="['/monitors']" [queryParams]="{ app: app ? app : '' }">
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>{{ 'monitors.list' | i18n }}</span> <span>监控列表</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="pie-chart"></i> <i nz-icon nzType="pie-chart"></i>
<span>{{ 'monitor.app.' + app | i18n }} {{ 'monitors.detail' | i18n }}</span> <span>{{ 'monitor.app.' + app | i18n }} 监控详情</span>
<a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%"> <a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%">
<span>{{ 'common.button.help' | i18n }} </span> <span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i> <i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
@@ -33,9 +33,7 @@
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">名称</p></div>
><p style="text-align: right">{{ 'monitors.detail.name' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.name }}</p></div ><p style="text-align: left">{{ monitor?.name }}</p></div
> >
@@ -47,66 +45,58 @@
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">端口</p></div>
><p style="text-align: right">{{ 'monitors.detail.port' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ port }}</p></div ><p style="text-align: left">{{ port }}</p></div
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">描述</p></div>
><p style="text-align: right">{{ 'monitors.detail.description' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.description }}</p></div ><p style="text-align: left">{{ monitor?.description }}</p></div
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">状态</p></div>
><p style="text-align: right">{{ 'monitors.detail.status' | i18n }}</p></div
>
<div nz-col nzSpan="16"> <div nz-col nzSpan="16">
<nz-tag *ngIf="monitor?.status == 0" nzColor="default"> <nz-tag *ngIf="monitor?.status == 0" nzColor="default">
<i nz-icon nzType="robot" nzTheme="outline"></i> <i nz-icon nzType="robot" nzTheme="outline"></i>
<span>{{ 'monitor.status.un-manage' | i18n }}</span> <span>未监控</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="monitor?.status == 1" nzColor="success"> <nz-tag *ngIf="monitor?.status == 1" nzColor="success">
<i nz-icon nzType="smile" nzTheme="outline"></i> <i nz-icon nzType="smile" nzTheme="outline"></i>
<span>{{ 'monitor.status.available' | i18n }}</span> <span>正常监控</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="monitor?.status == 2" nzColor="warning"> <nz-tag *ngIf="monitor?.status == 2" nzColor="warning">
<i nz-icon nzType="meh" nzTheme="outline"></i> <i nz-icon nzType="meh" nzTheme="outline"></i>
<span>{{ 'monitor.status.unavailable' | i18n }}</span> <span>监控不可用</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="monitor?.status == 3" nzColor="error"> <nz-tag *ngIf="monitor?.status == 3" nzColor="error">
<i nz-icon nzType="frown" nzTheme="outline"></i> <i nz-icon nzType="frown" nzTheme="outline"></i>
<span>{{ 'monitor.status.unreachable' | i18n }}</span> <span>监控不可达</span>
</nz-tag>
<nz-tag *ngIf="monitor?.status == 4" nzColor="default">
<i nz-icon nzType="sync"></i>
<span>监控已挂起</span>
</nz-tag> </nz-tag>
</div> </div>
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">采集间隔</p></div>
><p style="text-align: right">{{ 'monitor.intervals' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.intervals }}s</p></div ><p style="text-align: left">{{ monitor?.intervals }}s</p></div
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">创建时间</p></div>
><p style="text-align: right">{{ 'common.new-time' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss' }}</p></div ><p style="text-align: left">{{ monitor?.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss' }}</p></div
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">更新时间</p></div>
><p style="text-align: right">{{ 'common.edit-time' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.gmtUpdate | date: 'YYYY-MM-dd HH:mm:ss' }}</p></div ><p style="text-align: left">{{ monitor?.gmtUpdate | date: 'YYYY-MM-dd HH:mm:ss' }}</p></div
> >
</div> </div>
</nz-card> </nz-card>
@@ -117,7 +107,7 @@
<nz-tab [nzTitle]="titleTemplate"> <nz-tab [nzTitle]="titleTemplate">
<ng-template #titleTemplate> <ng-template #titleTemplate>
<i nz-icon nzType="pic-right" style="margin-left: 10px"></i> <i nz-icon nzType="pic-right" style="margin-left: 10px"></i>
{{ 'monitors.detail.realtime' | i18n }} 监控实时数据详情
</ng-template> </ng-template>
<div style="display: flex; justify-content: flex-start; flex-wrap: wrap"> <div style="display: flex; justify-content: flex-start; flex-wrap: wrap">
<div *ngFor="let metric of metrics; let i = index"> <div *ngFor="let metric of metrics; let i = index">
@@ -128,7 +118,7 @@
<nz-tab [nzTitle]="title2Template" (nzClick)="initMetricChart()"> <nz-tab [nzTitle]="title2Template" (nzClick)="initMetricChart()">
<ng-template #title2Template> <ng-template #title2Template>
<i nz-icon nzType="pic-right" style="margin-left: 10px"></i> <i nz-icon nzType="pic-right" style="margin-left: 10px"></i>
{{ 'monitors.detail.history' | i18n }} 监控历史图表详情
</ng-template> </ng-template>
<div style="display: flex; justify-content: flex-start; flex-wrap: wrap"> <div style="display: flex; justify-content: flex-start; flex-wrap: wrap">
<div *ngFor="let item of chartMetrics; let i = index"> <div *ngFor="let item of chartMetrics; let i = index">
@@ -148,5 +138,5 @@
</nz-layout> </nz-layout>
<ng-template #monitor_basic_card_title> <ng-template #monitor_basic_card_title>
<p style="font-size: small; text-align: left; margin-bottom: 3px">{{ 'monitors.detail.basic' | i18n }}</p> <p style="font-size: small; text-align: left; margin-bottom: 3px">监控基本属性</p>
</ng-template> </ng-template>

View File

@@ -3,20 +3,20 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/monitors']" [queryParams]="{ app: monitor.app ? monitor.app : '' }"> <a [routerLink]="['/monitors']" [queryParams]="{ app: monitor.app ? monitor.app : '' }">
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>{{ 'monitors.list' | i18n }}</span> <span>监控列表</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="edit"></i> <i nz-icon nzType="edit"></i>
<span>{{ 'monitors.edit' | i18n }} {{ 'monitor.app.' + monitor.app | i18n }} {{ 'monitor' | i18n }}</span> <span>修改 {{ 'monitor.app.' + monitor.app | i18n }} 监控</span>
<a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%"> <a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%">
<span>{{ 'common.button.help' | i18n }} </span> <span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i> <i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
@@ -27,19 +27,17 @@
<div class="-inner-content"> <div class="-inner-content">
<form nz-form #editForm="ngForm"> <form nz-form #editForm="ngForm">
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="host" nzRequired="true" [nzTooltipTitle]="'monitor.host.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="host" nzRequired="true" nzTooltipTitle="被监控的对端IP或域名"> 监控Host </nz-form-label>
{{ 'monitor.host' | i18n }}
</nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="monitor.host" nz-input name="host" type="text" id="host" required [placeholder]="'monitor.host.tip' | i18n" /> <input [(ngModel)]="monitor.host" nz-input name="host" type="text" id="host" required placeholder="请输入域名或IP" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true" [nzTooltipTitle]="'monitor.name.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true" nzTooltipTitle="标识此监控的名称,名称需要保证唯一性">
{{ 'monitor.name' | i18n }} 监控名称
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="monitor.name" nz-input required name="name" type="text" id="name" [placeholder]="'monitor.name.tip' | i18n" /> <input [(ngModel)]="monitor.name" nz-input required name="name" type="text" id="name" placeholder="监控名称需要保证唯一性" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
@@ -165,7 +163,7 @@
</nz-form-item> </nz-form-item>
<nz-collapse [nzGhost]="true"> <nz-collapse [nzGhost]="true">
<nz-collapse-panel [nzHeader]="extraColHeader" [nzShowArrow]="false"> <nz-collapse-panel nzHeader="高级" [nzHeader]="extraColHeader" [nzShowArrow]="false">
<nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index"> <nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index">
<nz-form-label <nz-form-label
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'" *ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
@@ -298,8 +296,8 @@
</nz-collapse-panel> </nz-collapse-panel>
</nz-collapse> </nz-collapse>
<ng-template #extraColHeader> <ng-template #extraColHeader>
<button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip [nzTooltipTitle]="'monitors.advanced.tip' | i18n"> <button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip nzTooltipTitle="设置高级可选参数">
<span>{{ 'monitors.advanced' | i18n }}</span> <span>高级设置</span>
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button> </button>
</ng-template> </ng-template>
@@ -307,9 +305,7 @@
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor="intervals" [nzTooltipTitle]="'monitor.intervals.tip' | i18n"> <nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
{{ 'monitor.intervals' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <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>
@@ -317,18 +313,14 @@
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor="detect" [nzTooltipTitle]="'monitors.detect.tip' | i18n"> <nz-form-label nzSpan="7" nzFor="detect" nzTooltipTitle="新增监控前是否先探测检查监控可用性"> 测试连接 </nz-form-label>
{{ 'monitors.detect' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch> <nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="description" [nzTooltipTitle]="'monitor.description.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="description" nzTooltipTitle="更多标识和描述此监控的备注信息"> 描述备注 </nz-form-label>
{{ 'monitor.description' | i18n }}
</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<nz-textarea-count [nzMaxCharacterCount]="100"> <nz-textarea-count [nzMaxCharacterCount]="100">
<textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea> <textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea>
@@ -338,9 +330,9 @@
<div nz-row> <div nz-row>
<div nz-col nzSpan="8" nzOffset="9"> <div nz-col nzSpan="8" nzOffset="9">
<button nz-button nzType="primary" type="submit" (click)="onDetect(editForm.form)"> {{ 'common.button.detect' | i18n }} </button> <button nz-button nzType="primary" type="submit" (click)="onDetect(editForm.form)"> 测试 </button>
<button nz-button nzType="primary" type="submit" (click)="onSubmit(editForm.form)"> {{ 'common.button.ok' | i18n }} </button> <button nz-button nzType="primary" type="submit" (click)="onSubmit(editForm.form)"> 确定 </button>
<button nz-button nzType="primary" type="reset" (click)="onCancel()"> {{ 'common.button.cancel' | i18n }} </button> <button nz-button nzType="primary" type="reset" (click)="onCancel()"> 取消 </button>
</div> </div>
</div> </div>
</form> </form>

View File

@@ -1,8 +1,7 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { ActivatedRoute, ParamMap, Router } from '@angular/router'; import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import { I18NService } from '@core'; import { TitleService } from '@delon/theme';
import { ALAIN_I18N_TOKEN, TitleService } from '@delon/theme';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { throwError } from 'rxjs'; import { throwError } from 'rxjs';
import { switchMap } from 'rxjs/operators'; import { switchMap } from 'rxjs/operators';
@@ -26,8 +25,7 @@ export class MonitorEditComponent implements OnInit {
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private titleSvc: TitleService, private titleSvc: TitleService,
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {} ) {}
paramDefines!: ParamDefine[]; paramDefines!: ParamDefine[];
@@ -66,8 +64,8 @@ export class MonitorEditComponent implements OnInit {
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);
this.notifySvc.error(this.i18nSvc.fanyi('monitors.not-found'), message.msg); this.notifySvc.error('查询异常,此监控不存在', message.msg);
return throwError(this.i18nSvc.fanyi('monitors.not-found')); return throwError('查询此监控异常');
} }
return this.appDefineSvc.getAppParamsDefine(this.monitor.app); return this.appDefineSvc.getAppParamsDefine(this.monitor.app);
}) })
@@ -170,15 +168,15 @@ export class MonitorEditComponent implements OnInit {
message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('monitors.edit.success'), ''); this.notifySvc.success('修改监控成功', '');
this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`); this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`);
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('monitors.edit.failed'), message.msg); this.notifySvc.error('修改监控失败', message.msg);
} }
}, },
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error(this.i18nSvc.fanyi('monitors.edit.failed'), error.error.msg); this.notifySvc.error('修改监控失败', error.error.msg);
} }
); );
} }
@@ -219,14 +217,14 @@ export class MonitorEditComponent implements OnInit {
message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('monitors.detect.success'), ''); this.notifySvc.success('探测成功', '');
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('monitors.detect.failed'), message.msg); this.notifySvc.error('探测失败', message.msg);
} }
}, },
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error(this.i18nSvc.fanyi('monitors.detect.failed'), error.error.msg); this.notifySvc.error('探测异常', error.error.msg);
} }
); );
} }

View File

@@ -3,12 +3,12 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>{{ 'monitor.app.' + app | i18n }} {{ 'monitors.list' | i18n }}</span> <span>{{ 'monitor.app.' + app | i18n }} 监控列表</span>
</nz-breadcrumb-item> </nz-breadcrumb-item>
</nz-breadcrumb> </nz-breadcrumb>
<nz-divider></nz-divider> <nz-divider></nz-divider>
@@ -17,37 +17,35 @@
<button nz-button nzType="primary"> <button nz-button nzType="primary">
<a routerLink="/monitors/new" [queryParams]="{ app: app }"> <a routerLink="/monitors/new" [queryParams]="{ app: app }">
<i nz-icon nzType="appstore-add" nzTheme="outline"></i> <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
{{ 'monitors.new' | i18n }} {{ 'monitor.app.' + app | i18n }} 新增 {{ 'monitor.app.' + app | i18n }}
</a> </a>
</button> </button>
<button nz-button nzType="primary" (click)="onEditMonitor()"> <button nz-button nzType="primary" (click)="onEditMonitor()">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
{{ 'monitors.edit' | i18n }} 编辑
</button> </button>
<button nz-button nzType="primary" (click)="onDeleteMonitors()"> <button nz-button nzType="primary" (click)="onDeleteMonitors()">
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
{{ 'monitors.delete' | i18n }} 删除
</button> </button>
<button nz-button nzType="primary" (click)="onEnableManageMonitors()"> <button nz-button nzType="primary" (click)="onEnableManageMonitors()">
<i nz-icon nzType="up-circle" nzTheme="outline"></i> <i nz-icon nzType="up-circle" nzTheme="outline"></i>
{{ 'monitors.enable' | i18n }} 启用监控
</button> </button>
<button nz-button nzType="primary" (click)="onCancelManageMonitors()"> <button nz-button nzType="primary" (click)="onCancelManageMonitors()">
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
{{ 'monitors.cancel' | i18n }} 取消监控
</button> </button>
<button nz-button nzType="primary" (click)="sync()" nz-tooltip [nzTooltipTitle]="'common.refresh' | i18n"> <button nz-button nzType="primary" (click)="sync()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="onFilterSearchMonitors()"> <button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="onFilterSearchMonitors()"> 搜索 </button>
{{ 'common.search' | i18n }}
</button>
<input <input
style="margin-right: 5px; float: right; width: 150px; border-radius: 9px; text-align: center" style="margin-right: 5px; float: right; width: 150px; border-radius: 9px; text-align: center"
nz-input nz-input
type="text" type="text"
[placeholder]="'monitors.search.placeholder' | i18n" placeholder="搜索监控"
nzSize="default" nzSize="default"
(keyup.enter)="onFilterSearchMonitors()" (keyup.enter)="onFilterSearchMonitors()"
[(ngModel)]="filterContent" [(ngModel)]="filterContent"
@@ -55,14 +53,14 @@
<nz-select <nz-select
style="margin-right: 10px; float: right; width: 120px" style="margin-right: 10px; float: right; width: 120px"
nzAllowClear nzAllowClear
[nzPlaceHolder]="'monitors.search.filter' | i18n" [nzPlaceHolder]="'监控状态过滤'"
[(ngModel)]="filterStatus" [(ngModel)]="filterStatus"
> >
<nz-option [nzLabel]="'monitor.status.all' | i18n" nzValue="9"></nz-option> <nz-option nzLabel="全部状态" nzValue="9"></nz-option>
<nz-option [nzLabel]="'monitor.status.available' | i18n" nzValue="1"></nz-option> <nz-option nzLabel="监控正常" nzValue="1"></nz-option>
<nz-option [nzLabel]="'monitor.status.unavailable' | i18n" nzValue="2"></nz-option> <nz-option nzLabel="不可用" nzValue="2"></nz-option>
<nz-option [nzLabel]="'monitor.status.unreachable' | i18n" nzValue="3"></nz-option> <nz-option nzLabel="不可达" nzValue="3"></nz-option>
<nz-option [nzLabel]="'monitor.status.un-manage' | i18n" nzValue="0"></nz-option> <nz-option nzLabel="未监控" nzValue="0"></nz-option>
</nz-select> </nz-select>
</div> </div>
@@ -84,12 +82,12 @@
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th> <th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th>
<th nzAlign="center" nzLeft>{{ 'monitor.name' | i18n }}</th> <th nzAlign="center" nzLeft>监控名称</th>
<th nzAlign="center">{{ 'monitor.status' | i18n }}</th> <th nzAlign="center">监控状态</th>
<th nzAlign="center">{{ 'monitor.host' | i18n }}</th> <th nzAlign="center">监控Host</th>
<th nzAlign="center">{{ 'monitor.app' | i18n }}</th> <th nzAlign="center">监控类型</th>
<th nzAlign="center">{{ 'common.edit-time' | i18n }}</th> <th nzAlign="center">最新修改时间</th>
<th nzAlign="center">{{ 'common.edit' | i18n }}</th> <th nzAlign="center">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -103,19 +101,23 @@
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.status == 0" nzColor="default"> <nz-tag *ngIf="data.status == 0" nzColor="default">
<i nz-icon nzType="robot" nzTheme="outline"></i> <i nz-icon nzType="robot" nzTheme="outline"></i>
<span>{{ 'monitor.status.un-manage' | i18n }}</span> <span>未监控</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.status == 1" nzColor="success"> <nz-tag *ngIf="data.status == 1" nzColor="success">
<i nz-icon nzType="smile" nzTheme="outline"></i> <i nz-icon nzType="smile" nzTheme="outline"></i>
<span>{{ 'monitor.status.available' | i18n }}</span> <span>正常监控</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.status == 2" nzColor="warning"> <nz-tag *ngIf="data.status == 2" nzColor="warning">
<i nz-icon nzType="meh" nzTheme="outline"></i> <i nz-icon nzType="meh" nzTheme="outline"></i>
<span>{{ 'monitor.status.unavailable' | i18n }}</span> <span>监控不可用</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.status == 3" nzColor="error"> <nz-tag *ngIf="data.status == 3" nzColor="error">
<i nz-icon nzType="frown" nzTheme="outline"></i> <i nz-icon nzType="frown" nzTheme="outline"></i>
<span>{{ 'monitor.status.unreachable' | i18n }}</span> <span>监控不可达</span>
</nz-tag>
<nz-tag *ngIf="data.status == 4" nzColor="default">
<i nz-icon nzType="sync"></i>
<span>监控已挂起</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ data.host }}</td> <td nzAlign="center">{{ data.host }}</td>
@@ -127,34 +129,16 @@
</td> </td>
<td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td> <td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center"> <td nzAlign="center">
<button nz-button nzType="primary" (click)="onEditOneMonitor(data.id)" nz-tooltip [nzTooltipTitle]="'monitors.edit-monitor' | i18n"> <button nz-button nzType="primary" (click)="onEditOneMonitor(data.id)" nz-tooltip nzTooltipTitle="修改监控">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onDeleteOneMonitor(data.id)" nz-tooltip nzTooltipTitle="删除监控">
nz-button
nzType="primary"
(click)="onDeleteOneMonitor(data.id)"
nz-tooltip
[nzTooltipTitle]="'monitors.delete-monitor' | i18n"
>
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onEnableManageOneMonitor(data.id)" nz-tooltip nzTooltipTitle="启用监控">
nz-button
nzType="primary"
(click)="onEnableManageOneMonitor(data.id)"
nz-tooltip
[nzTooltipTitle]="'monitors.enable' | i18n"
>
<i nz-icon nzType="up-circle" nzTheme="outline"></i> <i nz-icon nzType="up-circle" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onCancelManageOneMonitor(data.id)" nz-tooltip nzTooltipTitle="取消监控">
nz-button
nzType="primary"
(click)="onCancelManageOneMonitor(data.id)"
nz-tooltip
[nzTooltipTitle]="'monitors.cancel' | i18n"
>
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button> </button>
</td> </td>
@@ -162,4 +146,4 @@
</tbody> </tbody>
</nz-table> </nz-table>
<ng-template #rangeTemplate> {{ 'common.total' | i18n }} {{ total }} </ng-template> <ng-template #rangeTemplate> 总量 {{ total }} </ng-template>

View File

@@ -1,7 +1,5 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzMessageService } from 'ng-zorro-antd/message'; import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal'; import { NzModalService } from 'ng-zorro-antd/modal';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
@@ -22,8 +20,7 @@ export class MonitorListComponent implements OnInit {
private modal: NzModalService, private modal: NzModalService,
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private msg: NzMessageService, private msg: NzMessageService,
private monitorSvc: MonitorService, private monitorSvc: MonitorService
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {} ) {}
app!: string; app!: string;
@@ -105,7 +102,7 @@ export class MonitorListComponent implements OnInit {
onEditOneMonitor(monitorId: number) { onEditOneMonitor(monitorId: number) {
if (monitorId == null) { if (monitorId == null) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-edit'), ''); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
this.router.navigateByUrl(`/monitors/${monitorId}/edit`); this.router.navigateByUrl(`/monitors/${monitorId}/edit`);
@@ -116,11 +113,11 @@ export class MonitorListComponent implements OnInit {
onEditMonitor() { onEditMonitor() {
// 编辑时只能选中一个监控 // 编辑时只能选中一个监控
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-edit'), ''); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
if (this.checkedMonitorIds.size > 1) { if (this.checkedMonitorIds.size > 1) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.one-select-edit'), ''); this.notifySvc.warning('只能对一个选中项进行编辑!', '');
return; return;
} }
let monitorId = 0; let monitorId = 0;
@@ -132,9 +129,9 @@ export class MonitorListComponent implements OnInit {
let monitors = new Set<number>(); let monitors = new Set<number>();
monitors.add(monitorId); monitors.add(monitorId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), nzTitle: '请确认是否删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteMonitors(monitors) nzOnOk: () => this.deleteMonitors(monitors)
@@ -143,13 +140,13 @@ export class MonitorListComponent implements OnInit {
onDeleteMonitors() { onDeleteMonitors() {
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-delete'), ''); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete-batch'), nzTitle: '请确认是否批量删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteMonitors(this.checkedMonitorIds) nzOnOk: () => this.deleteMonitors(this.checkedMonitorIds)
@@ -158,7 +155,7 @@ export class MonitorListComponent implements OnInit {
deleteMonitors(monitors: Set<number>) { deleteMonitors(monitors: Set<number>) {
if (monitors == null || monitors.size == 0) { if (monitors == null || monitors.size == 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-delete'), ''); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.tableLoading = true; this.tableLoading = true;
@@ -166,30 +163,30 @@ export class MonitorListComponent implements OnInit {
message => { message => {
deleteMonitors$.unsubscribe(); deleteMonitors$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); this.notifySvc.success('删除成功!', '');
this.loadMonitorTable(); this.loadMonitorTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
deleteMonitors$.unsubscribe(); deleteMonitors$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
onCancelManageMonitors() { onCancelManageMonitors() {
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-cancel'), ''); this.notifySvc.warning('未选中任何待取消项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.cancel-batch'), nzTitle: '请确认是否批量取消监控!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.cancelManageMonitors(this.checkedMonitorIds) nzOnOk: () => this.cancelManageMonitors(this.checkedMonitorIds)
@@ -200,9 +197,9 @@ export class MonitorListComponent implements OnInit {
let monitors = new Set<number>(); let monitors = new Set<number>();
monitors.add(monitorId); monitors.add(monitorId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.cancel'), nzTitle: '请确认是否取消监控!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.cancelManageMonitors(monitors) nzOnOk: () => this.cancelManageMonitors(monitors)
@@ -215,30 +212,30 @@ export class MonitorListComponent implements OnInit {
message => { message => {
cancelManage$.unsubscribe(); cancelManage$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.cancel-success'), ''); this.notifySvc.success('取消监控成功!', '');
this.loadMonitorTable(); this.loadMonitorTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.cancel-fail'), message.msg); this.notifySvc.error('取消监控失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
cancelManage$.unsubscribe(); cancelManage$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.cancel-fail'), error.msg); this.notifySvc.error('取消监控失败!', error.msg);
} }
); );
} }
onEnableManageMonitors() { onEnableManageMonitors() {
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-enable'), ''); this.notifySvc.warning('未选中任何待启用监控项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.enable-batch'), nzTitle: '请确认是否批量启用监控!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.enableManageMonitors(this.checkedMonitorIds) nzOnOk: () => this.enableManageMonitors(this.checkedMonitorIds)
@@ -249,9 +246,9 @@ export class MonitorListComponent implements OnInit {
let monitors = new Set<number>(); let monitors = new Set<number>();
monitors.add(monitorId); monitors.add(monitorId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.enable'), nzTitle: '请确认是否启用监控!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.enableManageMonitors(monitors) nzOnOk: () => this.enableManageMonitors(monitors)
@@ -264,17 +261,17 @@ export class MonitorListComponent implements OnInit {
message => { message => {
enableManage$.unsubscribe(); enableManage$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.enable-success'), ''); this.notifySvc.success('启用监控成功!', '');
this.loadMonitorTable(); this.loadMonitorTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.enable-fail'), message.msg); this.notifySvc.error('启用监控失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
enableManage$.unsubscribe(); enableManage$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.enable-fail'), error.msg); this.notifySvc.error('启用监控失败!', error.msg);
} }
); );
} }

View File

@@ -3,20 +3,20 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/monitors']" [queryParams]="{ app: monitor.app ? monitor.app : '' }"> <a [routerLink]="['/monitors']" [queryParams]="{ app: monitor.app ? monitor.app : '' }">
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>{{ 'monitors.list' | i18n }}</span> <span>监控列表</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="plus-circle"></i> <i nz-icon nzType="plus-circle"></i>
<span>{{ 'monitors.new' | i18n }} {{ 'monitor.app.' + monitor.app | i18n }} {{ 'monitor' | i18n }}</span> <span>新增 {{ 'monitor.app.' + monitor.app | i18n }} 监控</span>
<a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%"> <a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%">
<span>{{ 'common.button.help' | i18n }} </span> <span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i> <i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
@@ -27,9 +27,7 @@
<div class="-inner-content"> <div class="-inner-content">
<form nz-form #newForm="ngForm"> <form nz-form #newForm="ngForm">
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="host" nzRequired="true" [nzTooltipTitle]="'monitor.host.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="host" nzRequired="true" nzTooltipTitle="被监控的对端IP或域名"> 监控Host </nz-form-label>
{{ 'monitor.host' | i18n }}
</nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<input <input
[(ngModel)]="monitor.host" [(ngModel)]="monitor.host"
@@ -38,17 +36,17 @@
type="text" type="text"
id="host" id="host"
required required
[placeholder]="'monitor.host.tip' | i18n" placeholder="请输入域名或IP"
(ngModelChange)="onHostChange($event)" (ngModelChange)="onHostChange($event)"
/> />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true" [nzTooltipTitle]="'monitor.name.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true" nzTooltipTitle="标识此监控的名称,名称需要保证唯一性">
{{ 'monitor.name' | i18n }} 监控名称
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="monitor.name" nz-input required name="name" type="text" id="name" [placeholder]="'monitor.name.tip' | i18n" /> <input [(ngModel)]="monitor.name" nz-input required name="name" type="text" id="name" placeholder="监控名称需要保证唯一性" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
@@ -174,7 +172,7 @@
</nz-form-item> </nz-form-item>
<nz-collapse [nzGhost]="true"> <nz-collapse [nzGhost]="true">
<nz-collapse-panel [nzHeader]="extraColHeader" [nzShowArrow]="false"> <nz-collapse-panel nzHeader="高级" [nzHeader]="extraColHeader" [nzShowArrow]="false">
<nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index"> <nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index">
<nz-form-label <nz-form-label
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'" *ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
@@ -307,8 +305,8 @@
</nz-collapse-panel> </nz-collapse-panel>
</nz-collapse> </nz-collapse>
<ng-template #extraColHeader> <ng-template #extraColHeader>
<button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip [nzTooltipTitle]="'monitors.advanced.tip' | i18n"> <button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip nzTooltipTitle="设置高级可选参数">
<span>{{ 'monitors.advanced' | i18n }}</span> <span>高级设置</span>
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button> </button>
</ng-template> </ng-template>
@@ -316,9 +314,7 @@
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor="intervals" [nzTooltipTitle]="'monitor.intervals.tip' | i18n"> <nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
{{ 'monitor.intervals' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <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>
@@ -326,18 +322,14 @@
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor="detect" [nzTooltipTitle]="'monitors.detect.tip' | i18n"> <nz-form-label nzSpan="7" nzFor="detect" nzTooltipTitle="新增监控前是否先探测检查监控可用性"> 测试连接 </nz-form-label>
{{ 'monitors.detect' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch> <nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="description" [nzTooltipTitle]="'monitor.description.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="description" nzTooltipTitle="更多标识和描述此监控的备注信息"> 描述备注 </nz-form-label>
{{ 'monitor.description' | i18n }}
</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<nz-textarea-count [nzMaxCharacterCount]="100"> <nz-textarea-count [nzMaxCharacterCount]="100">
<textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea> <textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea>
@@ -347,9 +339,9 @@
<div nz-row> <div nz-row>
<div nz-col nzSpan="8" nzOffset="9"> <div nz-col nzSpan="8" nzOffset="9">
<button nz-button nzType="primary" type="submit" (click)="onDetect(newForm.form)"> {{ 'common.button.detect' | i18n }} </button> <button nz-button nzType="primary" type="submit" (click)="onDetect(newForm.form)"> 测试 </button>
<button nz-button nzType="primary" type="submit" (click)="onSubmit(newForm.form)"> {{ 'common.button.ok' | i18n }} </button> <button nz-button nzType="primary" type="submit" (click)="onSubmit(newForm.form)"> 确定 </button>
<button nz-button nzType="primary" type="reset" (click)="onCancel()"> {{ 'common.button.cancel' | i18n }} </button> <button nz-button nzType="primary" type="reset" (click)="onCancel()"> 取消 </button>
</div> </div>
</div> </div>
</form> </form>

View File

@@ -1,8 +1,8 @@
import { ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core'; import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute, ParamMap, Router } from '@angular/router'; import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import { I18NService } from '@core'; import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN, TitleService } from '@delon/theme'; import { TitleService } from '@delon/theme';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { switchMap } from 'rxjs/operators'; import { switchMap } from 'rxjs/operators';
@@ -34,7 +34,7 @@ export class MonitorNewComponent implements OnInit {
private router: Router, private router: Router,
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService, private i18n: I18NService,
private titleSvc: TitleService, private titleSvc: TitleService,
private formBuilder: FormBuilder private formBuilder: FormBuilder
) { ) {
@@ -150,15 +150,15 @@ export class MonitorNewComponent implements OnInit {
message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('monitors.new.success'), ''); this.notifySvc.success('新增监控成功', '');
this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`); this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`);
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('monitors.new.failed'), message.msg); this.notifySvc.error('新增监控失败', message.msg);
} }
}, },
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error(this.i18nSvc.fanyi('monitors.new.failed'), error.error.msg); this.notifySvc.error('新增监控失败', error.error.msg);
} }
); );
} }
@@ -199,14 +199,14 @@ export class MonitorNewComponent implements OnInit {
message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('monitors.detect.success'), ''); this.notifySvc.success('探测成功', '');
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('monitors.detect.failed'), message.msg); this.notifySvc.error('探测失败', message.msg);
} }
}, },
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error(this.i18nSvc.fanyi('monitors.detect.failed'), error.error.msg); this.notifySvc.error('探测异常', error.error.msg);
} }
); );
} }

View File

@@ -1,7 +1,6 @@
import { NgModule, Type } from '@angular/core'; import { NgModule, Type } from '@angular/core';
import { SharedModule } from '@shared'; import { SharedModule } from '@shared';
import { NzBreadCrumbModule } from 'ng-zorro-antd/breadcrumb'; import { NzBreadCrumbModule } from 'ng-zorro-antd/breadcrumb';
import { NzCollapseModule } from 'ng-zorro-antd/collapse';
import { NzDividerModule } from 'ng-zorro-antd/divider'; import { NzDividerModule } from 'ng-zorro-antd/divider';
import { NzLayoutModule } from 'ng-zorro-antd/layout'; import { NzLayoutModule } from 'ng-zorro-antd/layout';
import { NzRadioModule } from 'ng-zorro-antd/radio'; import { NzRadioModule } from 'ng-zorro-antd/radio';
@@ -17,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,

View File

@@ -7,11 +7,11 @@
<nz-form-item> <nz-form-item>
<nz-form-control [nzErrorTip]="'validation.password.required' | i18n"> <nz-form-control [nzErrorTip]="'validation.password.required' | i18n">
<nz-input-group nzSuffixIcon="lock"> <nz-input-group nzSuffixIcon="lock">
<input type="text" nz-input formControlName="password" [placeholder]="'app.lock.placeholder' | i18n" /> <input type="text" nz-input formControlName="password" placeholder="输入任意解锁" />
</nz-input-group> </nz-input-group>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-row nzAlign="middle"> <nz-row nzType="flex" nzAlign="middle">
<nz-col [nzOffset]="12" [nzSpan]="12" style="text-align: right"> <nz-col [nzOffset]="12" [nzSpan]="12" style="text-align: right">
<button nz-button [disabled]="!f.valid" nzType="primary">{{ 'app.lock' | i18n }}</button> <button nz-button [disabled]="!f.valid" nzType="primary">{{ 'app.lock' | i18n }}</button>
</nz-col> </nz-col>

View File

@@ -3,16 +3,16 @@
<nz-tab [nzTitle]="'app.login.tab-login-credentials' | i18n"> <nz-tab [nzTitle]="'app.login.tab-login-credentials' | i18n">
<nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert> <nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert>
<nz-form-item> <nz-form-item>
<nz-form-control [nzErrorTip]="'app.login.message-need-identifier' | i18n"> <nz-form-control nzErrorTip="请输入用户名">
<nz-input-group nzSize="large" nzPrefixIcon="user"> <nz-input-group nzSize="large" nzPrefixIcon="user">
<input nz-input formControlName="userName" [placeholder]="'app.login.message-need-identifier' | i18n" /> <input nz-input formControlName="userName" placeholder="请输入用户名" />
</nz-input-group> </nz-input-group>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-control [nzErrorTip]="'app.login.message-need-credential' | i18n"> <nz-form-control nzErrorTip="请输入密码">
<nz-input-group nzSize="large" nzPrefixIcon="lock"> <nz-input-group nzSize="large" nzPrefixIcon="lock">
<input nz-input type="password" formControlName="password" [placeholder]="'app.login.message-need-credential' | i18n" /> <input nz-input type="password" formControlName="password" placeholder="请输入密码" />
</nz-input-group> </nz-input-group>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>

View File

@@ -1,10 +1,10 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnDestroy, Optional } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnDestroy, Optional } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { I18NService, StartupService } from '@core'; import { StartupService } from '@core';
import { ReuseTabService } from '@delon/abc/reuse-tab'; import { ReuseTabService } from '@delon/abc/reuse-tab';
import { DA_SERVICE_TOKEN, ITokenService, SocialService } from '@delon/auth'; import { DA_SERVICE_TOKEN, ITokenService, SocialOpenType, SocialService } from '@delon/auth';
import { SettingsService, _HttpClient, ALAIN_I18N_TOKEN } from '@delon/theme'; import { SettingsService, _HttpClient } from '@delon/theme';
import { User } from '@delon/theme/src/services/settings/types'; import { User } from '@delon/theme/src/services/settings/types';
import { NzTabChangeEvent } from 'ng-zorro-antd/tabs'; import { NzTabChangeEvent } from 'ng-zorro-antd/tabs';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
@@ -29,7 +29,6 @@ export class UserLoginComponent implements OnDestroy {
@Inject(ReuseTabService) @Inject(ReuseTabService)
private reuseTabService: ReuseTabService, private reuseTabService: ReuseTabService,
@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService, @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService,
private startupSrv: StartupService, private startupSrv: StartupService,
private http: _HttpClient, private http: _HttpClient,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
@@ -126,7 +125,7 @@ export class UserLoginComponent implements OnDestroy {
let user: User = { let user: User = {
name: this.userName.value, name: this.userName.value,
avatar: './assets/img/avatar.svg', avatar: './assets/img/avatar.svg',
email: this.i18nSvc.fanyi('app.role.admin') email: '管理员'
}; };
this.settingsService.setUser(user); this.settingsService.setUser(user);
// 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响 // 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响

View File

@@ -1,296 +1,138 @@
{ {
"menu": { "menu.search.placeholder": "Search for people, file, photos...",
"main": "Main", "menu.fullscreen": "Fullscreen",
"lang": "Language", "menu.fullscreen.exit": "Exit Fullscreen",
"dashboard": "DashBoard", "menu.clear.local.storage": "Clear Local Storage",
"search.placeholder": "SearchMonitor Name、IP", "menu.lang": "Language",
"fullscreen": "Full Screen", "menu.main": "Main Navigation",
"fullscreen.exit": "Exit", "menu.dashboard": "Dashboard",
"clear.local.storage": "Clear Local Storage", "menu.dashboard.v1": "Default",
"monitor": { "menu.dashboard.analysis": "Analysis",
"": "Monitor", "menu.dashboard.monitor": "Monitor",
"service": "Service Monitor", "menu.dashboard.workplace": "Workplace",
"db": "DB Monitor", "menu.shortcut": "Shortcut",
"os": "OS Monitor", "menu.widgets": "Widgets",
"mid": "Mid Monitor", "menu.alain": "Alain",
"custom": "Custom Monitor" "menu.style": "Style",
}, "menu.style.typography": "Typography",
"account": { "menu.style.gridmasonry": "Grid Masonry",
"": "Personal", "menu.style.colors": "Colors",
"center": "Personal Center", "menu.delon": "Delon Lib",
"settings": "Account Setting", "menu.delon.form": "Dynamic Form",
"security": "Security Setting", "menu.delon.table": "Simple table",
"binding": "Account Binding", "menu.delon.util": "Util",
"trigger": "Trigger Error", "menu.delon.print": "Print",
"logout": "Logout" "menu.delon.guard": "Route Guard",
}, "menu.delon.cache": "Cache",
"alert": { "menu.delon.qr": "QR",
"": "Alert", "menu.delon.acl": "ACL",
"center": "Alert Center", "menu.delon.downfile": "Download File",
"setting": "Alert Setting", "menu.delon.xlsx": "Excel",
"dispatch": "Alert Notify" "menu.delon.zip": "Zip",
}, "menu.pro": "Antd Pro",
"extras": { "menu.form": "Form",
"": "More", "menu.form.basicform": "Basic Form",
"help": "Help Center", "menu.form.stepform": "Step Form",
"setting": "Setting" "menu.form.stepform.info": "Step Form(write transfer information)",
}, "menu.form.stepform.confirm": "Step Form(confirm transfer information)",
"more": "More" "menu.form.stepform.result": "Step Form(finished)",
}, "menu.form.advancedform": "Advanced Form",
"monitor": { "menu.list": "List",
"": "Monitor", "menu.list.searchtable": "Search Table",
"name": "Monitor Name", "menu.list.basiclist": "Basic List",
"name.tip": "Monitor name, the name needs to be unique", "menu.list.cardlist": "Card List",
"host": "Monitor Host", "menu.list.searchlist": "Search List",
"host.tip": "The monitored peer IP or domain name", "menu.list.searchlist.articles": "Search List(articles)",
"description": "Description", "menu.list.searchlist.projects": "Search List(projects)",
"description.tip": "Description and remarks", "menu.list.searchlist.applications": "Search List(applications)",
"intervals": "Intervals", "menu.profile": "Profile",
"intervals.tip": "Monitor the interval time of periodic collection of data, second", "menu.profile.basic": "Basic Profile",
"category": { "menu.profile.advanced": "Advanced Profile",
"": "Category", "menu.result": "Result",
"service": "Service", "menu.result.success": "Success",
"db": "Database", "menu.result.fail": "Fail",
"os": "OS", "menu.exception": "Exception",
"mid": "Middleware", "menu.exception.not-permission": "403",
"custom": "Custom" "menu.exception.not-find": "404",
}, "menu.exception.server-error": "500",
"app": { "menu.account": "Account",
"": "Monitor Type", "menu.account.center": "Account Center",
"website": "Website Monitor", "menu.account.settings": "Account Settings",
"api": "HTTP API", "menu.account.trigger": "Trigger Error",
"http": "HTTP API", "menu.account.logout": "Logout",
"ping": "PING Connect", "menu.more": "More",
"port": "Port Available", "menu.report": "Report",
"mysql": "Mysql", "menu.report.relation": "Relation Map",
"oracle": "Oracle", "menu.extras": "Extra",
"redis": "Redis", "menu.extras.helpcenter": "Help Center",
"fullsite": "SiteMap Monitor" "menu.extras.settings": "Settings",
}, "menu.extras.poi": "Poi",
"status": { "app.analysis.test": "Gongzhuan No.{{no}} shop",
"": "Monitor Status", "app.analysis.introduce": "Introduce",
"all": "All Status", "app.analysis.total-sales": "Total Sales",
"available": "Available", "app.analysis.day-sales": "Day Sales",
"unavailable": "UnAvailable", "app.analysis.visits": "Visits",
"unreachable": "UnReachable", "app.analysis.visits-trend": "Visits Trend",
"un-manage": "UnManaged" "app.analysis.visits-ranking": "Visits Ranking",
} "app.analysis.day-visits": "Day Visits",
}, "app.analysis.week": "Week Ratio",
"alert": { "app.analysis.day": "Day Ratio",
"": "Alert", "app.analysis.payments": "Payments",
"status": { "app.analysis.conversion-rate": "Conversion Rate",
"": "Alert Status", "app.analysis.operational-effect": "Operational Effect",
"all": "All Status", "app.analysis.sales-trend": "Stores Sales Trend",
"0": "Pending", "app.analysis.sales-ranking": "Sales Ranking",
"2": "Restored", "app.analysis.all-year": "All Year",
"3": "Processed" "app.analysis.all-month": "All Month",
}, "app.analysis.all-week": "All Week",
"priority": { "app.analysis.all-today": "All day",
"": "Alarm Priority", "app.analysis.search-users": "Search Users",
"all": "All Priority", "app.analysis.per-capita-search": "Per Capita Search",
"0": "Emergency", "app.analysis.online-top-search": "Online Top Search",
"1": "Critical", "app.analysis.the-proportion-of-sales": "The Proportion Of Sales",
"2": "Warning" "app.analysis.channel.all": "ALL",
} "app.analysis.channel.online": "Online",
}, "app.analysis.channel.stores": "Stores",
"alert.setting.new": "New Threshold", "app.analysis.sales": "Sales",
"alert.setting.edit": "Edit Threshold", "app.analysis.traffic": "Traffic",
"alert.setting.delete": "Delete Threshold", "app.analysis.table.rank": "Rank",
"alert.setting.target": "Metric Target", "app.analysis.table.search-keyword": "Keyword",
"alert.setting.expr": "Threshold Trigger Expr", "app.analysis.table.users": "Users",
"alert.setting.times": "Trigger Times", "app.analysis.table.weekly-range": "Weekly Range",
"alert.setting.times.tip": "Set how many times the threshold is triggered before sending an alert", "app.monitor.trading-activity": "Real-Time Trading Activity",
"alert.setting.template": "Notice Template", "app.monitor.total-transactions": "Total transactions today",
"alert.setting.template.tip": "Supported notification template environment variables", "app.monitor.sales-target": "Sales target completion rate",
"alert.setting.template.label": "The notification information template sent after the alarm is triggered, see the template environment variable above", "app.monitor.remaining-time": "Remaining time of activity",
"alert.setting.template.example": "Please input notice template.Eg: ${app}.${metrics}.${metric}'s value is too high", "app.monitor.total-transactions-per-second": "Total transactions per second",
"alert.setting.template.monitor-type": "Monitor Type Name", "app.monitor.activity-forecast": "Activity forecast",
"alert.setting.template.metrics-name": "Metrics Name", "app.monitor.efficiency": "Efficiency",
"alert.setting.template.metric-name": "Metric Name", "app.monitor.ratio": "Ratio",
"alert.setting.template.metric-value": "Metric Target Value", "app.monitor.proportion-per-category": "Proportion Per Category",
"alert.setting.template.other-value": "Other Metric Value", "app.monitor.fast-food": "Fast food",
"alert.setting.template.instance-value": "Instance Value", "app.monitor.western-food": "Western food",
"alert.setting.default": "Global Default", "app.monitor.hot-pot": "Hot pot",
"alert.setting.default.tip": "Whether this alarm threshold configuration applies to all this type of monitoring globally", "app.monitor.waiting-for-implementation": "Waiting for implementation",
"alert.setting.enable": "Enable Alert", "app.monitor.popular-searches": "Popular Searches",
"alert.setting.enable.tip": "This alarm threshold configuration is enabled or disabled", "app.monitor.resource-surplus": "Resource Surplus",
"alert.setting.connect": "Alert Associate Monitors", "app.monitor.fund-surplus": "Fund Surplus",
"alert.setting.connect.left": "No Associate",
"alert.setting.connect.right": "Associated",
"alert.setting.expr.tip": "Supported Threshold Trigger Expression Environment Variables and Operators",
"alert.setting.expr.label": "Calculate and judge whether the threshold is triggered according to this expression. The expression environment variables and operators are shown above.",
"alert.setting.expr.example": "Calculate whether to trigger the threshold according to this expression.Eg",
"alert.setting.priority.tip": "The alarm level that triggers the threshold, from low to high:WarningCriticalEmergency",
"alert.setting.target.tip": "The selected metric object",
"alert.setting.target.other": "Other metric objects of the row",
"alert.setting.target.instance": "Instance of the row",
"alert.setting.operator": "Supported operator functions",
"alert.center.delete": "Delete Alerts",
"alert.center.deal": "Mark Processed",
"alert.center.no-deal": "Mark Pending",
"alert.center.search": "Search Alert Content",
"alert.center.filter-status": "Filter Alert Status",
"alert.center.filter-priority": "Filter Alert Priority",
"alert.center.target": "Metric Target",
"alert.center.monitor": "Belong Monitor",
"alert.center.priority": "Priority",
"alert.center.content": "Alert Content",
"alert.center.status": "Status",
"alert.center.time": "Alert Time",
"alert.center.notify.no-delete": "No items selected for deletion!",
"alert.center.confirm.delete": "Please confirm whether to delete!",
"alert.center.confirm.delete-batch": "Please confirm whether to delete in batch!",
"alert.center.notify.no-mark": "No items selected for mark!",
"alert.center.confirm.mark-done-batch": "Please confirm whether to mark processed in batch!",
"alert.center.confirm.mark-done": "Please confirm whether to mark processed!",
"alert.center.confirm.mark-no-batch": "Please confirm whether to mark Pending in batch!",
"alert.center.confirm.mark-no": "Please confirm whether to mark Pending!",
"alert.notice.receiver": "Alert Receiver",
"alert.notice.receiver.new": "New Receiver",
"alert.notice.receiver.edit": "Edit Receiver",
"alert.notice.receiver.delete": "Delete Receiver",
"alert.notice.receiver.people": "Receiver",
"alert.notice.receiver.people.name": "Receiver Name",
"alert.notice.receiver.type": "Notice Type",
"alert.notice.receiver.setting": "Setting",
"alert.notice.type.sms": "SMS",
"alert.notice.type.phone": "Phone",
"alert.notice.type.email": "Email",
"alert.notice.type.url": "URL",
"alert.notice.type.wechat": "Open WeChat",
"alert.notice.type.wechat-id": "WeChat OPENID",
"alert.notice.type.wework": "WeWork Robot",
"alert.notice.type.wework-key": "WeWork Robot KEY",
"alert.notice.type.access-token": "Robot ACCESS_TOKEN",
"alert.notice.type.ding": "DingDing Robot",
"alert.notice.type.fei-shu": "FeiShu Robot",
"alert.notice.type.fei-shu-key": "FeiShu Robot KEY",
"alert.notice.rule": "Alert Notice Rule",
"alert.notice.rule.new": "New Notice Rule",
"alert.notice.rule.edit": "Edit Notice Rule",
"alert.notice.rule.delete": "Delete Notice Rule",
"alert.notice.rule.name": "Rule Name",
"alert.notice.rule.all": "Dispatch ALl",
"alert.notice.rule.enable": "Enable",
"dashboard.alerts.title": "Recently Alerts List",
"dashboard.alerts.title-no": "Recently Pending Alerts",
"dashboard.alerts.no": "No Pending Alerts",
"dashboard.alerts.enter": "Go Alert Center",
"dashboard.alerts.distribute": "The Distribution Of Alerts",
"dashboard.alerts.num": "Alerts Num",
"dashboard.alerts.deal": "Alerts Dealing",
"dashboard.alerts.deal-percent": "Dealing Rate",
"dashboard.monitors.total": "Monitor Total",
"dashboard.monitors.title": "Monitoring Overview",
"dashboard.monitors.sub-title": "The Distribution Of Monitors",
"dashboard.monitors.formatter": " Monitors ",
"dashboard.monitors.distribute": "Monitor Distribution",
"monitors.list": "Monitor List",
"monitors.new": "New",
"monitors.new.success": "New Monitor Success",
"monitors.new.failed": "New Monitor Failed",
"monitors.edit": "Edit",
"monitors.edit.success": "Update Monitor Success",
"monitors.edit.failed": "Update Monitor Failed",
"monitors.not-found": "This Monitor Not Found",
"monitors.delete": "Delete",
"monitors.edit-monitor": "Edit Monitor",
"monitors.delete-monitor": "Delete Monitor",
"monitors.enable": "Enable Monitor",
"monitors.cancel": "Cancel Monitor",
"monitors.search.placeholder": "Search Monitor",
"monitors.search.filter": "Filter Monitor Status",
"monitors.total": "Total",
"monitors.advanced": "Advanced",
"monitors.advanced.tip": "Setting Advanced Param",
"monitors.detect": "Detect",
"monitors.detect.success": "Detect Success",
"monitors.detect.failed": "Detect Failed",
"monitors.detect.tip": "Detect monitor available before apply",
"monitors.detail": "Monitor Detail",
"monitors.detail.name": "Name",
"monitors.detail.port": "Port",
"monitors.detail.description": "Desc",
"monitors.detail.status": "Status",
"monitors.detail.basic": "Monitor Basic",
"monitors.detail.realtime": "Monitor Real-Time Detail",
"monitors.detail.history": "Monitor Historical Chart Detail",
"monitors.collect.time": "Collect Time",
"monitors.collect.time.tip": "Last collect time",
"monitors.detail.chart.zoom": "Zoom In",
"monitors.detail.chart.back": "Zoom restore",
"monitors.detail.chart.save": "Save as Image",
"monitors.detail.chart.query-1h": "Query 1 Hour",
"monitors.detail.chart.query-6h": "Query 6 Hours",
"monitors.detail.chart.query-1d": "Query 1 Day",
"monitors.detail.chart.query-1w": "Query 1 Week",
"monitors.detail.chart.query-1m": "Query 1 Month",
"monitors.detail.chart.no-data": "No Metrics Data",
"monitors.detail.chart.unit": "Unit",
"common.name": "Name",
"common.value": "Value",
"common.search": "Search",
"common.refresh": "Refresh",
"common.edit-time": "Last Update Time",
"common.new-time": "Create Time",
"common.edit": "Operate",
"common.total": "Total",
"common.yes": "Yes",
"common.no": "No",
"common.enable": "Enable",
"common.disable": "Disable",
"common.notify.no-select-edit": "No items selected for editing!",
"common.notify.one-select-edit": "Only one selection can be edited!",
"common.confirm.delete": "Please confirm whether to delete!",
"common.notify.no-select-delete": "No items selected for deletion!",
"common.confirm.delete-batch": "Please confirm whether to delete in batches!",
"common.notify.delete-success": "Delete Success!",
"common.notify.delete-fail": "Delete Failed!",
"common.notify.new-success": "Add Success!",
"common.notify.new-fail": "Add Failed!",
"common.notify.apply-success": "Apply Success!",
"common.notify.apply-fail": "Apply Failed!",
"common.notify.monitor-fail": "Query Monitor Failed!",
"common.notify.edit-success": "Edit Success!",
"common.notify.edit-fail": "Edit Failed!",
"common.notify.no-select-cancel": "No items selected for cancel!",
"common.confirm.cancel-batch": "Please confirm whether to cancel monitor in batches!",
"common.confirm.cancel": "Please confirm whether to cancel monitor!",
"common.notify.cancel-success": "Cancel Success!",
"common.notify.cancel-fail": "Cancel Failed!",
"common.notify.mark-success": "Mark Success!",
"common.notify.mark-fail": "Mark Failed!",
"common.notify.no-select-enable": "No items selected for enable!",
"common.confirm.enable-batch": "Please confirm whether to enable monitor in batches!",
"common.confirm.enable": "Please confirm whether to enable monitor!",
"common.notify.enable-success": "Enable Success!",
"common.notify.enable-fail": "Enable Failed!",
"common.confirm.clear-cache": "Please confirm whether to clear cache!",
"common.notify.clear-success": "Clear Success!",
"common.button.ok": "OK",
"common.button.cancel": "Cancel",
"common.button.help": "Help",
"common.button.edit": "Edit",
"common.button.delete": "Delete",
"common.button.detect": "Detect",
"validation.email.invalid": "Invalid email",
"validation.phone.invalid": "Invalid phone number",
"validation.verification-code.invalid": "Invalid verification code, should be 6 digits",
"validation.required": "Please fill in the required fields! ",
"app.theme.default": "Light Theme",
"app.theme.dark": "Dark Theme",
"app.theme.compact": "Compact Theme",
"app.role.admin": "Administrator",
"app.lock": "Lock", "app.lock": "Lock",
"app.lock.placeholder": "Enter Any To Unlock", "app.login.message-invalid-credentials": "Invalid username or passwordadmin/ant.design",
"app.passport.desc": "TanCloud-Friendly High Performance Monitoring Cloud Service", "app.login.message-invalid-verification-code": "Invalid verification code",
"app.passport.welcome": "Welcome To Use TanCloud-Monitoring Cloud Service-tancloud.cn",
"app.login.message-need-identifier": "Please enter your username",
"app.login.message-need-credential": "Please enter password",
"app.login.message-invalid-credentials": "Invalid username or password",
"app.login.tab-login-credentials": "Credentials", "app.login.tab-login-credentials": "Credentials",
"app.login.tab-login-mobile": "Mobile number",
"app.login.remember-me": "Remember me", "app.login.remember-me": "Remember me",
"app.login.forgot-password": "Forgot your password?",
"app.login.sign-in-with": "Sign in with",
"app.login.signup": "Sign up",
"app.login.login": "Login", "app.login.login": "Login",
"app.register.register": "Register",
"app.register.get-verification-code": "Get code",
"app.register.sign-in": "Already have an account?",
"app.register-result.msg": "Accountregistered at {{email}}",
"app.register-result.activation-email":
"The activation email has been sent to your email address and is valid for 24 hours. Please log in to the email in time and click on the link in the email to activate the account.",
"app.register-result.back-home": "Back to home",
"app.register-result.view-mailbox": "View mailbox",
"validation.email.required": "Please enter your email!", "validation.email.required": "Please enter your email!",
"validation.email.wrong-format": "The email address is in the wrong format!", "validation.email.wrong-format": "The email address is in the wrong format!",
"validation.password.required": "Please enter your password!", "validation.password.required": "Please enter your password!",

View File

@@ -27,7 +27,7 @@
"alert": { "alert": {
"": "告警", "": "告警",
"center": "告警中心", "center": "告警中心",
"setting": "告警阈值", "setting": "告警配置",
"dispatch": "告警通知" "dispatch": "告警通知"
}, },
"extras": { "extras": {
@@ -39,14 +39,6 @@
}, },
"monitor": { "monitor": {
"": "监控", "": "监控",
"name": "监控名称",
"name.tip": "标识监控的名称,名称需要保证唯一性",
"host": "监控Host",
"host.tip": "被监控的对端IP或域名",
"description": "描述备注",
"description.tip": "更多标识和描述此监控的备注信息",
"intervals": "采集间隔",
"intervals.tip": "监控周期性采集数据间隔时间,单位秒",
"category": { "category": {
"": "监控类别", "": "监控类别",
"service": "应用服务", "service": "应用服务",
@@ -66,227 +58,46 @@
"oracle": "Oracle", "oracle": "Oracle",
"redis": "Redis", "redis": "Redis",
"fullsite": "全站监控" "fullsite": "全站监控"
},
"status": {
"": "监控状态",
"all": "全部状态",
"available": "正常监控",
"unavailable": "不可用",
"unreachable": "不可达",
"un-manage": "未管理"
} }
}, },
"alert": { "alert": {
"": "告警", "": "告警",
"status": { "status": {
"": "告警状态", "": "告警状态",
"all": "全部状态", "0": "待处理",
"0": "未处理",
"2": "已恢复", "2": "已恢复",
"3": "已处理" "3": "已处理"
}, },
"priority": { "priority": {
"": "告警级别", "": "告警级别",
"all": "全部级别",
"0": "紧急告警", "0": "紧急告警",
"1": "严重告警", "1": "严重告警",
"2": "警告告警" "2": "警告告警"
} }
}, },
"alert.setting.new": "新增阈值",
"alert.setting.edit": "编辑阈值",
"alert.setting.delete": "删除阈值",
"alert.setting.target": "指标对象",
"alert.setting.expr": "阈值触发表达式",
"alert.setting.times": "触发次数",
"alert.setting.times.tip": "设置触发阈值多少次之后才会发送告警",
"alert.setting.template": "通知模版",
"alert.setting.template.tip": "支持的通知模版环境变量",
"alert.setting.template.label": "告警触发后发送的通知信息模版,模版环境变量见上方",
"alert.setting.template.example": "请输入告警的通知模版.示例: ${app}.${metrics}.${metric}'s value is too high",
"alert.setting.template.monitor-type": "监控类型名称",
"alert.setting.template.metrics-name": "监控指标集合名称",
"alert.setting.template.metric-name": "监控指标名称",
"alert.setting.template.metric-value": "监控指标对象值",
"alert.setting.template.other-value": "所属行其它指标值",
"alert.setting.template.instance-value": "所属行实例值",
"alert.setting.default": "全局默认",
"alert.setting.default.tip": "此告警阈值配置是否应用于全局所有此类型监控",
"alert.setting.enable": "启用告警",
"alert.setting.enable.tip": "此告警阈值配置开启生效或关闭",
"alert.setting.connect": "告警定义关联监控",
"alert.setting.connect.left": "未关联监控",
"alert.setting.connect.right": "已关联监控",
"alert.setting.expr.tip": "支持的阈值触发表达式环境变量与操作符",
"alert.setting.expr.label": "根据此表达式来计算判断是否触发阈值,表达式环境变量和操作符见上方",
"alert.setting.expr.example": "根据此表达式计算判断是否触发阈值.示例",
"alert.setting.priority.tip": "触发阈值的告警级别,从低到高依次为:警告-warning严重-critical紧急-emergency",
"alert.setting.target.tip": "选中的指标对象",
"alert.setting.target.other": "所属行其它指标对象",
"alert.setting.target.instance": "所属行实例",
"alert.setting.operator": "支持操作符函数",
"alert.center.delete": "删除告警",
"alert.center.deal": "标记已处理",
"alert.center.no-deal": "标记未处理",
"alert.center.search": "搜索告警内容",
"alert.center.filter-status": "告警状态过滤",
"alert.center.filter-priority": "告警级别过滤",
"alert.center.target": "告警指标",
"alert.center.monitor": "所属监控",
"alert.center.priority": "级别",
"alert.center.content": "告警内容",
"alert.center.status": "状态",
"alert.center.time": "告警时间",
"alert.center.notify.no-delete": "未选中任何待删除项!",
"alert.center.confirm.delete": "请确认是否删除!",
"alert.center.confirm.delete-batch": "请确认是否批量删除!",
"alert.center.notify.no-mark": "未选中任何待标记项!",
"alert.center.confirm.mark-done-batch": "请确认是否批量标记已处理!",
"alert.center.confirm.mark-done": "请确认是否标记已处理!",
"alert.center.confirm.mark-no-batch": "请确认是否批量标记未处理!",
"alert.center.confirm.mark-no": "请确认是否标记未处理!",
"alert.notice.receiver": "告警接收人",
"alert.notice.receiver.new": "新增接收人",
"alert.notice.receiver.edit": "编辑接收人",
"alert.notice.receiver.delete": "删除接收人",
"alert.notice.receiver.people": "接收人",
"alert.notice.receiver.people.name": "接收人名称",
"alert.notice.receiver.type": "通知方式",
"alert.notice.receiver.setting": "配置",
"alert.notice.type.sms": "短信",
"alert.notice.type.phone": "手机号",
"alert.notice.type.email": "邮箱",
"alert.notice.type.url": "URL地址",
"alert.notice.type.wechat": "微信公众号",
"alert.notice.type.wechat-id": "微信OPENID",
"alert.notice.type.wework": "企业微信机器人",
"alert.notice.type.wework-key": "企业微信机器人KEY",
"alert.notice.type.access-token": "机器人ACCESS_TOKEN",
"alert.notice.type.ding": "钉钉机器人",
"alert.notice.type.fei-shu": "飞书机器人",
"alert.notice.type.fei-shu-key": "飞书机器人KEY",
"alert.notice.rule": "告警通知策略",
"alert.notice.rule.new": "新增通知策略",
"alert.notice.rule.edit": "编辑通知策略",
"alert.notice.rule.delete": "删除通知策略",
"alert.notice.rule.name": "策略名称",
"alert.notice.rule.all": "转发所有",
"alert.notice.rule.enable": "是否启用",
"dashboard.alerts.title": "最近告警列表",
"dashboard.alerts.title-no": "最近未处理告警",
"dashboard.alerts.no": "暂无未处理告警",
"dashboard.alerts.enter": "进入告警中心",
"dashboard.alerts.distribute": "告警分布",
"dashboard.alerts.num": "告警数量",
"dashboard.alerts.deal": "告警处理",
"dashboard.alerts.deal-percent": "告警处理率",
"dashboard.monitors.total": "监控总量",
"dashboard.monitors.title": "监控总览",
"dashboard.monitors.sub-title": "监控类型纳管数量分布",
"dashboard.monitors.formatter": "个监控 占比",
"dashboard.monitors.distribute": "纳管数量分布",
"monitors.list": "监控列表",
"monitors.new": "新增",
"monitors.new.success": "新增监控成功",
"monitors.new.failed": "新增监控失败",
"monitors.edit": "编辑",
"monitors.edit.success": "修改监控成功",
"monitors.edit.failed": "修改监控失败",
"monitors.not-found": "查询异常,此监控不存在",
"monitors.delete": "删除",
"monitors.edit-monitor": "编辑监控",
"monitors.delete-monitor": "删除监控",
"monitors.enable": "启用监控",
"monitors.cancel": "取消监控",
"monitors.search.placeholder": "搜索监控",
"monitors.search.filter": "监控状态过滤",
"monitors.total": "总量",
"monitors.advanced": "高级设置",
"monitors.advanced.tip": "设置高级可选参数",
"monitors.detect": "测试连接",
"monitors.detect.success": "测试连接成功",
"monitors.detect.failed": "测试连接失败",
"monitors.detect.tip": "新增监控前是否先探测检查监控可用性",
"monitors.detail": "监控详情",
"monitors.detail.name": "名称",
"monitors.detail.port": "端口",
"monitors.detail.description": "描述",
"monitors.detail.status": "状态",
"monitors.detail.basic": "监控基本属性",
"monitors.detail.realtime": "监控实时数据详情",
"monitors.detail.history": "监控历史图表详情",
"monitors.collect.time": "采集时间",
"monitors.collect.time.tip": "最近采集时间",
"monitors.detail.chart.zoom": "区域缩放",
"monitors.detail.chart.back": "缩放还原",
"monitors.detail.chart.save": "保存图片",
"monitors.detail.chart.query-1h": "查询近1小时",
"monitors.detail.chart.query-6h": "查询近6小时",
"monitors.detail.chart.query-1d": "查询近1天",
"monitors.detail.chart.query-1w": "查询近1周",
"monitors.detail.chart.query-1m": "查询近1月",
"monitors.detail.chart.no-data": "暂无数据",
"monitors.detail.chart.unit": "单位",
"common.name": "名称",
"common.value": "值",
"common.search": "搜索",
"common.refresh": "刷新",
"common.edit-time": "更新时间",
"common.new-time": "创建时间",
"common.edit": "操作",
"common.total": "总量",
"common.yes": "是",
"common.no": "否",
"common.enable": "开启",
"common.disable": "关闭",
"common.notify.no-select-edit": "未选中任何待编辑项!",
"common.notify.one-select-edit": "只能对一个选中项进行编辑!",
"common.confirm.delete": "请确认是否删除!",
"common.notify.no-select-delete": "未选中任何待删除项!",
"common.confirm.delete-batch": "请确认是否批量删除!",
"common.notify.delete-success": "删除成功!",
"common.notify.delete-fail": "删除失败!",
"common.notify.new-success": "新增成功!",
"common.notify.new-fail": "新增失败!",
"common.notify.apply-success": "应用成功!",
"common.notify.apply-fail": "应用失败!",
"common.notify.monitor-fail": "查询此监控定义详情失败!",
"common.notify.edit-success": "修改成功!",
"common.notify.edit-fail": "修改失败!",
"common.notify.mark-success": "标记成功!",
"common.notify.mark-fail": "标记失败!",
"common.notify.no-select-cancel": "未选中任何待取消项!",
"common.confirm.cancel-batch": "请确认是否批量取消监控!",
"common.confirm.cancel": "请确认是否取消监控!",
"common.notify.cancel-success": "取消监控成功!",
"common.notify.cancel-fail": "取消监控失败!",
"common.notify.no-select-enable": "未选中任何待启用监控项!",
"common.confirm.enable-batch": "请确认是否批量启用监控!",
"common.confirm.enable": "请确认是否启用监控!",
"common.notify.enable-success": "启用监控成功!",
"common.notify.enable-fail": "启用监控失败!",
"common.confirm.clear-cache": "请确认是否清理缓存!",
"common.notify.clear-success": "清理成功!",
"common.button.ok": "确定",
"common.button.detect": "测试",
"common.button.cancel": "取消",
"common.button.help": "帮助",
"common.button.edit": "编辑",
"common.button.delete": "删除",
"app.theme.default": "浅色主题",
"app.theme.dark": "深色主题",
"app.theme.compact": "紧凑主题",
"app.role.admin": "管理员",
"app.lock": "锁屏", "app.lock": "锁屏",
"app.lock.placeholder": "输入任意解锁", "app.login.message-need-identifier": "输入邮箱或手机号",
"app.passport.desc": "TanCloud-易用友好的高性能监控云服务",
"app.passport.welcome": "欢迎使用TanCloud探云-监控云服务-tancloud.cn",
"app.login.message-need-identifier": "请输入用户名",
"app.login.message-need-credential": "请输入密码", "app.login.message-need-credential": "请输入密码",
"app.login.message-invalid-credentials": "账户或密码错误", "app.login.message-invalid-credentials": "账户或密码错误",
"app.login.message-invalid-verification-code": "验证码错误",
"app.login.tab-login-credentials": "账户密码登录", "app.login.tab-login-credentials": "账户密码登录",
"app.login.tab-login-mobile": "手机号登录",
"app.login.remember-me": "自动登录", "app.login.remember-me": "自动登录",
"app.login.forgot-password": "忘记密码",
"app.login.sign-in-with": "其他登录方式",
"app.login.signup": "注册账户",
"app.login.login": "登录", "app.login.login": "登录",
"app.password.forgot": "忘记密码",
"app.password.reset": "重置密码",
"app.register.register": "注册",
"app.register.get-verification-code": "获取验证码",
"app.register.sign-in": "使用已有账户登录",
"app.register-result.msg": "你的账户:{{email}} 注册成功",
"app.register-result.activation-email":
"额外赠送监控额度邮件已发送到你的邮箱中。请及时登录邮箱,点击邮件中的链接领取。",
"app.register-result.login": "开始登录",
"app.register-result.back-home": "返回首页",
"app.register-result.view-mailbox": "查看邮箱",
"validation.email.required": "请输入邮箱地址!", "validation.email.required": "请输入邮箱地址!",
"validation.email.wrong-format": "邮箱地址格式错误!", "validation.email.wrong-format": "邮箱地址格式错误!",
"validation.email.invalid": "无效的邮箱地址!", "validation.email.invalid": "无效的邮箱地址!",