Compare commits
2 Commits
feature#mu
...
feature#po
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c42655e9b9 | ||
|
|
7c12eda30e |
@@ -138,32 +138,24 @@ public class CalculateAlarm {
|
|||||||
}
|
}
|
||||||
List<CollectRep.Field> fields = metricsData.getFieldsList();
|
List<CollectRep.Field> fields = metricsData.getFieldsList();
|
||||||
Map<String, Object> fieldValueMap = new HashMap<>(16);
|
Map<String, Object> fieldValueMap = new HashMap<>(16);
|
||||||
fieldValueMap.put("app", app);
|
|
||||||
fieldValueMap.put("metrics", metrics);
|
|
||||||
for (CollectRep.ValueRow valueRow : metricsData.getValuesList()) {
|
for (CollectRep.ValueRow valueRow : metricsData.getValuesList()) {
|
||||||
if (!valueRow.getColumnsList().isEmpty()) {
|
if (!valueRow.getColumnsList().isEmpty()) {
|
||||||
|
fieldValueMap.clear();
|
||||||
String instance = valueRow.getInstance();
|
String instance = valueRow.getInstance();
|
||||||
if (!"".equals(instance)) {
|
if (!"".equals(instance)) {
|
||||||
fieldValueMap.put("instance", instance);
|
fieldValueMap.put("instance", instance);
|
||||||
} else {
|
|
||||||
fieldValueMap.remove("instance");
|
|
||||||
}
|
}
|
||||||
for (int index = 0; index < valueRow.getColumnsList().size(); index++) {
|
for (int index = 0; index < valueRow.getColumnsList().size(); index++) {
|
||||||
String valueStr = valueRow.getColumns(index);
|
String valueStr = valueRow.getColumns(index);
|
||||||
CollectRep.Field field = fields.get(index);
|
CollectRep.Field field = fields.get(index);
|
||||||
fieldValueMap.put("metric", field.getName());
|
|
||||||
if (field.getType() == CommonConstants.TYPE_NUMBER) {
|
if (field.getType() == CommonConstants.TYPE_NUMBER) {
|
||||||
Double doubleValue = CommonUtil.parseDoubleStr(valueStr);
|
Double doubleValue = CommonUtil.parseDoubleStr(valueStr);
|
||||||
if (doubleValue != null) {
|
if (doubleValue != null) {
|
||||||
fieldValueMap.put(field.getName(), doubleValue);
|
fieldValueMap.put(field.getName(), doubleValue);
|
||||||
} else {
|
|
||||||
fieldValueMap.remove(field.getName());
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!"".equals(valueStr)) {
|
if (!"".equals(valueStr)) {
|
||||||
fieldValueMap.put(field.getName(), valueStr);
|
fieldValueMap.put(field.getName(), valueStr);
|
||||||
} else {
|
|
||||||
fieldValueMap.remove(field.getName());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,6 +179,9 @@ public class CalculateAlarm {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int times = 1;
|
int times = 1;
|
||||||
|
fieldValueMap.put("app", app);
|
||||||
|
fieldValueMap.put("metrics", metrics);
|
||||||
|
fieldValueMap.put("metric", define.getField());
|
||||||
Alert alert = Alert.builder()
|
Alert alert = Alert.builder()
|
||||||
.monitorId(monitorId)
|
.monitorId(monitorId)
|
||||||
.alertDefineId(define.getId())
|
.alertDefineId(define.getId())
|
||||||
|
|||||||
@@ -91,6 +91,12 @@
|
|||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
<version>8.0.27</version>
|
<version>8.0.27</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- postgresql -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.3.3</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -11,6 +11,7 @@ import com.usthe.common.entity.job.protocol.JdbcProtocol;
|
|||||||
import com.usthe.common.entity.message.CollectRep;
|
import com.usthe.common.entity.message.CollectRep;
|
||||||
import com.usthe.common.util.CommonConstants;
|
import com.usthe.common.util.CommonConstants;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.postgresql.util.PSQLException;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
@@ -72,7 +73,16 @@ public class JdbcCommonCollect extends AbstractCollect {
|
|||||||
} catch (CommunicationsException communicationsException) {
|
} catch (CommunicationsException communicationsException) {
|
||||||
log.warn("Jdbc sql error: {}, code: {}.", communicationsException.getMessage(), communicationsException.getErrorCode());
|
log.warn("Jdbc sql error: {}, code: {}.", communicationsException.getMessage(), communicationsException.getErrorCode());
|
||||||
builder.setCode(CollectRep.Code.UN_REACHABLE);
|
builder.setCode(CollectRep.Code.UN_REACHABLE);
|
||||||
builder.setMsg("Query Error: " + communicationsException.getMessage() + " Code: " + communicationsException.getErrorCode());
|
builder.setMsg("Error: " + communicationsException.getMessage() + " Code: " + communicationsException.getErrorCode());
|
||||||
|
} catch (PSQLException psqlException) {
|
||||||
|
// for PostgreSQL 08001
|
||||||
|
if (CollectorConstants.POSTGRESQL_UN_REACHABLE_CODE.equals(psqlException.getSQLState())) {
|
||||||
|
// 对端链接失败 不可达
|
||||||
|
builder.setCode(CollectRep.Code.UN_REACHABLE);
|
||||||
|
} else {
|
||||||
|
builder.setCode(CollectRep.Code.FAIL);
|
||||||
|
}
|
||||||
|
builder.setMsg("Error: " + psqlException.getMessage() + " Code: " + psqlException.getSQLState());
|
||||||
} catch (SQLException sqlException) {
|
} catch (SQLException sqlException) {
|
||||||
log.warn("Jdbc sql error: {}, code: {}.", sqlException.getMessage(), sqlException.getErrorCode());
|
log.warn("Jdbc sql error: {}, code: {}.", sqlException.getMessage(), sqlException.getErrorCode());
|
||||||
builder.setCode(CollectRep.Code.FAIL);
|
builder.setCode(CollectRep.Code.FAIL);
|
||||||
@@ -253,6 +263,10 @@ public class JdbcCommonCollect extends AbstractCollect {
|
|||||||
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase())
|
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase())
|
||||||
+ "?useUnicode=true&characterEncoding=utf-8&useSSL=false";
|
+ "?useUnicode=true&characterEncoding=utf-8&useSSL=false";
|
||||||
break;
|
break;
|
||||||
|
case "postgresql":
|
||||||
|
url = "jdbc:postgresql://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
|
||||||
|
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Not support database platform: " + jdbcProtocol.getPlatform());
|
throw new IllegalArgumentException("Not support database platform: " + jdbcProtocol.getPlatform());
|
||||||
|
|
||||||
|
|||||||
@@ -14,4 +14,9 @@ public interface CollectorConstants {
|
|||||||
String ERROR_MSG = "errorMsg";
|
String ERROR_MSG = "errorMsg";
|
||||||
|
|
||||||
String URL = "url";
|
String URL = "url";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POSTGRESQL状态码 不可达
|
||||||
|
*/
|
||||||
|
String POSTGRESQL_UN_REACHABLE_CODE = "08001";
|
||||||
}
|
}
|
||||||
|
|||||||
121
manager/src/main/resources/define/app/postgresql.yml
Normal file
121
manager/src/main/resources/define/app/postgresql.yml
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
category: db
|
||||||
|
app: postgresql
|
||||||
|
name:
|
||||||
|
zh-CN: PostgreSQL数据库
|
||||||
|
en-US: PostgreSQL DB
|
||||||
|
# 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串
|
||||||
|
# 强制固定必须参数 - host
|
||||||
|
configmap:
|
||||||
|
- key: host
|
||||||
|
type: 1
|
||||||
|
- key: port
|
||||||
|
type: 0
|
||||||
|
- key: username
|
||||||
|
type: 1
|
||||||
|
- key: password
|
||||||
|
type: 2
|
||||||
|
- key: database
|
||||||
|
type: 1
|
||||||
|
- key: url
|
||||||
|
type: 1
|
||||||
|
# 指标组列表
|
||||||
|
metrics:
|
||||||
|
- name: basic
|
||||||
|
# 指标组调度优先级(0-127)越小优先级越高,优先级低的指标组会等优先级高的指标组采集完成后才会被调度,相同优先级的指标组会并行调度采集
|
||||||
|
# 优先级为0的指标组为可用性指标组,即它会被首先调度,采集成功才会继续调度其它指标组,采集失败则中断调度
|
||||||
|
priority: 0
|
||||||
|
# 指标组中的具体监控指标
|
||||||
|
fields:
|
||||||
|
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
||||||
|
- field: server_version
|
||||||
|
type: 1
|
||||||
|
instance: true
|
||||||
|
- field: port
|
||||||
|
type: 1
|
||||||
|
- field: server_encoding
|
||||||
|
type: 1
|
||||||
|
- field: data_directory
|
||||||
|
type: 1
|
||||||
|
- field: max_connections
|
||||||
|
type: 0
|
||||||
|
unit: 连接数
|
||||||
|
protocol: jdbc
|
||||||
|
jdbc:
|
||||||
|
# 主机host: ipv4 ipv6 域名
|
||||||
|
host: ^_^host^_^
|
||||||
|
# 端口
|
||||||
|
port: ^_^port^_^
|
||||||
|
platform: postgresql
|
||||||
|
username: ^_^username^_^
|
||||||
|
password: ^_^password^_^
|
||||||
|
database: ^_^database^_^
|
||||||
|
# SQL查询方式: oneRow, multiRow, columns
|
||||||
|
queryType: columns
|
||||||
|
# sql
|
||||||
|
sql: select name, setting as value from pg_settings where name = 'max_connections' or name = 'server_version' or name = 'server_encoding' or name = 'port' or name = 'data_directory';
|
||||||
|
url: ^_^url^_^
|
||||||
|
|
||||||
|
- name: state
|
||||||
|
priority: 1
|
||||||
|
fields:
|
||||||
|
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
||||||
|
- field: name
|
||||||
|
type: 1
|
||||||
|
- field: conflicts
|
||||||
|
type: 0
|
||||||
|
unit: 次数
|
||||||
|
- field: deadlocks
|
||||||
|
type: 0
|
||||||
|
unit: 个数
|
||||||
|
- field: blks_read
|
||||||
|
type: 0
|
||||||
|
unit: 次数
|
||||||
|
- field: blks_hit
|
||||||
|
type: 0
|
||||||
|
unit: 次数
|
||||||
|
- field: blk_read_time
|
||||||
|
type: 0
|
||||||
|
unit: ms
|
||||||
|
- field: blk_write_time
|
||||||
|
type: 0
|
||||||
|
unit: ms
|
||||||
|
- field: stats_reset
|
||||||
|
type: 1
|
||||||
|
protocol: jdbc
|
||||||
|
jdbc:
|
||||||
|
# 主机host: ipv4 ipv6 域名
|
||||||
|
host: ^_^host^_^
|
||||||
|
# 端口
|
||||||
|
port: ^_^port^_^
|
||||||
|
platform: postgresql
|
||||||
|
username: ^_^username^_^
|
||||||
|
password: ^_^password^_^
|
||||||
|
database: ^_^database^_^
|
||||||
|
# SQL查询方式: oneRow, multiRow, columns
|
||||||
|
queryType: multiRow
|
||||||
|
# sql
|
||||||
|
sql: SELECT COALESCE(datname,'shared-object') as name, conflicts, deadlocks, blks_read, blks_hit, blk_read_time, blk_write_time, stats_reset from pg_stat_database where (datname != 'template1' and datname != 'template0') or datname is null;
|
||||||
|
url: ^_^url^_^
|
||||||
|
|
||||||
|
- name: activity
|
||||||
|
priority: 2
|
||||||
|
fields:
|
||||||
|
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
||||||
|
- field: running
|
||||||
|
type: 0
|
||||||
|
unit: 连接数
|
||||||
|
protocol: jdbc
|
||||||
|
jdbc:
|
||||||
|
# 主机host: ipv4 ipv6 域名
|
||||||
|
host: ^_^host^_^
|
||||||
|
# 端口
|
||||||
|
port: ^_^port^_^
|
||||||
|
platform: postgresql
|
||||||
|
username: ^_^username^_^
|
||||||
|
password: ^_^password^_^
|
||||||
|
database: ^_^database^_^
|
||||||
|
# SQL查询方式: oneRow, multiRow, columns
|
||||||
|
queryType: oneRow
|
||||||
|
# sql
|
||||||
|
sql: SELECT count(*) as running FROM pg_stat_activity WHERE NOT pid=pg_backend_pid();
|
||||||
|
url: ^_^url^_^
|
||||||
30
manager/src/main/resources/define/param/postgresql.yml
Normal file
30
manager/src/main/resources/define/param/postgresql.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
app: postgresql
|
||||||
|
param:
|
||||||
|
- field: host
|
||||||
|
name: 主机Host
|
||||||
|
type: host
|
||||||
|
required: true
|
||||||
|
- field: port
|
||||||
|
name: 端口
|
||||||
|
type: number
|
||||||
|
range: '[0,65535]'
|
||||||
|
required: true
|
||||||
|
defaultValue: 5432
|
||||||
|
placeholder: '请输入端口'
|
||||||
|
- field: database
|
||||||
|
name: 数据库名称
|
||||||
|
type: text
|
||||||
|
required: false
|
||||||
|
- field: username
|
||||||
|
name: 用户名
|
||||||
|
type: text
|
||||||
|
limit: 20
|
||||||
|
required: false
|
||||||
|
- field: password
|
||||||
|
name: 密码
|
||||||
|
type: password
|
||||||
|
required: false
|
||||||
|
- field: url
|
||||||
|
name: URL
|
||||||
|
type: text
|
||||||
|
required: false
|
||||||
@@ -127,7 +127,14 @@
|
|||||||
<nz-form-item>
|
<nz-form-item>
|
||||||
<nz-form-label [nzSpan]="7" nzFor="target" nzRequired="true">指标对象</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 required name="target" id="target" [nzOptions]="appHierarchies" [(ngModel)]="cascadeValues"></nz-cascader>
|
<nz-cascader
|
||||||
|
required
|
||||||
|
name="target"
|
||||||
|
id="target"
|
||||||
|
[nzOptions]="appHierarchies"
|
||||||
|
[(ngModel)]="cascadeValues"
|
||||||
|
(ngModelChange)="cascadeOnChange($event)"
|
||||||
|
></nz-cascader>
|
||||||
</nz-form-control>
|
</nz-form-control>
|
||||||
</nz-form-item>
|
</nz-form-item>
|
||||||
<nz-form-item>
|
<nz-form-item>
|
||||||
@@ -138,8 +145,11 @@
|
|||||||
<nz-list-item *ngIf="cascadeValues.length == 3">
|
<nz-list-item *ngIf="cascadeValues.length == 3">
|
||||||
<code>{{ cascadeValues[2] }} : 选中的指标对象</code>
|
<code>{{ cascadeValues[2] }} : 选中的指标对象</code>
|
||||||
</nz-list-item>
|
</nz-list-item>
|
||||||
<nz-list-item>
|
<nz-list-item *ngFor="let item of otherMetrics">
|
||||||
<code>instance : 所属行实例值</code>
|
<code>{{ item }} : 所属行其它指标对象</code>
|
||||||
|
</nz-list-item>
|
||||||
|
<nz-list-item *ngIf="otherMetrics.length != 0">
|
||||||
|
<code>instance : 所属行实例</code>
|
||||||
</nz-list-item>
|
</nz-list-item>
|
||||||
<nz-list-item>
|
<nz-list-item>
|
||||||
<code>支持操作符函数 : equals(str1,str2), ==, <, <=, >, >=, !=, ( ), +, -, &&, ||</code>
|
<code>支持操作符函数 : equals(str1,str2), ==, <, <=, >, >=, !=, ( ), +, -, &&, ||</code>
|
||||||
@@ -167,7 +177,7 @@
|
|||||||
nz-input
|
nz-input
|
||||||
name="expr"
|
name="expr"
|
||||||
id="expr"
|
id="expr"
|
||||||
placeholder='根据此表达式计算判断是否触发阈值. 示例: equals(instance,"cpu1") && usage>40'
|
placeholder="根据此表达式计算判断是否触发阈值. 示例: responseTime>40"
|
||||||
>
|
>
|
||||||
</textarea>
|
</textarea>
|
||||||
</nz-textarea-count>
|
</nz-textarea-count>
|
||||||
@@ -204,20 +214,23 @@
|
|||||||
<nz-collapse>
|
<nz-collapse>
|
||||||
<nz-collapse-panel [nzActive]="isManageModalAdd" nzHeader="支持的通知模版环境变量">
|
<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>
|
||||||
<code>${metric} : 选中的指标对象名称</code>
|
<code>${app} : 监控类型名称</code>
|
||||||
|
</nz-list-item>
|
||||||
|
<nz-list-item>
|
||||||
|
<code>${metrics} : 监控指标集合名称</code>
|
||||||
</nz-list-item>
|
</nz-list-item>
|
||||||
<nz-list-item *ngIf="cascadeValues.length == 3">
|
<nz-list-item *ngIf="cascadeValues.length == 3">
|
||||||
<code>${{ '{' + cascadeValues[2] + '}' }} : 选中的指标对象值</code>
|
<code>${metric} : 监控指标名称</code>
|
||||||
|
</nz-list-item>
|
||||||
|
<nz-list-item *ngIf="cascadeValues.length == 3">
|
||||||
|
<code>${{ '{' + cascadeValues[2] + '}' }} : 监控指标对象值</code>
|
||||||
|
</nz-list-item>
|
||||||
|
<nz-list-item *ngFor="let item of otherMetrics">
|
||||||
|
<code>${{ '{' + item + '}' }} : 所属行其它指标值</code>
|
||||||
</nz-list-item>
|
</nz-list-item>
|
||||||
<nz-list-item>
|
<nz-list-item>
|
||||||
<code>${instance} : 所在行实例值</code>
|
<code>${instance} : 所属行实例值</code>
|
||||||
</nz-list-item>
|
|
||||||
<nz-list-item>
|
|
||||||
<code>${app} : 所属监控类型名称</code>
|
|
||||||
</nz-list-item>
|
|
||||||
<nz-list-item>
|
|
||||||
<code>${metrics} : 所属监控指标组名称</code>
|
|
||||||
</nz-list-item>
|
</nz-list-item>
|
||||||
</nz-list>
|
</nz-list>
|
||||||
</nz-collapse-panel>
|
</nz-collapse-panel>
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ export class AlertSettingComponent implements OnInit {
|
|||||||
if (message.code === 0) {
|
if (message.code === 0) {
|
||||||
this.define = message.data;
|
this.define = message.data;
|
||||||
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);
|
||||||
} else {
|
} else {
|
||||||
this.notifySvc.error('查询此监控定义详情失败!', message.msg);
|
this.notifySvc.error('查询此监控定义详情失败!', message.msg);
|
||||||
}
|
}
|
||||||
@@ -234,6 +235,26 @@ export class AlertSettingComponent implements OnInit {
|
|||||||
isManageModalAdd = true;
|
isManageModalAdd = true;
|
||||||
define!: AlertDefine;
|
define!: AlertDefine;
|
||||||
cascadeValues: string[] = [];
|
cascadeValues: string[] = [];
|
||||||
|
otherMetrics: string[] = [];
|
||||||
|
cascadeOnChange(values: string[]): void {
|
||||||
|
if (values == null || values.length != 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.appHierarchies.forEach(hierarchy => {
|
||||||
|
if (hierarchy.value == values[0]) {
|
||||||
|
hierarchy.children.forEach((metrics: { value: string; children: any[]}) => {
|
||||||
|
if (metrics.value == values[1]) {
|
||||||
|
this.otherMetrics = [];
|
||||||
|
metrics.children.forEach(item => {
|
||||||
|
if (item.value != values[2]) {
|
||||||
|
this.otherMetrics.push(item.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
onManageModalCancel() {
|
onManageModalCancel() {
|
||||||
this.isManageModalVisible = false;
|
this.isManageModalVisible = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
|
|||||||
};
|
};
|
||||||
this.alertsTheme = {
|
this.alertsTheme = {
|
||||||
title: {
|
title: {
|
||||||
subtext: '告警等级分布',
|
subtext: '告警分布',
|
||||||
left: 'center'
|
left: 'center'
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
|||||||
Reference in New Issue
Block a user