mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 18:19:02 +00:00
Compare commits
138
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f991f13ac | ||
|
|
3fe6db1723 | ||
|
|
b46d049158 | ||
|
|
4a8d664c93 | ||
|
|
dc52c88d88 | ||
|
|
df4e947c8a | ||
|
|
a4ec6c1f66 | ||
|
|
a8dd57d009 | ||
|
|
af3eabdd1c | ||
|
|
d6b300d3df | ||
|
|
b5789538e6 | ||
|
|
d6c5b2b8a2 | ||
|
|
3a04647c3c | ||
|
|
d2999c1aa6 | ||
|
|
b3dbc7092a | ||
|
|
edb3cb6b6a | ||
|
|
4dd78b2e98 | ||
|
|
2f91f56b7b | ||
|
|
be3dac488b | ||
|
|
553bdbaf9f | ||
|
|
40d3f1243b | ||
|
|
740e3f8385 | ||
|
|
47d089dff7 | ||
|
|
c6f1f07155 | ||
|
|
0ebd3499b7 | ||
|
|
c88d4a7b0e | ||
|
|
8bebae9db6 | ||
|
|
b6b1a48a5c | ||
|
|
63ed50ef45 | ||
|
|
e63715d1b0 | ||
|
|
edf3eac6d6 | ||
|
|
743f285c8d | ||
|
|
458433464c | ||
|
|
64740a4f85 | ||
|
|
b5a2bce261 | ||
|
|
5e351c854b | ||
|
|
0875bea046 | ||
|
|
9ad5f77816 | ||
|
|
998f9059bc | ||
|
|
a1439c3ec2 | ||
|
|
742b6f6755 | ||
|
|
5fdb34598c | ||
|
|
4f982d1ab0 | ||
|
|
4a28056d9f | ||
|
|
3f2fa71e22 | ||
|
|
08c81bf62f | ||
|
|
e16d6cb4ba | ||
|
|
a54d14e803 | ||
|
|
01ae281769 | ||
|
|
9cb10ff14d | ||
|
|
62f40d3ad1 | ||
|
|
57601ef989 | ||
|
|
0a05edbec5 | ||
|
|
fcef24fdbf | ||
|
|
1f1aafc70e | ||
|
|
e45c31abfb | ||
|
|
198c190ca7 | ||
|
|
392a59f9a9 | ||
|
|
c01b7f7bce | ||
|
|
0323b044b8 | ||
|
|
256302fdcf | ||
|
|
3f3330af41 | ||
|
|
33342baa3f | ||
|
|
563cbd7943 | ||
|
|
ddb1601290 | ||
|
|
8e9d3c09f3 | ||
|
|
ade04d2cf2 | ||
|
|
53555c88c7 | ||
|
|
03bf31269d | ||
|
|
ea5b678af5 | ||
|
|
5c329a8a66 | ||
|
|
dda9250243 | ||
|
|
65a97aed8f | ||
|
|
56528f4fc0 | ||
|
|
f218ba018a | ||
|
|
d6ce0c153a | ||
|
|
a1b23cacdc | ||
|
|
ed6214d0c1 | ||
|
|
9a3fc5911d | ||
|
|
d5d01459e7 | ||
|
|
d077c72211 | ||
|
|
11e3e4cc22 | ||
|
|
c24c6ab7aa | ||
|
|
a183176e83 | ||
|
|
a2e8739fec | ||
|
|
ebb6e3d4ff | ||
|
|
fc3f26368d | ||
|
|
fa24e5000f | ||
|
|
f242ead7a9 | ||
|
|
5402437eac | ||
|
|
ce61c7d456 | ||
|
|
320766a48e | ||
|
|
efb2ac02df | ||
|
|
06c939c810 | ||
|
|
e56823b240 | ||
|
|
3b18d1ddaf | ||
|
|
d44fe43eb0 | ||
|
|
a221ddfba2 | ||
|
|
8e31a3147b | ||
|
|
d2f9a56fe7 | ||
|
|
a0b41dc7bb | ||
|
|
3f572a1ddc | ||
|
|
767deccee5 | ||
|
|
9221e2f6c1 | ||
|
|
0a36b3df90 | ||
|
|
f3202133d8 | ||
|
|
6ee458c521 | ||
|
|
cbc1caf4ac | ||
|
|
86db630fc7 | ||
|
|
145c4d1d5e | ||
|
|
0217cbb7f9 | ||
|
|
9f5df95f29 | ||
|
|
0f955019bf | ||
|
|
129b6282d3 | ||
|
|
36c5d8f518 | ||
|
|
de8a473e24 | ||
|
|
ffc4641dc9 | ||
|
|
d0cb9f8bf3 | ||
|
|
0d4ff33f19 | ||
|
|
86f40e5e15 | ||
|
|
dbbbc045d4 | ||
|
|
b0fdd5e11d | ||
|
|
9c5ea20b15 | ||
|
|
7a74f80906 | ||
|
|
ee32a890eb | ||
|
|
ec1c04194b | ||
|
|
55d8dfdede | ||
|
|
918073dca7 | ||
|
|
2defaecd93 | ||
|
|
641ba47f4c | ||
|
|
ccbc2151ae | ||
|
|
1cb919a301 | ||
|
|
7351a03c81 | ||
|
|
26c3a802d1 | ||
|
|
47dbe2fd2a | ||
|
|
f4943e9d89 | ||
|
|
1f6614d1a1 | ||
|
|
4a96c02b9a |
@@ -52,6 +52,9 @@ github:
|
||||
required_pull_request_reviews:
|
||||
dismiss_stale_reviews: true
|
||||
required_approving_review_count: 1
|
||||
# enable GitHub Dependabot to create PRs for security alerts but not for every dependency update
|
||||
dependabot_alerts: true
|
||||
dependabot_updates: false
|
||||
notifications:
|
||||
commits: notifications@hertzbeat.apache.org
|
||||
issues: notifications@hertzbeat.apache.org
|
||||
|
||||
@@ -46,7 +46,16 @@ jobs:
|
||||
- uses: ./script/ci/github-actions/setup-deps
|
||||
|
||||
- name: Build with Maven
|
||||
run: mvn clean -B package -Prelease -Dmaven.test.skip=false --file pom.xml
|
||||
run: mvnd clean -B package -Prelease -Dmaven.test.skip=false --file pom.xml
|
||||
|
||||
- name: Upload test reports
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-reports-${{ github.run_id }}
|
||||
path: |
|
||||
**/target/surefire-reports
|
||||
**/target/failsafe-reports
|
||||
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@v4.0.1
|
||||
|
||||
@@ -49,11 +49,9 @@ jobs:
|
||||
- name: Dead Link Check
|
||||
run: |
|
||||
sudo npm install -g markdown-link-check@3.8.7
|
||||
for file in $(find ./home -name "*.md"); do
|
||||
if ! grep -Fxq "$file" ./script/ci/exclude_files.txt; then
|
||||
markdown-link-check -c ./script/ci/link_check.json -q "$file"
|
||||
fi
|
||||
done
|
||||
find ./home -name "*.md" > all_md_files.txt
|
||||
grep -vFf ./script/ci/exclude_files.txt all_md_files.txt > to_check.txt
|
||||
xargs -P 8 -a to_check.txt -I{} markdown-link-check -c ./script/ci/link_check.json -q "{}"
|
||||
|
||||
- name: NPM INSTALL
|
||||
working-directory: home
|
||||
|
||||
+4
-4
@@ -33,11 +33,11 @@
|
||||
### 特点
|
||||
|
||||
- 集 **监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web 服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
|
||||
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
|
||||
- 将 `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模板 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s` 或 `Docker` 等新的监控类型吗?
|
||||
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,无需学习成本。
|
||||
- 将 `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模板 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需简单配置即可快速适配一款 `K8s` 或 `Docker` 等新的监控类型吗?
|
||||
- 兼容 `Prometheus` 的系统生态并且更多,只需页面操作就可以监控 `Prometheus` 所能监控的。
|
||||
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
|
||||
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
|
||||
- 灵活的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
|
||||
- 提供强大的状态页构建能力,轻松向用户传达您产品服务的实时状态。
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
|
||||
- `-e IDENTITY=custom-collector-name` : 配置此采集器的唯一性标识符名称,多个采集器名称不能相同,建议自定义英文名称。
|
||||
- `-e MODE=public` : 配置运行模式(public or private), 公共集群模式或私有云边模式。
|
||||
- `-e MANAGER_HOST=127.0.0.1` : 配置连接主 HertaBeat 服务的对外 IP。
|
||||
- `-e MANAGER_HOST=127.0.0.1` : 配置连接主 HertzBeat 服务的对外 IP。
|
||||
- `-e MANAGER_PORT=1158` : 配置连接主 HertzBeat 服务的对外端口,默认1158。
|
||||
|
||||
|
||||
|
||||
+49
-18
@@ -17,6 +17,9 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.calculate;
|
||||
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.common.collect.Tables;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.alert.dao.SingleAlertDao;
|
||||
import org.apache.hertzbeat.alert.util.AlertUtil;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
@@ -24,7 +27,6 @@ import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@@ -33,49 +35,78 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
@Component
|
||||
public class AlarmCacheManager {
|
||||
|
||||
private static final String CUSTOM_FIRING_ROW_KEY = "CUSTOM_FIRING_";
|
||||
|
||||
/**
|
||||
* The alarm in the process is triggered
|
||||
* key - labels fingerprint
|
||||
* rowKey - define id
|
||||
* columnKey - labels fingerprint
|
||||
*/
|
||||
private final Map<String, SingleAlert> pendingAlertMap;
|
||||
private final Table<String, String, SingleAlert> pendingAlertMap;
|
||||
|
||||
/**
|
||||
* The not recover alert
|
||||
* key - labels fingerprint
|
||||
* rowKey - define id
|
||||
* columnKey - labels fingerprint
|
||||
*/
|
||||
private final Map<String, SingleAlert> firingAlertMap;
|
||||
private final Table<String, String, SingleAlert> firingAlertMap;
|
||||
|
||||
public AlarmCacheManager(SingleAlertDao singleAlertDao) {
|
||||
this.pendingAlertMap = new ConcurrentHashMap<>(8);
|
||||
this.firingAlertMap = new ConcurrentHashMap<>(8);
|
||||
this.pendingAlertMap = Tables.newCustomTable(new ConcurrentHashMap<>(8), ConcurrentHashMap::new);
|
||||
this.firingAlertMap = Tables.newCustomTable(new ConcurrentHashMap<>(8), ConcurrentHashMap::new);
|
||||
List<SingleAlert> singleAlerts = singleAlertDao.querySingleAlertsByStatus(CommonConstants.ALERT_STATUS_FIRING);
|
||||
for (SingleAlert singleAlert : singleAlerts) {
|
||||
String fingerprint = AlertUtil.calculateFingerprint(singleAlert.getLabels());
|
||||
String defineId = singleAlert.getLabels().get(CommonConstants.LABEL_DEFINE_ID);
|
||||
if (StringUtils.isBlank(defineId)) {
|
||||
defineId = getCustomKey(fingerprint);
|
||||
}
|
||||
singleAlert.setId(null);
|
||||
this.firingAlertMap.put(fingerprint, singleAlert);
|
||||
this.firingAlertMap.put(defineId, fingerprint, singleAlert);
|
||||
}
|
||||
}
|
||||
|
||||
public void putPending(String fingerPrint, SingleAlert alert) {
|
||||
this.pendingAlertMap.put(fingerPrint, alert);
|
||||
public void putPending(Long defineId, String fingerPrint, SingleAlert alert) {
|
||||
this.pendingAlertMap.put(String.valueOf(defineId), fingerPrint, alert);
|
||||
}
|
||||
|
||||
public SingleAlert getPending(String fingerPrint) {
|
||||
return this.pendingAlertMap.get(fingerPrint);
|
||||
public SingleAlert getPending(Long defineId, String fingerPrint) {
|
||||
return this.pendingAlertMap.get(String.valueOf(defineId), fingerPrint);
|
||||
}
|
||||
|
||||
public SingleAlert removePending(String fingerPrint) {
|
||||
return this.pendingAlertMap.remove(fingerPrint);
|
||||
public void removePending(Long defineId, String fingerPrint) {
|
||||
this.pendingAlertMap.remove(String.valueOf(defineId), fingerPrint);
|
||||
}
|
||||
|
||||
public void putFiring(Long defineId, String fingerPrint, SingleAlert alert) {
|
||||
this.firingAlertMap.put(String.valueOf(defineId), fingerPrint, alert);
|
||||
}
|
||||
|
||||
public void putFiring(String fingerPrint, SingleAlert alert) {
|
||||
this.firingAlertMap.put(fingerPrint, alert);
|
||||
this.firingAlertMap.put(getCustomKey(fingerPrint), fingerPrint, alert);
|
||||
}
|
||||
|
||||
public SingleAlert getFiring(Long defineId, String fingerPrint) {
|
||||
SingleAlert singleAlert = this.firingAlertMap.get(String.valueOf(defineId), fingerPrint);
|
||||
if (null != singleAlert) {
|
||||
return singleAlert;
|
||||
}
|
||||
return getFiring(fingerPrint);
|
||||
}
|
||||
|
||||
public SingleAlert removeFiring(Long defineId, String fingerPrint) {
|
||||
SingleAlert singleAlert = this.firingAlertMap.remove(String.valueOf(defineId), fingerPrint);
|
||||
if (null == singleAlert) {
|
||||
return this.firingAlertMap.remove(getCustomKey(fingerPrint), fingerPrint);
|
||||
}
|
||||
return singleAlert;
|
||||
}
|
||||
|
||||
public SingleAlert getFiring(String fingerPrint) {
|
||||
return this.firingAlertMap.get(fingerPrint);
|
||||
return this.firingAlertMap.get(getCustomKey(fingerPrint), fingerPrint);
|
||||
}
|
||||
|
||||
public SingleAlert removeFiring(String fingerPrint) {
|
||||
return this.firingAlertMap.remove(fingerPrint);
|
||||
private String getCustomKey(String fingerPrint) {
|
||||
return CUSTOM_FIRING_ROW_KEY + fingerPrint;
|
||||
}
|
||||
}
|
||||
|
||||
+27
-24
@@ -17,8 +17,9 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.calculate;
|
||||
|
||||
import java.util.HashMap;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce;
|
||||
import org.apache.hertzbeat.alert.service.DataSourceService;
|
||||
import org.apache.hertzbeat.alert.util.AlertTemplateUtil;
|
||||
@@ -26,11 +27,11 @@ import org.apache.hertzbeat.alert.util.AlertUtil;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Periodic Alert Calculator
|
||||
@@ -54,9 +55,9 @@ public class PeriodicAlertCalculator {
|
||||
this.alarmCacheManager = alarmCacheManager;
|
||||
}
|
||||
|
||||
public void calculate(AlertDefine rule) {
|
||||
if (!rule.isEnable() || StringUtils.isEmpty(rule.getExpr())) {
|
||||
log.error("Periodic rule {} is disabled or expression is empty", rule.getName());
|
||||
public void calculate(AlertDefine define) {
|
||||
if (!define.isEnable() || StringUtils.isEmpty(define.getExpr())) {
|
||||
log.error("Periodic define {} is disabled or expression is empty", define.getName());
|
||||
return;
|
||||
}
|
||||
long currentTimeMilli = System.currentTimeMillis();
|
||||
@@ -66,8 +67,8 @@ public class PeriodicAlertCalculator {
|
||||
// the return result should be matched with threshold
|
||||
try {
|
||||
List<Map<String, Object>> results = dataSourceService.calculate(
|
||||
rule.getDatasource(),
|
||||
rule.getExpr()
|
||||
define.getDatasource(),
|
||||
define.getExpr()
|
||||
);
|
||||
// if no match the expr threshold, the results item map {'value': null} should be null and others field keep
|
||||
// if results has multi list, should trigger multi alert
|
||||
@@ -77,8 +78,9 @@ public class PeriodicAlertCalculator {
|
||||
for (Map<String, Object> result : results) {
|
||||
Map<String, String> fingerPrints = new HashMap<>(8);
|
||||
// here use the alert name as finger, not care the alert name may be changed
|
||||
fingerPrints.put(CommonConstants.LABEL_ALERT_NAME, rule.getName());
|
||||
fingerPrints.putAll(rule.getLabels());
|
||||
fingerPrints.put(CommonConstants.LABEL_DEFINE_ID, String.valueOf(define.getId()));
|
||||
fingerPrints.put(CommonConstants.LABEL_ALERT_NAME, define.getName());
|
||||
fingerPrints.putAll(define.getLabels());
|
||||
for (Map.Entry<String, Object> entry : result.entrySet()) {
|
||||
if (entry.getValue() != null && !VALUE.equals(entry.getKey())
|
||||
&& !TIMESTAMP.equals(entry.getKey())) {
|
||||
@@ -87,32 +89,33 @@ public class PeriodicAlertCalculator {
|
||||
}
|
||||
if (result.get(VALUE) == null) {
|
||||
// recovery the alert
|
||||
handleRecoveredAlert(fingerPrints);
|
||||
handleRecoveredAlert(define.getId(), fingerPrints);
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> fieldValueMap = new HashMap<>(8);
|
||||
fieldValueMap.putAll(rule.getLabels());
|
||||
fieldValueMap.put(CommonConstants.LABEL_ALERT_NAME, rule.getName());
|
||||
fieldValueMap.putAll(define.getLabels());
|
||||
fieldValueMap.put(CommonConstants.LABEL_ALERT_NAME, define.getName());
|
||||
for (Map.Entry<String, Object> entry : result.entrySet()) {
|
||||
if (entry.getValue() != null) {
|
||||
fieldValueMap.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
afterThresholdRuleMatch(currentTimeMilli, fingerPrints, fieldValueMap, rule);
|
||||
afterThresholdRuleMatch(currentTimeMilli, fingerPrints, fieldValueMap, define);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// ignore the query exception eg: no result, timeout, etc
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Calculate periodic rule {} failed: {}", rule.getName(), e.getMessage());
|
||||
log.error("Calculate periodic define {} failed: {}", define.getName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void afterThresholdRuleMatch(long currentTimeMilli, Map<String, String> fingerPrints,
|
||||
Map<String, Object> fieldValueMap, AlertDefine define) {
|
||||
Long defineId = define.getId();
|
||||
String fingerprint = AlertUtil.calculateFingerprint(fingerPrints);
|
||||
SingleAlert existingAlert = alarmCacheManager.getPending(fingerprint);
|
||||
SingleAlert existingAlert = alarmCacheManager.getPending(defineId, fingerprint);
|
||||
Map<String, String> labels = new HashMap<>(8);
|
||||
fieldValueMap.putAll(define.getLabels());
|
||||
labels.putAll(fingerPrints);
|
||||
@@ -133,11 +136,11 @@ public class PeriodicAlertCalculator {
|
||||
// If required trigger times is 1, set to firing status directly
|
||||
if (requiredTimes <= 1) {
|
||||
newAlert.setStatus(CommonConstants.ALERT_STATUS_FIRING);
|
||||
alarmCacheManager.putFiring(fingerprint, newAlert);
|
||||
alarmCacheManager.putFiring(defineId, fingerprint, newAlert);
|
||||
alarmCommonReduce.reduceAndSendAlarm(newAlert.clone());
|
||||
} else {
|
||||
// Otherwise put into pending queue first
|
||||
alarmCacheManager.putPending(fingerprint, newAlert);
|
||||
alarmCacheManager.putPending(defineId, fingerprint, newAlert);
|
||||
}
|
||||
} else {
|
||||
// Update existing alert
|
||||
@@ -147,17 +150,17 @@ public class PeriodicAlertCalculator {
|
||||
// Check if required trigger times reached
|
||||
if (existingAlert.getStatus().equals(CommonConstants.ALERT_STATUS_PENDING) && existingAlert.getTriggerTimes() >= requiredTimes) {
|
||||
// Reached trigger times threshold, change to firing status
|
||||
alarmCacheManager.removePending(fingerprint);
|
||||
alarmCacheManager.removePending(defineId, fingerprint);
|
||||
existingAlert.setStatus(CommonConstants.ALERT_STATUS_FIRING);
|
||||
alarmCacheManager.putFiring(fingerprint, existingAlert);
|
||||
alarmCacheManager.putFiring(defineId, fingerprint, existingAlert);
|
||||
alarmCommonReduce.reduceAndSendAlarm(existingAlert.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRecoveredAlert(Map<String, String> fingerprints) {
|
||||
private void handleRecoveredAlert(Long defineId, Map<String, String> fingerprints) {
|
||||
String fingerprint = AlertUtil.calculateFingerprint(fingerprints);
|
||||
SingleAlert firingAlert = alarmCacheManager.removeFiring(fingerprint);
|
||||
SingleAlert firingAlert = alarmCacheManager.removeFiring(defineId, fingerprint);
|
||||
if (firingAlert != null) {
|
||||
// todo consider multi times to tig for resolved alert
|
||||
firingAlert.setTriggerTimes(1);
|
||||
@@ -165,7 +168,7 @@ public class PeriodicAlertCalculator {
|
||||
firingAlert.setStatus(CommonConstants.ALERT_STATUS_RESOLVED);
|
||||
alarmCommonReduce.reduceAndSendAlarm(firingAlert.clone());
|
||||
}
|
||||
alarmCacheManager.removePending(fingerprint);
|
||||
alarmCacheManager.removePending(defineId, fingerprint);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+17
-14
@@ -183,9 +183,11 @@ public class RealTimeAlertCalculator {
|
||||
if (StringUtils.isBlank(expr)) {
|
||||
continue;
|
||||
}
|
||||
Long defineId = define.getId();
|
||||
Map<String, String> commonFingerPrints = new HashMap<>(8);
|
||||
commonFingerPrints.put(CommonConstants.LABEL_INSTANCE, instance);
|
||||
// here use the alert name as finger, not care the alert name may be changed
|
||||
commonFingerPrints.put(CommonConstants.LABEL_DEFINE_ID, String.valueOf(define.getId()));
|
||||
commonFingerPrints.put(CommonConstants.LABEL_ALERT_NAME, define.getName());
|
||||
commonFingerPrints.put(CommonConstants.LABEL_INSTANCE_NAME, instanceName);
|
||||
commonFingerPrints.put(CommonConstants.LABEL_INSTANCE_HOST, instanceHost);
|
||||
@@ -200,9 +202,9 @@ public class RealTimeAlertCalculator {
|
||||
try {
|
||||
if (match) {
|
||||
// If the threshold rule matches, the number of times the threshold has been triggered is determined and an alarm is triggered
|
||||
afterThresholdRuleMatch(currentTimeMilli, commonFingerPrints, fieldValueMap, define, annotations);
|
||||
afterThresholdRuleMatch(defineId, currentTimeMilli, commonFingerPrints, fieldValueMap, define, annotations);
|
||||
} else {
|
||||
handleRecoveredAlert(commonFingerPrints);
|
||||
handleRecoveredAlert(defineId, commonFingerPrints);
|
||||
}
|
||||
// if this threshold pre compile success, ignore blew
|
||||
continue;
|
||||
@@ -254,9 +256,9 @@ public class RealTimeAlertCalculator {
|
||||
boolean match = execAlertExpression(fieldValueMap, expr, false);
|
||||
try {
|
||||
if (match) {
|
||||
afterThresholdRuleMatch(currentTimeMilli, fingerPrints, fieldValueMap, define, annotations);
|
||||
afterThresholdRuleMatch(defineId, currentTimeMilli, fingerPrints, fieldValueMap, define, annotations);
|
||||
} else {
|
||||
handleRecoveredAlert(fingerPrints);
|
||||
handleRecoveredAlert(defineId, fingerPrints);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@@ -334,9 +336,9 @@ public class RealTimeAlertCalculator {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void handleRecoveredAlert(Map<String, String> fingerprints) {
|
||||
private void handleRecoveredAlert(Long defineId, Map<String, String> fingerprints) {
|
||||
String fingerprint = AlertUtil.calculateFingerprint(fingerprints);
|
||||
SingleAlert firingAlert = alarmCacheManager.removeFiring(fingerprint);
|
||||
SingleAlert firingAlert = alarmCacheManager.removeFiring(defineId, fingerprint);
|
||||
if (firingAlert != null) {
|
||||
// todo consider multi times to tig for resolved alert
|
||||
firingAlert.setTriggerTimes(1);
|
||||
@@ -344,13 +346,14 @@ public class RealTimeAlertCalculator {
|
||||
firingAlert.setStatus(CommonConstants.ALERT_STATUS_RESOLVED);
|
||||
alarmCommonReduce.reduceAndSendAlarm(firingAlert.clone());
|
||||
}
|
||||
alarmCacheManager.removePending(fingerprint);
|
||||
alarmCacheManager.removePending(defineId, fingerprint);
|
||||
}
|
||||
|
||||
private void afterThresholdRuleMatch(long currentTimeMilli, Map<String, String> fingerPrints,
|
||||
Map<String, Object> fieldValueMap, AlertDefine define, Map<String, String> annotations) {
|
||||
private void afterThresholdRuleMatch(long defineId, long currentTimeMilli, Map<String, String> fingerPrints,
|
||||
Map<String, Object> fieldValueMap, AlertDefine define,
|
||||
Map<String, String> annotations) {
|
||||
String fingerprint = AlertUtil.calculateFingerprint(fingerPrints);
|
||||
SingleAlert existingAlert = alarmCacheManager.getPending(fingerprint);
|
||||
SingleAlert existingAlert = alarmCacheManager.getPending(defineId, fingerprint);
|
||||
fieldValueMap.putAll(define.getLabels());
|
||||
int requiredTimes = define.getTimes() == null ? 1 : define.getTimes();
|
||||
if (existingAlert == null) {
|
||||
@@ -382,11 +385,11 @@ public class RealTimeAlertCalculator {
|
||||
// If required trigger times is 1, set to firing status directly
|
||||
if (requiredTimes <= 1) {
|
||||
newAlert.setStatus(CommonConstants.ALERT_STATUS_FIRING);
|
||||
alarmCacheManager.putFiring(fingerprint, newAlert);
|
||||
alarmCacheManager.putFiring(defineId, fingerprint, newAlert);
|
||||
alarmCommonReduce.reduceAndSendAlarm(newAlert.clone());
|
||||
} else {
|
||||
// Otherwise put into pending queue first
|
||||
alarmCacheManager.putPending(fingerprint, newAlert);
|
||||
alarmCacheManager.putPending(define.getId(), fingerprint, newAlert);
|
||||
}
|
||||
} else {
|
||||
// Update existing alert
|
||||
@@ -396,9 +399,9 @@ public class RealTimeAlertCalculator {
|
||||
// Check if required trigger times reached
|
||||
if (existingAlert.getStatus().equals(CommonConstants.ALERT_STATUS_PENDING) && existingAlert.getTriggerTimes() >= requiredTimes) {
|
||||
// Reached trigger times threshold, change to firing status
|
||||
alarmCacheManager.removePending(fingerprint);
|
||||
alarmCacheManager.removePending(defineId, fingerprint);
|
||||
existingAlert.setStatus(CommonConstants.ALERT_STATUS_FIRING);
|
||||
alarmCacheManager.putFiring(fingerprint, existingAlert);
|
||||
alarmCacheManager.putFiring(defineId, fingerprint, existingAlert);
|
||||
alarmCommonReduce.reduceAndSendAlarm(existingAlert.clone());
|
||||
}
|
||||
}
|
||||
|
||||
+25
-3
@@ -17,17 +17,16 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.controller;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.MONITOR_NOT_EXIST_CODE;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.Objects;
|
||||
import org.apache.hertzbeat.alert.service.AlertDefineService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
import org.apache.hertzbeat.common.support.exception.AlertExpressionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -36,8 +35,17 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.FAIL_CODE;
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.MONITOR_NOT_EXIST_CODE;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
|
||||
/**
|
||||
* Alarm definition management API
|
||||
*/
|
||||
@@ -90,4 +98,18 @@ public class AlertDefineController {
|
||||
return ResponseEntity.ok(Message.success("Delete success"));
|
||||
}
|
||||
|
||||
@GetMapping(path = "/preview/{datasource}")
|
||||
@Operation(summary = "Alarm definition expression preview",
|
||||
description = "If the expression is formal, then the result of the query will be returned, otherwise it will respond with an error")
|
||||
public ResponseEntity<Message<List<Map<String, Object>>>> getDefinePreview(
|
||||
@Parameter(description = "Data Source Type", example = "promql") @PathVariable("datasource") String datasource,
|
||||
@Parameter(description = "alert threshold type:realtime,periodic") @RequestParam String type,
|
||||
@Parameter(description = "alert threshold expression") @RequestParam String expr) {
|
||||
try {
|
||||
return ResponseEntity.ok(Message.successWithData(alertDefineService.getDefinePreview(datasource, type, expr)));
|
||||
} catch (AlertExpressionException ae) {
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Message.fail(FAIL_CODE, ae.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* volcengine event alert entity class
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class VolcEngineExternEventAlert {
|
||||
@JsonProperty("Type")
|
||||
private String type;
|
||||
|
||||
@JsonProperty("AccountId")
|
||||
private String accountId;
|
||||
|
||||
@JsonProperty("Source")
|
||||
private String source;
|
||||
|
||||
@JsonProperty("ProjectName")
|
||||
private String projectName;
|
||||
|
||||
@JsonProperty("Id")
|
||||
private String id;
|
||||
|
||||
@JsonProperty("EventType")
|
||||
private String eventType;
|
||||
|
||||
@JsonProperty("DescriptionCN")
|
||||
private String descriptionCn;
|
||||
|
||||
@JsonProperty("HappenedAt")
|
||||
private Long happenedAt;
|
||||
|
||||
@JsonProperty("Region")
|
||||
private String region;
|
||||
|
||||
@JsonProperty("Details")
|
||||
private EventDetails details;
|
||||
|
||||
@JsonProperty("Rules")
|
||||
private List<EventRule> rules;
|
||||
|
||||
/**
|
||||
* event details
|
||||
*/
|
||||
@Data
|
||||
public static class EventDetails {
|
||||
@JsonProperty("specversion")
|
||||
private String specVersion;
|
||||
|
||||
@JsonProperty("id")
|
||||
private String id;
|
||||
|
||||
@JsonProperty("source")
|
||||
private String source;
|
||||
|
||||
@JsonProperty("type")
|
||||
private String type;
|
||||
|
||||
@JsonProperty("volcpublishtime")
|
||||
private String volcPublishTime;
|
||||
|
||||
@JsonProperty("volcregion")
|
||||
private String volcRegion;
|
||||
|
||||
@JsonProperty("volcaccountid")
|
||||
private String volcAccountId;
|
||||
|
||||
@JsonProperty("volceventbusname")
|
||||
private String volcEventBusName;
|
||||
|
||||
@JsonProperty("volcresourcename")
|
||||
private String volcResourceName;
|
||||
|
||||
@JsonProperty("subject")
|
||||
private String subject;
|
||||
|
||||
@JsonProperty("time")
|
||||
private String time;
|
||||
}
|
||||
|
||||
/**
|
||||
* event rule
|
||||
*/
|
||||
@Data
|
||||
public static class EventRule {
|
||||
@JsonProperty("RuleId")
|
||||
private String ruleId;
|
||||
|
||||
@JsonProperty("RuleName")
|
||||
private String ruleName;
|
||||
|
||||
@JsonProperty("Level")
|
||||
private String level;
|
||||
}
|
||||
}
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Volcengine alarm entity class
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class VolcEngineExternMetricAlert {
|
||||
|
||||
@JsonProperty("Type")
|
||||
private String type;
|
||||
|
||||
@JsonProperty("AccountId")
|
||||
private String accountId;
|
||||
|
||||
@JsonProperty("RuleName")
|
||||
private String ruleName;
|
||||
|
||||
@JsonProperty("RuleId")
|
||||
private String ruleId;
|
||||
|
||||
@JsonProperty("Namespace")
|
||||
private String namespace;
|
||||
|
||||
@JsonProperty("SubNamespace")
|
||||
private String subNamespace;
|
||||
|
||||
@JsonProperty("Level")
|
||||
private String level;
|
||||
|
||||
@JsonProperty("HappenedAt")
|
||||
private String happenedAt;
|
||||
|
||||
@JsonProperty("RuleCondition")
|
||||
private String ruleCondition;
|
||||
|
||||
@JsonProperty("Resources")
|
||||
private List<Resource> resources;
|
||||
|
||||
@JsonProperty("RecoveredResources")
|
||||
private List<Resource> recoveredResources;
|
||||
|
||||
@JsonProperty("NoDataResources")
|
||||
private List<NoDataResource> noDataResources;
|
||||
|
||||
@JsonProperty("NoDataRecoveredResources")
|
||||
private List<NoDataRecoveredResource> noDataRecoveredResources;
|
||||
|
||||
/**
|
||||
* alert resource entity class
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public static class Resource {
|
||||
@JsonProperty("Id")
|
||||
private String id;
|
||||
|
||||
@JsonProperty("Name")
|
||||
private String name;
|
||||
|
||||
@JsonProperty("Region")
|
||||
private String region;
|
||||
|
||||
@JsonProperty("FirstAlertTime")
|
||||
private Long firstAlertTime;
|
||||
|
||||
@JsonProperty("LastAlertTime")
|
||||
private Long lastAlertTime;
|
||||
|
||||
@JsonProperty("Metrics")
|
||||
private List<Metric> metrics;
|
||||
|
||||
@JsonProperty("AlertGroupId")
|
||||
private String alertGroupId;
|
||||
|
||||
@JsonProperty("Dimensions")
|
||||
private List<Dimension> dimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* alert no data resource entity class
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class NoDataResource extends Resource {
|
||||
@JsonProperty("NoDataMetrics")
|
||||
private List<Metric> noDataMetrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* alert no data recovered resource entity class
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class NoDataRecoveredResource extends Resource {
|
||||
@JsonProperty("DroppedMetrics")
|
||||
private List<DroppedMetric> droppedMetrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* alert metric entity class
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Metric {
|
||||
@JsonProperty("Name")
|
||||
private String name;
|
||||
|
||||
@JsonProperty("Unit")
|
||||
private String unit;
|
||||
|
||||
@JsonProperty("Threshold")
|
||||
private Double threshold;
|
||||
|
||||
@JsonProperty("CurrentValue")
|
||||
private Object currentValue;
|
||||
|
||||
@JsonProperty("Description")
|
||||
private String description;
|
||||
|
||||
@JsonProperty("Warning")
|
||||
private Boolean warning;
|
||||
}
|
||||
|
||||
/**
|
||||
* alert dropped metric entity class
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class DroppedMetric extends Metric {
|
||||
@JsonProperty("Reason")
|
||||
private String reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* resource dimension entity class
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Dimension {
|
||||
@JsonProperty("Name")
|
||||
private String name;
|
||||
|
||||
@JsonProperty("NameCN")
|
||||
private String nameCn;
|
||||
|
||||
@JsonProperty("Value")
|
||||
private String value;
|
||||
|
||||
@JsonProperty("Description")
|
||||
private String description;
|
||||
}
|
||||
|
||||
|
||||
public static final String ALERT_TYPE_METRIC = "Metric";
|
||||
public static final String ALERT_TYPE_EVENT = "Event";
|
||||
public static final String ALERT_TYPE_METRIC_RECOVERED = "MetricRecovered";
|
||||
public static final String ALERT_TYPE_METRICS_NODATA = "MetricsNoData";
|
||||
public static final String ALERT_TYPE_NO_DATA_RECOVERED = "NoDataRecovered";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+70
-107
@@ -25,6 +25,8 @@ import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Alert expression visitor implement
|
||||
@@ -32,7 +34,9 @@ import java.util.Map;
|
||||
public class AlertExpressionEvalVisitor extends AlertExpressionBaseVisitor<List<Map<String, Object>>> {
|
||||
|
||||
private static final String THRESHOLD = "__threshold__";
|
||||
private static final String NAME = "__name__";
|
||||
private static final String VALUE = "__value__";
|
||||
private static final String TIMESTAMP = "__timestamp__";
|
||||
|
||||
private final QueryExecutor executor;
|
||||
private final CommonTokenStream tokens;
|
||||
@@ -84,42 +88,26 @@ public class AlertExpressionEvalVisitor extends AlertExpressionBaseVisitor<List<
|
||||
public List<Map<String, Object>> visitAndExpr(AlertExpressionParser.AndExprContext ctx) {
|
||||
List<Map<String, Object>> leftOperand = visit(ctx.left);
|
||||
List<Map<String, Object>> rightOperand = visit(ctx.right);
|
||||
List<Map<String, Object>> results = new ArrayList<>();
|
||||
|
||||
Map<String, Object> leftMap = null;
|
||||
boolean leftMatch = false;
|
||||
Map<String, Object> rightMap = null;
|
||||
boolean rightMatch = false;
|
||||
for (Map<String, Object> item : leftOperand) {
|
||||
if (leftMap == null) {
|
||||
leftMap = item;
|
||||
// build a hash set of the right-side tag collection
|
||||
Set<String> rightLabelsSet = rightOperand.stream()
|
||||
.filter(item -> item.get(VALUE) != null)
|
||||
.map(this::labelKey)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// iterate over the left side, O(1) match
|
||||
for (Map<String, Object> leftItem : leftOperand) {
|
||||
Object leftVal = leftItem.get(VALUE);
|
||||
if (leftVal == null) {
|
||||
continue;
|
||||
}
|
||||
if (item.get(VALUE) != null) {
|
||||
leftMap = item;
|
||||
leftMatch = true;
|
||||
break;
|
||||
String labelKey = labelKey(leftItem);
|
||||
if (rightLabelsSet.contains(labelKey)) {
|
||||
results.add(new HashMap<>(leftItem));
|
||||
}
|
||||
}
|
||||
for (Map<String, Object> item : rightOperand) {
|
||||
if (rightMap == null) {
|
||||
rightMap = item;
|
||||
}
|
||||
if (item.get(VALUE) != null) {
|
||||
rightMap = item;
|
||||
rightMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (leftMatch && rightMatch) {
|
||||
rightMap.putAll(leftMap);
|
||||
return new LinkedList<>(List.of(rightMap));
|
||||
} else if (leftMap != null) {
|
||||
leftMap.put(VALUE, null);
|
||||
return new LinkedList<>(List.of(leftMap));
|
||||
} else if (rightMap != null) {
|
||||
rightMap.put(VALUE, null);
|
||||
return new LinkedList<>(List.of(rightMap));
|
||||
}
|
||||
return new LinkedList<>();
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,92 +115,51 @@ public class AlertExpressionEvalVisitor extends AlertExpressionBaseVisitor<List<
|
||||
List<Map<String, Object>> leftOperand = visit(ctx.left);
|
||||
List<Map<String, Object>> rightOperand = visit(ctx.right);
|
||||
|
||||
Map<String, Object> leftMap = null;
|
||||
boolean leftMatch = false;
|
||||
Map<String, Object> rightMap = null;
|
||||
boolean rightMatch = false;
|
||||
for (Map<String, Object> item : leftOperand) {
|
||||
if (leftMap == null) {
|
||||
leftMap = item;
|
||||
// build a hashMap of the left-hand label collection
|
||||
Map<String, Map<String, Object>> leftLabelMap = leftOperand.stream()
|
||||
.filter(item -> item.get(VALUE) != null)
|
||||
.collect(Collectors.toMap(this::labelKey, HashMap::new, (k1, k2) -> k1));
|
||||
|
||||
// first add all the non-empty items on the left side
|
||||
List<Map<String, Object>> results = new ArrayList<>(leftLabelMap.values());
|
||||
|
||||
// add the term that has a value on the right side and not on the left side
|
||||
for (Map<String, Object> rightItem : rightOperand) {
|
||||
Object rightVal = rightItem.get(VALUE);
|
||||
if (rightVal == null) {
|
||||
continue;
|
||||
}
|
||||
if (item.get(VALUE) != null) {
|
||||
leftMap = item;
|
||||
leftMatch = true;
|
||||
break;
|
||||
String key = labelKey(rightItem);
|
||||
if (!leftLabelMap.containsKey(key)) {
|
||||
results.add(new HashMap<>(rightItem));
|
||||
}
|
||||
}
|
||||
for (Map<String, Object> item : rightOperand) {
|
||||
if (rightMap == null) {
|
||||
rightMap = item;
|
||||
}
|
||||
if (item.get(VALUE) != null) {
|
||||
rightMap = item;
|
||||
rightMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (leftMatch && rightMatch) {
|
||||
rightMap.putAll(leftMap);
|
||||
return new LinkedList<>(List.of(rightMap));
|
||||
} else if (leftMatch) {
|
||||
return new LinkedList<>(List.of(leftMap));
|
||||
} else if (rightMatch) {
|
||||
return new LinkedList<>(List.of(rightMap));
|
||||
} else {
|
||||
if (leftMap != null && rightMap != null) {
|
||||
rightMap.putAll(leftMap);
|
||||
return new LinkedList<>(List.of(rightMap));
|
||||
} else if (leftMap != null) {
|
||||
return new LinkedList<>(List.of(leftMap));
|
||||
} else if (rightMap != null) {
|
||||
return new LinkedList<>(List.of(rightMap));
|
||||
}
|
||||
}
|
||||
return new LinkedList<>();
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> visitUnlessExpr(AlertExpressionParser.UnlessExprContext ctx) {
|
||||
List<Map<String, Object>> leftOperand = visit(ctx.left);
|
||||
List<Map<String, Object>> rightOperand = visit(ctx.right);
|
||||
Map<String, Object> leftMap = null;
|
||||
boolean leftMatch = false;
|
||||
Map<String, Object> rightMap = null;
|
||||
boolean rightMatch = false;
|
||||
for (Map<String, Object> item : leftOperand) {
|
||||
if (leftMap == null) {
|
||||
leftMap = item;
|
||||
List<Map<String, Object>> results = new ArrayList<>();
|
||||
|
||||
// build a hash set of the right-side tag collection
|
||||
Set<String> rightLabelSet = rightOperand.stream()
|
||||
.filter(item -> item.get(VALUE) != null)
|
||||
.map(this::labelKey)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// iterate over the left side, O(1) match
|
||||
for (Map<String, Object> leftItem : leftOperand) {
|
||||
Object leftVal = leftItem.get(VALUE);
|
||||
if (leftVal == null) {
|
||||
continue;
|
||||
}
|
||||
if (item.get(VALUE) != null) {
|
||||
leftMap = item;
|
||||
leftMatch = true;
|
||||
break;
|
||||
if (!rightLabelSet.contains(labelKey(leftItem))) {
|
||||
results.add(new HashMap<>(leftItem));
|
||||
}
|
||||
}
|
||||
for (Map<String, Object> item : rightOperand) {
|
||||
if (rightMap == null) {
|
||||
rightMap = item;
|
||||
}
|
||||
if (item.get(VALUE) != null) {
|
||||
rightMap = item;
|
||||
rightMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (leftMatch && !rightMatch) {
|
||||
return new LinkedList<>(List.of(leftMap));
|
||||
} else {
|
||||
if (leftMap != null) {
|
||||
leftMap.put(VALUE, null);
|
||||
return new LinkedList<>(List.of(leftMap));
|
||||
} else {
|
||||
if (rightMap != null) {
|
||||
rightMap.put(VALUE, null);
|
||||
return new LinkedList<>(List.of(rightMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
return new LinkedList<>();
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -327,4 +274,20 @@ public class AlertExpressionEvalVisitor extends AlertExpressionBaseVisitor<List<
|
||||
String script = text.substring(1, text.length() - 1);
|
||||
return executor.execute(script);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tag key (excluding `__name__` and `__value__` and `__timestamp__`)
|
||||
*/
|
||||
private String labelKey(Map<String, Object> labelsMap) {
|
||||
if (null == labelsMap || labelsMap.isEmpty()) {
|
||||
return "-";
|
||||
}
|
||||
String key = labelsMap.entrySet().stream()
|
||||
.filter(e -> !e.getKey().equals(VALUE) && !e.getKey().equals(NAME) && !e.getKey().equals(TIMESTAMP))
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.map(e -> e.getKey() + "=" + (e.getValue() == null ? "" : e.getValue()))
|
||||
.collect(Collectors.joining(","));
|
||||
return key.isEmpty() ? "-" : key;
|
||||
}
|
||||
|
||||
}
|
||||
+257
-279
@@ -2177,11 +2177,8 @@ public class AlertExpressionParser extends Parser {
|
||||
return getRuleContext(AggregationOperatorContext.class,0);
|
||||
}
|
||||
public TerminalNode LPAREN() { return getToken(AlertExpressionParser.LPAREN, 0); }
|
||||
public List<PromqlContext> promql() {
|
||||
return getRuleContexts(PromqlContext.class);
|
||||
}
|
||||
public PromqlContext promql(int i) {
|
||||
return getRuleContext(PromqlContext.class,i);
|
||||
public PromqlContext promql() {
|
||||
return getRuleContext(PromqlContext.class,0);
|
||||
}
|
||||
public TerminalNode RPAREN() { return getToken(AlertExpressionParser.RPAREN, 0); }
|
||||
public TerminalNode BY() { return getToken(AlertExpressionParser.BY, 0); }
|
||||
@@ -2192,9 +2189,6 @@ public class AlertExpressionParser extends Parser {
|
||||
return getRuleContext(FunctionCallContext.class,0);
|
||||
}
|
||||
public TerminalNode IDENTIFIER() { return getToken(AlertExpressionParser.IDENTIFIER, 0); }
|
||||
public BinaryOperatorContext binaryOperator() {
|
||||
return getRuleContext(BinaryOperatorContext.class,0);
|
||||
}
|
||||
public TerminalNode LBRACKET() { return getToken(AlertExpressionParser.LBRACKET, 0); }
|
||||
public List<DurationContext> duration() {
|
||||
return getRuleContexts(DurationContext.class);
|
||||
@@ -2289,7 +2283,7 @@ public class AlertExpressionParser extends Parser {
|
||||
break;
|
||||
}
|
||||
_ctx.stop = _input.LT(-1);
|
||||
setState(351);
|
||||
setState(347);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,39,_ctx);
|
||||
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
||||
@@ -2297,7 +2291,7 @@ public class AlertExpressionParser extends Parser {
|
||||
if ( _parseListeners!=null ) triggerExitRuleEvent();
|
||||
_prevctx = _localctx;
|
||||
{
|
||||
setState(349);
|
||||
setState(345);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,38,_ctx) ) {
|
||||
case 1:
|
||||
@@ -2305,24 +2299,30 @@ public class AlertExpressionParser extends Parser {
|
||||
_localctx = new PromqlContext(_parentctx, _parentState);
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_promql);
|
||||
setState(330);
|
||||
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
|
||||
if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
|
||||
setState(331);
|
||||
binaryOperator();
|
||||
match(LBRACKET);
|
||||
setState(332);
|
||||
promql(7);
|
||||
duration();
|
||||
setState(333);
|
||||
match(RBRACKET);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
_localctx = new PromqlContext(_parentctx, _parentState);
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_promql);
|
||||
setState(334);
|
||||
if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
|
||||
setState(335);
|
||||
match(LBRACKET);
|
||||
if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
|
||||
setState(336);
|
||||
duration();
|
||||
match(LBRACKET);
|
||||
setState(337);
|
||||
duration();
|
||||
setState(338);
|
||||
match(COLON);
|
||||
setState(339);
|
||||
duration();
|
||||
setState(340);
|
||||
match(RBRACKET);
|
||||
}
|
||||
break;
|
||||
@@ -2330,36 +2330,18 @@ public class AlertExpressionParser extends Parser {
|
||||
{
|
||||
_localctx = new PromqlContext(_parentctx, _parentState);
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_promql);
|
||||
setState(339);
|
||||
if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
|
||||
setState(340);
|
||||
match(LBRACKET);
|
||||
setState(341);
|
||||
duration();
|
||||
setState(342);
|
||||
match(COLON);
|
||||
setState(343);
|
||||
duration();
|
||||
setState(344);
|
||||
match(RBRACKET);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
_localctx = new PromqlContext(_parentctx, _parentState);
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_promql);
|
||||
setState(346);
|
||||
if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
|
||||
setState(347);
|
||||
setState(343);
|
||||
match(OFFSET);
|
||||
setState(348);
|
||||
setState(344);
|
||||
duration();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(353);
|
||||
setState(349);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,39,_ctx);
|
||||
}
|
||||
@@ -2401,19 +2383,19 @@ public class AlertExpressionParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(354);
|
||||
setState(350);
|
||||
match(LBRACE);
|
||||
setState(356);
|
||||
setState(352);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if (_la==IDENTIFIER) {
|
||||
{
|
||||
setState(355);
|
||||
setState(351);
|
||||
labelMatcherList();
|
||||
}
|
||||
}
|
||||
|
||||
setState(358);
|
||||
setState(354);
|
||||
match(RBRACE);
|
||||
}
|
||||
}
|
||||
@@ -2458,21 +2440,21 @@ public class AlertExpressionParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(360);
|
||||
setState(356);
|
||||
labelMatcherItem();
|
||||
setState(365);
|
||||
setState(361);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==COMMA) {
|
||||
{
|
||||
{
|
||||
setState(361);
|
||||
setState(357);
|
||||
match(COMMA);
|
||||
setState(362);
|
||||
setState(358);
|
||||
labelMatcherItem();
|
||||
}
|
||||
}
|
||||
setState(367);
|
||||
setState(363);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
@@ -2515,11 +2497,11 @@ public class AlertExpressionParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(368);
|
||||
setState(364);
|
||||
match(IDENTIFIER);
|
||||
setState(369);
|
||||
setState(365);
|
||||
labelMatcherOp();
|
||||
setState(370);
|
||||
setState(366);
|
||||
string();
|
||||
}
|
||||
}
|
||||
@@ -2556,7 +2538,7 @@ public class AlertExpressionParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(372);
|
||||
setState(368);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==EQ || _la==NE) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@@ -2609,27 +2591,27 @@ public class AlertExpressionParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(374);
|
||||
setState(370);
|
||||
match(LPAREN);
|
||||
setState(375);
|
||||
setState(371);
|
||||
match(IDENTIFIER);
|
||||
setState(380);
|
||||
setState(376);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==COMMA) {
|
||||
{
|
||||
{
|
||||
setState(376);
|
||||
setState(372);
|
||||
match(COMMA);
|
||||
setState(377);
|
||||
setState(373);
|
||||
match(IDENTIFIER);
|
||||
}
|
||||
}
|
||||
setState(382);
|
||||
setState(378);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
setState(383);
|
||||
setState(379);
|
||||
match(RPAREN);
|
||||
}
|
||||
}
|
||||
@@ -2668,11 +2650,11 @@ public class AlertExpressionParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(385);
|
||||
setState(381);
|
||||
match(LBRACKET);
|
||||
setState(386);
|
||||
setState(382);
|
||||
duration();
|
||||
setState(387);
|
||||
setState(383);
|
||||
match(RBRACKET);
|
||||
}
|
||||
}
|
||||
@@ -2717,7 +2699,7 @@ public class AlertExpressionParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(389);
|
||||
setState(385);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 121324437504L) != 0)) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@@ -2769,7 +2751,7 @@ public class AlertExpressionParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(391);
|
||||
setState(387);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 2216615441596430L) != 0)) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@@ -2828,19 +2810,17 @@ public class AlertExpressionParser extends Parser {
|
||||
private boolean promql_sempred(PromqlContext _localctx, int predIndex) {
|
||||
switch (predIndex) {
|
||||
case 6:
|
||||
return precpred(_ctx, 6);
|
||||
case 7:
|
||||
return precpred(_ctx, 4);
|
||||
case 8:
|
||||
case 7:
|
||||
return precpred(_ctx, 3);
|
||||
case 9:
|
||||
case 8:
|
||||
return precpred(_ctx, 2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\u0004\u0001E\u018a\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+
|
||||
"\u0004\u0001E\u0186\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+
|
||||
"\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+
|
||||
"\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+
|
||||
"\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002"+
|
||||
@@ -2894,217 +2874,215 @@ public class AlertExpressionParser extends Parser {
|
||||
"\u0016\u0001\u0016\u0003\u0016\u0149\b\u0016\u0001\u0016\u0001\u0016\u0001"+
|
||||
"\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+
|
||||
"\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+
|
||||
"\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0005\u0016\u015e"+
|
||||
"\b\u0016\n\u0016\f\u0016\u0161\t\u0016\u0001\u0017\u0001\u0017\u0003\u0017"+
|
||||
"\u0165\b\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018"+
|
||||
"\u0005\u0018\u016c\b\u0018\n\u0018\f\u0018\u016f\t\u0018\u0001\u0019\u0001"+
|
||||
"\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001\u001a\u0001\u001b\u0001"+
|
||||
"\u001b\u0001\u001b\u0001\u001b\u0005\u001b\u017b\b\u001b\n\u001b\f\u001b"+
|
||||
"\u017e\t\u001b\u0001\u001b\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001c"+
|
||||
"\u0001\u001c\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001e"+
|
||||
"\u0000\u0003\u0002$,\u001f\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012"+
|
||||
"\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,.02468:<\u0000\u0007\u0001"+
|
||||
"\u0000-2\u0001\u0000=?\u0004\u0000\u0017\u001b\u001f!%*BB\u0001\u0000"+
|
||||
"\u000f\u0010\u0001\u000012\u0002\u0000\u0017\u001d\"$\u0002\u0000\u0001"+
|
||||
"\u0003-2\u01b3\u0000>\u0001\u0000\u0000\u0000\u0002S\u0001\u0000\u0000"+
|
||||
"\u0000\u0004f\u0001\u0000\u0000\u0000\u0006k\u0001\u0000\u0000\u0000\b"+
|
||||
"w\u0001\u0000\u0000\u0000\ny\u0001\u0000\u0000\u0000\f{\u0001\u0000\u0000"+
|
||||
"\u0000\u000e}\u0001\u0000\u0000\u0000\u0010\u007f\u0001\u0000\u0000\u0000"+
|
||||
"\u0012\u0081\u0001\u0000\u0000\u0000\u0014\u009b\u0001\u0000\u0000\u0000"+
|
||||
"\u0016\u00c1\u0001\u0000\u0000\u0000\u0018\u00c3\u0001\u0000\u0000\u0000"+
|
||||
"\u001a\u00cb\u0001\u0000\u0000\u0000\u001c\u00db\u0001\u0000\u0000\u0000"+
|
||||
"\u001e\u00dd\u0001\u0000\u0000\u0000 \u00df\u0001\u0000\u0000\u0000\""+
|
||||
"\u00f4\u0001\u0000\u0000\u0000$\u00fc\u0001\u0000\u0000\u0000&\u0118\u0001"+
|
||||
"\u0000\u0000\u0000(\u0128\u0001\u0000\u0000\u0000*\u0136\u0001\u0000\u0000"+
|
||||
"\u0000,\u0148\u0001\u0000\u0000\u0000.\u0162\u0001\u0000\u0000\u00000"+
|
||||
"\u0168\u0001\u0000\u0000\u00002\u0170\u0001\u0000\u0000\u00004\u0174\u0001"+
|
||||
"\u0000\u0000\u00006\u0176\u0001\u0000\u0000\u00008\u0181\u0001\u0000\u0000"+
|
||||
"\u0000:\u0185\u0001\u0000\u0000\u0000<\u0187\u0001\u0000\u0000\u0000>"+
|
||||
"?\u0003\u0002\u0001\u0000?@\u0005\u0000\u0000\u0001@\u0001\u0001\u0000"+
|
||||
"\u0000\u0000AB\u0006\u0001\uffff\uffff\u0000BC\u00053\u0000\u0000CD\u0003"+
|
||||
"\u0002\u0001\u0000DE\u00054\u0000\u0000ET\u0001\u0000\u0000\u0000FT\u0003"+
|
||||
",\u0016\u0000GT\u0003\u0012\t\u0000HT\u0003\n\u0005\u0000IJ\u0005+\u0000"+
|
||||
"\u0000JK\u00053\u0000\u0000KL\u0003\f\u0006\u0000LM\u00054\u0000\u0000"+
|
||||
"MT\u0001\u0000\u0000\u0000NO\u0005,\u0000\u0000OP\u00053\u0000\u0000P"+
|
||||
"Q\u0003\f\u0006\u0000QR\u00054\u0000\u0000RT\u0001\u0000\u0000\u0000S"+
|
||||
"A\u0001\u0000\u0000\u0000SF\u0001\u0000\u0000\u0000SG\u0001\u0000\u0000"+
|
||||
"\u0000SH\u0001\u0000\u0000\u0000SI\u0001\u0000\u0000\u0000SN\u0001\u0000"+
|
||||
"\u0000\u0000Tc\u0001\u0000\u0000\u0000UV\n\t\u0000\u0000VW\u0007\u0000"+
|
||||
"\u0000\u0000Wb\u0003\u0002\u0001\nXY\n\b\u0000\u0000YZ\u0005\u0001\u0000"+
|
||||
"\u0000Zb\u0003\u0002\u0001\t[\\\n\u0007\u0000\u0000\\]\u0005\u0003\u0000"+
|
||||
"\u0000]b\u0003\u0002\u0001\b^_\n\u0006\u0000\u0000_`\u0005\u0002\u0000"+
|
||||
"\u0000`b\u0003\u0002\u0001\u0007aU\u0001\u0000\u0000\u0000aX\u0001\u0000"+
|
||||
"\u0000\u0000a[\u0001\u0000\u0000\u0000a^\u0001\u0000\u0000\u0000be\u0001"+
|
||||
"\u0000\u0000\u0000ca\u0001\u0000\u0000\u0000cd\u0001\u0000\u0000\u0000"+
|
||||
"d\u0003\u0001\u0000\u0000\u0000ec\u0001\u0000\u0000\u0000fg\u0003\u0010"+
|
||||
"\b\u0000gh\u00053\u0000\u0000hi\u0003\u0006\u0003\u0000ij\u00054\u0000"+
|
||||
"\u0000j\u0005\u0001\u0000\u0000\u0000kp\u0003\b\u0004\u0000lm\u00059\u0000"+
|
||||
"\u0000mo\u0003\b\u0004\u0000nl\u0001\u0000\u0000\u0000or\u0001\u0000\u0000"+
|
||||
"\u0000pn\u0001\u0000\u0000\u0000pq\u0001\u0000\u0000\u0000q\u0007\u0001"+
|
||||
"\u0000\u0000\u0000rp\u0001\u0000\u0000\u0000sx\u0003\u0002\u0001\u0000"+
|
||||
"tx\u0005\u0016\u0000\u0000ux\u0003\f\u0006\u0000vx\u0003\u000e\u0007\u0000"+
|
||||
"ws\u0001\u0000\u0000\u0000wt\u0001\u0000\u0000\u0000wu\u0001\u0000\u0000"+
|
||||
"\u0000wv\u0001\u0000\u0000\u0000x\t\u0001\u0000\u0000\u0000yz\u0007\u0001"+
|
||||
"\u0000\u0000z\u000b\u0001\u0000\u0000\u0000{|\u0005A\u0000\u0000|\r\u0001"+
|
||||
"\u0000\u0000\u0000}~\u0005@\u0000\u0000~\u000f\u0001\u0000\u0000\u0000"+
|
||||
"\u007f\u0080\u0007\u0002\u0000\u0000\u0080\u0011\u0001\u0000\u0000\u0000"+
|
||||
"\u0081\u0082\u0005\u0005\u0000\u0000\u0082\u0083\u0003\u0014\n\u0000\u0083"+
|
||||
"\u0084\u0005\u0006\u0000\u0000\u0084\u0087\u0003 \u0010\u0000\u0085\u0086"+
|
||||
"\u0005\u0007\u0000\u0000\u0086\u0088\u0003$\u0012\u0000\u0087\u0085\u0001"+
|
||||
"\u0000\u0000\u0000\u0087\u0088\u0001\u0000\u0000\u0000\u0088\u008c\u0001"+
|
||||
"\u0000\u0000\u0000\u0089\u008a\u0005\b\u0000\u0000\u008a\u008b\u0005\t"+
|
||||
"\u0000\u0000\u008b\u008d\u0003\u0018\f\u0000\u008c\u0089\u0001\u0000\u0000"+
|
||||
"\u0000\u008c\u008d\u0001\u0000\u0000\u0000\u008d\u0090\u0001\u0000\u0000"+
|
||||
"\u0000\u008e\u008f\u0005\n\u0000\u0000\u008f\u0091\u0003$\u0012\u0000"+
|
||||
"\u0090\u008e\u0001\u0000\u0000\u0000\u0090\u0091\u0001\u0000\u0000\u0000"+
|
||||
"\u0091\u0095\u0001\u0000\u0000\u0000\u0092\u0093\u0005\u000b\u0000\u0000"+
|
||||
"\u0093\u0094\u0005\t\u0000\u0000\u0094\u0096\u0003\u001a\r\u0000\u0095"+
|
||||
"\u0092\u0001\u0000\u0000\u0000\u0095\u0096\u0001\u0000\u0000\u0000\u0096"+
|
||||
"\u0099\u0001\u0000\u0000\u0000\u0097\u0098\u0005\f\u0000\u0000\u0098\u009a"+
|
||||
"\u0003\u001e\u000f\u0000\u0099\u0097\u0001\u0000\u0000\u0000\u0099\u009a"+
|
||||
"\u0001\u0000\u0000\u0000\u009a\u0013\u0001\u0000\u0000\u0000\u009b\u00a0"+
|
||||
"\u0003\u0016\u000b\u0000\u009c\u009d\u00059\u0000\u0000\u009d\u009f\u0003"+
|
||||
"\u0016\u000b\u0000\u009e\u009c\u0001\u0000\u0000\u0000\u009f\u00a2\u0001"+
|
||||
"\u0000\u0000\u0000\u00a0\u009e\u0001\u0000\u0000\u0000\u00a0\u00a1\u0001"+
|
||||
"\u0000\u0000\u0000\u00a1\u0015\u0001\u0000\u0000\u0000\u00a2\u00a0\u0001"+
|
||||
"\u0000\u0000\u0000\u00a3\u00a8\u0003\u0004\u0002\u0000\u00a4\u00a6\u0005"+
|
||||
"\u000e\u0000\u0000\u00a5\u00a4\u0001\u0000\u0000\u0000\u00a5\u00a6\u0001"+
|
||||
"\u0000\u0000\u0000\u00a6\u00a7\u0001\u0000\u0000\u0000\u00a7\u00a9\u0005"+
|
||||
"B\u0000\u0000\u00a8\u00a5\u0001\u0000\u0000\u0000\u00a8\u00a9\u0001\u0000"+
|
||||
"\u0000\u0000\u00a9\u00c2\u0001\u0000\u0000\u0000\u00aa\u00af\u0005B\u0000"+
|
||||
"\u0000\u00ab\u00ad\u0005\u000e\u0000\u0000\u00ac\u00ab\u0001\u0000\u0000"+
|
||||
"\u0000\u00ac\u00ad\u0001\u0000\u0000\u0000\u00ad\u00ae\u0001\u0000\u0000"+
|
||||
"\u0000\u00ae\u00b0\u0005B\u0000\u0000\u00af\u00ac\u0001\u0000\u0000\u0000"+
|
||||
"\u00af\u00b0\u0001\u0000\u0000\u0000\u00b0\u00c2\u0001\u0000\u0000\u0000"+
|
||||
"\u00b1\u00b6\u0005\u0016\u0000\u0000\u00b2\u00b4\u0005\u000e\u0000\u0000"+
|
||||
"\u00b3\u00b2\u0001\u0000\u0000\u0000\u00b3\u00b4\u0001\u0000\u0000\u0000"+
|
||||
"\u00b4\u00b5\u0001\u0000\u0000\u0000\u00b5\u00b7\u0005B\u0000\u0000\u00b6"+
|
||||
"\u00b3\u0001\u0000\u0000\u0000\u00b6\u00b7\u0001\u0000\u0000\u0000\u00b7"+
|
||||
"\u00c2\u0001\u0000\u0000\u0000\u00b8\u00b9\u0005B\u0000\u0000\u00b9\u00ba"+
|
||||
"\u0005:\u0000\u0000\u00ba\u00bf\u0005B\u0000\u0000\u00bb\u00bd\u0005\u000e"+
|
||||
"\u0000\u0000\u00bc\u00bb\u0001\u0000\u0000\u0000\u00bc\u00bd\u0001\u0000"+
|
||||
"\u0000\u0000\u00bd\u00be\u0001\u0000\u0000\u0000\u00be\u00c0\u0005B\u0000"+
|
||||
"\u0000\u00bf\u00bc\u0001\u0000\u0000\u0000\u00bf\u00c0\u0001\u0000\u0000"+
|
||||
"\u0000\u00c0\u00c2\u0001\u0000\u0000\u0000\u00c1\u00a3\u0001\u0000\u0000"+
|
||||
"\u0000\u00c1\u00aa\u0001\u0000\u0000\u0000\u00c1\u00b1\u0001\u0000\u0000"+
|
||||
"\u0000\u00c1\u00b8\u0001\u0000\u0000\u0000\u00c2\u0017\u0001\u0000\u0000"+
|
||||
"\u0000\u00c3\u00c8\u0005B\u0000\u0000\u00c4\u00c5\u00059\u0000\u0000\u00c5"+
|
||||
"\u00c7\u0005B\u0000\u0000\u00c6\u00c4\u0001\u0000\u0000\u0000\u00c7\u00ca"+
|
||||
"\u0001\u0000\u0000\u0000\u00c8\u00c6\u0001\u0000\u0000\u0000\u00c8\u00c9"+
|
||||
"\u0001\u0000\u0000\u0000\u00c9\u0019\u0001\u0000\u0000\u0000\u00ca\u00c8"+
|
||||
"\u0001\u0000\u0000\u0000\u00cb\u00d0\u0003\u001c\u000e\u0000\u00cc\u00cd"+
|
||||
"\u00059\u0000\u0000\u00cd\u00cf\u0003\u001c\u000e\u0000\u00ce\u00cc\u0001"+
|
||||
"\u0000\u0000\u0000\u00cf\u00d2\u0001\u0000\u0000\u0000\u00d0\u00ce\u0001"+
|
||||
"\u0000\u0000\u0000\u00d0\u00d1\u0001\u0000\u0000\u0000\u00d1\u001b\u0001"+
|
||||
"\u0000\u0000\u0000\u00d2\u00d0\u0001\u0000\u0000\u0000\u00d3\u00d5\u0005"+
|
||||
"B\u0000\u0000\u00d4\u00d6\u0007\u0003\u0000\u0000\u00d5\u00d4\u0001\u0000"+
|
||||
"\u0000\u0000\u00d5\u00d6\u0001\u0000\u0000\u0000\u00d6\u00dc\u0001\u0000"+
|
||||
"\u0000\u0000\u00d7\u00d9\u0003\u0004\u0002\u0000\u00d8\u00da\u0007\u0003"+
|
||||
"\u0000\u0000\u00d9\u00d8\u0001\u0000\u0000\u0000\u00d9\u00da\u0001\u0000"+
|
||||
"\u0000\u0000\u00da\u00dc\u0001\u0000\u0000\u0000\u00db\u00d3\u0001\u0000"+
|
||||
"\u0000\u0000\u00db\u00d7\u0001\u0000\u0000\u0000\u00dc\u001d\u0001\u0000"+
|
||||
"\u0000\u0000\u00dd\u00de\u0005?\u0000\u0000\u00de\u001f\u0001\u0000\u0000"+
|
||||
"\u0000\u00df\u00e4\u0003\"\u0011\u0000\u00e0\u00e1\u00059\u0000\u0000"+
|
||||
"\u00e1\u00e3\u0003\"\u0011\u0000\u00e2\u00e0\u0001\u0000\u0000\u0000\u00e3"+
|
||||
"\u00e6\u0001\u0000\u0000\u0000\u00e4\u00e2\u0001\u0000\u0000\u0000\u00e4"+
|
||||
"\u00e5\u0001\u0000\u0000\u0000\u00e5!\u0001\u0000\u0000\u0000\u00e6\u00e4"+
|
||||
"\u0001\u0000\u0000\u0000\u00e7\u00ec\u0005B\u0000\u0000\u00e8\u00ea\u0005"+
|
||||
"\u000e\u0000\u0000\u00e9\u00e8\u0001\u0000\u0000\u0000\u00e9\u00ea\u0001"+
|
||||
"\u0000\u0000\u0000\u00ea\u00eb\u0001\u0000\u0000\u0000\u00eb\u00ed\u0005"+
|
||||
"B\u0000\u0000\u00ec\u00e9\u0001\u0000\u0000\u0000\u00ec\u00ed\u0001\u0000"+
|
||||
"\u0000\u0000\u00ed\u00f5\u0001\u0000\u0000\u0000\u00ee\u00ef\u00053\u0000"+
|
||||
"\u0000\u00ef\u00f0\u0003\u0012\t\u0000\u00f0\u00f1\u00054\u0000\u0000"+
|
||||
"\u00f1\u00f2\u0005\u000e\u0000\u0000\u00f2\u00f3\u0005B\u0000\u0000\u00f3"+
|
||||
"\u00f5\u0001\u0000\u0000\u0000\u00f4\u00e7\u0001\u0000\u0000\u0000\u00f4"+
|
||||
"\u00ee\u0001\u0000\u0000\u0000\u00f5#\u0001\u0000\u0000\u0000\u00f6\u00f7"+
|
||||
"\u0006\u0012\uffff\uffff\u0000\u00f7\u00fd\u0003(\u0014\u0000\u00f8\u00f9"+
|
||||
"\u00053\u0000\u0000\u00f9\u00fa\u0003$\u0012\u0000\u00fa\u00fb\u00054"+
|
||||
"\u0000\u0000\u00fb\u00fd\u0001\u0000\u0000\u0000\u00fc\u00f6\u0001\u0000"+
|
||||
"\u0000\u0000\u00fc\u00f8\u0001\u0000\u0000\u0000\u00fd\u0106\u0001\u0000"+
|
||||
"\u0000\u0000\u00fe\u00ff\n\u0004\u0000\u0000\u00ff\u0100\u0005\u0001\u0000"+
|
||||
"\u0000\u0100\u0105\u0003$\u0012\u0005\u0101\u0102\n\u0003\u0000\u0000"+
|
||||
"\u0102\u0103\u0005\u0002\u0000\u0000\u0103\u0105\u0003$\u0012\u0004\u0104"+
|
||||
"\u00fe\u0001\u0000\u0000\u0000\u0104\u0101\u0001\u0000\u0000\u0000\u0105"+
|
||||
"\u0108\u0001\u0000\u0000\u0000\u0106\u0104\u0001\u0000\u0000\u0000\u0106"+
|
||||
"\u0107\u0001\u0000\u0000\u0000\u0107%\u0001\u0000\u0000\u0000\u0108\u0106"+
|
||||
"\u0001\u0000\u0000\u0000\u0109\u0119\u00051\u0000\u0000\u010a\u0119\u0005"+
|
||||
"/\u0000\u0000\u010b\u0119\u0005-\u0000\u0000\u010c\u0119\u00050\u0000"+
|
||||
"\u0000\u010d\u0119\u0005.\u0000\u0000\u010e\u0119\u00052\u0000\u0000\u010f"+
|
||||
"\u0119\u0005\u0014\u0000\u0000\u0110\u0111\u0005\u0004\u0000\u0000\u0111"+
|
||||
"\u0119\u0005\u0014\u0000\u0000\u0112\u0119\u0005\u0011\u0000\u0000\u0113"+
|
||||
"\u0114\u0005\u0004\u0000\u0000\u0114\u0119\u0005\u0011\u0000\u0000\u0115"+
|
||||
"\u0119\u0005\u0012\u0000\u0000\u0116\u0117\u0005\u0012\u0000\u0000\u0117"+
|
||||
"\u0119\u0005\u0004\u0000\u0000\u0118\u0109\u0001\u0000\u0000\u0000\u0118"+
|
||||
"\u010a\u0001\u0000\u0000\u0000\u0118\u010b\u0001\u0000\u0000\u0000\u0118"+
|
||||
"\u010c\u0001\u0000\u0000\u0000\u0118\u010d\u0001\u0000\u0000\u0000\u0118"+
|
||||
"\u010e\u0001\u0000\u0000\u0000\u0118\u010f\u0001\u0000\u0000\u0000\u0118"+
|
||||
"\u0110\u0001\u0000\u0000\u0000\u0118\u0112\u0001\u0000\u0000\u0000\u0118"+
|
||||
"\u0113\u0001\u0000\u0000\u0000\u0118\u0115\u0001\u0000\u0000\u0000\u0118"+
|
||||
"\u0116\u0001\u0000\u0000\u0000\u0119\'\u0001\u0000\u0000\u0000\u011a\u011b"+
|
||||
"\u0003*\u0015\u0000\u011b\u011c\u0003&\u0013\u0000\u011c\u011d\u0003*"+
|
||||
"\u0015\u0000\u011d\u0129\u0001\u0000\u0000\u0000\u011e\u011f\u00053\u0000"+
|
||||
"\u0000\u011f\u0120\u0003(\u0014\u0000\u0120\u0121\u00054\u0000\u0000\u0121"+
|
||||
"\u0129\u0001\u0000\u0000\u0000\u0122\u0123\u0005B\u0000\u0000\u0123\u0124"+
|
||||
"\u0005\u0015\u0000\u0000\u0124\u0125\u0003\n\u0005\u0000\u0125\u0126\u0005"+
|
||||
"\u0001\u0000\u0000\u0126\u0127\u0003\n\u0005\u0000\u0127\u0129\u0001\u0000"+
|
||||
"\u0000\u0000\u0128\u011a\u0001\u0000\u0000\u0000\u0128\u011e\u0001\u0000"+
|
||||
"\u0000\u0000\u0128\u0122\u0001\u0000\u0000\u0000\u0129)\u0001\u0000\u0000"+
|
||||
"\u0000\u012a\u0137\u0003\n\u0005\u0000\u012b\u0137\u0003\f\u0006\u0000"+
|
||||
"\u012c\u0137\u0005B\u0000\u0000\u012d\u012e\u0005B\u0000\u0000\u012e\u012f"+
|
||||
"\u0005:\u0000\u0000\u012f\u0137\u0005B\u0000\u0000\u0130\u0137\u0005\u0013"+
|
||||
"\u0000\u0000\u0131\u0132\u00053\u0000\u0000\u0132\u0133\u0003\u0012\t"+
|
||||
"\u0000\u0133\u0134\u00054\u0000\u0000\u0134\u0137\u0001\u0000\u0000\u0000"+
|
||||
"\u0135\u0137\u0003\u0004\u0002\u0000\u0136\u012a\u0001\u0000\u0000\u0000"+
|
||||
"\u0136\u012b\u0001\u0000\u0000\u0000\u0136\u012c\u0001\u0000\u0000\u0000"+
|
||||
"\u0136\u012d\u0001\u0000\u0000\u0000\u0136\u0130\u0001\u0000\u0000\u0000"+
|
||||
"\u0136\u0131\u0001\u0000\u0000\u0000\u0136\u0135\u0001\u0000\u0000\u0000"+
|
||||
"\u0137+\u0001\u0000\u0000\u0000\u0138\u0139\u0006\u0016\uffff\uffff\u0000"+
|
||||
"\u0139\u013b\u0003.\u0017\u0000\u013a\u013c\u00038\u001c\u0000\u013b\u013a"+
|
||||
"\u0001\u0000\u0000\u0000\u013b\u013c\u0001\u0000\u0000\u0000\u013c\u0149"+
|
||||
"\u0001\u0000\u0000\u0000\u013d\u013e\u0003:\u001d\u0000\u013e\u013f\u0005"+
|
||||
"3\u0000\u0000\u013f\u0142\u0003,\u0016\u0000\u0140\u0141\u0005\t\u0000"+
|
||||
"\u0000\u0141\u0143\u00036\u001b\u0000\u0142\u0140\u0001\u0000\u0000\u0000"+
|
||||
"\u0142\u0143\u0001\u0000\u0000\u0000\u0143\u0144\u0001\u0000\u0000\u0000"+
|
||||
"\u0144\u0145\u00054\u0000\u0000\u0145\u0149\u0001\u0000\u0000\u0000\u0146"+
|
||||
"\u0149\u0003\u0004\u0002\u0000\u0147\u0149\u0005B\u0000\u0000\u0148\u0138"+
|
||||
"\u0001\u0000\u0000\u0000\u0148\u013d\u0001\u0000\u0000\u0000\u0148\u0146"+
|
||||
"\u0001\u0000\u0000\u0000\u0148\u0147\u0001\u0000\u0000\u0000\u0149\u015f"+
|
||||
"\u0001\u0000\u0000\u0000\u014a\u014b\n\u0006\u0000\u0000\u014b\u014c\u0003"+
|
||||
"<\u001e\u0000\u014c\u014d\u0003,\u0016\u0007\u014d\u015e\u0001\u0000\u0000"+
|
||||
"\u0000\u014e\u014f\n\u0004\u0000\u0000\u014f\u0150\u00057\u0000\u0000"+
|
||||
"\u0150\u0151\u0003\u000e\u0007\u0000\u0151\u0152\u00058\u0000\u0000\u0152"+
|
||||
"\u015e\u0001\u0000\u0000\u0000\u0153\u0154\n\u0003\u0000\u0000\u0154\u0155"+
|
||||
"\u00057\u0000\u0000\u0155\u0156\u0003\u000e\u0007\u0000\u0156\u0157\u0005"+
|
||||
";\u0000\u0000\u0157\u0158\u0003\u000e\u0007\u0000\u0158\u0159\u00058\u0000"+
|
||||
"\u0000\u0159\u015e\u0001\u0000\u0000\u0000\u015a\u015b\n\u0002\u0000\u0000"+
|
||||
"\u015b\u015c\u0005\r\u0000\u0000\u015c\u015e\u0003\u000e\u0007\u0000\u015d"+
|
||||
"\u014a\u0001\u0000\u0000\u0000\u015d\u014e\u0001\u0000\u0000\u0000\u015d"+
|
||||
"\u0153\u0001\u0000\u0000\u0000\u015d\u015a\u0001\u0000\u0000\u0000\u015e"+
|
||||
"\u0161\u0001\u0000\u0000\u0000\u015f\u015d\u0001\u0000\u0000\u0000\u015f"+
|
||||
"\u0160\u0001\u0000\u0000\u0000\u0160-\u0001\u0000\u0000\u0000\u0161\u015f"+
|
||||
"\u0001\u0000\u0000\u0000\u0162\u0164\u00055\u0000\u0000\u0163\u0165\u0003"+
|
||||
"0\u0018\u0000\u0164\u0163\u0001\u0000\u0000\u0000\u0164\u0165\u0001\u0000"+
|
||||
"\u0000\u0000\u0165\u0166\u0001\u0000\u0000\u0000\u0166\u0167\u00056\u0000"+
|
||||
"\u0000\u0167/\u0001\u0000\u0000\u0000\u0168\u016d\u00032\u0019\u0000\u0169"+
|
||||
"\u016a\u00059\u0000\u0000\u016a\u016c\u00032\u0019\u0000\u016b\u0169\u0001"+
|
||||
"\u0000\u0000\u0000\u016c\u016f\u0001\u0000\u0000\u0000\u016d\u016b\u0001"+
|
||||
"\u0000\u0000\u0000\u016d\u016e\u0001\u0000\u0000\u0000\u016e1\u0001\u0000"+
|
||||
"\u0000\u0000\u016f\u016d\u0001\u0000\u0000\u0000\u0170\u0171\u0005B\u0000"+
|
||||
"\u0000\u0171\u0172\u00034\u001a\u0000\u0172\u0173\u0003\f\u0006\u0000"+
|
||||
"\u01733\u0001\u0000\u0000\u0000\u0174\u0175\u0007\u0004\u0000\u0000\u0175"+
|
||||
"5\u0001\u0000\u0000\u0000\u0176\u0177\u00053\u0000\u0000\u0177\u017c\u0005"+
|
||||
"B\u0000\u0000\u0178\u0179\u00059\u0000\u0000\u0179\u017b\u0005B\u0000"+
|
||||
"\u0000\u017a\u0178\u0001\u0000\u0000\u0000\u017b\u017e\u0001\u0000\u0000"+
|
||||
"\u0000\u017c\u017a\u0001\u0000\u0000\u0000\u017c\u017d\u0001\u0000\u0000"+
|
||||
"\u0000\u017d\u017f\u0001\u0000\u0000\u0000\u017e\u017c\u0001\u0000\u0000"+
|
||||
"\u0000\u017f\u0180\u00054\u0000\u0000\u01807\u0001\u0000\u0000\u0000\u0181"+
|
||||
"\u0182\u00057\u0000\u0000\u0182\u0183\u0003\u000e\u0007\u0000\u0183\u0184"+
|
||||
"\u00058\u0000\u0000\u01849\u0001\u0000\u0000\u0000\u0185\u0186\u0007\u0005"+
|
||||
"\u0000\u0000\u0186;\u0001\u0000\u0000\u0000\u0187\u0188\u0007\u0006\u0000"+
|
||||
"\u0000\u0188=\u0001\u0000\u0000\u0000+Sacpw\u0087\u008c\u0090\u0095\u0099"+
|
||||
"\u00a0\u00a5\u00a8\u00ac\u00af\u00b3\u00b6\u00bc\u00bf\u00c1\u00c8\u00d0"+
|
||||
"\u00d5\u00d9\u00db\u00e4\u00e9\u00ec\u00f4\u00fc\u0104\u0106\u0118\u0128"+
|
||||
"\u0136\u013b\u0142\u0148\u015d\u015f\u0164\u016d\u017c";
|
||||
"\u0016\u0005\u0016\u015a\b\u0016\n\u0016\f\u0016\u015d\t\u0016\u0001\u0017"+
|
||||
"\u0001\u0017\u0003\u0017\u0161\b\u0017\u0001\u0017\u0001\u0017\u0001\u0018"+
|
||||
"\u0001\u0018\u0001\u0018\u0005\u0018\u0168\b\u0018\n\u0018\f\u0018\u016b"+
|
||||
"\t\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001"+
|
||||
"\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0005\u001b\u0177"+
|
||||
"\b\u001b\n\u001b\f\u001b\u017a\t\u001b\u0001\u001b\u0001\u001b\u0001\u001c"+
|
||||
"\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d\u0001\u001e"+
|
||||
"\u0001\u001e\u0001\u001e\u0000\u0003\u0002$,\u001f\u0000\u0002\u0004\u0006"+
|
||||
"\b\n\f\u000e\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,."+
|
||||
"02468:<\u0000\u0007\u0001\u0000-2\u0001\u0000=?\u0004\u0000\u0017\u001b"+
|
||||
"\u001f!%*BB\u0001\u0000\u000f\u0010\u0001\u000012\u0002\u0000\u0017\u001d"+
|
||||
"\"$\u0002\u0000\u0001\u0003-2\u01ae\u0000>\u0001\u0000\u0000\u0000\u0002"+
|
||||
"S\u0001\u0000\u0000\u0000\u0004f\u0001\u0000\u0000\u0000\u0006k\u0001"+
|
||||
"\u0000\u0000\u0000\bw\u0001\u0000\u0000\u0000\ny\u0001\u0000\u0000\u0000"+
|
||||
"\f{\u0001\u0000\u0000\u0000\u000e}\u0001\u0000\u0000\u0000\u0010\u007f"+
|
||||
"\u0001\u0000\u0000\u0000\u0012\u0081\u0001\u0000\u0000\u0000\u0014\u009b"+
|
||||
"\u0001\u0000\u0000\u0000\u0016\u00c1\u0001\u0000\u0000\u0000\u0018\u00c3"+
|
||||
"\u0001\u0000\u0000\u0000\u001a\u00cb\u0001\u0000\u0000\u0000\u001c\u00db"+
|
||||
"\u0001\u0000\u0000\u0000\u001e\u00dd\u0001\u0000\u0000\u0000 \u00df\u0001"+
|
||||
"\u0000\u0000\u0000\"\u00f4\u0001\u0000\u0000\u0000$\u00fc\u0001\u0000"+
|
||||
"\u0000\u0000&\u0118\u0001\u0000\u0000\u0000(\u0128\u0001\u0000\u0000\u0000"+
|
||||
"*\u0136\u0001\u0000\u0000\u0000,\u0148\u0001\u0000\u0000\u0000.\u015e"+
|
||||
"\u0001\u0000\u0000\u00000\u0164\u0001\u0000\u0000\u00002\u016c\u0001\u0000"+
|
||||
"\u0000\u00004\u0170\u0001\u0000\u0000\u00006\u0172\u0001\u0000\u0000\u0000"+
|
||||
"8\u017d\u0001\u0000\u0000\u0000:\u0181\u0001\u0000\u0000\u0000<\u0183"+
|
||||
"\u0001\u0000\u0000\u0000>?\u0003\u0002\u0001\u0000?@\u0005\u0000\u0000"+
|
||||
"\u0001@\u0001\u0001\u0000\u0000\u0000AB\u0006\u0001\uffff\uffff\u0000"+
|
||||
"BC\u00053\u0000\u0000CD\u0003\u0002\u0001\u0000DE\u00054\u0000\u0000E"+
|
||||
"T\u0001\u0000\u0000\u0000FT\u0003,\u0016\u0000GT\u0003\u0012\t\u0000H"+
|
||||
"T\u0003\n\u0005\u0000IJ\u0005+\u0000\u0000JK\u00053\u0000\u0000KL\u0003"+
|
||||
"\f\u0006\u0000LM\u00054\u0000\u0000MT\u0001\u0000\u0000\u0000NO\u0005"+
|
||||
",\u0000\u0000OP\u00053\u0000\u0000PQ\u0003\f\u0006\u0000QR\u00054\u0000"+
|
||||
"\u0000RT\u0001\u0000\u0000\u0000SA\u0001\u0000\u0000\u0000SF\u0001\u0000"+
|
||||
"\u0000\u0000SG\u0001\u0000\u0000\u0000SH\u0001\u0000\u0000\u0000SI\u0001"+
|
||||
"\u0000\u0000\u0000SN\u0001\u0000\u0000\u0000Tc\u0001\u0000\u0000\u0000"+
|
||||
"UV\n\t\u0000\u0000VW\u0007\u0000\u0000\u0000Wb\u0003\u0002\u0001\nXY\n"+
|
||||
"\b\u0000\u0000YZ\u0005\u0001\u0000\u0000Zb\u0003\u0002\u0001\t[\\\n\u0007"+
|
||||
"\u0000\u0000\\]\u0005\u0003\u0000\u0000]b\u0003\u0002\u0001\b^_\n\u0006"+
|
||||
"\u0000\u0000_`\u0005\u0002\u0000\u0000`b\u0003\u0002\u0001\u0007aU\u0001"+
|
||||
"\u0000\u0000\u0000aX\u0001\u0000\u0000\u0000a[\u0001\u0000\u0000\u0000"+
|
||||
"a^\u0001\u0000\u0000\u0000be\u0001\u0000\u0000\u0000ca\u0001\u0000\u0000"+
|
||||
"\u0000cd\u0001\u0000\u0000\u0000d\u0003\u0001\u0000\u0000\u0000ec\u0001"+
|
||||
"\u0000\u0000\u0000fg\u0003\u0010\b\u0000gh\u00053\u0000\u0000hi\u0003"+
|
||||
"\u0006\u0003\u0000ij\u00054\u0000\u0000j\u0005\u0001\u0000\u0000\u0000"+
|
||||
"kp\u0003\b\u0004\u0000lm\u00059\u0000\u0000mo\u0003\b\u0004\u0000nl\u0001"+
|
||||
"\u0000\u0000\u0000or\u0001\u0000\u0000\u0000pn\u0001\u0000\u0000\u0000"+
|
||||
"pq\u0001\u0000\u0000\u0000q\u0007\u0001\u0000\u0000\u0000rp\u0001\u0000"+
|
||||
"\u0000\u0000sx\u0003\u0002\u0001\u0000tx\u0005\u0016\u0000\u0000ux\u0003"+
|
||||
"\f\u0006\u0000vx\u0003\u000e\u0007\u0000ws\u0001\u0000\u0000\u0000wt\u0001"+
|
||||
"\u0000\u0000\u0000wu\u0001\u0000\u0000\u0000wv\u0001\u0000\u0000\u0000"+
|
||||
"x\t\u0001\u0000\u0000\u0000yz\u0007\u0001\u0000\u0000z\u000b\u0001\u0000"+
|
||||
"\u0000\u0000{|\u0005A\u0000\u0000|\r\u0001\u0000\u0000\u0000}~\u0005@"+
|
||||
"\u0000\u0000~\u000f\u0001\u0000\u0000\u0000\u007f\u0080\u0007\u0002\u0000"+
|
||||
"\u0000\u0080\u0011\u0001\u0000\u0000\u0000\u0081\u0082\u0005\u0005\u0000"+
|
||||
"\u0000\u0082\u0083\u0003\u0014\n\u0000\u0083\u0084\u0005\u0006\u0000\u0000"+
|
||||
"\u0084\u0087\u0003 \u0010\u0000\u0085\u0086\u0005\u0007\u0000\u0000\u0086"+
|
||||
"\u0088\u0003$\u0012\u0000\u0087\u0085\u0001\u0000\u0000\u0000\u0087\u0088"+
|
||||
"\u0001\u0000\u0000\u0000\u0088\u008c\u0001\u0000\u0000\u0000\u0089\u008a"+
|
||||
"\u0005\b\u0000\u0000\u008a\u008b\u0005\t\u0000\u0000\u008b\u008d\u0003"+
|
||||
"\u0018\f\u0000\u008c\u0089\u0001\u0000\u0000\u0000\u008c\u008d\u0001\u0000"+
|
||||
"\u0000\u0000\u008d\u0090\u0001\u0000\u0000\u0000\u008e\u008f\u0005\n\u0000"+
|
||||
"\u0000\u008f\u0091\u0003$\u0012\u0000\u0090\u008e\u0001\u0000\u0000\u0000"+
|
||||
"\u0090\u0091\u0001\u0000\u0000\u0000\u0091\u0095\u0001\u0000\u0000\u0000"+
|
||||
"\u0092\u0093\u0005\u000b\u0000\u0000\u0093\u0094\u0005\t\u0000\u0000\u0094"+
|
||||
"\u0096\u0003\u001a\r\u0000\u0095\u0092\u0001\u0000\u0000\u0000\u0095\u0096"+
|
||||
"\u0001\u0000\u0000\u0000\u0096\u0099\u0001\u0000\u0000\u0000\u0097\u0098"+
|
||||
"\u0005\f\u0000\u0000\u0098\u009a\u0003\u001e\u000f\u0000\u0099\u0097\u0001"+
|
||||
"\u0000\u0000\u0000\u0099\u009a\u0001\u0000\u0000\u0000\u009a\u0013\u0001"+
|
||||
"\u0000\u0000\u0000\u009b\u00a0\u0003\u0016\u000b\u0000\u009c\u009d\u0005"+
|
||||
"9\u0000\u0000\u009d\u009f\u0003\u0016\u000b\u0000\u009e\u009c\u0001\u0000"+
|
||||
"\u0000\u0000\u009f\u00a2\u0001\u0000\u0000\u0000\u00a0\u009e\u0001\u0000"+
|
||||
"\u0000\u0000\u00a0\u00a1\u0001\u0000\u0000\u0000\u00a1\u0015\u0001\u0000"+
|
||||
"\u0000\u0000\u00a2\u00a0\u0001\u0000\u0000\u0000\u00a3\u00a8\u0003\u0004"+
|
||||
"\u0002\u0000\u00a4\u00a6\u0005\u000e\u0000\u0000\u00a5\u00a4\u0001\u0000"+
|
||||
"\u0000\u0000\u00a5\u00a6\u0001\u0000\u0000\u0000\u00a6\u00a7\u0001\u0000"+
|
||||
"\u0000\u0000\u00a7\u00a9\u0005B\u0000\u0000\u00a8\u00a5\u0001\u0000\u0000"+
|
||||
"\u0000\u00a8\u00a9\u0001\u0000\u0000\u0000\u00a9\u00c2\u0001\u0000\u0000"+
|
||||
"\u0000\u00aa\u00af\u0005B\u0000\u0000\u00ab\u00ad\u0005\u000e\u0000\u0000"+
|
||||
"\u00ac\u00ab\u0001\u0000\u0000\u0000\u00ac\u00ad\u0001\u0000\u0000\u0000"+
|
||||
"\u00ad\u00ae\u0001\u0000\u0000\u0000\u00ae\u00b0\u0005B\u0000\u0000\u00af"+
|
||||
"\u00ac\u0001\u0000\u0000\u0000\u00af\u00b0\u0001\u0000\u0000\u0000\u00b0"+
|
||||
"\u00c2\u0001\u0000\u0000\u0000\u00b1\u00b6\u0005\u0016\u0000\u0000\u00b2"+
|
||||
"\u00b4\u0005\u000e\u0000\u0000\u00b3\u00b2\u0001\u0000\u0000\u0000\u00b3"+
|
||||
"\u00b4\u0001\u0000\u0000\u0000\u00b4\u00b5\u0001\u0000\u0000\u0000\u00b5"+
|
||||
"\u00b7\u0005B\u0000\u0000\u00b6\u00b3\u0001\u0000\u0000\u0000\u00b6\u00b7"+
|
||||
"\u0001\u0000\u0000\u0000\u00b7\u00c2\u0001\u0000\u0000\u0000\u00b8\u00b9"+
|
||||
"\u0005B\u0000\u0000\u00b9\u00ba\u0005:\u0000\u0000\u00ba\u00bf\u0005B"+
|
||||
"\u0000\u0000\u00bb\u00bd\u0005\u000e\u0000\u0000\u00bc\u00bb\u0001\u0000"+
|
||||
"\u0000\u0000\u00bc\u00bd\u0001\u0000\u0000\u0000\u00bd\u00be\u0001\u0000"+
|
||||
"\u0000\u0000\u00be\u00c0\u0005B\u0000\u0000\u00bf\u00bc\u0001\u0000\u0000"+
|
||||
"\u0000\u00bf\u00c0\u0001\u0000\u0000\u0000\u00c0\u00c2\u0001\u0000\u0000"+
|
||||
"\u0000\u00c1\u00a3\u0001\u0000\u0000\u0000\u00c1\u00aa\u0001\u0000\u0000"+
|
||||
"\u0000\u00c1\u00b1\u0001\u0000\u0000\u0000\u00c1\u00b8\u0001\u0000\u0000"+
|
||||
"\u0000\u00c2\u0017\u0001\u0000\u0000\u0000\u00c3\u00c8\u0005B\u0000\u0000"+
|
||||
"\u00c4\u00c5\u00059\u0000\u0000\u00c5\u00c7\u0005B\u0000\u0000\u00c6\u00c4"+
|
||||
"\u0001\u0000\u0000\u0000\u00c7\u00ca\u0001\u0000\u0000\u0000\u00c8\u00c6"+
|
||||
"\u0001\u0000\u0000\u0000\u00c8\u00c9\u0001\u0000\u0000\u0000\u00c9\u0019"+
|
||||
"\u0001\u0000\u0000\u0000\u00ca\u00c8\u0001\u0000\u0000\u0000\u00cb\u00d0"+
|
||||
"\u0003\u001c\u000e\u0000\u00cc\u00cd\u00059\u0000\u0000\u00cd\u00cf\u0003"+
|
||||
"\u001c\u000e\u0000\u00ce\u00cc\u0001\u0000\u0000\u0000\u00cf\u00d2\u0001"+
|
||||
"\u0000\u0000\u0000\u00d0\u00ce\u0001\u0000\u0000\u0000\u00d0\u00d1\u0001"+
|
||||
"\u0000\u0000\u0000\u00d1\u001b\u0001\u0000\u0000\u0000\u00d2\u00d0\u0001"+
|
||||
"\u0000\u0000\u0000\u00d3\u00d5\u0005B\u0000\u0000\u00d4\u00d6\u0007\u0003"+
|
||||
"\u0000\u0000\u00d5\u00d4\u0001\u0000\u0000\u0000\u00d5\u00d6\u0001\u0000"+
|
||||
"\u0000\u0000\u00d6\u00dc\u0001\u0000\u0000\u0000\u00d7\u00d9\u0003\u0004"+
|
||||
"\u0002\u0000\u00d8\u00da\u0007\u0003\u0000\u0000\u00d9\u00d8\u0001\u0000"+
|
||||
"\u0000\u0000\u00d9\u00da\u0001\u0000\u0000\u0000\u00da\u00dc\u0001\u0000"+
|
||||
"\u0000\u0000\u00db\u00d3\u0001\u0000\u0000\u0000\u00db\u00d7\u0001\u0000"+
|
||||
"\u0000\u0000\u00dc\u001d\u0001\u0000\u0000\u0000\u00dd\u00de\u0005?\u0000"+
|
||||
"\u0000\u00de\u001f\u0001\u0000\u0000\u0000\u00df\u00e4\u0003\"\u0011\u0000"+
|
||||
"\u00e0\u00e1\u00059\u0000\u0000\u00e1\u00e3\u0003\"\u0011\u0000\u00e2"+
|
||||
"\u00e0\u0001\u0000\u0000\u0000\u00e3\u00e6\u0001\u0000\u0000\u0000\u00e4"+
|
||||
"\u00e2\u0001\u0000\u0000\u0000\u00e4\u00e5\u0001\u0000\u0000\u0000\u00e5"+
|
||||
"!\u0001\u0000\u0000\u0000\u00e6\u00e4\u0001\u0000\u0000\u0000\u00e7\u00ec"+
|
||||
"\u0005B\u0000\u0000\u00e8\u00ea\u0005\u000e\u0000\u0000\u00e9\u00e8\u0001"+
|
||||
"\u0000\u0000\u0000\u00e9\u00ea\u0001\u0000\u0000\u0000\u00ea\u00eb\u0001"+
|
||||
"\u0000\u0000\u0000\u00eb\u00ed\u0005B\u0000\u0000\u00ec\u00e9\u0001\u0000"+
|
||||
"\u0000\u0000\u00ec\u00ed\u0001\u0000\u0000\u0000\u00ed\u00f5\u0001\u0000"+
|
||||
"\u0000\u0000\u00ee\u00ef\u00053\u0000\u0000\u00ef\u00f0\u0003\u0012\t"+
|
||||
"\u0000\u00f0\u00f1\u00054\u0000\u0000\u00f1\u00f2\u0005\u000e\u0000\u0000"+
|
||||
"\u00f2\u00f3\u0005B\u0000\u0000\u00f3\u00f5\u0001\u0000\u0000\u0000\u00f4"+
|
||||
"\u00e7\u0001\u0000\u0000\u0000\u00f4\u00ee\u0001\u0000\u0000\u0000\u00f5"+
|
||||
"#\u0001\u0000\u0000\u0000\u00f6\u00f7\u0006\u0012\uffff\uffff\u0000\u00f7"+
|
||||
"\u00fd\u0003(\u0014\u0000\u00f8\u00f9\u00053\u0000\u0000\u00f9\u00fa\u0003"+
|
||||
"$\u0012\u0000\u00fa\u00fb\u00054\u0000\u0000\u00fb\u00fd\u0001\u0000\u0000"+
|
||||
"\u0000\u00fc\u00f6\u0001\u0000\u0000\u0000\u00fc\u00f8\u0001\u0000\u0000"+
|
||||
"\u0000\u00fd\u0106\u0001\u0000\u0000\u0000\u00fe\u00ff\n\u0004\u0000\u0000"+
|
||||
"\u00ff\u0100\u0005\u0001\u0000\u0000\u0100\u0105\u0003$\u0012\u0005\u0101"+
|
||||
"\u0102\n\u0003\u0000\u0000\u0102\u0103\u0005\u0002\u0000\u0000\u0103\u0105"+
|
||||
"\u0003$\u0012\u0004\u0104\u00fe\u0001\u0000\u0000\u0000\u0104\u0101\u0001"+
|
||||
"\u0000\u0000\u0000\u0105\u0108\u0001\u0000\u0000\u0000\u0106\u0104\u0001"+
|
||||
"\u0000\u0000\u0000\u0106\u0107\u0001\u0000\u0000\u0000\u0107%\u0001\u0000"+
|
||||
"\u0000\u0000\u0108\u0106\u0001\u0000\u0000\u0000\u0109\u0119\u00051\u0000"+
|
||||
"\u0000\u010a\u0119\u0005/\u0000\u0000\u010b\u0119\u0005-\u0000\u0000\u010c"+
|
||||
"\u0119\u00050\u0000\u0000\u010d\u0119\u0005.\u0000\u0000\u010e\u0119\u0005"+
|
||||
"2\u0000\u0000\u010f\u0119\u0005\u0014\u0000\u0000\u0110\u0111\u0005\u0004"+
|
||||
"\u0000\u0000\u0111\u0119\u0005\u0014\u0000\u0000\u0112\u0119\u0005\u0011"+
|
||||
"\u0000\u0000\u0113\u0114\u0005\u0004\u0000\u0000\u0114\u0119\u0005\u0011"+
|
||||
"\u0000\u0000\u0115\u0119\u0005\u0012\u0000\u0000\u0116\u0117\u0005\u0012"+
|
||||
"\u0000\u0000\u0117\u0119\u0005\u0004\u0000\u0000\u0118\u0109\u0001\u0000"+
|
||||
"\u0000\u0000\u0118\u010a\u0001\u0000\u0000\u0000\u0118\u010b\u0001\u0000"+
|
||||
"\u0000\u0000\u0118\u010c\u0001\u0000\u0000\u0000\u0118\u010d\u0001\u0000"+
|
||||
"\u0000\u0000\u0118\u010e\u0001\u0000\u0000\u0000\u0118\u010f\u0001\u0000"+
|
||||
"\u0000\u0000\u0118\u0110\u0001\u0000\u0000\u0000\u0118\u0112\u0001\u0000"+
|
||||
"\u0000\u0000\u0118\u0113\u0001\u0000\u0000\u0000\u0118\u0115\u0001\u0000"+
|
||||
"\u0000\u0000\u0118\u0116\u0001\u0000\u0000\u0000\u0119\'\u0001\u0000\u0000"+
|
||||
"\u0000\u011a\u011b\u0003*\u0015\u0000\u011b\u011c\u0003&\u0013\u0000\u011c"+
|
||||
"\u011d\u0003*\u0015\u0000\u011d\u0129\u0001\u0000\u0000\u0000\u011e\u011f"+
|
||||
"\u00053\u0000\u0000\u011f\u0120\u0003(\u0014\u0000\u0120\u0121\u00054"+
|
||||
"\u0000\u0000\u0121\u0129\u0001\u0000\u0000\u0000\u0122\u0123\u0005B\u0000"+
|
||||
"\u0000\u0123\u0124\u0005\u0015\u0000\u0000\u0124\u0125\u0003\n\u0005\u0000"+
|
||||
"\u0125\u0126\u0005\u0001\u0000\u0000\u0126\u0127\u0003\n\u0005\u0000\u0127"+
|
||||
"\u0129\u0001\u0000\u0000\u0000\u0128\u011a\u0001\u0000\u0000\u0000\u0128"+
|
||||
"\u011e\u0001\u0000\u0000\u0000\u0128\u0122\u0001\u0000\u0000\u0000\u0129"+
|
||||
")\u0001\u0000\u0000\u0000\u012a\u0137\u0003\n\u0005\u0000\u012b\u0137"+
|
||||
"\u0003\f\u0006\u0000\u012c\u0137\u0005B\u0000\u0000\u012d\u012e\u0005"+
|
||||
"B\u0000\u0000\u012e\u012f\u0005:\u0000\u0000\u012f\u0137\u0005B\u0000"+
|
||||
"\u0000\u0130\u0137\u0005\u0013\u0000\u0000\u0131\u0132\u00053\u0000\u0000"+
|
||||
"\u0132\u0133\u0003\u0012\t\u0000\u0133\u0134\u00054\u0000\u0000\u0134"+
|
||||
"\u0137\u0001\u0000\u0000\u0000\u0135\u0137\u0003\u0004\u0002\u0000\u0136"+
|
||||
"\u012a\u0001\u0000\u0000\u0000\u0136\u012b\u0001\u0000\u0000\u0000\u0136"+
|
||||
"\u012c\u0001\u0000\u0000\u0000\u0136\u012d\u0001\u0000\u0000\u0000\u0136"+
|
||||
"\u0130\u0001\u0000\u0000\u0000\u0136\u0131\u0001\u0000\u0000\u0000\u0136"+
|
||||
"\u0135\u0001\u0000\u0000\u0000\u0137+\u0001\u0000\u0000\u0000\u0138\u0139"+
|
||||
"\u0006\u0016\uffff\uffff\u0000\u0139\u013b\u0003.\u0017\u0000\u013a\u013c"+
|
||||
"\u00038\u001c\u0000\u013b\u013a\u0001\u0000\u0000\u0000\u013b\u013c\u0001"+
|
||||
"\u0000\u0000\u0000\u013c\u0149\u0001\u0000\u0000\u0000\u013d\u013e\u0003"+
|
||||
":\u001d\u0000\u013e\u013f\u00053\u0000\u0000\u013f\u0142\u0003,\u0016"+
|
||||
"\u0000\u0140\u0141\u0005\t\u0000\u0000\u0141\u0143\u00036\u001b\u0000"+
|
||||
"\u0142\u0140\u0001\u0000\u0000\u0000\u0142\u0143\u0001\u0000\u0000\u0000"+
|
||||
"\u0143\u0144\u0001\u0000\u0000\u0000\u0144\u0145\u00054\u0000\u0000\u0145"+
|
||||
"\u0149\u0001\u0000\u0000\u0000\u0146\u0149\u0003\u0004\u0002\u0000\u0147"+
|
||||
"\u0149\u0005B\u0000\u0000\u0148\u0138\u0001\u0000\u0000\u0000\u0148\u013d"+
|
||||
"\u0001\u0000\u0000\u0000\u0148\u0146\u0001\u0000\u0000\u0000\u0148\u0147"+
|
||||
"\u0001\u0000\u0000\u0000\u0149\u015b\u0001\u0000\u0000\u0000\u014a\u014b"+
|
||||
"\n\u0004\u0000\u0000\u014b\u014c\u00057\u0000\u0000\u014c\u014d\u0003"+
|
||||
"\u000e\u0007\u0000\u014d\u014e\u00058\u0000\u0000\u014e\u015a\u0001\u0000"+
|
||||
"\u0000\u0000\u014f\u0150\n\u0003\u0000\u0000\u0150\u0151\u00057\u0000"+
|
||||
"\u0000\u0151\u0152\u0003\u000e\u0007\u0000\u0152\u0153\u0005;\u0000\u0000"+
|
||||
"\u0153\u0154\u0003\u000e\u0007\u0000\u0154\u0155\u00058\u0000\u0000\u0155"+
|
||||
"\u015a\u0001\u0000\u0000\u0000\u0156\u0157\n\u0002\u0000\u0000\u0157\u0158"+
|
||||
"\u0005\r\u0000\u0000\u0158\u015a\u0003\u000e\u0007\u0000\u0159\u014a\u0001"+
|
||||
"\u0000\u0000\u0000\u0159\u014f\u0001\u0000\u0000\u0000\u0159\u0156\u0001"+
|
||||
"\u0000\u0000\u0000\u015a\u015d\u0001\u0000\u0000\u0000\u015b\u0159\u0001"+
|
||||
"\u0000\u0000\u0000\u015b\u015c\u0001\u0000\u0000\u0000\u015c-\u0001\u0000"+
|
||||
"\u0000\u0000\u015d\u015b\u0001\u0000\u0000\u0000\u015e\u0160\u00055\u0000"+
|
||||
"\u0000\u015f\u0161\u00030\u0018\u0000\u0160\u015f\u0001\u0000\u0000\u0000"+
|
||||
"\u0160\u0161\u0001\u0000\u0000\u0000\u0161\u0162\u0001\u0000\u0000\u0000"+
|
||||
"\u0162\u0163\u00056\u0000\u0000\u0163/\u0001\u0000\u0000\u0000\u0164\u0169"+
|
||||
"\u00032\u0019\u0000\u0165\u0166\u00059\u0000\u0000\u0166\u0168\u00032"+
|
||||
"\u0019\u0000\u0167\u0165\u0001\u0000\u0000\u0000\u0168\u016b\u0001\u0000"+
|
||||
"\u0000\u0000\u0169\u0167\u0001\u0000\u0000\u0000\u0169\u016a\u0001\u0000"+
|
||||
"\u0000\u0000\u016a1\u0001\u0000\u0000\u0000\u016b\u0169\u0001\u0000\u0000"+
|
||||
"\u0000\u016c\u016d\u0005B\u0000\u0000\u016d\u016e\u00034\u001a\u0000\u016e"+
|
||||
"\u016f\u0003\f\u0006\u0000\u016f3\u0001\u0000\u0000\u0000\u0170\u0171"+
|
||||
"\u0007\u0004\u0000\u0000\u01715\u0001\u0000\u0000\u0000\u0172\u0173\u0005"+
|
||||
"3\u0000\u0000\u0173\u0178\u0005B\u0000\u0000\u0174\u0175\u00059\u0000"+
|
||||
"\u0000\u0175\u0177\u0005B\u0000\u0000\u0176\u0174\u0001\u0000\u0000\u0000"+
|
||||
"\u0177\u017a\u0001\u0000\u0000\u0000\u0178\u0176\u0001\u0000\u0000\u0000"+
|
||||
"\u0178\u0179\u0001\u0000\u0000\u0000\u0179\u017b\u0001\u0000\u0000\u0000"+
|
||||
"\u017a\u0178\u0001\u0000\u0000\u0000\u017b\u017c\u00054\u0000\u0000\u017c"+
|
||||
"7\u0001\u0000\u0000\u0000\u017d\u017e\u00057\u0000\u0000\u017e\u017f\u0003"+
|
||||
"\u000e\u0007\u0000\u017f\u0180\u00058\u0000\u0000\u01809\u0001\u0000\u0000"+
|
||||
"\u0000\u0181\u0182\u0007\u0005\u0000\u0000\u0182;\u0001\u0000\u0000\u0000"+
|
||||
"\u0183\u0184\u0007\u0006\u0000\u0000\u0184=\u0001\u0000\u0000\u0000+S"+
|
||||
"acpw\u0087\u008c\u0090\u0095\u0099\u00a0\u00a5\u00a8\u00ac\u00af\u00b3"+
|
||||
"\u00b6\u00bc\u00bf\u00c1\u00c8\u00d0\u00d5\u00d9\u00db\u00e4\u00e9\u00ec"+
|
||||
"\u00f4\u00fc\u0104\u0106\u0118\u0128\u0136\u013b\u0142\u0148\u0159\u015b"+
|
||||
"\u0160\u0169\u0178";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
||||
+115
-110
@@ -17,8 +17,6 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.notice.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -29,11 +27,14 @@ import org.apache.hertzbeat.common.entity.alerter.NoticeTemplate;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Send alert information through FeiShu
|
||||
*/
|
||||
@@ -47,19 +48,18 @@ final class FlyBookAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl
|
||||
*/
|
||||
private static final String[] TITLE_COLOR = {"red", "yellow", "orange"};
|
||||
|
||||
|
||||
@Override
|
||||
public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, GroupAlert alert) {
|
||||
try {
|
||||
String notificationContent = JsonUtil.toJson(renderContent(noticeTemplate, alert));
|
||||
// todo priority custom the color
|
||||
// todo priority custom the color
|
||||
String cardMessage = createLarkMessage(receiver.getUserId(), notificationContent, (byte) 1);
|
||||
String webHookUrl = alerterProperties.getFlyBookWebhookUrl() + receiver.getAccessToken();
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<String> flyEntity = new HttpEntity<>(cardMessage, headers);
|
||||
ResponseEntity<CommonRobotNotifyResp> entity = restTemplate.postForEntity(webHookUrl,
|
||||
flyEntity, CommonRobotNotifyResp.class);
|
||||
flyEntity, CommonRobotNotifyResp.class);
|
||||
if (entity.getStatusCode() == HttpStatus.OK) {
|
||||
assert entity.getBody() != null;
|
||||
if (entity.getBody().getCode() == null || entity.getBody().getCode() == 0) {
|
||||
@@ -87,115 +87,120 @@ final class FlyBookAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl
|
||||
*/
|
||||
private String createLarkMessage(String userId, String notificationContent, byte priority) {
|
||||
String larkCardMessage = """
|
||||
{
|
||||
"msg_type": "interactive",
|
||||
"card": {
|
||||
"config": {
|
||||
"update_multi": true
|
||||
},
|
||||
"i18n_elements": {
|
||||
"zh_cn": [
|
||||
{
|
||||
"tag": "column_set",
|
||||
"flex_mode": "none",
|
||||
"horizontal_spacing": "default",
|
||||
"background_style": "default",
|
||||
"columns": [
|
||||
{
|
||||
"tag": "column",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "div",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "",
|
||||
"text_size": "normal",
|
||||
"text_align": "left",
|
||||
"text_color": "default"
|
||||
}
|
||||
}
|
||||
],
|
||||
"width": "weighted",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "column_set",
|
||||
"flex_mode": "none",
|
||||
"horizontal_spacing": "default",
|
||||
"background_style": "default",
|
||||
"columns": [
|
||||
{
|
||||
"tag": "column",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "div",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": %s,
|
||||
"text_size": "normal",
|
||||
"text_align": "left",
|
||||
"text_color": "default"
|
||||
}
|
||||
}
|
||||
],
|
||||
"width": "weighted",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
%s
|
||||
{
|
||||
"tag": "action",
|
||||
"actions": [
|
||||
{
|
||||
"tag": "button",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "登入控制台"
|
||||
},
|
||||
"type": "default",
|
||||
"complex_interaction": true,
|
||||
"width": "default",
|
||||
"size": "medium",
|
||||
"multi_url": {
|
||||
"url": "%s"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"i18n_header": {
|
||||
"zh_cn": {
|
||||
"title": {
|
||||
"tag": "plain_text",
|
||||
"content": "HertzBeat 告警"
|
||||
},
|
||||
"template": "%s"
|
||||
}
|
||||
}
|
||||
{
|
||||
"msg_type": "interactive",
|
||||
"card": {
|
||||
"schema": "2.0",
|
||||
"config": {
|
||||
"update_multi": true,
|
||||
"locales": [
|
||||
"en_us",
|
||||
"zh_cn"
|
||||
],
|
||||
"style": {
|
||||
"text_size": {
|
||||
"normal_v2": {
|
||||
"default": "normal",
|
||||
"pc": "normal",
|
||||
"mobile": "heading"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"direction": "vertical",
|
||||
"padding": "12px 12px 12px 12px",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "markdown",
|
||||
"content": "%s",
|
||||
"i18n_content": {
|
||||
"en_us": ""
|
||||
},
|
||||
"text_align": "left",
|
||||
"text_size": "normal_v2",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
},
|
||||
{
|
||||
"tag": "hr",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
},
|
||||
{
|
||||
"tag": "column_set",
|
||||
"horizontal_align": "left",
|
||||
"columns": [
|
||||
{
|
||||
"tag": "column",
|
||||
"width": "weighted",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "button",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "登入控制台",
|
||||
"i18n_content": {
|
||||
"en_us": "Login In"
|
||||
}
|
||||
},
|
||||
"type": "default",
|
||||
"width": "default",
|
||||
"size": "medium",
|
||||
"behaviors": [
|
||||
{
|
||||
"type": "open_url",
|
||||
"default_url": "%s",
|
||||
"pc_url": "",
|
||||
"ios_url": "",
|
||||
"android_url": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"vertical_spacing": "8px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"weight": 1
|
||||
}
|
||||
],
|
||||
"margin": "0px 0px 0px 0px"
|
||||
}
|
||||
]
|
||||
},
|
||||
"header": {
|
||||
"title": {
|
||||
"tag": "plain_text",
|
||||
"content": "HertzBeat 告警",
|
||||
"i18n_content": {
|
||||
"en_us": "HertzBeat Alarm"
|
||||
}
|
||||
},
|
||||
"subtitle": {
|
||||
"tag": "plain_text",
|
||||
"content": ""
|
||||
},
|
||||
"template": "%s",
|
||||
"padding": "12px 12px 12px 12px"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
""";
|
||||
|
||||
String atUserElement = "";
|
||||
if (StringUtils.isNotBlank(userId)) {
|
||||
String atUserId = Arrays.stream(userId.split(","))
|
||||
.map(id -> "<at id=" + id + "></at>")
|
||||
.collect(Collectors.joining(" "));
|
||||
atUserElement = String.format("""
|
||||
{
|
||||
"tag": "div",
|
||||
"text": {
|
||||
"content": "%s",
|
||||
"tag": "lark_md"
|
||||
}
|
||||
},
|
||||
""", atUserId);
|
||||
atUserElement = "\\n" + Arrays.stream(userId.split(","))
|
||||
.map(id -> "<at id=" + id + "></at>")
|
||||
.collect(Collectors.joining(" "));
|
||||
}
|
||||
return String.format(larkCardMessage, notificationContent, atUserElement, alerterProperties.getConsoleUrl(), TITLE_COLOR[priority]);
|
||||
|
||||
if (notificationContent.startsWith("\"") && notificationContent.endsWith("\"")) {
|
||||
notificationContent = StringUtils.removeStart(notificationContent, "\"");
|
||||
notificationContent = StringUtils.removeEnd(notificationContent, "\"");
|
||||
}
|
||||
|
||||
return String.format(larkCardMessage,
|
||||
notificationContent.replace("\"", "\\\"") + atUserElement,
|
||||
alerterProperties.getConsoleUrl(), TITLE_COLOR[priority]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
-3
@@ -18,12 +18,15 @@
|
||||
package org.apache.hertzbeat.alert.service;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.support.exception.AlertExpressionException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Alarm define manager service
|
||||
*/
|
||||
@@ -107,5 +110,11 @@ public interface AlertDefineService {
|
||||
* @return Real-time alarm definition list
|
||||
*/
|
||||
List<AlertDefine> getRealTimeAlertDefines();
|
||||
|
||||
|
||||
/**
|
||||
* Get define preview
|
||||
* @return Data queried based on expressions
|
||||
* @throws AlertExpressionException expression error
|
||||
*/
|
||||
List<Map<String, Object>> getDefinePreview(String datasource, String type, String expr);
|
||||
}
|
||||
|
||||
+6
@@ -28,6 +28,9 @@ import org.apache.hertzbeat.alert.dto.ExportAlertDefineDTO;
|
||||
import org.apache.hertzbeat.alert.service.AlertDefineImExportService;
|
||||
import org.apache.hertzbeat.alert.service.AlertDefineService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.util.LogUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -41,12 +44,15 @@ public abstract class AlertDefineAbstractImExportServiceImpl implements AlertDef
|
||||
@Lazy
|
||||
private AlertDefineService alertDefineService;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AlertDefineAbstractImExportServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public void importConfig(InputStream is) {
|
||||
var formList = parseImport(is)
|
||||
.stream()
|
||||
.map(this::convert)
|
||||
.toList();
|
||||
LogUtil.info(logger, "Importing alert defines from {0}", formList);
|
||||
if (!CollectionUtils.isEmpty(formList)) {
|
||||
formList.forEach(alertDefine -> {
|
||||
alertDefineService.validate(alertDefine, false);
|
||||
|
||||
+22
-4
@@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.ALERT_THRESHOLD_TYPE_REALTIME;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -29,7 +28,9 @@ import org.apache.hertzbeat.alert.calculate.PeriodicAlertRuleScheduler;
|
||||
import org.apache.hertzbeat.alert.dao.AlertDefineDao;
|
||||
import org.apache.hertzbeat.alert.service.AlertDefineImExportService;
|
||||
import org.apache.hertzbeat.alert.service.AlertDefineService;
|
||||
import org.apache.hertzbeat.alert.service.DataSourceService;
|
||||
import org.apache.hertzbeat.common.cache.CacheFactory;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.constants.ExportFileConstants;
|
||||
import org.apache.hertzbeat.common.constants.SignConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
@@ -72,18 +73,21 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
@Autowired
|
||||
private PeriodicAlertRuleScheduler periodicAlertRuleScheduler;
|
||||
|
||||
private final DataSourceService dataSourceService;
|
||||
|
||||
private final Map<String, AlertDefineImExportService> alertDefineImExportServiceMap = new HashMap<>();
|
||||
|
||||
private static final String CONTENT_TYPE = MediaType.APPLICATION_OCTET_STREAM_VALUE + SignConstants.SINGLE_MARK + "charset=" + StandardCharsets.UTF_8;
|
||||
|
||||
public AlertDefineServiceImpl(List<AlertDefineImExportService> alertDefineImExportServiceList) {
|
||||
public AlertDefineServiceImpl(List<AlertDefineImExportService> alertDefineImExportServiceList, DataSourceService dataSourceService) {
|
||||
alertDefineImExportServiceList.forEach(it -> alertDefineImExportServiceMap.put(it.type(), it));
|
||||
this.dataSourceService = dataSourceService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(AlertDefine alertDefine, boolean isModify) throws IllegalArgumentException {
|
||||
if (StringUtils.hasText(alertDefine.getExpr())) {
|
||||
if (ALERT_THRESHOLD_TYPE_REALTIME.equals(alertDefine.getType())) {
|
||||
if (CommonConstants.ALERT_THRESHOLD_TYPE_REALTIME.equals(alertDefine.getType())) {
|
||||
try {
|
||||
JexlExpressionRunner.compile(alertDefine.getExpr());
|
||||
} catch (Exception e) {
|
||||
@@ -213,9 +217,23 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
public List<AlertDefine> getRealTimeAlertDefines() {
|
||||
List<AlertDefine> alertDefines = CacheFactory.getAlertDefineCache();
|
||||
if (alertDefines == null) {
|
||||
alertDefines = alertDefineDao.findAlertDefinesByTypeAndEnableTrue(ALERT_THRESHOLD_TYPE_REALTIME);
|
||||
alertDefines = alertDefineDao.findAlertDefinesByTypeAndEnableTrue(CommonConstants.ALERT_THRESHOLD_TYPE_REALTIME);
|
||||
CacheFactory.setAlertDefineCache(alertDefines);
|
||||
}
|
||||
return alertDefines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getDefinePreview(String datasource, String type, String expr) {
|
||||
if (!StringUtils.hasText(expr) || !StringUtils.hasText(datasource) || !StringUtils.hasText(type)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
switch (type) {
|
||||
case CommonConstants.ALERT_THRESHOLD_TYPE_PERIODIC:
|
||||
return dataSourceService.calculate(datasource, expr);
|
||||
default:
|
||||
log.error("Get define preview unsupported type: {}", type);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -27,11 +27,14 @@ import org.apache.hertzbeat.common.entity.alerter.NoticeReceiver;
|
||||
import org.apache.hertzbeat.common.entity.alerter.NoticeTemplate;
|
||||
import org.apache.hertzbeat.common.support.exception.SendMessageException;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.apache.hertzbeat.common.util.LogUtil;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -62,6 +65,7 @@ public class AlibabaSmsClientImpl implements SmsClient {
|
||||
private final String accessKeySecret;
|
||||
private final String signName;
|
||||
private final String templateCode;
|
||||
private static final Logger logger = LoggerFactory.getLogger(AlibabaSmsClientImpl.class);
|
||||
|
||||
public AlibabaSmsClientImpl(AlibabaSmsProperties config) {
|
||||
if (config != null) {
|
||||
@@ -173,7 +177,7 @@ public class AlibabaSmsClientImpl implements SmsClient {
|
||||
log.info("Successfully sent SMS to phone: {}", phoneNumber);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to send SMS: {}", e.getMessage());
|
||||
LogUtil.warn(logger, "Failed to send SMS: {0}", e.getMessage());
|
||||
throw new SendMessageException(e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -192,6 +196,7 @@ public class AlibabaSmsClientImpl implements SmsClient {
|
||||
// Step 4: Build authorization header
|
||||
return ALGORITHM + " Credential=" + accessKeyId + ",SignedHeaders=host;x-acs-action;x-acs-content-sha256;x-acs-date;" + "x-acs-signature-nonce;x-acs-version,Signature=" + signature;
|
||||
} catch (Exception e) {
|
||||
LogUtil.warn(logger, "Failed to calculate authorization {0}", e.getMessage());
|
||||
throw new RuntimeException("Failed to calculate authorization", e);
|
||||
}
|
||||
}
|
||||
|
||||
+13
-2
@@ -24,11 +24,14 @@ import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.apache.hertzbeat.alert.expr.AlertExpressionEvalVisitor;
|
||||
import org.apache.hertzbeat.alert.expr.AlertExpressionLexer;
|
||||
import org.apache.hertzbeat.alert.expr.AlertExpressionParser;
|
||||
import org.apache.hertzbeat.alert.service.DataSourceService;
|
||||
import org.apache.hertzbeat.common.support.exception.AlertExpressionException;
|
||||
import org.apache.hertzbeat.common.util.ResourceBundleUtil;
|
||||
import org.apache.hertzbeat.warehouse.db.QueryExecutor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -36,6 +39,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -45,6 +49,8 @@ import java.util.concurrent.TimeUnit;
|
||||
@Slf4j
|
||||
public class DataSourceServiceImpl implements DataSourceService {
|
||||
|
||||
protected ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter");
|
||||
|
||||
@Setter
|
||||
@Autowired(required = false)
|
||||
private List<QueryExecutor> executors;
|
||||
@@ -69,7 +75,7 @@ public class DataSourceServiceImpl implements DataSourceService {
|
||||
throw new IllegalArgumentException("Empty expression");
|
||||
}
|
||||
if (executors == null || executors.isEmpty()) {
|
||||
throw new IllegalArgumentException("No query executor found");
|
||||
throw new IllegalArgumentException(bundle.getString("alerter.datasource.executor.not.found"));
|
||||
}
|
||||
QueryExecutor executor = executors.stream().filter(e -> e.support(datasource)).findFirst().orElse(null);
|
||||
|
||||
@@ -80,6 +86,9 @@ public class DataSourceServiceImpl implements DataSourceService {
|
||||
expr = expr.replaceAll("\\s+", " ");
|
||||
try {
|
||||
return evaluate(expr, executor);
|
||||
} catch (AlertExpressionException ae) {
|
||||
log.error("Calculate query parse error {}: {}", datasource, ae.getMessage());
|
||||
throw ae;
|
||||
} catch (Exception e) {
|
||||
log.error("Error executing query on datasource {}: {}", datasource, e.getMessage());
|
||||
throw new RuntimeException("Query execution failed", e);
|
||||
@@ -90,9 +99,11 @@ public class DataSourceServiceImpl implements DataSourceService {
|
||||
CommonTokenStream tokens = tokenStreamCache.get(expr, this::createTokenStream);
|
||||
AlertExpressionParser parser = new AlertExpressionParser(tokens);
|
||||
ParseTree tree = expressionCache.get(expr, e -> parser.expr());
|
||||
if (null != tokens && tokens.LA(1) != Token.EOF) {
|
||||
throw new AlertExpressionException(bundle.getString("alerter.calculate.parse.error"));
|
||||
}
|
||||
AlertExpressionEvalVisitor visitor = new AlertExpressionEvalVisitor(executor, tokens);
|
||||
return visitor.visit(tree);
|
||||
|
||||
}
|
||||
|
||||
private CommonTokenStream createTokenStream(String expr) {
|
||||
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.hertzbeat.alert.dto.VolcEngineExternEventAlert;
|
||||
import org.apache.hertzbeat.alert.dto.VolcEngineExternMetricAlert;
|
||||
import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce;
|
||||
import org.apache.hertzbeat.alert.service.ExternAlertService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Volcengine alarm entity class
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class VolcEngineExternAlertService implements ExternAlertService {
|
||||
|
||||
private final AlarmCommonReduce alarmCommonReduce;
|
||||
private static final Map<String, Integer> severityOrder = Map.of(
|
||||
CommonConstants.ALERT_SEVERITY_CRITICAL, 1,
|
||||
CommonConstants.ALERT_SEVERITY_WARNING, 2,
|
||||
CommonConstants.ALERT_SEVERITY_INFO, 3
|
||||
);
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void addExternAlert(String content) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode root = mapper.readTree(content);
|
||||
String type = root.get("Type").asText();
|
||||
if (VolcEngineExternMetricAlert.ALERT_TYPE_EVENT.equals(type)) {
|
||||
VolcEngineExternEventAlert eventAlert = JsonUtil.fromJson(content, VolcEngineExternEventAlert.class);
|
||||
if (eventAlert == null) {
|
||||
log.warn("parse extern event alert content failed! content: {}", content);
|
||||
return;
|
||||
}
|
||||
SingleAlert singleAlert = new VolcEngineAlertConverter().convertEventToSingleAlert(eventAlert);
|
||||
alarmCommonReduce.reduceAndSendAlarm(singleAlert);
|
||||
|
||||
} else {
|
||||
// deal with metric alert
|
||||
VolcEngineExternMetricAlert report = JsonUtil.fromJson(content, VolcEngineExternMetricAlert.class);
|
||||
if (report == null) {
|
||||
log.warn("parse extern metrics alert content failed! content: {}", content);
|
||||
return;
|
||||
}
|
||||
for (SingleAlert singleAlert : new VolcEngineAlertConverter().convertMetricAlertToSingeAlert(report)) {
|
||||
alarmCommonReduce.reduceAndSendAlarm(singleAlert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportSource() {
|
||||
return "volcengine";
|
||||
}
|
||||
|
||||
/**
|
||||
* Converter: VolcEngine alert to SingleAlert
|
||||
*/
|
||||
public static class VolcEngineAlertConverter {
|
||||
|
||||
/**
|
||||
* Convert VolcEngine metric alert to SingleAlert List
|
||||
*/
|
||||
public List<SingleAlert> convertMetricAlertToSingeAlert(VolcEngineExternMetricAlert alert) {
|
||||
String status = convertStatus(alert);
|
||||
if (Objects.equals(alert.getType(), VolcEngineExternMetricAlert.ALERT_TYPE_METRIC)) {
|
||||
return convertMetricAlert(alert, status, alert.getResources());
|
||||
}
|
||||
if (Objects.equals(alert.getType(), VolcEngineExternMetricAlert.ALERT_TYPE_METRICS_NODATA)) {
|
||||
return convertMetricAlert(alert, status, alert.getNoDataResources());
|
||||
}
|
||||
if (Objects.equals(alert.getType(), VolcEngineExternMetricAlert.ALERT_TYPE_NO_DATA_RECOVERED)) {
|
||||
return convertMetricAlert(alert, status, alert.getNoDataRecoveredResources());
|
||||
}
|
||||
if (Objects.equals(alert.getType(), VolcEngineExternMetricAlert.ALERT_TYPE_METRIC_RECOVERED)) {
|
||||
return convertMetricAlert(alert, status, alert.getRecoveredResources());
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
public SingleAlert convertEventToSingleAlert(VolcEngineExternEventAlert alert) {
|
||||
SingleAlert.SingleAlertBuilder builder = SingleAlert.builder()
|
||||
.status(CommonConstants.ALERT_STATUS_FIRING)
|
||||
.startAt(alert.getHappenedAt() * 1000)
|
||||
.activeAt(alert.getHappenedAt() * 1000)
|
||||
.labels(buildEventLabels(alert))
|
||||
.content(alert.getDescriptionCn())
|
||||
.annotations(new HashMap<>());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* build labels for volcengine event alert
|
||||
*/
|
||||
private Map<String, String> buildEventLabels(VolcEngineExternEventAlert event) {
|
||||
Map<String, String> labels = new HashMap<>();
|
||||
labels.put("severity", convertEventSeverity(event));
|
||||
labels.put("__source__", "volcengine");
|
||||
labels.put("resource_name", event.getDetails().getVolcResourceName());
|
||||
labels.put("account_id", event.getAccountId());
|
||||
labels.put("region", event.getRegion());
|
||||
labels.put("event_type", event.getEventType());
|
||||
labels.put("source", event.getSource());
|
||||
return labels;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* convert volcengine event alert status to heartbeat alert status
|
||||
* use the most severe level in the rules
|
||||
*
|
||||
* @param alert volcengine event alert
|
||||
* @return status
|
||||
*/
|
||||
private String convertEventSeverity(VolcEngineExternEventAlert alert) {
|
||||
return alert.getRules().stream().map(VolcEngineExternEventAlert.EventRule::getLevel)
|
||||
.min((o1, o2) -> severityOrder.get(convertCommonSeverity(o1)).compareTo(severityOrder.get(convertCommonSeverity(o2))))
|
||||
.orElse(CommonConstants.ALERT_SEVERITY_INFO);
|
||||
}
|
||||
|
||||
private String convertCommonSeverity(String level) {
|
||||
return switch (level) {
|
||||
case "critical" -> CommonConstants.ALERT_SEVERITY_CRITICAL;
|
||||
case "warning" -> CommonConstants.ALERT_SEVERITY_WARNING;
|
||||
default -> CommonConstants.ALERT_SEVERITY_INFO;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* create SingleAlert for each resources in volcengine alert
|
||||
*
|
||||
* @param alert volcengine alert
|
||||
* @param status status
|
||||
* @param resources resources
|
||||
* @return List of SingleAlert
|
||||
*/
|
||||
private List<SingleAlert> convertMetricAlert(VolcEngineExternMetricAlert alert, String status,
|
||||
List<? extends VolcEngineExternMetricAlert.Resource> resources) {
|
||||
if (CollectionUtils.isEmpty(resources)) {
|
||||
return List.of();
|
||||
}
|
||||
List<SingleAlert> result = new ArrayList<>();
|
||||
for (VolcEngineExternMetricAlert.Resource resource : resources) {
|
||||
SingleAlert.SingleAlertBuilder builder = SingleAlert.builder()
|
||||
.status(status)
|
||||
.startAt(resource.getFirstAlertTime() * 1000)
|
||||
.endAt(resource.getLastAlertTime() * 1000)
|
||||
.labels(buildLabels(alert, resource))
|
||||
.activeAt(convertHappenAt(alert.getHappenedAt()))
|
||||
.content(resource.getName() + alert.getRuleCondition())
|
||||
.annotations(buildAnnotations(resource));
|
||||
result.add(builder.build());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Long convertHappenAt(String happenAt) {
|
||||
String cleanedStr = happenAt.replace("UTC", "").replace("(", "").replace(")", "");
|
||||
DateTimeFormatter altFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssXXX");
|
||||
OffsetDateTime odt = OffsetDateTime.parse(cleanedStr, altFormatter);
|
||||
return odt.toEpochSecond() * 1000;
|
||||
}
|
||||
|
||||
private Map<String, String> buildLabels(VolcEngineExternMetricAlert alert, VolcEngineExternMetricAlert.Resource resource) {
|
||||
Map<String, String> labels = new HashMap<>();
|
||||
labels.put("__source__", "volcengine");
|
||||
labels.put("resource_name", resource.getName());
|
||||
labels.put("resource_id", resource.getId());
|
||||
labels.put("rule_id", alert.getRuleId());
|
||||
return labels;
|
||||
}
|
||||
|
||||
private Map<String, String> buildAnnotations(VolcEngineExternMetricAlert.Resource resource) {
|
||||
Map<String, String> annotations = new HashMap<>();
|
||||
if (resource instanceof VolcEngineExternMetricAlert.NoDataResource noDataResource) {
|
||||
for (VolcEngineExternMetricAlert.Metric noDataMetric : noDataResource.getNoDataMetrics()) {
|
||||
annotations.put(noDataMetric.getName(), "N/A");
|
||||
}
|
||||
}
|
||||
for (VolcEngineExternMetricAlert.Metric metric : resource.getMetrics()) {
|
||||
annotations.put(metric.getName(), metric.getCurrentValue() + metric.getUnit());
|
||||
}
|
||||
annotations.put("region", resource.getRegion());
|
||||
List<VolcEngineExternMetricAlert.Dimension> dimensions = resource.getDimensions();
|
||||
if (CollectionUtils.isNotEmpty(dimensions)) {
|
||||
for (VolcEngineExternMetricAlert.Dimension dimension : dimensions) {
|
||||
annotations.put(dimension.getNameCn(), dimension.getValue());
|
||||
}
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert volcengine alert status to heartbeat alert status
|
||||
*
|
||||
* @param alert volcengine alert
|
||||
* @return status
|
||||
*/
|
||||
private String convertStatus(VolcEngineExternMetricAlert alert) {
|
||||
String type = alert.getType();
|
||||
if (Objects.equals(type, VolcEngineExternMetricAlert.ALERT_TYPE_METRIC)
|
||||
|| Objects.equals(type, VolcEngineExternMetricAlert.ALERT_TYPE_EVENT)
|
||||
|| Objects.equals(type, VolcEngineExternMetricAlert.ALERT_TYPE_METRICS_NODATA)) {
|
||||
return CommonConstants.ALERT_STATUS_FIRING;
|
||||
}
|
||||
return CommonConstants.ALERT_STATUS_RESOLVED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,3 +32,5 @@ alerter.notify.console = Console Login
|
||||
alerter.priority.0 = Emergency Alert
|
||||
alerter.priority.1 = Critical Alert
|
||||
alerter.priority.2 = Warning Alert
|
||||
alerter.calculate.parse.error = Expression is not fully parsed, may have syntax errors or incomplete inputs
|
||||
alerter.datasource.executor.not.found = No query executor found
|
||||
|
||||
@@ -32,3 +32,5 @@ alerter.notify.console = 登入控制台
|
||||
alerter.priority.0 = 紧急告警
|
||||
alerter.priority.1 = 严重告警
|
||||
alerter.priority.2 = 警告告警
|
||||
alerter.calculate.parse.error = 表达式未完全解析,可能存在语法错误或输入不完整
|
||||
alerter.datasource.executor.not.found = 未找到查询执行器
|
||||
|
||||
@@ -32,3 +32,5 @@ alerter.notify.console = 控制台登錄
|
||||
alerter.priority.0 = 緊急警報
|
||||
alerter.priority.1 = 嚴重警報
|
||||
alerter.priority.2 = 警告警報
|
||||
alerter.calculate.parse.error = 表達式未完全解析,可能存在語法錯誤或輸入不完整
|
||||
alerter.datasource.executor.not.found = 未找到查詢執行器
|
||||
|
||||
@@ -156,7 +156,6 @@ conditionUnit
|
||||
promql
|
||||
: metricSelector instantVectorOp?
|
||||
| aggregationOperator LPAREN promql (BY labelList)? RPAREN
|
||||
| promql binaryOperator promql
|
||||
| functionCall
|
||||
| promql LBRACKET duration RBRACKET
|
||||
| promql LBRACKET duration COLON duration RBRACKET
|
||||
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.calculate;
|
||||
|
||||
import org.apache.hertzbeat.alert.dao.SingleAlertDao;
|
||||
import org.apache.hertzbeat.alert.util.AlertUtil;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* alert cache manager test
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class AlarmCacheManagerTest {
|
||||
|
||||
@Mock
|
||||
private SingleAlertDao singleAlertDao;
|
||||
|
||||
private AlarmCacheManager alarmCacheManager;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
Map<String, String> labels = new HashMap<>();
|
||||
labels.put(CommonConstants.LABEL_ALERT_SEVERITY, CommonConstants.ALERT_SEVERITY_CRITICAL);
|
||||
labels.put(CommonConstants.LABEL_DEFINE_ID, String.valueOf(1L));
|
||||
SingleAlert alert = new SingleAlert();
|
||||
alert.setContent("Alert cache manager test");
|
||||
alert.setLabels(labels);
|
||||
when(singleAlertDao.querySingleAlertsByStatus(CommonConstants.ALERT_STATUS_FIRING)).thenReturn(Collections.singletonList(alert));
|
||||
alarmCacheManager = new AlarmCacheManager(singleAlertDao);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInit() {
|
||||
Map<String, String> labels = new HashMap<>();
|
||||
labels.put(CommonConstants.LABEL_ALERT_SEVERITY, CommonConstants.ALERT_SEVERITY_CRITICAL);
|
||||
labels.put(CommonConstants.LABEL_DEFINE_ID, String.valueOf(1L));
|
||||
|
||||
String fingerprint = AlertUtil.calculateFingerprint(labels);
|
||||
SingleAlert firingSingleAlert = alarmCacheManager.getFiring(1L, fingerprint);
|
||||
assertNotNull(firingSingleAlert);
|
||||
assertEquals("Alert cache manager test", firingSingleAlert.getContent());
|
||||
alarmCacheManager.removeFiring(1L, fingerprint);
|
||||
firingSingleAlert = alarmCacheManager.getFiring(1L, fingerprint);
|
||||
assertNull(firingSingleAlert);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPending() {
|
||||
Map<String, String> labels = new HashMap<>();
|
||||
labels.put(CommonConstants.LABEL_ALERT_SEVERITY, CommonConstants.ALERT_SEVERITY_CRITICAL);
|
||||
labels.put(CommonConstants.ALERT_SEVERITY_INFO, CommonConstants.ALERT_STATUS_PENDING);
|
||||
labels.put(CommonConstants.LABEL_DEFINE_ID, String.valueOf(2L));
|
||||
|
||||
SingleAlert alert = new SingleAlert();
|
||||
alert.setContent("Alert cache manager test");
|
||||
alert.setLabels(labels);
|
||||
|
||||
String fingerprint = AlertUtil.calculateFingerprint(alert.getLabels());
|
||||
alarmCacheManager.putPending(2L, fingerprint, alert);
|
||||
|
||||
SingleAlert pendingSingleAlert = alarmCacheManager.getPending(2L, fingerprint);
|
||||
assertNotNull(pendingSingleAlert);
|
||||
alarmCacheManager.removePending(2L, fingerprint);
|
||||
pendingSingleAlert = alarmCacheManager.getPending(2L, fingerprint);
|
||||
assertNull(pendingSingleAlert);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFiring() {
|
||||
Map<String, String> labels = new HashMap<>();
|
||||
labels.put(CommonConstants.LABEL_ALERT_SEVERITY, CommonConstants.ALERT_SEVERITY_CRITICAL);
|
||||
labels.put(CommonConstants.ALERT_SEVERITY_INFO, CommonConstants.ALERT_STATUS_PENDING);
|
||||
labels.put(CommonConstants.LABEL_DEFINE_ID, String.valueOf(3L));
|
||||
|
||||
SingleAlert alert = new SingleAlert();
|
||||
alert.setContent("Alert cache manager test");
|
||||
alert.setLabels(labels);
|
||||
|
||||
String fingerprint = AlertUtil.calculateFingerprint(alert.getLabels());
|
||||
alarmCacheManager.putFiring(3L, fingerprint, alert);
|
||||
|
||||
SingleAlert firingSingleAlert = alarmCacheManager.getFiring(3L, fingerprint);
|
||||
assertNotNull(firingSingleAlert);
|
||||
alarmCacheManager.removeFiring(3L, fingerprint);
|
||||
firingSingleAlert = alarmCacheManager.getFiring(3L, fingerprint);
|
||||
assertNull(firingSingleAlert);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHistorical() {
|
||||
SingleAlert alert = new SingleAlert();
|
||||
alert.setContent("Alert cache manager test");
|
||||
alert.setLabels(Collections.singletonMap(CommonConstants.LABEL_ALERT_SEVERITY, CommonConstants.ALERT_SEVERITY_CRITICAL));
|
||||
when(singleAlertDao.querySingleAlertsByStatus(CommonConstants.ALERT_STATUS_FIRING)).thenReturn(Collections.singletonList(alert));
|
||||
alarmCacheManager = new AlarmCacheManager(singleAlertDao);
|
||||
|
||||
String fingerprint = AlertUtil.calculateFingerprint(alert.getLabels());
|
||||
SingleAlert historicalSingleAlert = alarmCacheManager.getFiring(4L, fingerprint);
|
||||
assertNotNull(historicalSingleAlert);
|
||||
SingleAlert singleAlert = alarmCacheManager.removeFiring(4L, fingerprint);
|
||||
assertNotNull(singleAlert);
|
||||
historicalSingleAlert = alarmCacheManager.getFiring(4L, fingerprint);
|
||||
assertNull(historicalSingleAlert);
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -42,6 +42,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -92,12 +93,12 @@ class PeriodicAlertCalculatorTest {
|
||||
result.put("__value__", 95.0); // Non-null, matched with threshold
|
||||
result.put("__timestamp__", System.currentTimeMillis());
|
||||
when(dataSourceService.calculate(anyString(), anyString())).thenReturn(List.of(result));
|
||||
when(alarmCacheManager.getPending(anyString())).thenReturn(null);
|
||||
when(alarmCacheManager.getPending(eq(rule.getId()), anyString())).thenReturn(null);
|
||||
periodicAlertCalculator.calculate(rule);
|
||||
// Verify that putFiring is called
|
||||
ArgumentCaptor<String> idCaptor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<SingleAlert> alertCaptor = ArgumentCaptor.forClass(SingleAlert.class);
|
||||
verify(alarmCacheManager).putFiring(idCaptor.capture(), alertCaptor.capture());
|
||||
verify(alarmCacheManager).putFiring(eq(rule.getId()), idCaptor.capture(), alertCaptor.capture());
|
||||
// Assertion alarm status and content
|
||||
SingleAlert alert = alertCaptor.getValue();
|
||||
assertAll(() -> assertEquals(CommonConstants.ALERT_STATUS_FIRING, alert.getStatus()),
|
||||
@@ -112,7 +113,7 @@ class PeriodicAlertCalculatorTest {
|
||||
result.put("__timestamp__", System.currentTimeMillis());
|
||||
when(dataSourceService.calculate(anyString(), anyString())).thenReturn(List.of(result));
|
||||
periodicAlertCalculator.calculate(rule);
|
||||
verify(alarmCacheManager, times(0)).putFiring(any(), any());
|
||||
verify(alarmCacheManager, times(0)).putFiring(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,7 +127,7 @@ class PeriodicAlertCalculatorTest {
|
||||
.triggerTimes(2).startAt(System.currentTimeMillis() - 60000)
|
||||
.activeAt(System.currentTimeMillis() - 30000)
|
||||
.build();
|
||||
when(alarmCacheManager.removeFiring(anyString())).thenReturn(pendingAlert);
|
||||
when(alarmCacheManager.removeFiring(eq(rule.getId()), anyString())).thenReturn(pendingAlert);
|
||||
when(dataSourceService.calculate(anyString(), anyString())).thenReturn(List.of(result));
|
||||
periodicAlertCalculator.calculate(rule);
|
||||
ArgumentCaptor<SingleAlert> resolvedCaptor = ArgumentCaptor.forClass(SingleAlert.class);
|
||||
|
||||
+9
-6
@@ -132,6 +132,7 @@ public class RealTimeAlertCalculatorMatchTest {
|
||||
|
||||
|
||||
AlertDefine matchDefine = new AlertDefine();
|
||||
matchDefine.setId(1L);
|
||||
matchDefine.setName("test");
|
||||
matchDefine.setExpr(
|
||||
"equals(__app__,\"prometheus\") && "
|
||||
@@ -151,8 +152,8 @@ public class RealTimeAlertCalculatorMatchTest {
|
||||
|
||||
Thread.sleep(3000);
|
||||
|
||||
verify(alarmCacheManager, times(1)).getPending(any());
|
||||
verify(alarmCacheManager, times(1)).putFiring(any(), any());
|
||||
verify(alarmCacheManager, times(1)).getPending(any(), any());
|
||||
verify(alarmCacheManager, times(1)).putFiring(any(), any(), any());
|
||||
verify(alarmCommonReduce, times(1)).reduceAndSendAlarm(any());
|
||||
}
|
||||
|
||||
@@ -180,6 +181,7 @@ public class RealTimeAlertCalculatorMatchTest {
|
||||
CollectRep.MetricsData metricsData = builder.build();
|
||||
|
||||
AlertDefine matchDefine = new AlertDefine();
|
||||
matchDefine.setId(1L);
|
||||
matchDefine.setName("test");
|
||||
matchDefine.setExpr("equals(__app__,\"prometheus\") && equals(__metrics__,\"canal_instance\") && metric_value > 0");
|
||||
matchDefine.setTemplate("Canal instance val: ${value}%");
|
||||
@@ -194,8 +196,8 @@ public class RealTimeAlertCalculatorMatchTest {
|
||||
|
||||
Thread.sleep(3000);
|
||||
|
||||
verify(alarmCacheManager, times(1)).getPending(any());
|
||||
verify(alarmCacheManager, times(1)).putFiring(any(), any());
|
||||
verify(alarmCacheManager, times(1)).getPending(any(), any());
|
||||
verify(alarmCacheManager, times(1)).putFiring(any(), any(), any());
|
||||
verify(alarmCommonReduce, times(1)).reduceAndSendAlarm(any());
|
||||
}
|
||||
|
||||
@@ -229,6 +231,7 @@ public class RealTimeAlertCalculatorMatchTest {
|
||||
CollectRep.MetricsData metricsData = builder.build();
|
||||
|
||||
AlertDefine matchDefine = new AlertDefine();
|
||||
matchDefine.setId(1L);
|
||||
matchDefine.setName("test");
|
||||
matchDefine.setExpr("equals(__app__,\"springboot3\") && equals(__metrics__,\"available\") && equals(__instance__, \"518679137103104\") && responseTime > 0");
|
||||
matchDefine.setTemplate("Canal instance val: ${value}%");
|
||||
@@ -243,8 +246,8 @@ public class RealTimeAlertCalculatorMatchTest {
|
||||
|
||||
Thread.sleep(3000);
|
||||
|
||||
verify(alarmCacheManager, times(1)).getPending(any());
|
||||
verify(alarmCacheManager, times(1)).putFiring(any(), any());
|
||||
verify(alarmCacheManager, times(1)).getPending(any(), any());
|
||||
verify(alarmCacheManager, times(1)).putFiring(any(), any(), any());
|
||||
verify(alarmCommonReduce, times(1)).reduceAndSendAlarm(any());
|
||||
}
|
||||
|
||||
|
||||
+38
@@ -17,15 +17,22 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.controller;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.hertzbeat.alert.service.impl.AlertDefineServiceImpl;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefineMonitorBind;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.support.exception.AlertExpressionException;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -100,6 +107,37 @@ class AlertDefineControllerTest {
|
||||
.andReturn();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetDefinePreview() throws Exception {
|
||||
List<Map<String, Object>> previewData = new ArrayList<>();
|
||||
Map<String, Object> row = new HashMap<>();
|
||||
row.put("__value__", 123);
|
||||
row.put("job", "spring-boot");
|
||||
previewData.add(row);
|
||||
|
||||
Mockito.when(alertDefineService.getDefinePreview(anyString(), anyString(), anyString()))
|
||||
.thenReturn(previewData);
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/api/alert/define/preview/{datasource}", "promql")
|
||||
.param("type", "periodic")
|
||||
.param("expr", "up == 1"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data[0].__value__").value(123))
|
||||
.andExpect(jsonPath("$.data[0].job").value("spring-boot"));
|
||||
|
||||
Mockito.when(alertDefineService.getDefinePreview(anyString(), anyString(), anyString()))
|
||||
.thenThrow(new AlertExpressionException("Expression error"));
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/api/alert/define/preview/{datasource}", "promql")
|
||||
.param("type", "periodic")
|
||||
.param("expr", "http_server_requests_seconds_count{!@~!!#$%^&}"))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.code").exists())
|
||||
.andExpect(jsonPath("$.msg").value("Expression error"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void modifyAlertDefine() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.put("/api/alert/define")
|
||||
|
||||
+298
-13
@@ -24,12 +24,14 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
@@ -240,11 +242,187 @@ class AlertExpressionEvalVisitorTest {
|
||||
assertEquals(10.0, result.get(0).get("__value__"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnlessOpPromql() {
|
||||
String promql = "http_server_requests_seconds_count > 10 unless http_server_requests_seconds_max > 0";
|
||||
|
||||
Map<String, Object> countValue1 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 1307);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/actuator/prometheus");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> maxValue1 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 10.007799125);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_max");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/actuator/health");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
when(mockExecutor.execute("http_server_requests_seconds_count")).thenReturn(List.of(countValue1));
|
||||
when(mockExecutor.execute("http_server_requests_seconds_max")).thenReturn(List.of(maxValue1));
|
||||
List<Map<String, Object>> result = evaluate(promql);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(1307, result.get(0).get("__value__"));
|
||||
|
||||
maxValue1.put("uri", "/actuator/prometheus");
|
||||
result = evaluate(promql);
|
||||
assertEquals(0, result.size());
|
||||
|
||||
Map<String, Object> sumValue1 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 20.018);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_sum");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/**");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
maxValue1.put("uri", "/actuator/health");
|
||||
when(mockExecutor.execute("http_server_requests_seconds_sum")).thenReturn(List.of(sumValue1));
|
||||
promql = "(http_server_requests_seconds_count > 10 unless http_server_requests_seconds_max > 0) unless http_server_requests_seconds_sum > 10";
|
||||
result = evaluate(promql);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(1307, result.get(0).get("__value__"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOrOpPromql() {
|
||||
String promql = "http_server_requests_seconds_count > 10 or jvm_threads_states_threads > 0";
|
||||
|
||||
Map<String, Object> countValue1 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 1307);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/actuator/prometheus");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> countValue2 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 16);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/**");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> countValue3 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 7);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/actuator/health");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> threadsValue1 = new HashMap<>() {
|
||||
{
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 10.007799125);
|
||||
put("__name__", "jvm_threads_states_threads");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("job", "spring-boot-app");
|
||||
put("state=", "runnable");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> threadsValue2 = new HashMap<>() {
|
||||
{
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 1);
|
||||
put("__name__", "jvm_threads_states_threads");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("job", "spring-boot-app");
|
||||
put("state=", "timed-waiting");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> threadsValue3 = new HashMap<>() {
|
||||
{
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 19.02);
|
||||
put("__name__", "jvm_threads_states_threads");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("job", "spring-boot-app");
|
||||
put("state=", "waiting");
|
||||
}
|
||||
};
|
||||
|
||||
when(mockExecutor.execute("http_server_requests_seconds_count")).thenReturn(List.of(countValue1, countValue2, countValue3));
|
||||
when(mockExecutor.execute("jvm_threads_states_threads")).thenReturn(List.of(threadsValue1, threadsValue2, threadsValue3));
|
||||
List<Map<String, Object>> result = evaluate(promql);
|
||||
assertEquals(5, result.size());
|
||||
assertTrue(result.stream().allMatch(t -> null != t.get("__value__")));
|
||||
|
||||
|
||||
when(mockExecutor.execute("jvm_threads_states_threads")).thenReturn(new ArrayList<>());
|
||||
result = evaluate(promql);
|
||||
assertEquals(2, result.size());
|
||||
assertTrue(result.stream().allMatch(t -> null != t.get("__value__")));
|
||||
assertEquals(1307, result.get(0).get("__value__"));
|
||||
|
||||
when(mockExecutor.execute("http_server_requests_seconds_count")).thenReturn(new ArrayList<>());
|
||||
when(mockExecutor.execute("jvm_threads_states_threads")).thenReturn(List.of(threadsValue1, threadsValue2, threadsValue3));
|
||||
result = evaluate(promql);
|
||||
assertEquals(3, result.size());
|
||||
assertTrue(result.stream().allMatch(t -> null != t.get("__value__")));
|
||||
assertEquals(10.007799125, result.get(0).get("__value__"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMultipleUnlessConditions() {
|
||||
when(mockExecutor.execute("metric1")).thenReturn(List.of(new HashMap<>(Map.of("__value__", 40.0))));
|
||||
when(mockExecutor.execute("metric2")).thenReturn(List.of(new HashMap<>(Map.of("__value__", 50.0))));
|
||||
when(mockExecutor.execute("metric3")).thenReturn(List.of(new HashMap<>(Map.of("__value__", 60.0))));
|
||||
when(mockExecutor.execute("metric1")).thenReturn(List.of(new HashMap<>(Map.of("job", "api", "__value__", 40.0))));
|
||||
when(mockExecutor.execute("metric2")).thenReturn(List.of(new HashMap<>(Map.of("job", "web", "__value__", 50.0))));
|
||||
when(mockExecutor.execute("metric3")).thenReturn(List.of(new HashMap<>(Map.of("job", "api", "__value__", 60.0))));
|
||||
when(mockExecutor.execute("select cpu_usage from metrics where service = 'web'")).thenReturn(
|
||||
List.of(new HashMap<>(Map.of("__value__", 40.0))));
|
||||
when(mockExecutor.execute("select memory_usage from metrics where service = 'db'")).thenReturn(
|
||||
@@ -252,15 +430,13 @@ class AlertExpressionEvalVisitorTest {
|
||||
when(mockExecutor.execute("select disk_usage from metrics where service = 'cache'")).thenReturn(
|
||||
List.of(new HashMap<>(Map.of("__value__", 60.0))));
|
||||
// promql
|
||||
List<Map<String, Object>> result = evaluate("metric1 > 30 unless metric2 > 45 unless metric3 < 70");
|
||||
assertEquals(1, result.size());
|
||||
assertNull(result.get(0).get("__value__"));
|
||||
List<Map<String, Object>> result = evaluate("(metric1 > 30 unless metric2 > 45) unless metric3 > 50");
|
||||
assertEquals(0, result.size());
|
||||
// sql
|
||||
result = evaluate("(select cpu_usage from metrics where service = 'web') > 30"
|
||||
+ " unless (select memory_usage from metrics where service = 'db') > 45"
|
||||
+ " unless (select disk_usage from metrics where service = 'cache') < 70");
|
||||
assertEquals(1, result.size());
|
||||
assertNull(result.get(0).get("__value__"));
|
||||
result = evaluate("((select cpu_usage from metrics where service = 'web') > 30"
|
||||
+ " unless (select memory_usage from metrics where service = 'db') > 55)"
|
||||
+ " unless (select disk_usage from metrics where service = 'cache') > 50");
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -320,11 +496,11 @@ class AlertExpressionEvalVisitorTest {
|
||||
List.of(new HashMap<>(Map.of("__value__", 250.0))));
|
||||
when(mockExecutor.execute("select min(response_time) from api_metrics where endpoint = '/api/users'")).thenReturn(
|
||||
List.of(new HashMap<>(Map.of("__value__", 50.0))));
|
||||
|
||||
|
||||
List<Map<String, Object>> result = evaluate("(select max(response_time) from api_metrics where endpoint = '/api/users') > 200");
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(250.0, result.get(0).get("__value__"));
|
||||
|
||||
|
||||
result = evaluate("(select min(response_time) from api_metrics where endpoint = '/api/users') < 100");
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(50.0, result.get(0).get("__value__"));
|
||||
@@ -473,6 +649,115 @@ class AlertExpressionEvalVisitorTest {
|
||||
assertEquals(80, result.get(0).get("__value__"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAndOpPromql() {
|
||||
String promql = "http_server_requests_seconds_count > 10 and http_server_requests_seconds_max > 5";
|
||||
|
||||
Map<String, Object> countValue1 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 1307);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/actuator/prometheus");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> countValue2 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 16);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/**");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> countValue3 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 7);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/actuator/health");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> maxValue1 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 10.007799125);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_max");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/actuator/prometheus");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> maxValue2 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 10);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/**");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
Map<String, Object> maxValue3 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 0);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/actuator/health");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
|
||||
when(mockExecutor.execute("http_server_requests_seconds_count")).thenReturn(List.of(countValue1, countValue2, countValue3));
|
||||
when(mockExecutor.execute("http_server_requests_seconds_max")).thenReturn(List.of(maxValue1, maxValue2, maxValue3));
|
||||
List<Map<String, Object>> result = evaluate(promql);
|
||||
assertEquals(2, result.size());
|
||||
assertEquals(1307, result.get(0).get("__value__"));
|
||||
assertEquals(16, result.get(1).get("__value__"));
|
||||
}
|
||||
|
||||
|
||||
private List<Map<String, Object>> evaluate(String expression) {
|
||||
AlertExpressionLexer lexer = new AlertExpressionLexer(CharStreams.fromString(expression));
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
|
||||
+57
-13
@@ -17,19 +17,7 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anySet;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.hertzbeat.alert.calculate.PeriodicAlertRuleScheduler;
|
||||
import org.apache.hertzbeat.alert.dao.AlertDefineDao;
|
||||
import org.apache.hertzbeat.alert.service.impl.AlertDefineServiceImpl;
|
||||
@@ -45,6 +33,27 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.ALERT_THRESHOLD_TYPE_PERIODIC;
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.ALERT_THRESHOLD_TYPE_REALTIME;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anySet;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Test case for {@link AlertDefineService}
|
||||
*/
|
||||
@@ -62,6 +71,9 @@ class AlertDefineServiceTest {
|
||||
@Mock
|
||||
private List<AlertDefineImExportService> alertDefineImExportServiceList;
|
||||
|
||||
@Mock
|
||||
private DataSourceService dataSourceService;
|
||||
|
||||
@InjectMocks
|
||||
private AlertDefineServiceImpl alertDefineService;
|
||||
|
||||
@@ -131,4 +143,36 @@ class AlertDefineServiceTest {
|
||||
assertNotNull(alertDefineService.getAlertDefines(null, null, "id", "desc", 1, 10));
|
||||
verify(alertDefineDao, times(1)).findAll(any(Specification.class), any(PageRequest.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDefinePreview() {
|
||||
String expr = "http_server_requests_seconds_count > 10";
|
||||
|
||||
Map<String, Object> countValue1 = new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 1307);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/actuator/prometheus");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
};
|
||||
when(dataSourceService.calculate(eq("promql"), eq(expr))).thenReturn(Lists.newArrayList(countValue1));
|
||||
List<Map<String, Object>> result = alertDefineService.getDefinePreview("promql", ALERT_THRESHOLD_TYPE_PERIODIC, expr);
|
||||
assertNotNull(result);
|
||||
assertEquals(1307, result.get(0).get("__value__"));
|
||||
|
||||
result = alertDefineService.getDefinePreview("promql", ALERT_THRESHOLD_TYPE_PERIODIC, null);
|
||||
assertEquals(0, result.size());
|
||||
|
||||
result = alertDefineService.getDefinePreview("promql", ALERT_THRESHOLD_TYPE_REALTIME, null);
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-2
@@ -23,7 +23,6 @@ import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce;
|
||||
import org.apache.hertzbeat.alert.service.impl.AlibabaCloudSlsExternAlertService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
@@ -43,7 +42,6 @@ import static org.mockito.Mockito.verify;
|
||||
/**
|
||||
* unit test for {@link AlibabaCloudSlsExternAlertServiceTest }
|
||||
*/
|
||||
@Disabled
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class AlibabaCloudSlsExternAlertServiceTest {
|
||||
|
||||
|
||||
+64
-41
@@ -17,29 +17,35 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.apache.hertzbeat.alert.service.impl.DataSourceServiceImpl;
|
||||
import org.apache.hertzbeat.common.support.exception.AlertExpressionException;
|
||||
import org.apache.hertzbeat.warehouse.db.QueryExecutor;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* test case for {@link DataSourceService}
|
||||
*/
|
||||
class DataSourceServiceTest {
|
||||
|
||||
|
||||
private DataSourceServiceImpl dataSourceService;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
dataSourceService = new DataSourceServiceImpl();
|
||||
@@ -51,12 +57,12 @@ class DataSourceServiceTest {
|
||||
new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
|
||||
new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
|
||||
);
|
||||
|
||||
|
||||
QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
|
||||
Mockito.when(mockExecutor.support("promql")).thenReturn(true);
|
||||
Mockito.when(mockExecutor.execute(Mockito.anyString())).thenReturn(prometheusData);
|
||||
dataSourceService.setExecutors(List.of(mockExecutor));
|
||||
|
||||
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total > 150");
|
||||
assertEquals(2, result.size());
|
||||
assertNull(result.get(0).get("__value__"));
|
||||
@@ -296,45 +302,36 @@ class DataSourceServiceTest {
|
||||
@Test
|
||||
void calculate15() {
|
||||
List<Map<String, Object>> prometheusData1 = List.of(
|
||||
new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
|
||||
new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
|
||||
new HashMap<>(Map.of("__value__", 1))
|
||||
);
|
||||
List<Map<String, Object>> prometheusData2 = List.of(
|
||||
new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
|
||||
new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
|
||||
);
|
||||
|
||||
QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
|
||||
Mockito.when(mockExecutor.support("promql")).thenReturn(true);
|
||||
Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
|
||||
Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
|
||||
Mockito.when(mockExecutor.execute("count(node_cpu_seconds_total{mode=\"user\"} > 250)")).thenReturn(prometheusData1);
|
||||
Mockito.when(mockExecutor.execute("count(node_cpu_seconds_total{mode=\"idle\"} < 220 )")).thenReturn(new ArrayList<>());
|
||||
dataSourceService.setExecutors(List.of(mockExecutor));
|
||||
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 250 and node_cpu_seconds_total{mode=\"idle\"} < 220");
|
||||
assertEquals(1, result.size());
|
||||
assertNull(result.get(0).get("__value__"));
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "count(node_cpu_seconds_total{mode=\"user\"} > 250) > 0 and count(node_cpu_seconds_total{mode=\"idle\"} < 220 ) > 0");
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void calculate16() {
|
||||
List<Map<String, Object>> prometheusData1 = List.of(
|
||||
new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
|
||||
new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
|
||||
new HashMap<>(Map.of("__value__", 1))
|
||||
);
|
||||
List<Map<String, Object>> prometheusData2 = List.of(
|
||||
new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
|
||||
new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
|
||||
new HashMap<>(Map.of("__value__", 1))
|
||||
);
|
||||
|
||||
QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
|
||||
Mockito.when(mockExecutor.support("promql")).thenReturn(true);
|
||||
Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
|
||||
Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
|
||||
Mockito.when(mockExecutor.execute("count(node_cpu_seconds_total{mode=\"user\"} > 250)")).thenReturn(prometheusData1);
|
||||
Mockito.when(mockExecutor.execute("count(node_cpu_seconds_total{mode=\"idle\"} < 220 )")).thenReturn(prometheusData2);
|
||||
dataSourceService.setExecutors(List.of(mockExecutor));
|
||||
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 50 and node_cpu_seconds_total{mode=\"idle\"} < 20");
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "count(node_cpu_seconds_total{mode=\"user\"} > 250) > 0 and count(node_cpu_seconds_total{mode=\"idle\"} < 220 ) > 0");
|
||||
assertEquals(1, result.size());
|
||||
assertNull(result.get(0).get("__value__"));
|
||||
assertNotNull(result.get(0).get("__value__"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -399,8 +396,7 @@ class DataSourceServiceTest {
|
||||
dataSourceService.setExecutors(List.of(mockExecutor));
|
||||
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 250 or node_cpu_seconds_total{mode=\"idle\"} < 20");
|
||||
assertEquals(1, result.size());
|
||||
assertNull(result.get(0).get("__value__"));
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -421,8 +417,7 @@ class DataSourceServiceTest {
|
||||
dataSourceService.setExecutors(List.of(mockExecutor));
|
||||
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 50 or node_cpu_seconds_total{mode=\"idle\"} < 320");
|
||||
assertEquals(1, result.size());
|
||||
assertNotNull(result.get(0).get("__value__"));
|
||||
assertEquals(4, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -443,8 +438,8 @@ class DataSourceServiceTest {
|
||||
dataSourceService.setExecutors(List.of(mockExecutor));
|
||||
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 50 unless node_cpu_seconds_total{mode=\"idle\"} < 320");
|
||||
assertEquals(1, result.size());
|
||||
assertNull(result.get(0).get("__value__"));
|
||||
assertEquals(2, result.size());
|
||||
assertEquals(100.0, result.get(0).get("__value__"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -465,8 +460,8 @@ class DataSourceServiceTest {
|
||||
dataSourceService.setExecutors(List.of(mockExecutor));
|
||||
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 50 unless node_cpu_seconds_total{mode=\"idle\"} < 20");
|
||||
assertEquals(1, result.size());
|
||||
assertNotNull(result.get(0).get("__value__"));
|
||||
assertEquals(2, result.size());
|
||||
assertEquals(100.0, result.get(0).get("__value__"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -487,8 +482,7 @@ class DataSourceServiceTest {
|
||||
dataSourceService.setExecutors(List.of(mockExecutor));
|
||||
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 250 unless node_cpu_seconds_total{mode=\"idle\"} < 20");
|
||||
assertEquals(1, result.size());
|
||||
assertNull(result.get(0).get("__value__"));
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -565,7 +559,6 @@ class DataSourceServiceTest {
|
||||
tokenStreamCache.invalidateAll();
|
||||
long beforeHits = tokenStreamCache.stats().hitCount();
|
||||
dataSourceService.calculate("promql", expr);
|
||||
expressionCache.invalidateAll();
|
||||
dataSourceService.calculate("promql", expr);
|
||||
long actualHits = tokenStreamCache.stats().hitCount() - beforeHits;
|
||||
assertEquals(1, actualHits, "expression cache should hit but miss");
|
||||
@@ -616,4 +609,34 @@ class DataSourceServiceTest {
|
||||
long actualHits = tokenStreamCache.stats().hitCount() - beforeHits;
|
||||
assertEquals(0, actualHits, "expression cache should miss but hit");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAlertExpressionException() {
|
||||
List<Map<String, Object>> prometheusData = List.of(
|
||||
new HashMap<>() {
|
||||
{
|
||||
put("exception", "none");
|
||||
put("instance", "host.docker.internal:8989");
|
||||
put("__value__", 1307);
|
||||
put("method", "GET");
|
||||
put("__name__", "http_server_requests_seconds_count");
|
||||
put("__timestamp__", "1.750320922467E9");
|
||||
put("error", "none");
|
||||
put("job", "spring-boot-app");
|
||||
put("uri", "/actuator/prometheus");
|
||||
put("outcome", "SUCCESS");
|
||||
put("status", "200");
|
||||
}
|
||||
});
|
||||
QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
|
||||
when(mockExecutor.support(eq("promql"))).thenReturn(true);
|
||||
when(mockExecutor.execute(eq("http_server_requests_seconds_count"))).thenReturn(prometheusData);
|
||||
|
||||
dataSourceService.setExecutors(List.of(mockExecutor));
|
||||
List<Map<String, Object>> result = dataSourceService.calculate("promql", "http_server_requests_seconds_count > 10");
|
||||
assertNotNull(result);
|
||||
assertEquals(1307, result.get(0).get("__value__"));
|
||||
|
||||
assertThrows(AlertExpressionException.class, () -> dataSourceService.calculate("promql", "http_server_requests_seconds_count{!@~!!#$%^&}"));
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -23,7 +23,6 @@ import org.apache.hertzbeat.alert.service.impl.HuaweiCloudExternAlertService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
@@ -39,7 +38,6 @@ import static org.mockito.Mockito.verify;
|
||||
/**
|
||||
* unit test for {@link AlibabaCloudSlsExternAlertServiceTest }
|
||||
*/
|
||||
@Disabled
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class HuaweiCloudExternAlertServiceTest {
|
||||
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.hertzbeat.alert.config.SmsConfig;
|
||||
import org.apache.hertzbeat.alert.config.SmslocalSmsProperties;
|
||||
import org.apache.hertzbeat.base.dao.GeneralConfigDao;
|
||||
import org.apache.hertzbeat.common.constants.GeneralConfigTypeEnum;
|
||||
import org.apache.hertzbeat.common.entity.manager.GeneralConfig;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
/**
|
||||
* unit test for {@link SmsClientFactory }
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class SmsClientFactoryTest {
|
||||
|
||||
|
||||
@Mock
|
||||
private GeneralConfigDao generalConfigDao;
|
||||
|
||||
@Mock
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Mock
|
||||
private SmsConfig yamlSmsConfig;
|
||||
|
||||
@InjectMocks
|
||||
private SmsClientFactory smsClientFactory;
|
||||
|
||||
|
||||
@Test
|
||||
void testloadDbConfig() throws JsonProcessingException {
|
||||
GeneralConfig generalConfig = new GeneralConfig();
|
||||
|
||||
SmsConfig smsConfig = new SmsConfig();
|
||||
smsConfig.setType("smslocal");
|
||||
smsConfig.setEnable(true);
|
||||
smsConfig.setSmslocal(new SmslocalSmsProperties("11"));
|
||||
|
||||
generalConfig.setContent(JsonUtil.toJson(smsConfig));
|
||||
when(objectMapper.readValue(generalConfig.getContent(), SmsConfig.class)).thenReturn(smsConfig);
|
||||
when(generalConfigDao.findByType(GeneralConfigTypeEnum.sms.name())).thenReturn(generalConfig);
|
||||
|
||||
assertNotNull(smsClientFactory.getSmsClient());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testloadYamlConfig() {
|
||||
when(generalConfigDao.findByType(GeneralConfigTypeEnum.sms.name())).thenReturn(null);
|
||||
when(yamlSmsConfig.getType()).thenReturn("smslocal");
|
||||
when(yamlSmsConfig.isEnable()).thenReturn(true);
|
||||
when(yamlSmsConfig.getSmslocal()).thenReturn(new SmslocalSmsProperties("11"));
|
||||
assertNotNull(smsClientFactory.getSmsClient());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNull() {
|
||||
when(generalConfigDao.findByType(GeneralConfigTypeEnum.sms.name())).thenReturn(null);
|
||||
when(yamlSmsConfig.getType()).thenReturn("");
|
||||
assertNull(smsClientFactory.getSmsClient());
|
||||
}
|
||||
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.hertzbeat.alert.config.SmslocalSmsProperties;
|
||||
import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
|
||||
import org.apache.hertzbeat.common.entity.alerter.NoticeReceiver;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.apache.hertzbeat.common.support.exception.SendMessageException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Test case for {@link SmsLocalSmsClientImpl}
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class SmsLocalSmsClientImplTest {
|
||||
|
||||
@Mock
|
||||
private SmslocalSmsProperties smslocalSmsProperties;
|
||||
|
||||
private SmsLocalSmsClientImpl smsLocalSmsClient;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
smsLocalSmsClient = new SmsLocalSmsClientImpl(smslocalSmsProperties);
|
||||
when(smslocalSmsProperties.getApiKey()).thenReturn("2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSendMessage() {
|
||||
assertEquals("smslocal", smsLocalSmsClient.getType());
|
||||
assertTrue(smsLocalSmsClient.checkConfig());
|
||||
//
|
||||
NoticeReceiver noticeReceiver = new NoticeReceiver();
|
||||
noticeReceiver.setPhone("13888888888");
|
||||
|
||||
SingleAlert singleAlert = new SingleAlert();
|
||||
singleAlert.setContent("test");
|
||||
|
||||
GroupAlert groupAlert = new GroupAlert();
|
||||
groupAlert.setAlerts(Lists.newArrayList(singleAlert));
|
||||
|
||||
assertThrows(SendMessageException.class,
|
||||
() -> smsLocalSmsClient.sendMessage(noticeReceiver, null, groupAlert));
|
||||
}
|
||||
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import org.apache.hertzbeat.alert.config.UniSmsProperties;
|
||||
import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
|
||||
import org.apache.hertzbeat.common.entity.alerter.NoticeReceiver;
|
||||
import org.apache.hertzbeat.common.support.exception.SendMessageException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
/**
|
||||
* Test case for {@link UniSmsClientImpl}
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class UniSmsClientImplTest {
|
||||
|
||||
@Mock
|
||||
private UniSmsProperties uniSmsProperties;
|
||||
|
||||
private UniSmsClientImpl uniSmsClient;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
uniSmsClient = new UniSmsClientImpl(uniSmsProperties);
|
||||
when(uniSmsProperties.getSignature()).thenReturn("2");
|
||||
when(uniSmsProperties.getTemplateId()).thenReturn("any(String.class)");
|
||||
when(uniSmsProperties.getAuthMode()).thenReturn("hmac");
|
||||
when(uniSmsProperties.getAccessKeyId()).thenReturn("hmac");
|
||||
when(uniSmsProperties.getAccessKeySecret()).thenReturn("hmac");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSendMessage() {
|
||||
assertEquals("unisms", uniSmsClient.getType());
|
||||
assertTrue(uniSmsClient.checkConfig());
|
||||
//
|
||||
NoticeReceiver noticeReceiver = new NoticeReceiver();
|
||||
noticeReceiver.setPhone("13888888888");
|
||||
|
||||
Map<String, String> commonLabels = new HashMap<>();
|
||||
commonLabels.put("instance", "");
|
||||
commonLabels.put("priority", "unknown");
|
||||
|
||||
Map<String, String> commonAnnotations = new HashMap<>();
|
||||
commonAnnotations.put("test", "test");
|
||||
|
||||
GroupAlert groupAlert = new GroupAlert();
|
||||
groupAlert.setCommonLabels(commonLabels);
|
||||
groupAlert.setCommonAnnotations(commonAnnotations);
|
||||
|
||||
assertThrows(SendMessageException.class,
|
||||
() -> uniSmsClient.sendMessage(noticeReceiver, null, groupAlert));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.util;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* Test case for {@link CryptoUtils}
|
||||
*/
|
||||
public class CryptoUtilsTest {
|
||||
|
||||
|
||||
@Test
|
||||
void testSha256Hex() {
|
||||
String sign = CryptoUtils.sha256Hex("Hello world.");
|
||||
assertEquals("aa3ec16e6acc809d8b2818662276256abfd2f1b441cb51574933f3d4bd115d11", sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHmacSha256Base64Debug() {
|
||||
String signature = CryptoUtils.hmacSha256Base64("your-real-key", "your-real-data");
|
||||
assertEquals("8JrfX0v5Tt3s8PfI85o6jcf5XM3C+vLlMwvFp45LupU=", signature);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHmacSha256Hex() {
|
||||
String signature = CryptoUtils.hmacSha256Hex("your-real-key", "your-real-data");;
|
||||
assertEquals("41878ccd7ecd795a2dd7ec39be7f33fed4be3ec75f5307689e39dd6f41fdbaac", signature);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package org.apache.hertzbeat.alert.util;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.util.Optional;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -58,4 +59,13 @@ class DateUtilTest {
|
||||
actualTimestamp = DateUtil.getTimeStampFromFormat(date, format);
|
||||
assertFalse(actualTimestamp.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getZonedTimeStampFromFormat() {
|
||||
String dataStr = "2025/06/02 22:56:15 GMT+08:00";
|
||||
Long time = DateUtil.getZonedTimeStampFromFormat(dataStr, "yyyy/MM/dd HH:mm:ss 'GMT'XXX");
|
||||
assertNotNull(time);
|
||||
assertEquals(1748876175000L, time);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<mqtt.version>1.3.3</mqtt.version>
|
||||
<mqtt.version>1.2.5</mqtt.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -140,10 +140,19 @@
|
||||
</dependency>
|
||||
<!-- mqtt -->
|
||||
<dependency>
|
||||
<groupId>com.hivemq</groupId>
|
||||
<artifactId>hivemq-mqtt-client</artifactId>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
|
||||
<version>${mqtt.version}</version>
|
||||
</dependency>
|
||||
<!--Bouncy Castle-->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.68</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!--plc-->
|
||||
<dependency>
|
||||
<groupId>org.apache.plc4x</groupId>
|
||||
|
||||
+156
-8
@@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.database;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
@@ -74,6 +75,7 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
// code execution related - may result in remote code execution
|
||||
"init=", "javaobjectserializer=", "runscript", "serverstatusdiffinterceptor",
|
||||
"queryinterceptors=", "statementinterceptors=", "exceptioninterceptors=",
|
||||
"xp_cmdshell", "create function", "dbms_java", "sp_sysexecute", "load_file",
|
||||
|
||||
// multiple statement execution - may lead to SQL injection
|
||||
"allowmultiqueries",
|
||||
@@ -82,6 +84,96 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
"autodeserialize", "detectcustomcollations",
|
||||
};
|
||||
|
||||
// universal bypass detection mode - applicable to all databases for dangerous command bypass detection
|
||||
private static final String[] UNIVERSAL_BYPASS_PATTERNS = {
|
||||
".*create\\s*([/\\\\]|\\\\n|/n|\\n)\\s*trigger.*",
|
||||
".*create\\s*([/\\\\]|\\\\n|/n|\\n)\\s*function.*",
|
||||
".*drop\\s*([/\\\\]|\\\\n|/n|\\n)\\s*table.*",
|
||||
".*drop\\s*([/\\\\]|\\\\n|/n|\\n)\\s*database.*",
|
||||
".*run\\s*([/\\\\]|\\\\n|/n|\\n)\\s*script.*",
|
||||
".*alter\\s*([/\\\\]|\\\\n|/n|\\n)\\s*system.*",
|
||||
".*grant\\s*([/\\\\]|\\\\n|/n|\\n)\\s*all.*",
|
||||
".*revoke\\s*([/\\\\]|\\\\n|/n|\\n)\\s*all.*",
|
||||
".*xp\\s*([/\\\\]|\\\\n|/n|\\n)\\s*cmdshell.*",
|
||||
".*load\\s*([/\\\\]|\\\\n|/n|\\n)\\s*file.*"
|
||||
};
|
||||
|
||||
// database platform specific bypass detection mode
|
||||
private static final HashMap<String, String[]> PLATFORM_BYPASS_PATTERNS = new HashMap<>();
|
||||
|
||||
static {
|
||||
// H2 database special character bypass mode
|
||||
PLATFORM_BYPASS_PATTERNS.put("h2", new String[]{
|
||||
".*(\\\\\\\\|/|\\\\|\\\\n|/n|\\n)\\s*init\\s*=.*",
|
||||
".*in\\s*([/\\\\]|\\\\n|/n|\\n)\\s*it\\s*=.*",
|
||||
".*(\\\\\\\\|/|\\\\|\\\\n|/n|\\n)\\s*runscript\\s+from.*",
|
||||
".*ru\\s*([/\\\\]|\\\\n|/n|\\n)\\s*script\\s+from.*"
|
||||
});
|
||||
|
||||
// MySQL/MariaDB bypass mode
|
||||
String[] mysqlPatterns = {
|
||||
".*allow\\s*([/\\\\]|\\\\n|/n|\\n)\\s*load\\s*([/\\\\]|\\\\n|/n|\\n)\\s*local\\s*([/\\\\]|\\\\n|/n|\\n)\\s*infile.*",
|
||||
".*allow\\s*([/\\\\]|\\\\n|/n|\\n)\\s*multi\\s*([/\\\\]|\\\\n|/n|\\n)\\s*queries.*",
|
||||
".*query\\s*([/\\\\]|\\\\n|/n|\\n)\\s*interceptors.*",
|
||||
".*statement\\s*([/\\\\]|\\\\n|/n|\\n)\\s*interceptors.*",
|
||||
".*exception\\s*([/\\\\]|\\\\n|/n|\\n)\\s*interceptors.*",
|
||||
".*auto\\s*([/\\\\]|\\\\n|/n|\\n)\\s*deserialize.*"
|
||||
};
|
||||
PLATFORM_BYPASS_PATTERNS.put("mysql", mysqlPatterns);
|
||||
PLATFORM_BYPASS_PATTERNS.put("mariadb", mysqlPatterns);
|
||||
|
||||
// PostgreSQL bypass mode
|
||||
PLATFORM_BYPASS_PATTERNS.put("postgresql", new String[]{
|
||||
".*socket\\s*([/\\\\]|\\\\n|/n|\\n)\\s*factory.*",
|
||||
".*logger\\s*([/\\\\]|\\\\n|/n|\\n)\\s*file.*",
|
||||
".*ssl\\s*([/\\\\]|\\\\n|/n|\\n)\\s*mode.*",
|
||||
".*logger\\s*([/\\\\]|\\\\n|/n|\\n)\\s*level.*"
|
||||
});
|
||||
|
||||
// SQL Server bypass mode
|
||||
PLATFORM_BYPASS_PATTERNS.put("sqlserver", new String[]{
|
||||
".*integrated\\s*([/\\\\]|\\\\n|/n|\\n)\\s*security.*",
|
||||
".*authentication\\s*([/\\\\]|\\\\n|/n|\\n)\\s*scheme.*",
|
||||
".*select\\s*([/\\\\]|\\\\n|/n|\\n)\\s*method.*",
|
||||
".*send\\s*([/\\\\]|\\\\n|/n|\\n)\\s*string\\s*([/\\\\]|\\\\n|/n|\\n)\\s*parameters\\s*([/\\\\]|\\\\n|/n|\\n)\\s*as\\s*([/\\\\]|\\\\n|/n|\\n)\\s*unicode.*",
|
||||
".*x\\s*([/\\\\]|\\\\n|/n|\\n)\\s*open\\s*([/\\\\]|\\\\n|/n|\\n)\\s*state.*",
|
||||
".*application\\s*([/\\\\]|\\\\n|/n|\\n)\\s*intent.*"
|
||||
});
|
||||
|
||||
// ClickHouse bypass mode
|
||||
PLATFORM_BYPASS_PATTERNS.put("clickhouse", new String[]{
|
||||
".*custom\\s*([/\\\\]|\\\\n|/n|\\n)\\s*http\\s*([/\\\\]|\\\\n|/n|\\n)\\s*params.*",
|
||||
".*http\\s*([/\\\\]|\\\\n|/n|\\n)\\s*connection\\s*([/\\\\]|\\\\n|/n|\\n)\\s*provider.*",
|
||||
".*check\\s*([/\\\\]|\\\\n|/n|\\n)\\s*all\\s*([/\\\\]|\\\\n|/n|\\n)\\s*nodes.*",
|
||||
".*fail\\s*([/\\\\]|\\\\n|/n|\\n)\\s*over.*",
|
||||
".*use\\s*([/\\\\]|\\\\n|/n|\\n)\\s*objects\\s*([/\\\\]|\\\\n|/n|\\n)\\s*in\\s*([/\\\\]|\\\\n|/n|\\n)\\s*arrays.*"
|
||||
});
|
||||
|
||||
// Oracle bypass mode
|
||||
PLATFORM_BYPASS_PATTERNS.put("oracle", new String[]{
|
||||
".*oracle\\s*([/\\\\]|\\\\n|/n|\\n)\\s*jdbc.*",
|
||||
".*oracle\\s*([/\\\\]|\\\\n|/n|\\n)\\s*net.*",
|
||||
".*oracle\\.jdbc\\.timezoneinfotable\\s*=.*",
|
||||
".*oracle\\.net\\.wallet_location\\s*=.*",
|
||||
".*oracle\\.net\\.ssl_server_dn_match\\s*=\\s*false.*",
|
||||
".*oracle\\.jdbc\\.enablesqlinjectionattack\\s*=\\s*true.*",
|
||||
".*oracle\\.jdbc\\.implicitstatementcachesize\\s*=\\s*0.*",
|
||||
".*oracle\\.jdbc\\.timezoneinfotable\\s*=.*",
|
||||
".*oracle\\.net\\.wallet_location\\s*=.*",
|
||||
".*oracle\\.net\\.ssl_server_dn_match\\s*=\\s*false.*",
|
||||
".*oracle\\.jdbc\\.enablesqlinjectionattack\\s*=\\s*true.*",
|
||||
".*oracle\\.jdbc\\.implicitstatementcachesize\\s*=\\s*0.*"
|
||||
});
|
||||
|
||||
// DM bypass mode
|
||||
PLATFORM_BYPASS_PATTERNS.put("dm", new String[]{
|
||||
".*login\\s*([/\\\\]|\\\\n|/n|\\n)\\s*mode.*",
|
||||
".*compatible\\s*([/\\\\]|\\\\n|/n|\\n)\\s*mode.*",
|
||||
".*en\\s*([/\\\\]|\\\\n|/n|\\n)\\s*crypt.*",
|
||||
".*ci\\s*([/\\\\]|\\\\n|/n|\\n)\\s*pher.*"
|
||||
});
|
||||
}
|
||||
|
||||
private final GlobalConnectionCache connectionCommonCache = GlobalConnectionCache.getInstance();
|
||||
|
||||
|
||||
@@ -91,8 +183,9 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
throw new IllegalArgumentException("Database collect must has jdbc params");
|
||||
}
|
||||
if (StringUtils.hasText(metrics.getJdbc().getUrl())) {
|
||||
String url = metrics.getJdbc().getUrl().toLowerCase();
|
||||
for (String keyword : VULNERABLE_KEYWORDS) {
|
||||
if (metrics.getJdbc().getUrl().contains(keyword)) {
|
||||
if (url.contains(keyword.toLowerCase())) {
|
||||
throw new IllegalArgumentException("Jdbc url prohibit contains vulnerable param " + keyword);
|
||||
}
|
||||
}
|
||||
@@ -340,6 +433,27 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively decode the URL to prevent multiple encoding bypasses.
|
||||
*
|
||||
* @param url jdbc url
|
||||
* @return decoded decoded jdbc url
|
||||
*/
|
||||
private String recursiveDecode(String url) {
|
||||
String prev;
|
||||
String decoded = url;
|
||||
int max = 5; // Decode it at most 5 times to prevent infinite loops.
|
||||
do {
|
||||
prev = decoded;
|
||||
try {
|
||||
decoded = java.net.URLDecoder.decode(prev, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
break;
|
||||
}
|
||||
} while (!prev.equals(decoded) && --max > 0);
|
||||
return decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* construct jdbc url due the jdbc protocol
|
||||
*
|
||||
@@ -355,20 +469,54 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
throw new IllegalArgumentException("JDBC URL length exceeds maximum limit of 2048 characters");
|
||||
}
|
||||
// remove special characters
|
||||
String cleanedUrl = jdbcProtocol.getUrl().replaceAll("[\\x00-\\x1F\\x7F]", "");
|
||||
String url = cleanedUrl.toLowerCase();
|
||||
String cleanedUrl = jdbcProtocol.getUrl().replaceAll("[\\x00-\\x1F\\x7F\\xA0]", "");
|
||||
String url = recursiveDecode(cleanedUrl);
|
||||
url = url.toLowerCase();
|
||||
// url format check
|
||||
if (!url.matches("^jdbc:[a-zA-Z0-9]+:([^\\s;]+)(;[^\\s;]+)*$")) {
|
||||
throw new IllegalArgumentException("Invalid JDBC URL format");
|
||||
}
|
||||
// backlist check
|
||||
for (String keyword : BLACK_LIST) {
|
||||
if (url.contains(keyword)) {
|
||||
if (url.contains(keyword.toLowerCase())) {
|
||||
throw new IllegalArgumentException("Invalid JDBC URL: contains potentially malicious parameter: " + keyword);
|
||||
}
|
||||
}
|
||||
// url format check
|
||||
if (!url.matches("^jdbc:[a-zA-Z0-9]+://[^\\s]+$")) {
|
||||
throw new IllegalArgumentException("Invalid JDBC URL format");
|
||||
// universal detection
|
||||
String normalizedUrl = url.replaceAll("[\\x00-\\x1F\\x7F\\xA0]", " ").toLowerCase();
|
||||
// universal detection of JDBC injection and deserialization attacks
|
||||
if (normalizedUrl.matches(".*jndi\\s*[:=].*")
|
||||
|| normalizedUrl.matches(".*ldap\\s*[:=].*")
|
||||
|| normalizedUrl.matches(".*rmi\\s*[:=].*")
|
||||
|| normalizedUrl.matches(".*java\\s*[:=].*")
|
||||
|| normalizedUrl.matches(".*serialization\\s*[:=].*")
|
||||
|| normalizedUrl.matches(".*deserializ.*\\s*[:=].*")
|
||||
|| normalizedUrl.matches(".*objectinputstream\\s*[:=].*")
|
||||
|| normalizedUrl.matches(".*readobject\\s*[:=].*")) {
|
||||
throw new IllegalArgumentException("Invalid JDBC URL: contains potentially malicious JNDI or deserialization parameter");
|
||||
}
|
||||
return cleanedUrl;
|
||||
// universal detection of bypass
|
||||
for (String pattern : UNIVERSAL_BYPASS_PATTERNS) {
|
||||
if (normalizedUrl.matches(pattern)) {
|
||||
throw new IllegalArgumentException("Invalid JDBC URL: contains potentially malicious bypass pattern");
|
||||
}
|
||||
}
|
||||
// database platform specific bypass detection
|
||||
if (jdbcProtocol.getPlatform() != null) {
|
||||
String platform = jdbcProtocol.getPlatform().toLowerCase();
|
||||
// check for specific bypass modes on the platform
|
||||
String[] platformPatterns = PLATFORM_BYPASS_PATTERNS.get(platform);
|
||||
if (platformPatterns != null) {
|
||||
for (String pattern : platformPatterns) {
|
||||
if (normalizedUrl.matches(pattern)) {
|
||||
throw new IllegalArgumentException("Invalid " + platform.toUpperCase() + " JDBC URL: contains potentially malicious bypass pattern");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return normalizedUrl;
|
||||
}
|
||||
assert jdbcProtocol.getPlatform() != null;
|
||||
return switch (jdbcProtocol.getPlatform()) {
|
||||
case "mysql", "mariadb" -> "jdbc:mysql://" + host + ":" + port
|
||||
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase())
|
||||
|
||||
+46
-32
@@ -68,6 +68,7 @@ import org.apache.hertzbeat.common.util.Base64Util;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.apache.hertzbeat.common.util.IpDomainUtil;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
@@ -144,37 +145,46 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
builder.setMsg(NetworkConstants.STATUS_CODE + SignConstants.BLANK + statusCode);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
this could create large objects, potentially impacting JVM memory space significantly.
|
||||
Option 1: Parse using InputStream, but this requires significant code changes;
|
||||
Option 2: Manually trigger garbage collection, similar to how it's done in Dubbo for large inputs.
|
||||
*/
|
||||
String resp = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
||||
if (!StringUtils.hasText(resp)) {
|
||||
log.info("http response entity is empty, status: {}.", statusCode);
|
||||
}
|
||||
Long responseTime = System.currentTimeMillis() - startTime;
|
||||
|
||||
long responseTime = System.currentTimeMillis() - startTime;
|
||||
String parseType = metrics.getHttp().getParseType();
|
||||
HttpEntity entity = response.getEntity();
|
||||
|
||||
try {
|
||||
switch (parseType) {
|
||||
case DispatchConstants.PARSE_JSON_PATH ->
|
||||
parseResponseByJsonPath(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||
case DispatchConstants.PARSE_PROM_QL ->
|
||||
parseResponseByPromQl(resp, metrics.getAliasFields(), metrics.getHttp(), builder);
|
||||
case DispatchConstants.PARSE_PROMETHEUS ->
|
||||
parseResponseByPrometheusExporter(response.getEntity().getContent(), metrics.getAliasFields(), builder);
|
||||
case DispatchConstants.PARSE_XML_PATH ->
|
||||
parseResponseByXmlPath(resp, metrics, builder, responseTime);
|
||||
case DispatchConstants.PARSE_WEBSITE ->
|
||||
parseResponseByWebsite(resp, metrics, metrics.getHttp(), builder, responseTime);
|
||||
case DispatchConstants.PARSE_SITE_MAP ->
|
||||
parseResponseBySiteMap(resp, metrics.getAliasFields(), builder);
|
||||
case DispatchConstants.PARSE_HEADER ->
|
||||
parseResponseByHeader(builder, metrics.getAliasFields(), response);
|
||||
case DispatchConstants.PARSE_CONFIG ->
|
||||
parseResponseByConfig(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||
default ->
|
||||
parseResponseByDefault(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||
if (DispatchConstants.PARSE_PROMETHEUS.equals(parseType)) {
|
||||
if (entity != null) {
|
||||
parseResponseByPrometheusExporter(entity.getContent(), metrics.getAliasFields(), builder);
|
||||
}
|
||||
} else if (DispatchConstants.PARSE_HEADER.equals(parseType)) {
|
||||
parseResponseByHeader(builder, metrics.getAliasFields(), response);
|
||||
// Consume entity to release connection
|
||||
EntityUtils.consumeQuietly(entity);
|
||||
} else {
|
||||
/*
|
||||
this could create large objects, potentially impacting JVM memory space significantly.
|
||||
Option 1: Parse using InputStream, but this requires significant code changes;
|
||||
Option 2: Manually trigger garbage collection, similar to how it's done in Dubbo for large inputs.
|
||||
*/
|
||||
String resp = entity == null ? "" : EntityUtils.toString(entity, StandardCharsets.UTF_8);
|
||||
if (!StringUtils.hasText(resp)) {
|
||||
log.info("http response entity is empty, status: {}.", statusCode);
|
||||
}
|
||||
switch (parseType) {
|
||||
case DispatchConstants.PARSE_JSON_PATH ->
|
||||
parseResponseByJsonPath(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||
case DispatchConstants.PARSE_PROM_QL ->
|
||||
parseResponseByPromQl(resp, metrics.getAliasFields(), metrics.getHttp(), builder);
|
||||
case DispatchConstants.PARSE_XML_PATH ->
|
||||
parseResponseByXmlPath(resp, metrics, builder, responseTime);
|
||||
case DispatchConstants.PARSE_WEBSITE ->
|
||||
parseResponseByWebsite(resp, metrics, metrics.getHttp(), builder, responseTime, statusCode);
|
||||
case DispatchConstants.PARSE_SITE_MAP ->
|
||||
parseResponseBySiteMap(resp, metrics.getAliasFields(), builder);
|
||||
case DispatchConstants.PARSE_CONFIG ->
|
||||
parseResponseByConfig(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||
default ->
|
||||
parseResponseByDefault(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.info("parse error: {}.", e.getMessage(), e);
|
||||
@@ -237,11 +247,15 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
}
|
||||
|
||||
private void parseResponseByWebsite(String resp, Metrics metrics, HttpProtocol http,
|
||||
CollectRep.MetricsData.Builder builder, Long responseTime) {
|
||||
CollectRep.MetricsData.Builder builder, Long responseTime, int statusCode) {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
int keywordNum = CollectUtil.countMatchKeyword(resp, http.getKeyword());
|
||||
for (String alias : metrics.getAliasFields()) {
|
||||
addColumnForSummary(responseTime, valueRowBuilder, keywordNum, alias);
|
||||
if (CollectorConstants.STATUS_CODE.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(Integer.toString(statusCode));
|
||||
} else {
|
||||
addColumnForSummary(responseTime, valueRowBuilder, keywordNum, alias);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
}
|
||||
@@ -852,4 +866,4 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
}
|
||||
return successCodeSet.contains(statusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-7
@@ -42,7 +42,6 @@ import javax.management.remote.JMXServiceURL;
|
||||
import javax.management.remote.rmi.RMIConnectorServer;
|
||||
import javax.naming.Context;
|
||||
import javax.rmi.ssl.SslRMIClientSocketFactory;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
import org.apache.hertzbeat.collector.collect.common.cache.AbstractConnection;
|
||||
import org.apache.hertzbeat.collector.collect.common.cache.CacheIdentifier;
|
||||
@@ -54,13 +53,15 @@ import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.JmxProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.apache.hertzbeat.common.util.LogUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* jmx protocol acquisition implementation
|
||||
*/
|
||||
@Slf4j
|
||||
public class JmxCollectImpl extends AbstractCollect {
|
||||
|
||||
private static final String JMX_URL_PREFIX = "service:jmx:rmi:///jndi/rmi://";
|
||||
@@ -75,6 +76,8 @@ public class JmxCollectImpl extends AbstractCollect {
|
||||
|
||||
private final ClassLoader jmxClassLoader;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JmxCollectImpl.class);
|
||||
|
||||
public JmxCollectImpl() {
|
||||
jmxClassLoader = new JmxClassLoader(ClassLoader.getSystemClassLoader());
|
||||
}
|
||||
@@ -195,12 +198,12 @@ public class JmxCollectImpl extends AbstractCollect {
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(exception);
|
||||
log.error("JMX IOException :{}", errorMsg);
|
||||
LogUtil.error(logger, "JMX IOException: {0}", errorMsg);
|
||||
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
|
||||
builder.setMsg(errorMsg);
|
||||
} catch (Exception e) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e);
|
||||
log.error("JMX Error :{}", errorMsg);
|
||||
LogUtil.error(logger, "JMX Error: {0}", errorMsg);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(errorMsg);
|
||||
} finally {
|
||||
@@ -221,7 +224,7 @@ public class JmxCollectImpl extends AbstractCollect {
|
||||
for (Attribute attribute : attributeList.asList()) {
|
||||
Object value = attribute.getValue();
|
||||
if (value == null) {
|
||||
log.info("attribute {} value is null.", attribute.getName());
|
||||
LogUtil.info(logger, "attribute {0} value is null.", attribute.getName());
|
||||
continue;
|
||||
}
|
||||
if (value instanceof Number || value instanceof String || value instanceof ObjectName
|
||||
@@ -245,7 +248,7 @@ public class JmxCollectImpl extends AbstractCollect {
|
||||
}
|
||||
attributeValueMap.put(attribute.getName(), builder.toString());
|
||||
} else {
|
||||
log.warn("attribute value type {} not support.", value.getClass().getName());
|
||||
LogUtil.warn(logger, "attribute value type {0} not support.", value.getClass().getName());
|
||||
}
|
||||
}
|
||||
return attributeValueMap;
|
||||
@@ -319,7 +322,7 @@ public class JmxCollectImpl extends AbstractCollect {
|
||||
connectionCommonCache.addCache(identifier, new JmxConnect(conn));
|
||||
return conn;
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to connect to JMX server: {}", e.getMessage());
|
||||
LogUtil.error(logger, "Failed to connect to JMX connection: {0}", e.getMessage());
|
||||
throw new IOException("Failed to connect to JMX server: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.mqtt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Formats the private key and certificate, supporting concatenation of multiple certificates in PEM format.
|
||||
*/
|
||||
public class CertificateFormatter {
|
||||
|
||||
public static String formatCertificateChain(String input) {
|
||||
if (input == null || input.trim().isEmpty()) {
|
||||
return input;
|
||||
}
|
||||
|
||||
String normalized = normalizeInput(input);
|
||||
|
||||
List<String> certificates = extractCertificates(normalized);
|
||||
|
||||
if (certificates.isEmpty()) {
|
||||
return formatAsSingleCertificate(normalized);
|
||||
}
|
||||
|
||||
StringBuilder formattedChain = new StringBuilder();
|
||||
for (String cert : certificates) {
|
||||
if (cert.trim().isEmpty()) continue;
|
||||
|
||||
String formatted = formatPemBlock(cert);
|
||||
formattedChain.append(formatted).append("\n");
|
||||
}
|
||||
|
||||
return formattedChain.toString().trim();
|
||||
}
|
||||
|
||||
private static String normalizeInput(String input) {
|
||||
return input
|
||||
.replace("\r\n", "\n")
|
||||
.replace("\r", "\n")
|
||||
.replaceAll("\\s*\\\\n\\s*", "\n")
|
||||
.replaceAll("(?m)^\\s+|\\s+$", "")
|
||||
.trim();
|
||||
}
|
||||
|
||||
private static List<String> extractCertificates(String input) {
|
||||
List<String> certificates = new ArrayList<>();
|
||||
String regex = "(-----BEGIN\\s+[\\w\\s]+?-----)[\\s\\S]*?(-----END\\s+[\\w\\s]+?-----)";
|
||||
|
||||
|
||||
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
|
||||
int lastEnd = 0;
|
||||
while (matcher.find()) {
|
||||
|
||||
if (matcher.start() > lastEnd) {
|
||||
String gap = input.substring(lastEnd, matcher.start());
|
||||
if (!gap.trim().isEmpty()) {
|
||||
certificates.add(gap);
|
||||
}
|
||||
}
|
||||
|
||||
certificates.add(matcher.group());
|
||||
lastEnd = matcher.end();
|
||||
}
|
||||
|
||||
|
||||
if (lastEnd < input.length()) {
|
||||
certificates.add(input.substring(lastEnd));
|
||||
}
|
||||
|
||||
return certificates;
|
||||
}
|
||||
|
||||
private static String formatPemBlock(String block) {
|
||||
try {
|
||||
Pattern pattern = Pattern.compile(
|
||||
"(-----BEGIN\\s+[\\w\\s]+?-----)(.*?)(-----END\\s+[\\w\\s]+?-----)",
|
||||
Pattern.DOTALL | Pattern.CASE_INSENSITIVE
|
||||
);
|
||||
|
||||
Matcher matcher = pattern.matcher(block);
|
||||
if (matcher.find()) {
|
||||
String header = matcher.group(1).trim();
|
||||
String body = matcher.group(2);
|
||||
String footer = matcher.group(3).trim();
|
||||
|
||||
|
||||
if (body == null) body = "";
|
||||
|
||||
String cleanBody = body
|
||||
.replaceAll("\\s", "")
|
||||
.replaceAll("\"", "")
|
||||
.trim();
|
||||
|
||||
|
||||
if (cleanBody.isEmpty() && body != null && !body.trim().isEmpty()) {
|
||||
|
||||
cleanBody = body.replaceAll("[^a-zA-Z0-9+/=]", "").trim();
|
||||
}
|
||||
|
||||
String formattedBody = formatBase64Body(cleanBody);
|
||||
|
||||
return header + "\n" + formattedBody + "\n" + footer;
|
||||
} else {
|
||||
|
||||
return formatAsCertificate(block);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
||||
private static String formatAsCertificate(String content) {
|
||||
|
||||
String cleanContent = content.replaceAll("[^a-zA-Z0-9+/=]", "").trim();
|
||||
|
||||
if (cleanContent.isEmpty()) {
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
String formattedBody = formatBase64Body(cleanContent);
|
||||
|
||||
|
||||
if (cleanContent.toLowerCase().contains("private")) {
|
||||
if (cleanContent.startsWith("MII") || cleanContent.length() > 1000) {
|
||||
return "-----BEGIN PRIVATE KEY-----\n" + formattedBody + "\n-----END PRIVATE KEY-----";
|
||||
} else {
|
||||
return "-----BEGIN RSA PRIVATE KEY-----\n" + formattedBody + "\n-----END RSA PRIVATE KEY-----";
|
||||
}
|
||||
} else {
|
||||
return "-----BEGIN CERTIFICATE-----\n" + formattedBody + "\n-----END CERTIFICATE-----";
|
||||
}
|
||||
}
|
||||
|
||||
private static String formatAsSingleCertificate(String input) {
|
||||
String cleanContent = input.replaceAll("[^a-zA-Z0-9+/=]", "").trim();
|
||||
return formatAsCertificate(cleanContent);
|
||||
}
|
||||
|
||||
private static String formatBase64Body(String body) {
|
||||
|
||||
StringBuilder formatted = new StringBuilder();
|
||||
int index = 0;
|
||||
while (index < body.length()) {
|
||||
int end = Math.min(index + 64, body.length());
|
||||
formatted.append(body.substring(index, end));
|
||||
if (end < body.length()) {
|
||||
formatted.append("\n");
|
||||
}
|
||||
index = end;
|
||||
}
|
||||
return formatted.toString().trim();
|
||||
}
|
||||
|
||||
public static String formatPrivateKey(String input) {
|
||||
if (input == null || input.trim().isEmpty()) {
|
||||
return input;
|
||||
}
|
||||
|
||||
|
||||
String normalized = normalizeInput(input);
|
||||
|
||||
|
||||
if (isPemEncapsulated(normalized)) {
|
||||
return formatPemBlock(normalized);
|
||||
}
|
||||
|
||||
return formatAsCertificate(normalized);
|
||||
}
|
||||
|
||||
private static boolean isPemEncapsulated(String block) {
|
||||
return block.contains("-----BEGIN") && block.contains("-----END");
|
||||
}
|
||||
}
|
||||
+221
-161
@@ -17,26 +17,7 @@
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.mqtt;
|
||||
|
||||
import com.hivemq.client.mqtt.MqttVersion;
|
||||
import com.hivemq.client.mqtt.datatypes.MqttQos;
|
||||
import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient;
|
||||
import com.hivemq.client.mqtt.mqtt3.Mqtt3Client;
|
||||
import com.hivemq.client.mqtt.mqtt3.Mqtt3ClientBuilder;
|
||||
import com.hivemq.client.mqtt.mqtt3.message.connect.connack.Mqtt3ConnAck;
|
||||
import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient;
|
||||
import com.hivemq.client.mqtt.mqtt5.Mqtt5Client;
|
||||
import com.hivemq.client.mqtt.mqtt5.Mqtt5ClientBuilder;
|
||||
import com.hivemq.client.mqtt.mqtt5.message.connect.connack.Mqtt5ConnAck;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
import org.apache.hertzbeat.collector.constants.CollectorConstants;
|
||||
@@ -46,13 +27,27 @@ import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.MqttProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep.MetricsData.Builder;
|
||||
import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
|
||||
import org.eclipse.paho.client.mqttv3.MqttClientPersistence;
|
||||
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
||||
import org.eclipse.paho.client.mqttv3.MqttCallback;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
|
||||
import org.eclipse.paho.client.mqttv3.IMqttToken;
|
||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* collect mqtt metrics
|
||||
* collect mqtt metrics using Eclipse Paho
|
||||
*/
|
||||
public class MqttCollectImpl extends AbstractCollect {
|
||||
|
||||
@@ -61,138 +56,224 @@ public class MqttCollectImpl extends AbstractCollect {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MqttCollectImpl.class);
|
||||
|
||||
@Override
|
||||
public void preCheck(Metrics metrics) throws IllegalArgumentException {
|
||||
MqttProtocol mqttProtocol = metrics.getMqtt();
|
||||
Assert.hasText(mqttProtocol.getHost(), "MQTT protocol host is required");
|
||||
Assert.hasText(mqttProtocol.getPort(), "MQTT protocol port is required");
|
||||
Assert.hasText(mqttProtocol.getProtocolVersion(), "MQTT protocol version is required");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(Builder builder, Metrics metrics) {
|
||||
MqttProtocol mqtt = metrics.getMqtt();
|
||||
String protocolVersion = mqtt.getProtocolVersion();
|
||||
MqttVersion mqttVersion = MqttVersion.valueOf(protocolVersion);
|
||||
if (mqttVersion == MqttVersion.MQTT_3_1_1) {
|
||||
collectWithVersion3(metrics, builder);
|
||||
} else if (mqttVersion == MqttVersion.MQTT_5_0) {
|
||||
collectWithVersion5(metrics, builder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportProtocol() {
|
||||
return DispatchConstants.PROTOCOL_MQTT;
|
||||
}
|
||||
|
||||
/**
|
||||
* collecting data of MQTT 5
|
||||
*/
|
||||
private void collectWithVersion5(Metrics metrics, Builder builder) {
|
||||
@Override
|
||||
public void preCheck(Metrics metrics) throws IllegalArgumentException {
|
||||
MqttProtocol mqttProtocol = metrics.getMqtt();
|
||||
Assert.hasText(mqttProtocol.getHost(), "MQTT protocol host is required");
|
||||
Assert.hasText(mqttProtocol.getPort(), "MQTT protocol port is required");
|
||||
|
||||
if ("mqtts".equalsIgnoreCase(mqttProtocol.getProtocol())) {
|
||||
if (Boolean.parseBoolean(mqttProtocol.getEnableMutualAuth())) {
|
||||
Assert.hasText(mqttProtocol.getCaCert(), "CA certificate is required for mutual auth");
|
||||
Assert.hasText(mqttProtocol.getClientCert(), "Client certificate is required for mutual auth");
|
||||
Assert.hasText(mqttProtocol.getClientKey(), "Client private key is required for mutual auth");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(Builder builder, Metrics metrics) {
|
||||
MqttProtocol mqttProtocol = metrics.getMqtt();
|
||||
Map<Object, String> data = new HashMap<>();
|
||||
Mqtt5AsyncClient client = buildMqtt5Client(mqttProtocol);
|
||||
long responseTime = connectClient(client, mqtt5AsyncClient -> {
|
||||
CompletableFuture<Mqtt5ConnAck> connectFuture = mqtt5AsyncClient.connect();
|
||||
try {
|
||||
connectFuture.get(Long.parseLong(mqttProtocol.getTimeout()), TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(getErrorMessage(e.getMessage()));
|
||||
|
||||
try {
|
||||
MqttAsyncClient client = buildMqttClient(mqttProtocol);
|
||||
long responseTime = connectClient(client, mqttProtocol);
|
||||
testSubscribeAndPublish(client, mqttProtocol, data);
|
||||
convertToMetricsData(builder, metrics, responseTime, data);
|
||||
client.disconnect();
|
||||
} catch (Exception e) {
|
||||
logger.error("MQTT collection error: {}", e.getMessage(), e);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg("Collection failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private MqttAsyncClient buildMqttClient(MqttProtocol protocol) throws Exception {
|
||||
String clientId = protocol.getClientId();
|
||||
|
||||
String serverUri = String.format("%s://%s:%s",
|
||||
StringUtils.equals(protocol.getProtocol(), "MQTT") ? "tcp" : "ssl",
|
||||
protocol.getHost(),
|
||||
protocol.getPort());
|
||||
|
||||
MqttClientPersistence persistence = new MemoryPersistence();
|
||||
|
||||
return new MqttAsyncClient(serverUri, clientId, persistence);
|
||||
}
|
||||
|
||||
private long connectClient(MqttAsyncClient client, MqttProtocol protocol) throws Exception {
|
||||
MqttConnectOptions connOpts = new MqttConnectOptions();
|
||||
|
||||
if (protocol.hasAuth()) {
|
||||
connOpts.setUserName(protocol.getUsername());
|
||||
connOpts.setPassword(protocol.getPassword().toCharArray());
|
||||
}
|
||||
|
||||
connOpts.setKeepAliveInterval(Integer.parseInt(protocol.getKeepalive()));
|
||||
connOpts.setConnectionTimeout(Integer.parseInt(protocol.getTimeout()) / 1000);
|
||||
connOpts.setCleanSession(true);
|
||||
connOpts.setAutomaticReconnect(false);
|
||||
if ("mqtts".equalsIgnoreCase(protocol.getProtocol())) {
|
||||
boolean insecureSkipVerify = Boolean.parseBoolean(protocol.getInsecureSkipVerify());
|
||||
if (insecureSkipVerify) {
|
||||
connOpts.setHttpsHostnameVerificationEnabled(false);
|
||||
}
|
||||
if (Boolean.parseBoolean(protocol.getEnableMutualAuth())) {
|
||||
connOpts.setSocketFactory(MqttSslFactory.getMslSocketFactory(protocol, insecureSkipVerify));
|
||||
} else {
|
||||
connOpts.setSocketFactory(MqttSslFactory.getSslSocketFactory(protocol, insecureSkipVerify));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StopWatch connectWatch = new StopWatch();
|
||||
connectWatch.start();
|
||||
|
||||
client.connect(connOpts).waitForCompletion(Long.parseLong(protocol.getTimeout()));
|
||||
connectWatch.stop();
|
||||
return connectWatch.getTotalTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test MQTT subscribe and publish capabilities
|
||||
*/
|
||||
private void testSubscribeAndPublish(MqttAsyncClient client, MqttProtocol protocol, Map<Object, String> data) {
|
||||
|
||||
// 1 test subscribe
|
||||
if (StringUtils.isNotBlank(protocol.getTopic())) {
|
||||
String subscribe = testSubscribe(client, protocol.getTopic());
|
||||
if (StringUtils.isBlank(subscribe)) {
|
||||
data.put("canSubscribe", "Subscription successful");
|
||||
} else {
|
||||
data.put("canSubscribe", String.format("Subscription failed: %s", subscribe));
|
||||
}
|
||||
|
||||
} else {
|
||||
data.put("canSubscribe", "No topic, subscription test skipped");
|
||||
}
|
||||
|
||||
|
||||
// 2 test publish
|
||||
if (StringUtils.isNotBlank(protocol.getTestMessage())) {
|
||||
String publish = testPublish(client, protocol.getTopic(), protocol.getTestMessage());
|
||||
if (StringUtils.isBlank(publish)) {
|
||||
data.put("canPublish", "Message published successfully");
|
||||
|
||||
// 3 test receive message
|
||||
String receivedData = getReceivedData(client, protocol.getTopic());
|
||||
data.put("canReceive", receivedData);
|
||||
} else {
|
||||
data.put("canPublish", String.format("Message publishing failed: %s", publish));
|
||||
data.put("canReceive", "Message reception skipped due to failed publish");
|
||||
}
|
||||
} else {
|
||||
data.put("canPublish", "No test message, publish test skipped");
|
||||
data.put("canReceive", "No test message, receive test skipped");
|
||||
}
|
||||
|
||||
|
||||
// 4 test unsubscribe
|
||||
if (StringUtils.isNotBlank(protocol.getTopic())) {
|
||||
String subscribe = testUnSubscribe(client, protocol.getTopic());
|
||||
if (StringUtils.isBlank(subscribe)) {
|
||||
data.put("canUnSubscribe", "Unsubscription successful");
|
||||
} else {
|
||||
data.put("canUnSubscribe", String.format("Unsubscription failed: %s", subscribe));
|
||||
}
|
||||
} else {
|
||||
data.put("canUnSubscribe", "No topic, unsubscription test skipped");
|
||||
}
|
||||
}
|
||||
|
||||
private String getReceivedData(MqttAsyncClient client, String topic) {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final StringBuilder messageHolder = new StringBuilder();
|
||||
|
||||
|
||||
client.setCallback(new MqttCallback() {
|
||||
@Override
|
||||
public void connectionLost(Throwable cause) {
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageArrived(String arrivedTopic, MqttMessage message) {
|
||||
|
||||
if (topic.equals(arrivedTopic)) {
|
||||
messageHolder.append(new String(message.getPayload()));
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deliveryComplete(IMqttDeliveryToken token) {
|
||||
}
|
||||
});
|
||||
testDescribeAndPublish5(client, mqttProtocol, data);
|
||||
convertToMetricsData(builder, metrics, responseTime, data);
|
||||
client.disconnect();
|
||||
|
||||
try {
|
||||
boolean received = latch.await(5, TimeUnit.SECONDS);
|
||||
if (messageHolder.length() > 0) {
|
||||
return messageHolder.toString();
|
||||
} else if (!received) {
|
||||
return "Message reception timed out after 5 seconds";
|
||||
} else {
|
||||
return "No valid message received";
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return e.getMessage();
|
||||
} finally {
|
||||
client.setCallback(null);
|
||||
}
|
||||
}
|
||||
|
||||
private String testSubscribe(MqttAsyncClient client, String topic) {
|
||||
try {
|
||||
IMqttToken subToken = client.subscribe(topic, 1);
|
||||
subToken.waitForCompletion(5000);
|
||||
return "";
|
||||
} catch (MqttException e) {
|
||||
logger.warn("MQTT subscribe test failed: {}", e.getMessage());
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private String testPublish(MqttAsyncClient client, String topic, String message) {
|
||||
try {
|
||||
MqttMessage mqttMessage = new MqttMessage(message.getBytes());
|
||||
mqttMessage.setQos(1);
|
||||
|
||||
IMqttToken pubToken = client.publish(topic, mqttMessage);
|
||||
pubToken.waitForCompletion(5000);
|
||||
|
||||
return "";
|
||||
} catch (MqttException e) {
|
||||
logger.warn("MQTT publish test failed: {}", e.getMessage());
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private String testUnSubscribe(MqttAsyncClient client, String topic) {
|
||||
try {
|
||||
IMqttToken unsubToken = client.unsubscribe(topic);
|
||||
unsubToken.waitForCompletion(5000);
|
||||
return "";
|
||||
} catch (MqttException e) {
|
||||
logger.warn("MQTT unsubscribe test failed: {}", e.getMessage());
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* collecting data of MQTT 3.1.1
|
||||
* Convert collected data to MetricsData
|
||||
*/
|
||||
private void collectWithVersion3(Metrics metrics, Builder builder) {
|
||||
MqttProtocol mqttProtocol = metrics.getMqtt();
|
||||
Map<Object, String> data = new HashMap<>();
|
||||
Mqtt3AsyncClient client = buildMqtt3Client(mqttProtocol);
|
||||
long responseTime = connectClient(client, mqtt3AsyncClient -> {
|
||||
CompletableFuture<Mqtt3ConnAck> connectFuture = mqtt3AsyncClient.connect();
|
||||
try {
|
||||
connectFuture.get(Long.parseLong(mqttProtocol.getTimeout()), TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(getErrorMessage(e.getMessage()));
|
||||
}
|
||||
});
|
||||
testDescribeAndPublish3(client, mqttProtocol, data);
|
||||
convertToMetricsData(builder, metrics, responseTime, data);
|
||||
client.disconnect();
|
||||
}
|
||||
|
||||
private void testDescribeAndPublish3(Mqtt3AsyncClient client, MqttProtocol mqttProtocol, Map<Object, String> data) {
|
||||
data.put("canDescribe", test(() -> {
|
||||
client.subscribeWith().topicFilter(mqttProtocol.getTopic()).qos(MqttQos.AT_LEAST_ONCE).send();
|
||||
client.unsubscribeWith().topicFilter(mqttProtocol.getTopic()).send();
|
||||
}, "subscribe").toString());
|
||||
|
||||
data.put("canPublish", !mqttProtocol.testPublish() ? Boolean.FALSE.toString() : test(() -> {
|
||||
client.publishWith().topic(mqttProtocol.getTopic())
|
||||
.payload(mqttProtocol.getTestMessage().getBytes(StandardCharsets.UTF_8))
|
||||
.qos(MqttQos.AT_LEAST_ONCE).send();
|
||||
data.put("canPublish", Boolean.TRUE.toString());
|
||||
}, "publish").toString());
|
||||
}
|
||||
|
||||
private void testDescribeAndPublish5(Mqtt5AsyncClient client, MqttProtocol mqttProtocol, Map<Object, String> data) {
|
||||
data.put("canDescribe", test(() -> {
|
||||
client.subscribeWith().topicFilter(mqttProtocol.getTopic()).qos(MqttQos.AT_LEAST_ONCE).send();
|
||||
client.unsubscribeWith().topicFilter(mqttProtocol.getTopic()).send();
|
||||
}, "subscribe").toString());
|
||||
|
||||
data.put("canPublish", !mqttProtocol.testPublish() ? Boolean.FALSE.toString() : test(() -> {
|
||||
client.publishWith().topic(mqttProtocol.getTopic())
|
||||
.payload(mqttProtocol.getTestMessage().getBytes(StandardCharsets.UTF_8))
|
||||
.qos(MqttQos.AT_LEAST_ONCE).send();
|
||||
data.put("canPublish", Boolean.TRUE.toString());
|
||||
}, "publish").toString());
|
||||
}
|
||||
|
||||
private Mqtt5AsyncClient buildMqtt5Client(MqttProtocol mqttProtocol) {
|
||||
Mqtt5ClientBuilder mqtt5ClientBuilder = Mqtt5Client.builder()
|
||||
.serverHost(mqttProtocol.getHost())
|
||||
.identifier(mqttProtocol.getClientId())
|
||||
.serverPort(Integer.parseInt(mqttProtocol.getPort()));
|
||||
|
||||
if (mqttProtocol.hasAuth()) {
|
||||
mqtt5ClientBuilder.simpleAuth().username(mqttProtocol.getUsername())
|
||||
.password(mqttProtocol.getPassword().getBytes(StandardCharsets.UTF_8))
|
||||
.applySimpleAuth();
|
||||
}
|
||||
return mqtt5ClientBuilder.buildAsync();
|
||||
}
|
||||
|
||||
private Mqtt3AsyncClient buildMqtt3Client(MqttProtocol mqttProtocol) {
|
||||
|
||||
Mqtt3ClientBuilder mqtt3ClientBuilder = Mqtt3Client.builder()
|
||||
.serverHost(mqttProtocol.getHost())
|
||||
.identifier(mqttProtocol.getClientId())
|
||||
.serverPort(Integer.parseInt(mqttProtocol.getPort()));
|
||||
|
||||
if (mqttProtocol.hasAuth()) {
|
||||
mqtt3ClientBuilder.simpleAuth().username(mqttProtocol.getUsername())
|
||||
.password(mqttProtocol.getPassword().getBytes(StandardCharsets.UTF_8))
|
||||
.applySimpleAuth();
|
||||
}
|
||||
return mqtt3ClientBuilder.buildAsync();
|
||||
}
|
||||
|
||||
public <T> long connectClient(T client, Consumer<T> connect) {
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
connect.accept(client);
|
||||
stopWatch.stop();
|
||||
return stopWatch.getTotalTimeMillis();
|
||||
}
|
||||
|
||||
private void convertToMetricsData(Builder builder, Metrics metrics, long responseTime, Map<Object, String> data) {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String column : metrics.getAliasFields()) {
|
||||
@@ -207,25 +288,4 @@ public class MqttCollectImpl extends AbstractCollect {
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
}
|
||||
|
||||
private Boolean test(Runnable runnable, String operationName) {
|
||||
try {
|
||||
runnable.run();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
logger.error("{} fail", operationName, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getErrorMessage(String errorMessage) {
|
||||
if (StringUtils.isBlank(errorMessage)) {
|
||||
return "connect failed";
|
||||
}
|
||||
String[] split = errorMessage.split(":");
|
||||
if (split.length > 1) {
|
||||
return Arrays.stream(split).skip(1).collect(Collectors.joining(":"));
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.mqtt;
|
||||
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.MqttProtocol;
|
||||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.openssl.PEMKeyPair;
|
||||
import org.bouncycastle.openssl.PEMParser;
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
||||
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Security;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Support MQTT SSL Factory
|
||||
*/
|
||||
public class MqttSslFactory {
|
||||
|
||||
/**
|
||||
* Get MSL Socket Factory
|
||||
*/
|
||||
public static SSLSocketFactory getMslSocketFactory(MqttProtocol mqttProtocol, boolean insecureSkipVerify) {
|
||||
try {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
ks.load(null, null);
|
||||
|
||||
Certificate[] chain = null;
|
||||
if (mqttProtocol.getClientCert() != null && !mqttProtocol.getClientCert().isEmpty()) {
|
||||
String formatClientCert = CertificateFormatter.formatCertificateChain(mqttProtocol.getClientCert());
|
||||
try (InputStream certIn = new ByteArrayInputStream(formatClientCert.getBytes())) {
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
Collection<? extends Certificate> certs = cf.generateCertificates(certIn);
|
||||
chain = certs.toArray(new Certificate[0]);
|
||||
}
|
||||
}
|
||||
|
||||
PrivateKey privateKey;
|
||||
if (mqttProtocol.getClientKey() != null && !mqttProtocol.getClientKey().isEmpty()) {
|
||||
String formatClientKey = CertificateFormatter.formatPrivateKey(mqttProtocol.getClientKey());
|
||||
try (PEMParser pemParser = new PEMParser(new StringReader(formatClientKey))) {
|
||||
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
|
||||
Object object = pemParser.readObject();
|
||||
|
||||
if (object instanceof PEMKeyPair) {
|
||||
privateKey = converter.getPrivateKey(((PEMKeyPair) object).getPrivateKeyInfo());
|
||||
} else if (object instanceof PrivateKeyInfo) {
|
||||
privateKey = converter.getPrivateKey((PrivateKeyInfo) object);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported private key type");
|
||||
}
|
||||
|
||||
ks.setKeyEntry("private-key", privateKey, "".toCharArray(), chain);
|
||||
}
|
||||
}
|
||||
|
||||
TrustManager[] trustManagers;
|
||||
if (insecureSkipVerify) {
|
||||
trustManagers = createInsecureTrustManager();
|
||||
} else {
|
||||
String formatCaCert = CertificateFormatter.formatCertificateChain(mqttProtocol.getCaCert());
|
||||
KeyStore trustStore = createMergedTrustStore(formatCaCert);
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
tmf.init(trustStore);
|
||||
trustManagers = tmf.getTrustManagers();
|
||||
}
|
||||
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
kmf.init(ks, "".toCharArray());
|
||||
|
||||
|
||||
SSLContext context = SSLContext.getInstance(mqttProtocol.getTlsVersion());
|
||||
context.init(kmf.getKeyManagers(), trustManagers, null);
|
||||
|
||||
return context.getSocketFactory();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Fails to SSL initialize: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SSL Socket Factory
|
||||
*/
|
||||
public static SSLSocketFactory getSslSocketFactory(MqttProtocol mqttProtocol, boolean insecureSkipVerify) {
|
||||
try {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
|
||||
TrustManager[] trustManagers;
|
||||
if (insecureSkipVerify) {
|
||||
trustManagers = createInsecureTrustManager();
|
||||
} else {
|
||||
|
||||
String formatCaCert = CertificateFormatter.formatCertificateChain(mqttProtocol.getCaCert());
|
||||
KeyStore trustStore = createMergedTrustStore(formatCaCert);
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
tmf.init(trustStore);
|
||||
trustManagers = tmf.getTrustManagers();
|
||||
}
|
||||
|
||||
SSLContext sslContext = SSLContext.getInstance(mqttProtocol.getTlsVersion());
|
||||
sslContext.init(null, trustManagers, null);
|
||||
|
||||
return sslContext.getSocketFactory();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Fails to SSL initialize: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static TrustManager[] createInsecureTrustManager() {
|
||||
return new TrustManager[]{
|
||||
new X509TrustManager() {
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static KeyStore createMergedTrustStore(String caCertPem) throws Exception {
|
||||
KeyStore mergedKs = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
mergedKs.load(null, null);
|
||||
|
||||
|
||||
TrustManagerFactory systemTmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
systemTmf.init((KeyStore) null);
|
||||
X509TrustManager systemTm = (X509TrustManager) systemTmf.getTrustManagers()[0];
|
||||
|
||||
int systemIndex = 1;
|
||||
for (X509Certificate cert : systemTm.getAcceptedIssuers()) {
|
||||
mergedKs.setCertificateEntry("system-ca-" + systemIndex++, cert);
|
||||
}
|
||||
|
||||
|
||||
if (caCertPem != null && !caCertPem.isEmpty()) {
|
||||
try (InputStream caIn = new ByteArrayInputStream(caCertPem.getBytes())) {
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
Collection<? extends Certificate> customCerts = cf.generateCertificates(caIn);
|
||||
|
||||
int customIndex = 1;
|
||||
for (Certificate cert : customCerts) {
|
||||
mergedKs.setCertificateEntry("custom-ca-" + customIndex++, cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mergedKs;
|
||||
}
|
||||
}
|
||||
+26
@@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.http;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@@ -25,6 +26,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.HttpProtocol;
|
||||
@@ -73,6 +75,30 @@ class HttpCollectImplTest {
|
||||
assert "http".equals(protocol);
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseResponseByWebsite() {
|
||||
HttpProtocol http = HttpProtocol.builder().build();
|
||||
http.setMethod("GET");
|
||||
http.setHost("http://127.0.0.1");
|
||||
http.setUrl("/");
|
||||
http.setPort("8428");
|
||||
http.setParseType("website");
|
||||
http.setEnableUrlEncoding("true");
|
||||
Metrics metrics = Metrics.builder()
|
||||
.http(http)
|
||||
.aliasFields(Lists.newArrayList("responseTime", "keyword", "statusCode"))
|
||||
.build();
|
||||
CollectRep.MetricsData.Builder builder = CollectRep.MetricsData.newBuilder();
|
||||
httpCollectImpl.collect(builder, metrics);
|
||||
|
||||
assertNotNull(builder.getValuesList());
|
||||
for (CollectRep.ValueRow row : builder.getValuesList()) {
|
||||
assertNotNull(row.getColumns(0));
|
||||
assertEquals(row.getColumns(1), "0");
|
||||
assertEquals(row.getColumns(2), "200");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseResponseByXmlPath() throws Exception {
|
||||
// Create a sample XML response
|
||||
|
||||
+61
-78
@@ -17,108 +17,91 @@
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.mqtt;
|
||||
|
||||
import com.hivemq.client.mqtt.MqttVersion;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.MqttProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
/**
|
||||
* Test case for {@link MqttCollectImpl}
|
||||
*/
|
||||
public class MqttCollectTest {
|
||||
class MqttCollectTest {
|
||||
private MqttCollectImpl mqttCollect;
|
||||
private Metrics metrics;
|
||||
private CollectRep.MetricsData.Builder builder;
|
||||
private MqttProtocol.MqttProtocolBuilder mqttBuilder;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
mqttCollect = new MqttCollectImpl();
|
||||
MqttProtocol mqtt = MqttProtocol.builder().build();
|
||||
metrics = Metrics.builder()
|
||||
.mqtt(mqtt)
|
||||
.build();
|
||||
builder = CollectRep.MetricsData.newBuilder();
|
||||
metrics = new Metrics();
|
||||
|
||||
// Initialize base MQTT parameters for test cases
|
||||
mqttBuilder = MqttProtocol.builder()
|
||||
.host("example.com")
|
||||
.port("1883")
|
||||
.protocol("mqtt")
|
||||
.timeout("5000")
|
||||
.keepalive("60");
|
||||
}
|
||||
|
||||
// Region: preCheck validation tests
|
||||
|
||||
@Test
|
||||
// Verify preCheck throws exception when host is missing
|
||||
void preCheckShouldThrowWhenHostMissing() {
|
||||
metrics.setMqtt(mqttBuilder.host("").build());
|
||||
assertThrows(IllegalArgumentException.class, () -> mqttCollect.preCheck(metrics));
|
||||
}
|
||||
|
||||
@Test
|
||||
void preCheck() {
|
||||
// host is empty
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
mqttCollect.preCheck(metrics);
|
||||
});
|
||||
|
||||
// port is empty
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
MqttProtocol mqtt = MqttProtocol.builder().build();
|
||||
mqtt.setHost("example.com");
|
||||
metrics.setMqtt(mqtt);
|
||||
mqttCollect.preCheck(metrics);
|
||||
});
|
||||
|
||||
// protocol version is empty
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
MqttProtocol mqtt = MqttProtocol.builder().build();
|
||||
mqtt.setHost("example.com");
|
||||
mqtt.setPort("1883");
|
||||
metrics.setMqtt(mqtt);
|
||||
mqttCollect.preCheck(metrics);
|
||||
});
|
||||
|
||||
// everything is ok
|
||||
assertDoesNotThrow(() -> {
|
||||
MqttProtocol mqtt = MqttProtocol.builder().build();
|
||||
mqtt.setHost("example.com");
|
||||
mqtt.setPort("1883");
|
||||
metrics.setMqtt(mqtt);
|
||||
mqtt.setProtocolVersion("3.1.1");
|
||||
mqttCollect.preCheck(metrics);
|
||||
});
|
||||
// Verify preCheck throws exception when port is missing
|
||||
void preCheckShouldThrowWhenPortMissing() {
|
||||
metrics.setMqtt(mqttBuilder.port("").build());
|
||||
assertThrows(IllegalArgumentException.class, () -> mqttCollect.preCheck(metrics));
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportProtocol() {
|
||||
Assertions.assertEquals(DispatchConstants.PROTOCOL_MQTT, mqttCollect.supportProtocol());
|
||||
// Verify preCheck throws exception when MQTTS mutual auth is enabled but CA cert is missing
|
||||
void preCheckShouldThrowWhenMqttsMutualAuthMissingCerts() {
|
||||
metrics.setMqtt(mqttBuilder
|
||||
.protocol("mqtts")
|
||||
.enableMutualAuth("true")
|
||||
.caCert("")
|
||||
.clientCert("client.crt")
|
||||
.clientKey("client.key")
|
||||
.build());
|
||||
assertThrows(IllegalArgumentException.class, () -> mqttCollect.preCheck(metrics));
|
||||
}
|
||||
|
||||
@Test
|
||||
void collect() {
|
||||
// with version 3.1.1
|
||||
assertDoesNotThrow(() -> {
|
||||
MqttProtocol mqtt = MqttProtocol.builder().build();
|
||||
mqtt.setHost("example.com");
|
||||
mqtt.setPort("1883");
|
||||
mqtt.setClientId("clientid");
|
||||
mqtt.setTimeout("1");
|
||||
mqtt.setProtocolVersion(MqttVersion.MQTT_3_1_1.name());
|
||||
// Verify preCheck succeeds with valid standard MQTT parameters
|
||||
void preCheckShouldSucceedWithValidMqttParams() {
|
||||
metrics.setMqtt(mqttBuilder.build());
|
||||
assertDoesNotThrow(() -> mqttCollect.preCheck(metrics));
|
||||
}
|
||||
|
||||
metrics.setMqtt(mqtt);
|
||||
metrics.setAliasFields(new ArrayList<>());
|
||||
@Test
|
||||
// Verify preCheck succeeds with valid MQTTS parameters including mutual authentication
|
||||
void preCheckShouldSucceedWithValidMqttsMutualAuth() {
|
||||
metrics.setMqtt(mqttBuilder
|
||||
.protocol("mqtts")
|
||||
.enableMutualAuth("true")
|
||||
.caCert("ca.pem")
|
||||
.clientCert("client.crt")
|
||||
.clientKey("client.key")
|
||||
.build());
|
||||
assertDoesNotThrow(() -> mqttCollect.preCheck(metrics));
|
||||
}
|
||||
// End region
|
||||
|
||||
mqttCollect.collect(builder, metrics);
|
||||
});
|
||||
|
||||
|
||||
assertDoesNotThrow(() -> {
|
||||
MqttProtocol mqtt = MqttProtocol.builder().build();
|
||||
mqtt.setHost("example.com");
|
||||
mqtt.setPort("1883");
|
||||
mqtt.setClientId("clientid");
|
||||
mqtt.setTimeout("1");
|
||||
mqtt.setProtocolVersion(MqttVersion.MQTT_5_0.name());
|
||||
|
||||
metrics.setMqtt(mqtt);
|
||||
metrics.setAliasFields(new ArrayList<>());
|
||||
|
||||
mqttCollect.collect(builder, metrics);
|
||||
});
|
||||
@Test
|
||||
// Verify supportProtocol method returns correct MQTT constant
|
||||
void supportProtocolShouldReturnMqttConstant() {
|
||||
assertEquals(DispatchConstants.PROTOCOL_MQTT, mqttCollect.supportProtocol());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ spring:
|
||||
|
||||
collector:
|
||||
info:
|
||||
version: ${COLLECTOR_VERSION:1.7.1}
|
||||
version: ${COLLECTOR_VERSION:1.7.2}
|
||||
ip: ${COLLECTOR_IP:}
|
||||
dispatch:
|
||||
entrance:
|
||||
|
||||
+1
-1
@@ -47,6 +47,6 @@ public interface CollectorConstants extends NetworkConstants {
|
||||
|
||||
String RESPONSE_TIME = "responseTime";
|
||||
|
||||
String STATUS_CODE = "StatusCode";
|
||||
String STATUS_CODE = "statusCode";
|
||||
|
||||
}
|
||||
+5
@@ -87,6 +87,11 @@ public interface CommonConstants {
|
||||
*/
|
||||
String LABEL_INSTANCE = "instance";
|
||||
|
||||
/**
|
||||
* label key: defineid
|
||||
*/
|
||||
String LABEL_DEFINE_ID = "defineid";
|
||||
|
||||
/**
|
||||
* label key: alert name
|
||||
*/
|
||||
|
||||
+2
-2
@@ -81,12 +81,12 @@ public class GroupAlert {
|
||||
|
||||
@Schema(title = "Common Annotations", example = "{\"summary\": \"High CPU usage detected\", \"description\": \"CPU usage is back to normal for server1\"}")
|
||||
@Convert(converter = JsonMapAttributeConverter.class)
|
||||
@Column(length = 4096)
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private Map<String, String> commonAnnotations;
|
||||
|
||||
@Schema(title = "Alert Fingerprints", example = "[\"dxsdfdsf\"]")
|
||||
@Convert(converter = JsonStringListAttributeConverter.class)
|
||||
@Column(length = 8192)
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private List<String> alertFingerprints;
|
||||
|
||||
@Schema(title = "The creator of this record", example = "tom")
|
||||
|
||||
+58
-41
@@ -33,49 +33,73 @@ import org.apache.commons.lang3.StringUtils;
|
||||
public class MqttProtocol implements CommonRequestProtocol, Protocol {
|
||||
|
||||
/**
|
||||
* ip address or domain name of the peer host
|
||||
*/
|
||||
private String host;
|
||||
|
||||
/**
|
||||
* peer host port
|
||||
*/
|
||||
private String port;
|
||||
|
||||
/**
|
||||
* username
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* password
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* time out period
|
||||
*/
|
||||
private String timeout;
|
||||
|
||||
/**
|
||||
* client id
|
||||
* mqtt client id
|
||||
*/
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* message used to test whether the mqtt connection can be pushed normally
|
||||
* mqtt username
|
||||
*/
|
||||
private String testMessage;
|
||||
|
||||
private String username;
|
||||
/**
|
||||
* protocol version of mqtt
|
||||
* mqtt password
|
||||
*/
|
||||
private String protocolVersion;
|
||||
|
||||
private String password;
|
||||
/**
|
||||
* monitor topic
|
||||
* mqtt host
|
||||
*/
|
||||
private String host;
|
||||
/**
|
||||
* mqtt port
|
||||
*/
|
||||
private String port;
|
||||
/**
|
||||
* mqtt protocol version
|
||||
* MQTT,MQTTS
|
||||
*/
|
||||
private String protocol;
|
||||
/**
|
||||
* mqtt connect timeout
|
||||
* the maximum time to wait for a connection to be established
|
||||
*/
|
||||
private String timeout;
|
||||
/**
|
||||
* mqtt keepalive
|
||||
* between ping requests to the broker to keep the connection alive
|
||||
*/
|
||||
private String keepalive;
|
||||
/**
|
||||
* mqtt topic name
|
||||
*/
|
||||
private String topic;
|
||||
/**
|
||||
* mqtt publish message
|
||||
*/
|
||||
private String testMessage;
|
||||
/**
|
||||
* mqtt tls version
|
||||
* TLSv1.2, TLSv1.3
|
||||
*/
|
||||
private String tlsVersion;
|
||||
/**
|
||||
* mqtt tls insecure skip verify server certificate
|
||||
*/
|
||||
private String insecureSkipVerify;
|
||||
/**
|
||||
* mqtt tls ca cert
|
||||
*/
|
||||
private String caCert;
|
||||
/**
|
||||
* mqtt tls enable mutual auth
|
||||
*/
|
||||
private String enableMutualAuth;
|
||||
/**
|
||||
* mqtt tls client cert
|
||||
*/
|
||||
private String clientCert;
|
||||
/**
|
||||
* mqtt tls client key
|
||||
*/
|
||||
private String clientKey;
|
||||
|
||||
/**
|
||||
* Determine whether authentication is required
|
||||
@@ -85,11 +109,4 @@ public class MqttProtocol implements CommonRequestProtocol, Protocol {
|
||||
return StringUtils.isNotBlank(this.username) && StringUtils.isNotBlank(this.password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether you need to test whether messages can be pushed normally
|
||||
* @return turn if it has test message
|
||||
*/
|
||||
public boolean testPublish(){
|
||||
return StringUtils.isNotBlank(this.testMessage);
|
||||
}
|
||||
}
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.support.exception;
|
||||
|
||||
/**
|
||||
* Alert expression exception
|
||||
*/
|
||||
public class AlertExpressionException extends RuntimeException {
|
||||
|
||||
public AlertExpressionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package org.apache.hertzbeat.common.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
@@ -44,6 +46,7 @@ public final class JsonUtil {
|
||||
OBJECT_MAPPER
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
|
||||
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
|
||||
.registerModule(new JavaTimeModule());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.util;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
/**
|
||||
* Log utility class that provides formatted logging methods with location information.
|
||||
* This class enhances standard SLF4J logging by automatically adding caller location details.
|
||||
*/
|
||||
public class LogUtil {
|
||||
|
||||
private static final String TEMPLATE_REGEX = "\\{\\d}";
|
||||
|
||||
/**
|
||||
* Print debug level formatted log
|
||||
* Example: LogUtil.debug(logger, "hello,{0},here has a {1} exception", "other information");
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static void debug(Logger logger, String msg, Object... params) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
if (ArrayUtils.isEmpty(params)) {
|
||||
logger.debug(LogUtil.buildLocationInfo() + msg);
|
||||
} else {
|
||||
logger.debug(LogUtil.buildLocationInfo() + format(msg, params));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print info level formatted log
|
||||
* Example: LogUtil.info(logger, "hello,{0},{1} exception", "dear", "database operation");
|
||||
*/
|
||||
public static void info(Logger logger, String msg, Object... params) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
if (ArrayUtils.isEmpty(params)) {
|
||||
logger.info(LogUtil.buildLocationInfo() + msg);
|
||||
} else {
|
||||
logger.info(LogUtil.buildLocationInfo() + format(msg, params));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print warn level formatted log
|
||||
*/
|
||||
public static void warn(Logger logger, String msg, Object... params) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
if (ArrayUtils.isEmpty(params)) {
|
||||
logger.warn(LogUtil.buildLocationInfo() + msg);
|
||||
} else {
|
||||
logger.warn(LogUtil.buildLocationInfo() + format(msg, params));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print error level formatted log, use {0},{1},.. for parameter replacement
|
||||
* Example: LogUtil.error(logger, "hello,{0}, a {1} exception occurred here", "dear", "database operation");
|
||||
*/
|
||||
public static void error(Logger logger, String msg, Object... params) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
if (ArrayUtils.isEmpty(params)) {
|
||||
logger.error(LogUtil.buildLocationInfo() + msg);
|
||||
} else {
|
||||
logger.error(LogUtil.buildLocationInfo() + format(msg, params));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print warn level formatted log with exception, use {0},{1},.. for parameter replacement
|
||||
* Example: LogUtil.warn(logger, e, "hello,{0}, a {1} exception occurred here", "dear", "database operation");
|
||||
*/
|
||||
public static void warn(Logger logger, Throwable e, String msg, Object... params) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
if (ArrayUtils.isEmpty(params)) {
|
||||
logger.warn(LogUtil.buildLocationInfo() + msg, e);
|
||||
} else {
|
||||
logger.warn(LogUtil.buildLocationInfo() + format(msg, params), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print error level formatted log with exception, use {0},{1},.. for parameter replacement
|
||||
* Example: LogUtil.error(logger, e, "hello,{0}, a {1} exception occurred here", "dear", "database operation");
|
||||
*/
|
||||
public static void error(Logger logger, Throwable e, String msg, Object... params) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
if (ArrayUtils.isEmpty(params)) {
|
||||
logger.error(LogUtil.buildLocationInfo() + msg, e);
|
||||
} else {
|
||||
logger.error(LogUtil.buildLocationInfo() + format(msg, params), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the class name, method and line number that calls LogUtil
|
||||
*
|
||||
* @return location information string
|
||||
*/
|
||||
private static String buildLocationInfo() {
|
||||
StringBuilder header = new StringBuilder();
|
||||
// LOG4J2-1029 new Throwable().getStackTrace is faster than Thread.currentThread().getStackTrace().
|
||||
final StackTraceElement[] stackTraceElements = new Throwable().getStackTrace();
|
||||
|
||||
for (int i = 0; i < stackTraceElements.length - 1; i++) {
|
||||
StackTraceElement currentStackTrace = stackTraceElements[i];
|
||||
StackTraceElement nextStackTrace = stackTraceElements[i + 1];
|
||||
|
||||
// If current stack trace is in LogUtil
|
||||
// and next stack trace is not in LogUtil
|
||||
// then the next node is the caller of LogUtil
|
||||
if (LogUtil.class.getName().equals(currentStackTrace.getClassName())
|
||||
&& !LogUtil.class.getName().equals(nextStackTrace.getClassName())) {
|
||||
String stackTrace = nextStackTrace.toString();
|
||||
header.append(" ").append(StringUtils.removeStart(stackTrace, nextStackTrace.getClassName() + "."));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return header.append(":").toString();
|
||||
}
|
||||
|
||||
private static String format(String msg, Object... params) {
|
||||
if (StringUtils.isEmpty(msg)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
if (params != null && params.length > 0) {
|
||||
msg = MessageFormat.format(msg, params);
|
||||
}
|
||||
return msg.replaceAll(TEMPLATE_REGEX, StringUtils.EMPTY);
|
||||
}
|
||||
|
||||
private static String toString(Object object) {
|
||||
return ToStringBuilder.reflectionToString(object, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.util;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.slf4j.Logger;
|
||||
import java.lang.reflect.Method;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.contains;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class LogUtilTest {
|
||||
|
||||
@Mock
|
||||
private Logger mockLogger;
|
||||
|
||||
private AutoCloseable mocks;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
mocks = MockitoAnnotations.openMocks(this);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws Exception {
|
||||
if (mocks != null) {
|
||||
mocks.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFormat_noParams_returnsOriginalMessage() throws Exception {
|
||||
String original = "hello world";
|
||||
Method formatMethod = LogUtil.class.getDeclaredMethod("format", String.class, Object[].class);
|
||||
formatMethod.setAccessible(true);
|
||||
String formatted = (String) formatMethod.invoke(null, original, new Object[0]);
|
||||
assertEquals(original, formatted);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFormat_withParams_replacesPlaceholders() throws Exception {
|
||||
String template = "hello,{0}, world {1}!";
|
||||
Method formatMethod = LogUtil.class.getDeclaredMethod("format", String.class, Object[].class);
|
||||
formatMethod.setAccessible(true);
|
||||
Object[] params = {"Alice", 123};
|
||||
String result = (String) formatMethod.invoke(null, template, params);
|
||||
assertTrue(result.contains("hello,Alice"));
|
||||
assertTrue(result.contains("world 123!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDebug_noParams_logsRawMessage() {
|
||||
when(mockLogger.isDebugEnabled()).thenReturn(true);
|
||||
String msg = "test-debug";
|
||||
LogUtil.debug(mockLogger, msg);
|
||||
verify(mockLogger).debug(contains(msg));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDebug_withParams_logsFormattedMessage() {
|
||||
when(mockLogger.isDebugEnabled()).thenReturn(true);
|
||||
LogUtil.debug(mockLogger, "user={0}", "Bob");
|
||||
verify(mockLogger).debug(contains("user=Bob"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInfo_levelOff_doesNotLog() {
|
||||
when(mockLogger.isInfoEnabled()).thenReturn(false);
|
||||
LogUtil.info(mockLogger, "should-not-log");
|
||||
verify(mockLogger, never()).info(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWarn_withException_logsMessageAndException() {
|
||||
when(mockLogger.isWarnEnabled()).thenReturn(true);
|
||||
RuntimeException ex = new RuntimeException("warn-ex");
|
||||
LogUtil.warn(mockLogger, ex, "warning {0}", "occurred");
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(mockLogger).warn(captor.capture(), eq(ex));
|
||||
assertTrue(captor.getValue().contains("warning occurred"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testError_withExceptionAndParams_logsError() {
|
||||
when(mockLogger.isErrorEnabled()).thenReturn(true);
|
||||
RuntimeException ex = new RuntimeException("err");
|
||||
LogUtil.error(mockLogger, ex, "fail code {0}", 500);
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(mockLogger).error(captor.capture(), eq(ex));
|
||||
assertTrue(captor.getValue().contains("fail code 500"));
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,6 @@
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<mysql.version>8.0.30</mysql.version>
|
||||
<postgresql.version>42.5.5</postgresql.version>
|
||||
</properties>
|
||||
|
||||
@@ -82,9 +81,8 @@
|
||||
|
||||
<!-- JDBC Drivers -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.version}</version>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<scope>test</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
+7
-5
@@ -79,7 +79,7 @@ public class KafkaCollectE2eTest {
|
||||
.withNetwork(network)
|
||||
.withNetworkAliases(ZOOKEEPER_NAME)
|
||||
.waitingFor(Wait.forListeningPort())
|
||||
.withStartupTimeout(Duration.ofSeconds(30));
|
||||
.withStartupTimeout(Duration.ofSeconds(120));
|
||||
zookeeperContainer.setPortBindings(Collections.singletonList(ZOOKEEPER_PORT + ":" + ZOOKEEPER_PORT));
|
||||
|
||||
Startables.deepStart(Stream.of(zookeeperContainer)).join();
|
||||
@@ -90,7 +90,8 @@ public class KafkaCollectE2eTest {
|
||||
.withNetworkAliases(KAFKA_NAME)
|
||||
.withLogConsumer(
|
||||
new Slf4jLogConsumer(
|
||||
DockerLoggerFactory.getLogger(KAFKA_IMAGE_NAME)));
|
||||
DockerLoggerFactory.getLogger(KAFKA_IMAGE_NAME)))
|
||||
.withStartupTimeout(Duration.ofSeconds(120));
|
||||
Startables.deepStart(Stream.of(kafkaContainer)).join();
|
||||
}
|
||||
|
||||
@@ -113,11 +114,12 @@ public class KafkaCollectE2eTest {
|
||||
// Create Topic
|
||||
Properties properties = new Properties();
|
||||
properties.put("bootstrap.servers", bootstrapServers);
|
||||
AdminClient adminClient = KafkaAdminClient.create(properties);
|
||||
int numPartitions = 1;
|
||||
short replicationFactor = 1;
|
||||
NewTopic newTopic = new NewTopic(topicName, numPartitions, replicationFactor);
|
||||
adminClient.createTopics(Collections.singletonList(newTopic)).all().get(60, TimeUnit.SECONDS);
|
||||
try (AdminClient adminClient = KafkaAdminClient.create(properties)) {
|
||||
NewTopic newTopic = new NewTopic(topicName, numPartitions, replicationFactor);
|
||||
adminClient.createTopics(Collections.singletonList(newTopic)).all().get(60, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
// Verify the information of topic list monitoring
|
||||
builder = CollectRep.MetricsData.newBuilder();
|
||||
|
||||
+2
-2
@@ -43,12 +43,12 @@ public class SwaggerConfig {
|
||||
.info(new Info()
|
||||
.title("HertzBeat")
|
||||
.description("An Open-Source Real-time Monitoring Tool.")
|
||||
.termsOfService("https://hertzbeat.com/")
|
||||
.termsOfService("https://hertzbeat.apache.org/")
|
||||
.contact(new Contact().name("tom").url("https://github.com/tomsun28").email("tomsun28@outlook.com"))
|
||||
.version("v1.0")
|
||||
.license(new License().name("Apache 2.0").url("https://www.apache.org/licenses/LICENSE-2.0")))
|
||||
.externalDocs(new ExternalDocumentation()
|
||||
.description("HertzBeat Docs").url("https://hertzbeat.com/docs/"))
|
||||
.description("HertzBeat Docs").url("https://hertzbeat.apache.org/docs/"))
|
||||
.addSecurityItem(new SecurityRequirement().addList(SECURITY_SCHEME_NAME))
|
||||
.components(new Components().addSecuritySchemes(SECURITY_SCHEME_NAME,
|
||||
new SecurityScheme()
|
||||
|
||||
+8
@@ -121,6 +121,14 @@ public class MonitorsController {
|
||||
monitorService.export(ids, type, res);
|
||||
}
|
||||
|
||||
@GetMapping("/export/all")
|
||||
@Operation(summary = "export all monitor config", description = "export all monitor config")
|
||||
public void exportAll(
|
||||
@Parameter(description = "Export Type:JSON,EXCEL,YAML") @RequestParam(defaultValue = "JSON") String type,
|
||||
HttpServletResponse res) throws Exception {
|
||||
monitorService.exportAll(type, res);
|
||||
}
|
||||
|
||||
@PostMapping("/import")
|
||||
@Operation(summary = "import monitor config", description = "import monitor config")
|
||||
public ResponseEntity<Message<Void>> export(MultipartFile file) throws Exception {
|
||||
|
||||
+9
@@ -173,6 +173,15 @@ public interface MonitorService {
|
||||
*/
|
||||
void export(List<Long> ids, String type, HttpServletResponse res) throws Exception;
|
||||
|
||||
/**
|
||||
* Export All Monitoring Configuration
|
||||
*
|
||||
* @param type file type
|
||||
* @param res response
|
||||
* @throws Exception This exception will be thrown if the export fails
|
||||
*/
|
||||
void exportAll(String type, HttpServletResponse res) throws Exception;
|
||||
|
||||
/**
|
||||
* Import Monitoring Configuration
|
||||
*
|
||||
|
||||
+3
@@ -120,6 +120,9 @@ public class BulletinServiceImpl implements BulletinService {
|
||||
List<BulletinMetricsData.Data> dataList = new ArrayList<>();
|
||||
for (Long monitorId : bulletin.getMonitorIds()) {
|
||||
Monitor monitor = monitorService.getMonitor(monitorId);
|
||||
if (null == monitor) {
|
||||
continue;
|
||||
}
|
||||
BulletinMetricsData.Data.DataBuilder dataBuilder = BulletinMetricsData.Data.builder()
|
||||
.monitorId(monitorId)
|
||||
.monitorName(monitor.getName())
|
||||
|
||||
+12
@@ -235,6 +235,18 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
imExportService.exportConfig(res.getOutputStream(), ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportAll(String type, HttpServletResponse res) throws Exception {
|
||||
// Get all monitor IDs from the database
|
||||
List<Long> allMonitorIds = monitorDao.findAll()
|
||||
.stream()
|
||||
.map(Monitor::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Use the existing export method to export all monitors
|
||||
export(allMonitorIds, type, res);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importConfig(MultipartFile file) throws Exception {
|
||||
var fileName = FileUtil.getFileName(file);
|
||||
|
||||
@@ -62,14 +62,6 @@ sureness:
|
||||
8tVt4bisXQ13rbN0oxhUZR73M6EByXIO+SV5
|
||||
dKhaX0csgOCTlCxq20yhmUea6H6JIpSE2Rwp'
|
||||
|
||||
otel:
|
||||
traces:
|
||||
exporter: none
|
||||
metrics:
|
||||
exporter: none
|
||||
logs:
|
||||
exporter: none
|
||||
|
||||
---
|
||||
spring:
|
||||
config:
|
||||
@@ -146,7 +138,7 @@ warehouse:
|
||||
username: root
|
||||
password: root
|
||||
insert:
|
||||
buffer-size: 1000
|
||||
buffer-size: 100
|
||||
flush-interval: 3
|
||||
cluster:
|
||||
enabled: false
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
|
||||
-- ensure every sql can rerun without error
|
||||
|
||||
-- Modify common_annotations column to TEXT (H2 TEXT is equivalent to CLOB)
|
||||
ALTER TABLE HZB_ALERT_GROUP ALTER COLUMN common_annotations CLOB;
|
||||
|
||||
-- Modify alert_fingerprints column to TEXT (H2 TEXT is equivalent to CLOB)
|
||||
ALTER TABLE HZB_ALERT_GROUP ALTER COLUMN alert_fingerprints CLOB;
|
||||
@@ -0,0 +1,64 @@
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
|
||||
-- ensure every sql can rerun without error
|
||||
|
||||
-- Modify hzb_alert_group table columns to TEXT type to resolve MySQL row size limit issue
|
||||
|
||||
DELIMITER //
|
||||
CREATE PROCEDURE ModifyGroupAlertColumns()
|
||||
BEGIN
|
||||
DECLARE table_exists INT;
|
||||
DECLARE col_exists INT;
|
||||
|
||||
-- Check if the table exists
|
||||
SELECT COUNT(*) INTO table_exists
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'HZB_ALERT_GROUP';
|
||||
|
||||
IF table_exists = 1 THEN
|
||||
-- Check and modify common_annotations column to TEXT
|
||||
SELECT COUNT(*) INTO col_exists
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'HZB_ALERT_GROUP'
|
||||
AND COLUMN_NAME = 'common_annotations'
|
||||
AND DATA_TYPE != 'text';
|
||||
|
||||
IF col_exists = 1 THEN
|
||||
ALTER TABLE HZB_ALERT_GROUP MODIFY COLUMN common_annotations TEXT;
|
||||
END IF;
|
||||
|
||||
-- Check and modify alert_fingerprints column to TEXT
|
||||
SELECT COUNT(*) INTO col_exists
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'HZB_ALERT_GROUP'
|
||||
AND COLUMN_NAME = 'alert_fingerprints'
|
||||
AND DATA_TYPE != 'text';
|
||||
|
||||
IF col_exists = 1 THEN
|
||||
ALTER TABLE HZB_ALERT_GROUP MODIFY COLUMN alert_fingerprints TEXT;
|
||||
END IF;
|
||||
END IF;
|
||||
END //
|
||||
|
||||
DELIMITER ;
|
||||
|
||||
CALL ModifyGroupAlertColumns();
|
||||
DROP PROCEDURE IF EXISTS ModifyGroupAlertColumns;
|
||||
COMMIT;
|
||||
@@ -0,0 +1,25 @@
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
|
||||
-- ensure every sql can rerun without error
|
||||
|
||||
-- Modify hzb_alert_group table columns to TEXT type to resolve row size limit issue
|
||||
|
||||
ALTER TABLE HZB_ALERT_GROUP ALTER COLUMN common_annotations TYPE TEXT;
|
||||
ALTER TABLE HZB_ALERT_GROUP ALTER COLUMN alert_fingerprints TYPE TEXT;
|
||||
|
||||
commit;
|
||||
@@ -26,8 +26,8 @@ name:
|
||||
help:
|
||||
zh-CN: HertzBeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMX 协议</a> 对 Apache ActiveMQ 消息中间件的运行状态,节点,Topic等相关指标(broker、topic、memory pool、class loading、thread)进行监测。<br><span class='help_module_span'>⚠️注意:您需要在 ActiveMQ 开启 JMX 服务。<a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>点击查看开启步骤</a>。</span>
|
||||
en-US: "HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMX protocol</a> to monitor the running status, nodes, topics, and other metrics of Apache ActiveMQ message-oriented middleware. <br><span class='help_module_span'>⚠️Note: You should enable the JMX service in ActiveMQ. <a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/activemq'>Click here to view the specific steps.</a></span>"
|
||||
zh-TW: HertzBeat使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMX 協定</a> 對 Apache ActiveMQ 消息中介軟體的運行狀態,節點,Topic 等相關名額(broker、topic、memory pool、class loading、thread)進行監測。<br><span class='help_module_span'> ⚠️注意:您需要在 ActiveMQ 開啟 JMX 服務。<a class='help_module_content' href=' https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>點擊查看開啟步驟</a>。</span>
|
||||
ja-JP: HertzBeatは <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMXプロトコルを介して</a> Apache ActiveMQメッセージングシステムのランタイムステータス、ノード、トピック、その他の関連メトリックを監視します。<br><span class='help_module_span'> ⚠️注意:ActiveMQ で JMX サービスを有効にする必要があります。<a class='help_module_content' href=' https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>クリックしてガイドを見ます</a>。</span>
|
||||
zh-TW: HertzBeat使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMX 協定</a> 對 Apache ActiveMQ 消息中介軟體的運行狀態,節點,Topic 等相關名額(broker、topic、memory pool、class loading、thread)進行監測。<br><span class='help_module_span'> ⚠️注意:您需要在 ActiveMQ 開啟 JMX 服務。<a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>點擊查看開啟步驟</a>。</span>
|
||||
ja-JP: HertzBeatは <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMXプロトコルを介して</a> Apache ActiveMQメッセージングシステムのランタイムステータス、ノード、トピック、その他の関連メトリクスを監視します。<br><span class='help_module_span'> ⚠️注意:ActiveMQ で JMX サービスを有効にする必要があります。<a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/activemq'>クリックしてガイドを見ます</a>。</span>
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/activemq
|
||||
en-US: https://hertzbeat.apache.org/docs/help/activemq
|
||||
@@ -196,7 +196,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 持久化
|
||||
en-US: Persistence
|
||||
ja-JP: 永続性
|
||||
ja-JP: 永続化
|
||||
type: 1
|
||||
- field: DataDirectory
|
||||
i18n:
|
||||
@@ -271,19 +271,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 平均消息大小
|
||||
en-US: Average Message Size
|
||||
ja-JP: 平均メッセージサイズ
|
||||
ja-JP: メッセージの平均サイズ
|
||||
type: 0
|
||||
- field: MaxMessageSize
|
||||
i18n:
|
||||
zh-CN: 最大消息大小
|
||||
en-US: Max Message Size
|
||||
ja-JP: 最大メッセージサイズ
|
||||
ja-JP: メッセージの最大サイズ
|
||||
type: 0
|
||||
- field: MinMessageSize
|
||||
i18n:
|
||||
zh-CN: 最小消息大小
|
||||
en-US: Min Message Size
|
||||
ja-JP: 最小メッセージサイズ
|
||||
ja-JP: メッセージの最小サイズ
|
||||
type: 0
|
||||
protocol: jmx
|
||||
jmx:
|
||||
@@ -372,7 +372,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 存储消息大小
|
||||
en-US: Store Message Size
|
||||
ja-JP: ストレージメッセージサイズ
|
||||
ja-JP: ストレージメッセージのサイズ
|
||||
- field: AverageEnqueueTime
|
||||
type: 0
|
||||
unit: ms
|
||||
@@ -407,21 +407,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 平均消息大小
|
||||
en-US: Average Message Size
|
||||
ja-JP: 平均メッセージサイズ
|
||||
ja-JP: メッセージの平均サイズ
|
||||
- field: MaxMessageSize
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
zh-CN: 最大消息大小
|
||||
en-US: Max Message Size
|
||||
ja-JP: 最大メッセージサイズ
|
||||
ja-JP: メッセージの最大サイズ
|
||||
- field: MinMessageSize
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
zh-CN: 最小消息大小
|
||||
en-US: Min Message Size
|
||||
ja-JP: 最小メッセージサイズ
|
||||
ja-JP: メッセージの最小サイズ
|
||||
units:
|
||||
- MemoryLimit=B->MB
|
||||
protocol: jmx
|
||||
@@ -446,14 +446,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 指标名称
|
||||
en-US: Name
|
||||
ja-JP: 指標名
|
||||
ja-JP: メトリクス名
|
||||
- field: committed
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 已分配内存
|
||||
en-US: Committed
|
||||
ja-JP: コミットメモリー
|
||||
ja-JP: コミットされたメモリ
|
||||
- field: init
|
||||
type: 0
|
||||
unit: MB
|
||||
@@ -474,7 +474,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 已使用内存
|
||||
en-US: Used
|
||||
ja-JP: 使用済みメモリ
|
||||
ja-JP: 使用したメモリ
|
||||
units:
|
||||
- committed=B->MB
|
||||
- init=B->MB
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 对 Apache Airflow 通用性能指标(airflow health、airflow version)进行采集监控。<br>您可以点击“<i>新建 Apache Airflow </i>”并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat monitors Apache Airflow through general performance metrics such as airflow health and airflow version. You could click the "<i>New Apache Airflow</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat對Apache Airflow通用性能指標(airflow health、airflow version)進行採集監控。<br>您可以點擊“<i>新建 Apache Airflow</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeatは、Apache Airflowの一般的なパフォーマンスのメトリックを監視します。 <br><i>新規Apache Airflow</i>をクリックして設定しましょう。
|
||||
ja-JP: Hertzbeatは、Apache Airflowの一般的なパフォーマンスのメトリクスを監視します。 <br><i>新規Apache Airflow</i>をクリックして設定しましょう。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/airflow/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/airflow/
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 AlmaLinux 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 AlmaLinux</i>”并配置HOST端口账户等相关参数进行添加,支持SSH账户密码或密钥认证。或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH protocol</a> to monitors AlmaLinux operating system's general performance metrics such as cpu, memory, disk, basic, interface, disk_free, top_process etc. <br>You can click the "<i>New AlmaLinux</i>" and config host port and other related params to add, auth support password or secretKey. Or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 AlmaLinux 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建AlmaLinux</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> AlmaLinuxシステムの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 AlmaLinux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> AlmaLinuxシステムの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 AlmaLinux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/almalinux
|
||||
en-US: https://hertzbeat.apache.org/docs/help/almalinux
|
||||
@@ -80,7 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: コネクション再利用
|
||||
ja-JP: 接続再利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -92,7 +92,7 @@ params:
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシコネクション利用
|
||||
ja-JP: プロキシ接続利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -246,7 +246,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: システムバージョン
|
||||
ja-JP: オーエスバージョン
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
@@ -415,7 +415,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 剩余可用内存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能なメモリ
|
||||
ja-JP: 使用可能のメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
@@ -544,14 +544,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 入站数据流量
|
||||
en-US: Receive Bytes
|
||||
ja-JP: 受信バイト数
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: transmit_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 出站数据流量
|
||||
en-US: Transmit Bytes
|
||||
ja-JP: 送信バイト数
|
||||
ja-JP: 転送されたバイト数
|
||||
units:
|
||||
- receive_bytes=B->MB
|
||||
- transmit_bytes=B->MB
|
||||
@@ -679,7 +679,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -738,7 +738,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 将调用 HTTP API 接口,查看接口是否可用,并以 ms 为指标单位对其响应时间等指标进行监测。您可以先点击“新增 HTTP API”按钮并进行配置,或在“更多操作”中导入已有配置。
|
||||
en-US: The platform will invoke an HTTP API endpoint to verify its accessibility and monitor various metrics, including response time, measured in milliseconds (ms). <br>To set up this functionality, you could click the "Add HTTP API" button and proceed with the configuration or import an existing setup through the "More Actions" menu.
|
||||
zh-TW: Hertzbeat將調用HTTP API介面,查看介面是否可用,並以ms為名額組織對其回應時間等名額進行監測。 您可以先點擊“新增HTTP API”按鈕並進行配寘,或在“更多操作”中導入已有配寘。
|
||||
ja-JP: Hertzbeatは、HTTP APIを呼び出して利用可能かどうかを確認し、応答時間(ms)などのメトリックを監視します。「新規HTTP API」をクリックして設定しましょう。
|
||||
ja-JP: Hertzbeatは、HTTP APIを呼び出して利用可能かどうかを確認し、応答時間(ms)などのメトリクスを監視します。「新規HTTP API」をクリックして設定しましょう。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/api
|
||||
en-US: https://hertzbeat.apache.org/docs/help/api
|
||||
@@ -170,9 +170,9 @@ params:
|
||||
name:
|
||||
zh-CN: 请求BODY
|
||||
en-US: BODY
|
||||
ja-JP: ボディ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
# 参数输入框提示信息
|
||||
# param field input placeholder
|
||||
placeholder: 'Available When POST PUT'
|
||||
# dependent parameter values list
|
||||
@@ -304,6 +304,12 @@ metrics:
|
||||
zh-CN: 关键词数量
|
||||
en-US: Keyword
|
||||
ja-JP: キーワード
|
||||
- field: statusCode
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 状态码
|
||||
en-US: Status Code
|
||||
ja-JP: 状態コード
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: http
|
||||
# the config content when protocol is http
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: 监控 HTTP API 接口,对 API 返回的业务自定义状态码(非 Http 状态码)进行监控。此需通过配置 JsonPath 来解析您 API 的业务状态码路径。<br>您可以点击 “<i>新建 API Code</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Monitor HTTP API to monitor business-defined status codes (non-HTTP status codes) returned by API. To do this, you need to configure JsonPath to resolve the business status code path of your API. <br>You could click the "<i>New API Codes</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: 監控 HTTP API 接口,對 API 返回的業務自定義狀態碼(非 Http 狀態碼)進行監控。此需通過配置 JsonPath 來解析您 API 的業務狀態碼路徑。<br>您可以點擊“<i>新建API Code</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeatは、HTTP APIを呼び出して利用可能かどうかを確認し、ビジネスステータスコード(HTTPステータスコードではない)のメトリックを監視します。これには、API のビジネスステータスコードのパスを解析するように JsonPath を構成する必要があります。「新規API Code」をクリックして設定しましょう。
|
||||
ja-JP: Hertzbeatは、HTTP APIを呼び出して利用可能かどうかを確認し、ビジネスステータスコード(HTTPステータスコードではない)のメトリクスを監視します。これには、API のビジネスステータスコードのパスを解析するように JsonPath を構成する必要があります。「新規API Code」をクリックして設定しましょう。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/api_code
|
||||
en-US: https://hertzbeat.apache.org/docs/help/api_code
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 Centos 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 Centos</i>”并配置HOST端口账户等相关参数进行添加,支持SSH账户密码或密钥认证。或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH protocol</a> to monitors Centos operating system's general performance metrics such as cpu, memory, disk, basic, interface, disk_free, top_process etc. <br>You can click the "<i>New Centos</i>" and config host port and other related params to add, auth support password or secretKey. Or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 Centos 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 Centos</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Centosシステムの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 Centos Linux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Centosシステムの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Centos Linux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/centos/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/centos/
|
||||
@@ -73,7 +73,6 @@ params:
|
||||
# required-true or false
|
||||
required: false
|
||||
# default value
|
||||
# 默认值
|
||||
defaultValue: 6000
|
||||
# field-param field key
|
||||
- field: reuseConnection
|
||||
@@ -81,7 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: コネクション再利用
|
||||
ja-JP: 接続再利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -93,7 +92,7 @@ params:
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシコネクション利用
|
||||
ja-JP: プロキシ接続利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -247,7 +246,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: システムバージョン
|
||||
ja-JP: オーエスバージョン
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
@@ -416,7 +415,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 剩余可用内存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能なメモリ
|
||||
ja-JP: 使用可能のメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
@@ -545,14 +544,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 入站数据流量
|
||||
en-US: Receive Bytes
|
||||
ja-JP: 受信バイト数
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: transmit_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 出站数据流量
|
||||
en-US: Transmit Bytes
|
||||
ja-JP: 送信バイト数
|
||||
ja-JP: 転送されたバイト数
|
||||
units:
|
||||
- receive_bytes=B->MB
|
||||
- transmit_bytes=B->MB
|
||||
@@ -680,7 +679,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -739,7 +738,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP 协议</a> 对 思科交换机 的通用指标(可用性,系统信息,端口流量等)进行采集监控。<br>您可以点击 “<i>新建 思科通用交换机</i>” 并进行配置SNMP相关参数添加,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP Protocol</a> to monitoring Cisco Switch general performance metrics. <br>You can click the "<i>New Cisco Switch</i>" button and config snmp params to add monitor or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP 協議</a> 對 思科交換機 的通用指標(可用性,系統信息,端口流量等)進行采集監控。<br>您可以點擊 “<i>新建 思科通用交換機</i>” 並進行配置SNMP相關參數添加,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP プロトコルを介して</a> シスコ・スイッチングハブの一般的なメトリック監視します。<br>「<i>新規 シスコ・スイッチングハブ</i>」をクリックしてSNMPなどのパラメタを設定した後、新規することができます。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP プロトコルを介して</a> シスコ・スイッチングハブの一般的なメトリクスを監視します。<br>「<i>新規 シスコ・スイッチングハブ</i>」をクリックしてSNMPなどのパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/cisco_switch
|
||||
en-US: https://hertzbeat.apache.org/docs/help/cisco_switch
|
||||
@@ -361,13 +361,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 入流量
|
||||
en-US: In Octets
|
||||
ja-JP: 受信バイト数
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: in_discards
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 入丢包数
|
||||
en-US: In Discards
|
||||
ja-JP: 受信パケットロス数
|
||||
ja-JP: 受信されたパケットのロス数
|
||||
- field: in_errors
|
||||
type: 0
|
||||
i18n:
|
||||
@@ -380,19 +380,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 出流量
|
||||
en-US: Out Octets
|
||||
ja-JP: 送信バイト数
|
||||
ja-JP: 転送されたバイト数
|
||||
- field: out_discards
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 出丢包数
|
||||
en-US: Out Discards
|
||||
ja-JP: 送信パケットロス数
|
||||
ja-JP: 転送されたパケットロス数
|
||||
- field: out_errors
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 出错包数
|
||||
en-US: Out Errors
|
||||
ja-JP: 送信異常パケット数
|
||||
ja-JP: 転送された異常パケット数
|
||||
- field: admin_status
|
||||
type: 1
|
||||
i18n:
|
||||
@@ -404,7 +404,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 当前状态
|
||||
en-US: Current Status
|
||||
ja-JP: ステータス
|
||||
ja-JP: 現在のステータス
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- ifIndex
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 对 ClickHouse 数据库监控通用指标进行测量监控。<br>您可以点击 “<i>新建 ClickHouse 数据库</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitors the status codes which returned by the API. You could click the "<i>New ClickHouse Database</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 對 ClickHouse 資料庫監控通用名額進行量測監控。<br>您可以點擊 “<i>新建ClickHouse資料庫</i>” 並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は ClickHouse データベースの一般的なメトリック監視します。<br>「<i>新規 ClickHouse データベース</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
ja-JP: Hertzbeat は ClickHouse データベースの一般的なメトリクスを監視します。<br>「<i>新規 ClickHouse データベース</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/clickhouse
|
||||
en-US: https://hertzbeat.apache.org/docs/help/clickhouse
|
||||
@@ -161,19 +161,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 指标名称
|
||||
en-US: metric
|
||||
ja-JP: メトリック名
|
||||
ja-JP: メトリクス名
|
||||
- field: value
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 指标值
|
||||
en-US: value
|
||||
ja-JP: メトリック値
|
||||
ja-JP: メトリクス値
|
||||
- field: description
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 说明
|
||||
en-US: description
|
||||
ja-JP: メトリック説明
|
||||
ja-JP: メトリクス説明
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -236,19 +236,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 指标名称
|
||||
en-US: metric
|
||||
ja-JP: メトリック名
|
||||
ja-JP: メトリクス名
|
||||
- field: value
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 指标值
|
||||
en-US: value
|
||||
ja-JP: メトリック値
|
||||
ja-JP: メトリクス値
|
||||
- field: description
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 说明
|
||||
en-US: description
|
||||
ja-JP: メトリック説明
|
||||
ja-JP: メトリクス説明
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 Fedora CoreOS 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 Fedora CoreOS</i>”并配置HOST端口账户等相关参数进行添加,支持SSH账户密码或密钥认证。或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH protocol</a> to monitors Fedora CoreOS operating system's general performance metrics such as cpu, memory, disk, basic, interface, disk_free, top_process etc. <br>You can click the "<i>New Fedora CoreOS</i>" and config host port and other related params to add, auth support password or secretKey. Or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 Fedora CoreOS 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 Fedora CoreOS</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH プロトコルを介して</a> Fedora CoreOSの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 Fedora CoreOS</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH プロトコルを介して</a> Fedora CoreOSの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Fedora CoreOS</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/coreos
|
||||
en-US: https://hertzbeat.apache.org/docs/help/coreos
|
||||
@@ -80,7 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: コネクション再利用
|
||||
ja-JP: 接続再利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -92,7 +92,7 @@ params:
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシコネクション利用
|
||||
ja-JP: プロキシ接続利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -246,7 +246,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: システムバージョン
|
||||
ja-JP: オーエスバージョン
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
@@ -415,7 +415,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 剩余可用内存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能なメモリ
|
||||
ja-JP: 使用可能のメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
@@ -544,14 +544,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 入站数据流量
|
||||
en-US: Receive Bytes
|
||||
ja-JP: 受信バイト数
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: transmit_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 出站数据流量
|
||||
en-US: Transmit Bytes
|
||||
ja-JP: 送信バイト数
|
||||
ja-JP: 転送されたバイト数
|
||||
units:
|
||||
- receive_bytes=B->MB
|
||||
- transmit_bytes=B->MB
|
||||
@@ -679,7 +679,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -738,7 +738,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -73,14 +73,14 @@ params:
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: SSL
|
||||
ja-JP: HTTPS利用
|
||||
ja-JP: SSL利用
|
||||
type: boolean
|
||||
required: false
|
||||
defaultValue: false
|
||||
|
||||
# collect metrics config list
|
||||
metrics:
|
||||
- name: network_info # 指标集合名称
|
||||
- name: network_info
|
||||
i18n:
|
||||
zh-CN: 网络信息
|
||||
en-US: Network Info
|
||||
|
||||
@@ -20,18 +20,18 @@ app: darwin
|
||||
# The monitoring i18n name
|
||||
name:
|
||||
zh-CN: Darwin操作系统
|
||||
en-US: Darwin Linux
|
||||
ja-JP: Darwin Linux
|
||||
en-US: OS Darwin
|
||||
ja-JP: Darwinオーエス
|
||||
zh-TW: Darwin操作系統
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: HertzBeat 使用 <a class='help_module_content' href='https://HertzBeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 Darwin 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 Darwin</i>”并配置HOST端口账户等相关参数进行添加,支持SSH账户密码或密钥认证。或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://HertzBeat.apache.org/docs/advanced/extend-ssh'> SSH protocol</a> to monitors Darwin operating system's general performance metrics such as cpu, memory, disk, basic, interface, disk_free, top_process etc. <br>You can click the "<i>New Darwin</i>" and config host port and other related params to add, auth support password or secretKey. Or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
# zh-TW: HertzBeat 使用 <a class='help_module_content' href='https://HertzBeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 Darwin 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 Darwin</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
# ja-JP: HertzBeat は <a class='help_module_content' href='https://HertzBeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Darwinシステムの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 Darwin Linux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
zh-TW: HertzBeat 使用 <a class='help_module_content' href='https://HertzBeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 Darwin 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 Darwin</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: HertzBeat は <a class='help_module_content' href='https://HertzBeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Darwinシステムの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Darwin Linux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://HertzBeat.apache.org/zh-cn/docs/help/Darwin/
|
||||
en-US: https://HertzBeat.apache.org/docs/help/Darwin/
|
||||
zh-CN: https://HertzBeat.apache.org/zh-cn/docs/help/darwin/
|
||||
en-US: https://HertzBeat.apache.org/docs/help/darwin/
|
||||
# Input params define for monitoring(render web ui by the definition)
|
||||
params:
|
||||
# field-param field key
|
||||
@@ -77,7 +77,6 @@ params:
|
||||
# required-true or false
|
||||
required: false
|
||||
# default value
|
||||
# 默认值
|
||||
defaultValue: 6000
|
||||
# field-param field key
|
||||
- field: reuseConnection
|
||||
@@ -85,7 +84,7 @@ params:
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: コネクション再利用
|
||||
ja-JP: 接続再利用
|
||||
zh-TW: 復用連接
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
@@ -98,7 +97,7 @@ params:
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシコネクション利用
|
||||
ja-JP: プロキシ接続利用
|
||||
zh-TW: 使用代理
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
@@ -264,7 +263,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: システムバージョン
|
||||
ja-JP: オーエスバージョン
|
||||
zh-TW: 操作系統版本
|
||||
- field: uptime
|
||||
type: 1
|
||||
@@ -453,7 +452,7 @@ metrics:
|
||||
zh-CN: 剩余可用内存
|
||||
zh-TW: 剩餘可用內存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能なメモリ
|
||||
ja-JP: 使用可能のメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
@@ -526,74 +525,75 @@ metrics:
|
||||
}'
|
||||
parseType: multiRow
|
||||
|
||||
# - name: disk
|
||||
# i18n:
|
||||
# zh-CN: 磁盘信息
|
||||
# zh-TW: 磁盤信息
|
||||
# en-US: Disk Info
|
||||
# ja-JP: ディスク情報
|
||||
# priority: 3
|
||||
# fields:
|
||||
# - field: disk_num
|
||||
# type: 1
|
||||
# i18n:
|
||||
# zh-CN: 磁盘总数
|
||||
# zh-TW: 磁盤總數
|
||||
# en-US: Disk Num
|
||||
# ja-JP: ディスク番号
|
||||
# - field: partition_num
|
||||
# type: 1
|
||||
# i18n:
|
||||
# zh-CN: 分区总数
|
||||
# zh-TW: 分區總數
|
||||
# en-US: Partition Num
|
||||
# ja-JP: パーティション
|
||||
# - field: block_write
|
||||
# type: 0
|
||||
# i18n:
|
||||
# zh-CN: 写磁盘块数
|
||||
# zh-TW: 寫磁盤塊數
|
||||
# en-US: Block Write
|
||||
# ja-JP: 書き込みディスクブロック数
|
||||
# - field: block_read
|
||||
# type: 0
|
||||
# i18n:
|
||||
# zh-CN: 读磁盘块数
|
||||
# zh-TW: 讀磁盤塊數
|
||||
# en-US: Block Read
|
||||
# ja-JP: 読み取りブロック数
|
||||
# - field: write_rate
|
||||
# type: 0
|
||||
# unit: iops
|
||||
# i18n:
|
||||
# zh-CN: 磁盘写速率
|
||||
# zh-TW: 磁盤寫速率
|
||||
# en-US: Write Rate
|
||||
# ja-JP: ディスク書き込み速度
|
||||
# protocol: ssh
|
||||
# ssh:
|
||||
# host: ^_^host^_^
|
||||
# port: ^_^port^_^
|
||||
# username: ^_^username^_^
|
||||
# password: ^_^password^_^
|
||||
# privateKey: ^_^privateKey^_^
|
||||
# privateKeyPassphrase: ^_^privateKeyPassphrase^_^
|
||||
# timeout: ^_^timeout^_^
|
||||
# reuseConnection: ^_^reuseConnection^_^
|
||||
# # whether to use proxy server for ssh connection
|
||||
# useProxy: ^_^useProxy^_^
|
||||
# # ssh proxy host: ipv4 domain
|
||||
# proxyHost: ^_^proxyHost^_^
|
||||
# # ssh proxy port
|
||||
# proxyPort: ^_^proxyPort^_^
|
||||
# # ssh proxy username
|
||||
# proxyUsername: ^_^proxyUsername^_^
|
||||
# # ssh proxy password
|
||||
# proxyPassword: ^_^proxyPassword^_^
|
||||
# # ssh proxy private key
|
||||
# proxyPrivateKey: ^_^proxyPrivateKey^_^
|
||||
# script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {gsub(":", "", $1); print $1,$2,$10}'
|
||||
# parseType: oneRow
|
||||
- name: disk
|
||||
i18n:
|
||||
zh-CN: 磁盘信息
|
||||
zh-TW: 磁盤信息
|
||||
en-US: Disk Info
|
||||
ja-JP: ディスク情報
|
||||
priority: 3
|
||||
fields:
|
||||
- field: disk_num
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 磁盘总数
|
||||
zh-TW: 磁盤總數
|
||||
en-US: Disk Num
|
||||
ja-JP: ディスク番号
|
||||
- field: partition_num
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 分区总数
|
||||
zh-TW: 分區總數
|
||||
en-US: Partition Num
|
||||
ja-JP: パーティション
|
||||
# - field: block_write
|
||||
# type: 0
|
||||
# i18n:
|
||||
# zh-CN: 写磁盘块数
|
||||
# zh-TW: 寫磁盤塊數
|
||||
# en-US: Block Write
|
||||
# ja-JP: 書き込みディスクブロック数
|
||||
# - field: block_read
|
||||
# type: 0
|
||||
# i18n:
|
||||
# zh-CN: 读磁盘块数
|
||||
# zh-TW: 讀磁盤塊數
|
||||
# en-US: Block Read
|
||||
# ja-JP: 読み取りブロック数
|
||||
# - field: write_rate
|
||||
# type: 0
|
||||
# unit: iops
|
||||
# i18n:
|
||||
# zh-CN: 磁盘写速率
|
||||
# zh-TW: 磁盤寫速率
|
||||
# en-US: Write Rate
|
||||
# ja-JP: ディスク書き込み速度
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
username: ^_^username^_^
|
||||
password: ^_^password^_^
|
||||
privateKey: ^_^privateKey^_^
|
||||
privateKeyPassphrase: ^_^privateKeyPassphrase^_^
|
||||
timeout: ^_^timeout^_^
|
||||
reuseConnection: ^_^reuseConnection^_^
|
||||
# whether to use proxy server for ssh connection
|
||||
useProxy: ^_^useProxy^_^
|
||||
# ssh proxy host: ipv4 domain
|
||||
proxyHost: ^_^proxyHost^_^
|
||||
# ssh proxy port
|
||||
proxyPort: ^_^proxyPort^_^
|
||||
# ssh proxy username
|
||||
proxyUsername: ^_^proxyUsername^_^
|
||||
# ssh proxy password
|
||||
proxyPassword: ^_^proxyPassword^_^
|
||||
# ssh proxy private key
|
||||
proxyPrivateKey: ^_^proxyPrivateKey^_^
|
||||
# script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {gsub(":", "", $1); print $1,$2,$10}'
|
||||
script: diskutil list | grep '^/dev/' | wc -l; diskutil list | grep -E 'Apple_HFS|Apple_APFS|Microsoft Basic Data|Linux Filesystem' | wc -l;
|
||||
parseType: oneRow
|
||||
|
||||
- name: interface
|
||||
i18n:
|
||||
@@ -618,7 +618,7 @@ metrics:
|
||||
zh-CN: 入站数据流量
|
||||
zh-TW: 入站數據流量
|
||||
en-US: Receive Bytes
|
||||
ja-JP: 受信バイト数
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: transmit_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
@@ -626,7 +626,7 @@ metrics:
|
||||
zh-CN: 出站数据流量
|
||||
zh-TW: 出站數據流量
|
||||
en-US: Transmit Bytes
|
||||
ja-JP: 送信バイト数
|
||||
ja-JP: 転送されたバイト数
|
||||
units:
|
||||
- receive_bytes=B->MB
|
||||
- transmit_bytes=B->MB
|
||||
@@ -765,7 +765,7 @@ metrics:
|
||||
zh-CN: 执行命令
|
||||
zh-TW: 執行指令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -829,7 +829,7 @@ metrics:
|
||||
zh-CN: 执行命令
|
||||
zh-TW: 執行指令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 Debian 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 Debian</i>”并配置HOST端口账户等相关参数进行添加,支持SSH账户密码或密钥认证。或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH protocol</a> to monitors Debian operating system's general performance metrics such as cpu, memory, disk, basic, interface, disk_free, top_process etc. <br>You can click the "<i>New Debian</i>" and config host port and other related params to add, auth support password or secretKey. Or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 Debian 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 Debian</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Centosシステムの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 Debian</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Centosシステムの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Debian</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/debian
|
||||
en-US: https://hertzbeat.apache.org/docs/help/debian
|
||||
@@ -80,7 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: コネクション再利用
|
||||
ja-JP: 接続再利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -92,7 +92,7 @@ params:
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシコネクション利用
|
||||
ja-JP: プロキシ接続利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -245,7 +245,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: システムバージョン
|
||||
ja-JP: オーエスバージョン
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
@@ -414,7 +414,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 剩余可用内存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能なメモリ
|
||||
ja-JP: 使用可能のメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
@@ -543,14 +543,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 入站数据流量
|
||||
en-US: Receive Bytes
|
||||
ja-JP: 受信バイト数
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: transmit_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 出站数据流量
|
||||
en-US: Transmit Bytes
|
||||
ja-JP: 送信バイト数
|
||||
ja-JP: 転送されたバイト数
|
||||
units:
|
||||
- receive_bytes=B->MB
|
||||
- transmit_bytes=B->MB
|
||||
@@ -678,7 +678,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -737,7 +737,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: HertzBeat 对 DM达梦数据库 的通用性能指标(basic、status、thread)进行采集监控,支持版本为 DM8+。<br>您可以点击“<i>新建 达梦数据库</i>”并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat monitors DM database of basic performance metrics such as status and thread, the version we support is DM8+. You could click the "<i>New DM</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: HertzBeat 對 DM達夢數據庫 的通用性能指標(basic、status、thread)進行采集監控,支持版本爲 DM8+。<br>您可以點擊“<i>新建 達夢數據庫</i>”並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は DM データベースの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 DM データベース</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
ja-JP: Hertzbeat は DM データベースの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 DM データベース</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/dm
|
||||
en-US: https://hertzbeat.apache.org/docs/help/dm
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: HertzBeat 对 DNS 服务相关指标进行监测。
|
||||
en-US: HertzBeat monitors related indicators of the DNS service.
|
||||
zh-TW: HertzBeat對DNS服務相關名額進行監測。
|
||||
ja-JP: HertzBeatはDNSのメトリックを監視します。
|
||||
ja-JP: HertzBeatはDNSのメトリクスを監視します。
|
||||
# Input params define for monitoring(render web ui by the definition)
|
||||
params:
|
||||
# field-param field key
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: HertzBeat 对 Docker 容器的通用性能指标(system、containers、stats)进行采集监控。<br><span class='help_module_span'>注意⚠️:为了监控 Docker 中的容器信息,您需要打开端口,让采集请求获取到对应的信息, <a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/help/docker'>点击查看开启步骤</a>。</span>
|
||||
en-US: HertzBeat monitoring Docker of general performance metrics such as containers, status etc. <br><span class='help_module_span'>Note⚠️:In order to monitoring metrics of Docker, you need to enable the data export port so that the collector can collect data from here,<a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/docker'>Click here to view the steps</a>.</span>
|
||||
zh-TW: HertzBeat 對 Docker 容器的通用性能指標(system、containers、stats)進行采集監控。<br><span class='help_module_span'>注意⚠️:爲了監控 Docker 中的容器信息,您需要打開端口,讓采集請求獲取到對應的信息, <a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/help/docker'>點擊查看開啓步驟</a>。</span>
|
||||
ja-JP: HertzBeat は Dockerコンテナの一般的なパフォーマンスのメトリック監視します。<br><span class='help_module_span'>注意⚠️:Dockerコンテナの情報を監視するために、ポートを有効にする必要があります。<a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/docker'>クリックしてガイドを見ます</a>。</span>
|
||||
ja-JP: HertzBeat は Dockerコンテナの一般的なパフォーマンスのメトリクスを監視します。<br><span class='help_module_span'>注意⚠️:Dockerコンテナの情報を監視するために、ポートを有効にする必要があります。<a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/docker'>クリックしてガイドを見ます</a>。</span>
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/docker/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/docker/
|
||||
@@ -226,13 +226,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 命令行
|
||||
en-US: command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
type: 1
|
||||
- field: state
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: state
|
||||
ja-JP: ステート
|
||||
ja-JP: 状態
|
||||
type: 1
|
||||
- field: status
|
||||
i18n:
|
||||
@@ -274,9 +274,9 @@ metrics:
|
||||
|
||||
- name: stats
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
zh-CN: 统计
|
||||
en-US: stats
|
||||
ja-JP: スタッツ
|
||||
ja-JP: 統計
|
||||
priority: 2
|
||||
fields:
|
||||
- field: name
|
||||
@@ -289,14 +289,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 可用内存
|
||||
en-US: available memory
|
||||
ja-JP: 使用可能なメモリ
|
||||
ja-JP: 使用可能のメモリ
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: used_memory
|
||||
i18n:
|
||||
zh-CN: 已用内存
|
||||
en-US: used memory
|
||||
ja-JP: 使用済みメモリ
|
||||
ja-JP: 使用したメモリ
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: memory_usage
|
||||
@@ -316,7 +316,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 可使用CPU数
|
||||
en-US: cpus number
|
||||
ja-JP: 使用可能なCPUコア数
|
||||
ja-JP: 使用可能のCPUコア数
|
||||
type: 0
|
||||
- field: cpu_usage
|
||||
i18n:
|
||||
|
||||
@@ -26,7 +26,7 @@ help:
|
||||
zh-CN: Hertzbeat 对 DORIS 数据库BE的通用性能指标(load channel count、memtable flush total、process thread num、light work max threads等)进行采集监控,支持版本为DORIS2.0.0。<br>您可以点击 “<i>新建 Doris DatabaseBE</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitoring Doris DatabaseBE through general performance metric such as load channel count, memtable flush total, process thread num and light work max threads. The version we support is DORIS2.0.0. You could click the "<i>New Doris DatabaseBE Monitor</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 對 DORIS 資料庫BE的通用性能指標(load channel count、memtable flush total、process thread num、light work max threads等)進行採集監控,支持版本為DORIS2.0.0。<br>您可以點擊“<i>新建Doris DatabaseBE</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は DORIS 2.0.0のデータベースBEの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 Doris DatabaseBE</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
ja-JP: Hertzbeat は DORIS 2.0.0のデータベースBEの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Doris DatabaseBE</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/doris_be/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/doris_be/
|
||||
@@ -178,7 +178,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 批量发送线程池队列大小
|
||||
en-US: Send Batch Thread Pool Queue Size
|
||||
ja-JP: バッチ送信スレッドプールのキューサイズ
|
||||
ja-JP: バッチ転送されたスレッドプールのキューサイズ
|
||||
priority: 6
|
||||
fields:
|
||||
- field: value
|
||||
|
||||
@@ -26,7 +26,7 @@ help:
|
||||
zh-CN: Hertzbeat 对 Doris 数据库FE的通用指标(doris_fe connection total、doris_fe edit log clean、doris_fe image、doris_fe rps等)进行测量监控,支持版本为DORIS2.0.0。<br>您可以点击 “<i>新建 Doris DatabaseFE</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitoring Doris DatabaseFE through general performance metric such as doris_fe connection total, doris_fe edit log clean, doris_fe image and doris_fe rps. The version we support is DORIS2.0.0. You could click the "<i>New Doris DatabaseFE Monitor</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 對 Doris 資料庫FE的通用名額(doris_fe connection total、doris_fe edit log clean、doris_fe image、doris_fe rps等)進行量測監控,支持版本為DORIS2.0.0。<br>您可以點擊“<i>新建Doris DatabaseFE</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は DORIS 2.0.0のデータベースFEの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 Doris DatabaseFE</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
ja-JP: Hertzbeat は DORIS 2.0.0のデータベースFEの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Doris DatabaseFE</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/doris_fe/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/doris_fe/
|
||||
@@ -70,7 +70,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 连接总数
|
||||
en-US: Connection Total
|
||||
ja-JP: コネクション数
|
||||
ja-JP: 接続総数
|
||||
priority: 0
|
||||
fields:
|
||||
- field: value
|
||||
|
||||
@@ -26,8 +26,8 @@ name:
|
||||
help:
|
||||
zh-CN: HertzBeat 对 DynamicTp actuator 暴露的线程池性能指标(thread pool)进行采集监控。<br><span class='help_module_span'>注意⚠️:您需要集成使用 DynamicTp,<a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/help/dynamic_tp'>点击查看集成步骤</a>。
|
||||
en-US: HertzBeat monitoring DynamicTp of the thread Pool Performance Metrics which exposed by DynamicTp actuator. <br><span class='help_module_span'>Note⚠️:You should integrate and use DynamicTp, <a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/dynamic_tp'>Click here to view the specific steps.</a>"
|
||||
zh-TW: HertzBeat 對 DynamicTp actuator暴露的執行緒池性能指標(thread pool)進行採集監控。<br><span class='help_ module_ span'>注意⚠️:您需要集成使用DynamicTp,<a class='help_ module_ content' href='https://hertzbeat.apache.org/zh-cn/docs/help/dynamic_tp'>點擊查看集成步驟</a>。
|
||||
ja-JP: HertzBeat は DynamicTpスレッドプールの一般的なパフォーマンスのメトリック監視します。<br><span class='help_module_span'>注意⚠️:DynamicTpの使用を統合する必要があり、<a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/dynamic_tp'>クリックしてガイドを見ます</a>。
|
||||
zh-TW: HertzBeat 對 DynamicTp actuator暴露的執行緒池性能指標(thread pool)進行採集監控。<br><span class='help_module_span'>注意⚠️:您需要集成使用DynamicTp,<a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/help/dynamic_tp'>點擊查看集成步驟</a>。
|
||||
ja-JP: HertzBeat は DynamicTpスレッドプールの一般的なパフォーマンスのメトリクスを監視します。<br><span class='help_module_span'>注意⚠️:DynamicTpの使用を統合する必要があり、<a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/dynamic_tp'>クリックしてガイドを見ます</a>。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/dynamic_tp/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/dynamic_tp/
|
||||
@@ -128,7 +128,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 公平
|
||||
en-US: fair
|
||||
ja-JP: 目標ホスト
|
||||
ja-JP: 公平
|
||||
type: 1
|
||||
- field: reject_handler_name
|
||||
type: 1
|
||||
@@ -211,7 +211,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 队列剩余容量
|
||||
en-US: queue remaining capacity
|
||||
ja-JP: 使用可能なキュー容量
|
||||
ja-JP: 使用可能のキュー容量
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: active_count
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 对 ElasticSearch 数据库监控通用指标进行测量监控。<br>您可以点击 “<i>新建 ElasticSearch</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitoring ElasticSearch through general performance metrics. You could click the "<i>New ElasticSearch</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 對 ElasticSearch 資料庫監控通用名額進行量測監控。<br>您可以點擊“<i>新建ElasticSearch</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: HertzBeat は ElasticSearch データベースの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 ElasticSearch</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
ja-JP: HertzBeat は ElasticSearch データベースの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 ElasticSearch</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/elasticsearch
|
||||
en-US: https://hertzbeat.apache.org/docs/help/elasticsearch
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: EMQX 是一款开源的大规模分布式 MQTT 消息服务器。Hertzbeat对EMQX MQTT消息服务器 5.0+ 版本的通用指标进行测量监控,<br>您可以点击 “<i>新建 EMQX 消息服务器</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: EMQX is an open source large-scale distributed MQTT message server. Hertzbeat measures and monitors common metrics of the EMQX message server 5.0+ version.<br>You can click "<i>New EMQX message server</i>" and configure it, or select "<i>More operations</i>", Import existing configuration.
|
||||
zh-TW: EMQX 是一款開源的大規模分散式 MQTT 訊息伺服器。 Hertzbeat對EMQX MQTT訊息伺服器 5.0+ 版本的通用指標進行測量監控,<br>您可以點擊“<i>新建 EMQX 訊息伺服器</i>” 並進行配置,或者選擇“<i>更多操作</i>” ,導入已有配置。
|
||||
ja-JP: EMQXは、オープンソースの大規模分散MQTTメッセージサーバーです。HertzbeatはEMQX MQTTメッセージサーバー(バージョン5.0+)の一般的なフォーマンスのメトリック監視します。<br>「<i>新規 EMQX</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
ja-JP: EMQXは、オープンソースの大規模分散MQTTメッセージサーバーです。HertzbeatはEMQX MQTTメッセージサーバー(バージョン5.0+)の一般的なフォーマンスのメトリクスを監視します。<br>「<i>新規 EMQX</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/emqx
|
||||
en-US: https://hertzbeat.apache.org/docs/help/emqx
|
||||
@@ -179,7 +179,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 指标
|
||||
en-US: Metrics
|
||||
ja-JP: メトリック
|
||||
ja-JP: メトリクス
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 1
|
||||
@@ -203,31 +203,31 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 发送数据包
|
||||
en-US: Packets Sent
|
||||
ja-JP: 送信パケット
|
||||
ja-JP: 転送されたパケット
|
||||
- field: packets_received
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 接收数据包
|
||||
en-US: Packets Received
|
||||
ja-JP: 受信パケット
|
||||
ja-JP: 受信されたパケット
|
||||
- field: bytes_sent
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 发送字节
|
||||
en-US: Bytes Sent
|
||||
ja-JP: 送信バイト数
|
||||
ja-JP: 転送されたバイト数
|
||||
- field: bytes_received
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 接收字节
|
||||
en-US: Bytes Received
|
||||
ja-JP: 受信バイト数
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: messages_sent
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 发送消息
|
||||
en-US: Messages Sent
|
||||
ja-JP: 送信メッセージ
|
||||
ja-JP: 転送されたメッセージ
|
||||
- field: messages_acked
|
||||
type: 0
|
||||
i18n:
|
||||
@@ -257,13 +257,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 会话创建
|
||||
en-US: Session Created
|
||||
ja-JP: 目標ホスト
|
||||
ja-JP: 作成されたセッション
|
||||
- field: session_discarded
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 会话丢弃
|
||||
en-US: Session Discarded
|
||||
ja-JP: 目標ホスト
|
||||
ja-JP: 廃棄されたセッション
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- client.connected
|
||||
@@ -324,7 +324,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 统计
|
||||
en-US: Stats
|
||||
ja-JP: スタッツ
|
||||
ja-JP: 統計
|
||||
priority: 2
|
||||
fields:
|
||||
# metrics content contains field-metric name, type-metric type:0-number,1-string, instance-if is metrics, unit-metric unit('%','ms','MB')
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 EulerOS 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 EulerOS</i>”并配置HOST端口账户等相关参数进行添加,支持SSH账户密码或密钥认证。或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH protocol</a> to monitors EulerOS operating system's general performance metrics such as cpu, memory, disk, basic, interface, disk_free, top_process etc. <br>You can click the "<i>New EulerOS</i>" and config host port and other related params to add, auth support password or secretKey. Or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 EulerOS 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 EulerOS</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> EulerOS システムの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 EulerOS</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> EulerOS システムの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 EulerOS</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/euleros
|
||||
en-US: https://hertzbeat.apache.org/docs/help/euleros
|
||||
@@ -80,7 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: コネクション再利用
|
||||
ja-JP: 接続再利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -92,7 +92,7 @@ params:
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシコネクション利用
|
||||
ja-JP: プロキシ接続利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -246,7 +246,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: システムバージョン
|
||||
ja-JP: オーエスバージョン
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
@@ -415,7 +415,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 剩余可用内存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能なメモリ
|
||||
ja-JP: 使用可能のメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
@@ -544,14 +544,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 入站数据流量
|
||||
en-US: Receive Bytes
|
||||
ja-JP: 受信バイト数
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: transmit_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 出站数据流量
|
||||
en-US: Transmit Bytes
|
||||
ja-JP: 送信バイト数
|
||||
ja-JP: 転送されたバイト数
|
||||
units:
|
||||
- receive_bytes=B->MB
|
||||
- transmit_bytes=B->MB
|
||||
@@ -679,7 +679,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -738,7 +738,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -27,7 +27,7 @@ help:
|
||||
zh-CN: Hertzbeat 对 Flink流引擎的通用指标进行测量监控。<br>您可以点击 “<i>新建 Flink流引擎</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitoring Flink Stream through general performance metric. You could click the "<i>New Flink Stream</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 對 Flink流引擎的通用名額進行量測監控。<br>您可以點擊“<i>新建Flink流引擎</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: HertzBeat は Flinkの一般的なメトリック監視します。<br>「<i>新規 Flink</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
ja-JP: HertzBeat は Flinkの一般的なメトリクスを監視します。<br>「<i>新規 Flink</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/flink
|
||||
en-US: https://hertzbeat.apache.org/docs/help/flink
|
||||
@@ -158,7 +158,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 已用插槽数
|
||||
en-US: Slots Used
|
||||
ja-JP: 使用済みスロット数
|
||||
ja-JP: 使用したスロット数
|
||||
- field: task_total # task count
|
||||
type: 0
|
||||
i18n:
|
||||
|
||||
@@ -21,11 +21,13 @@ app: flink_on_yarn
|
||||
name:
|
||||
zh-CN: Apache Flink On Yarn
|
||||
en-US: Apache Flink On Yarn
|
||||
ja-JP: Apache Flink On Yarn
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 对 Flink 流引擎 Yarn 模式的通用指标进行测量监控。<br>您可以点击 “<i>新建 Flink On Yarn</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitoring Flink Stream through general performance metric. You could click the "<i>New Flink Stream</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 對 Flink 流引擎 Yarn 模式的通用指標進行測量監控。<br>您可以點擊 “<i>新建 Flink On Yarn</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: HertzBeat は Flink 「Yarn モード」の一般的なメトリクスを監視します。<br>「<i>新規 Flink</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/flink_on_yarn
|
||||
en-US: https://hertzbeat.apache.org/docs/help/flink_on_yarn
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: Yarn端口
|
||||
en-US: Yarn Port
|
||||
ja-JP: Yarnポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: 应用ID
|
||||
en-US: Application ID
|
||||
ja-JP: 応用ID
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
@@ -71,6 +76,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启动SSL
|
||||
en-US: SSL
|
||||
ja-JP: SSL利用
|
||||
# type-param field type(boolean mapping the html switch tag)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -80,6 +86,7 @@ params:
|
||||
name:
|
||||
zh-CN: 认证方式
|
||||
en-US: Auth Type
|
||||
ja-JP: 認証方法
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: radio
|
||||
required: false
|
||||
@@ -94,6 +101,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
type: text
|
||||
limit: 50
|
||||
required: false
|
||||
@@ -102,6 +110,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
type: password
|
||||
required: false
|
||||
hide: true
|
||||
@@ -111,6 +120,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: JobManager Metrics
|
||||
en-US: JobManager Metrics
|
||||
ja-JP: JobManagerメトリクス
|
||||
priority: 0
|
||||
fields:
|
||||
- field: id
|
||||
@@ -119,11 +129,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 监控项
|
||||
en-US: key
|
||||
ja-JP: キー
|
||||
- field: value
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 值
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
@@ -143,6 +155,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: JobManager Config
|
||||
en-US: JobManager Config
|
||||
ja-JP: JobManager設定
|
||||
priority: 1
|
||||
fields:
|
||||
- field: key
|
||||
@@ -150,11 +163,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 监控项
|
||||
en-US: key
|
||||
ja-JP: キー
|
||||
- field: value
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 值
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
@@ -175,6 +190,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: TaskManager
|
||||
en-US: TaskManager
|
||||
ja-JP: TaskManager
|
||||
priority: 2
|
||||
fields:
|
||||
- field: id
|
||||
@@ -183,168 +199,198 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Container ID
|
||||
en-US: Container ID
|
||||
ja-JP: コンテナID
|
||||
- field: path
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Path
|
||||
en-US: Path
|
||||
ja-JP: パス
|
||||
- field: dataPort
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Data Port
|
||||
en-US: Data Port
|
||||
ja-JP: データポート
|
||||
- field: jmxPort
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: JMX Port
|
||||
en-US: JMX Port
|
||||
ja-JP: JMXポート
|
||||
- field: timeSinceLastHeartbeat
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Last Heartbeat
|
||||
en-US: Last Heartbeat
|
||||
ja-JP: 最後のハートビート
|
||||
- field: slotsNumber
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: All Slots
|
||||
en-US: All Slots
|
||||
ja-JP: スロット
|
||||
- field: freeSlots
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Free Slots
|
||||
en-US: Free Slots
|
||||
ja-JP: 利用可能なスロット
|
||||
- field: totalResourceCpuCores
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: totalResourceCpuCores
|
||||
en-US: totalResourceCpuCores
|
||||
ja-JP: totalResourceCpuCores
|
||||
- field: totalResourceTaskHeapMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: totalResourceTaskHeapMemory
|
||||
en-US: totalResourceTaskHeapMemory
|
||||
ja-JP: totalResourceTaskHeapMemory
|
||||
unit: MB
|
||||
- field: totalResourceManagedMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: totalResourceManagedMemory
|
||||
en-US: totalResourceManagedMemory
|
||||
ja-JP: totalResourceManagedMemory
|
||||
unit: MB
|
||||
- field: totalResourceNetworkMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: totalResourceNetworkMemory
|
||||
en-US: totalResourceNetworkMemory
|
||||
ja-JP: totalResourceNetworkMemory
|
||||
unit: MB
|
||||
- field: freeResourceCpuCores
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: freeResourceCpuCores
|
||||
en-US: freeResourceCpuCores
|
||||
ja-JP: freeResourceCpuCores
|
||||
- field: freeResourceTaskHeapMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: freeResourceTaskHeapMemory
|
||||
en-US: freeResourceTaskHeapMemory
|
||||
ja-JP: freeResourceTaskHeapMemory
|
||||
unit: MB
|
||||
- field: freeResourceTaskOffHeapMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: freeResourceTaskOffHeapMemory
|
||||
en-US: freeResourceTaskOffHeapMemory
|
||||
ja-JP: freeResourceTaskOffHeapMemory
|
||||
unit: MB
|
||||
- field: freeResourceManagedMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: freeResourceManagedMemory
|
||||
en-US: freeResourceManagedMemory
|
||||
ja-JP: freeResourceManagedMemory
|
||||
unit: MB
|
||||
- field: freeResourceNetworkMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: freeResourceNetworkMemory
|
||||
en-US: freeResourceNetworkMemory
|
||||
ja-JP: freeResourceNetworkMemory
|
||||
unit: MB
|
||||
- field: hardwareCpuCores
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: CPU Cores
|
||||
en-US: CPU Cores
|
||||
ja-JP: Cpuコア数
|
||||
- field: hardwarePhysicalMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Physical MEM
|
||||
en-US: Physical MEM
|
||||
ja-JP: 物理メモリ
|
||||
unit: GB
|
||||
- field: hardwareFreeMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM Heap Size
|
||||
en-US: JVM Heap Size
|
||||
ja-JP: Java仮想マシンのヒープサイズ
|
||||
unit: MB
|
||||
- field: hardwareManagedMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Flink Managed MEM
|
||||
en-US: Flink Managed MEM
|
||||
ja-JP: Flink管理メモリ
|
||||
unit: MB
|
||||
- field: memoryConfigurationFrameworkHeap
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Framework Heap
|
||||
en-US: Framework Heap
|
||||
ja-JP: フレームワークのヒープ
|
||||
unit: MB
|
||||
- field: memoryConfigurationTaskHeap
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Task Heap
|
||||
en-US: Task Heap
|
||||
ja-JP: タスクヒープ
|
||||
unit: MB
|
||||
- field: memoryConfigurationFrameworkOffHeap
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Framework Off-Heap
|
||||
en-US: Framework Off-Heap
|
||||
ja-JP: フレームワークのオフヒープ
|
||||
unit: MB
|
||||
- field: memoryConfigurationTaskOffHeap
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Task Off-Heap
|
||||
en-US: Task Off-Heap
|
||||
ja-JP: タスクオフヒープ
|
||||
unit: MB
|
||||
- field: memoryConfigurationNetworkMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Network
|
||||
en-US: Network
|
||||
ja-JP: ネットワーク
|
||||
unit: MB
|
||||
- field: memoryConfigurationManagedMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Managed Memory
|
||||
en-US: Managed Memory
|
||||
ja-JP: 管理メモリ
|
||||
unit: MB
|
||||
- field: memoryConfigurationJvmMetaspace
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM Metaspace
|
||||
en-US: JVM Metaspace
|
||||
ja-JP: Java仮想マシンのメタスペース
|
||||
unit: MB
|
||||
- field: memoryConfigurationJvmOverhead
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM Overhead
|
||||
en-US: JVM Overhead
|
||||
ja-JP: Java仮想マシンのオーバーヘッド
|
||||
- field: memoryConfigurationTotalFlinkMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: memoryConfigurationTotalFlinkMemory
|
||||
en-US: memoryConfigurationTotalFlinkMemory
|
||||
ja-JP: memoryConfigurationTotalFlinkMemory
|
||||
- field: memoryConfigurationTotalProcessMemory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: memoryConfigurationTotalProcessMemory
|
||||
en-US: memoryConfigurationTotalProcessMemory
|
||||
ja-JP: memoryConfigurationTotalProcessMemory
|
||||
aliasFields:
|
||||
- $.id
|
||||
- $.path
|
||||
@@ -439,12 +485,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: TaskManager Metrics
|
||||
en-US: TaskManager Metrics
|
||||
ja-JP: TaskManagerメトリクス
|
||||
priority: 3
|
||||
fields:
|
||||
- field: container_id
|
||||
i18n:
|
||||
zh-CN: Container ID
|
||||
en-US: Container ID
|
||||
ja-JP: コンテナID
|
||||
type: 1
|
||||
label: true
|
||||
- field: id
|
||||
@@ -452,12 +500,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 监控项
|
||||
en-US: key
|
||||
ja-JP: キー
|
||||
label: true
|
||||
- field: value
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 值
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
unit: MB
|
||||
units:
|
||||
- value=B->MB
|
||||
|
||||
@@ -21,11 +21,13 @@ app: freebsd
|
||||
name:
|
||||
zh-CN: FreeBSD操作系统
|
||||
en-US: OS FreeBSD
|
||||
ja-JP: OS FreeBSD
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 FreeBSD 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 FreeBSD</i>”并配置HOST端口账户等相关参数进行添加,支持SSH账户密码或密钥认证。或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH protocol</a> to monitors FreeBSD operating system's general performance metrics such as cpu, memory, disk, basic, interface, disk_free, top_process etc. <br>You can click the "<i>New FreeBSD</i>" and config host port and other related params to add, auth support password or secretKey. Or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 FreeBSD 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 FreeBSD</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Centosシステムの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 FreeBSD</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn//docs/help/freebsd
|
||||
en-US: https://hertzbeat.apache.org/docs/help/freebsd
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: 超时时间(ms)
|
||||
en-US: Timeout(ms)
|
||||
ja-JP: タイムアウト(ms)
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -75,6 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: 接続再利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -86,6 +92,7 @@ params:
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシ接続利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -97,6 +104,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -109,6 +117,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -119,6 +128,7 @@ params:
|
||||
name:
|
||||
zh-CN: 私钥
|
||||
en-US: PrivateKey
|
||||
ja-JP: 秘密鍵
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
@@ -132,6 +142,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密钥短语
|
||||
en-US: PrivateKey PassPhrase
|
||||
ja-JP: 秘密鍵フレーズ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -144,6 +155,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理主机
|
||||
en-US: Proxy Host
|
||||
ja-JP: プロキシホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
@@ -155,6 +167,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理端口
|
||||
en-US: Proxy Port
|
||||
ja-JP: プロキシポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -171,6 +184,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理用户名
|
||||
en-US: Proxy Username
|
||||
ja-JP: プロキシユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -185,6 +199,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理密码
|
||||
en-US: Proxy Password
|
||||
ja-JP: プロキシパスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -197,6 +212,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理主机私钥
|
||||
en-US: proxyPrivateKey
|
||||
ja-JP: プロキシ秘密鍵
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
@@ -211,6 +227,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 系统基本信息
|
||||
en-US: Basic Info
|
||||
ja-JP: システム基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -223,16 +240,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 主机名称
|
||||
en-US: Host Name
|
||||
ja-JP: ホスト名
|
||||
- field: version
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: オーエスバージョン
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 启动时间
|
||||
en-US: Uptime
|
||||
ja-JP: アップタイム
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: ssh
|
||||
# the config content when protocol is ssh
|
||||
@@ -272,6 +292,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: CPU 信息
|
||||
en-US: CPU Info
|
||||
ja-JP: CPU情報
|
||||
priority: 1
|
||||
fields:
|
||||
- field: info
|
||||
@@ -279,32 +300,38 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 型号
|
||||
en-US: Info
|
||||
ja-JP: バージョン
|
||||
- field: cores
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 核数
|
||||
en-US: Cores
|
||||
ja-JP: コア数
|
||||
- field: interrupt
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 中断数
|
||||
en-US: Interrupt
|
||||
ja-JP: 割り込み数
|
||||
- field: load
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 负载
|
||||
en-US: Load
|
||||
ja-JP: ロード
|
||||
- field: context_switch
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 上下文切换
|
||||
en-US: Context Switch
|
||||
ja-JP: コンテキストスイッチ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 使用率
|
||||
en-US: Usage
|
||||
ja-JP: 使用率
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
# (可选)监控指标别名, 做为中间字段与采集数据字段和指标字段映射转换
|
||||
aliasFields:
|
||||
@@ -352,6 +379,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 内存信息
|
||||
en-US: Memory Info
|
||||
ja-JP: メモリ情報
|
||||
priority: 2
|
||||
fields:
|
||||
- field: physmem
|
||||
@@ -360,30 +388,35 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 物理内存
|
||||
en-US: Physics Memory
|
||||
ja-JP: 物理メモリ
|
||||
- field: usermem
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 用户内存
|
||||
en-US: User Program Memory
|
||||
ja-JP: ユーザープログラムメモリ
|
||||
- field: realmem
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 实际内存
|
||||
en-US: Real Memory
|
||||
ja-JP: 実際のメモリ
|
||||
- field: availmem
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 可用内存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能のメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存使用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
aliasFields:
|
||||
- physmem
|
||||
- usermem
|
||||
@@ -429,6 +462,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 文件系统
|
||||
en-US: Disk Free
|
||||
ja-JP: ディスク情報
|
||||
priority: 3
|
||||
fields:
|
||||
- field: filesystem
|
||||
@@ -436,30 +470,35 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 文件系统
|
||||
en-US: Filesystem
|
||||
ja-JP: ファイルシステム
|
||||
- field: used
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 已使用量
|
||||
en-US: Used
|
||||
ja-JP: 使用済み
|
||||
- field: available
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 可用量
|
||||
en-US: Available
|
||||
ja-JP: 利用可能
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 使用率
|
||||
en-US: Usage
|
||||
ja-JP: 使用率
|
||||
- field: mounted
|
||||
type: 1
|
||||
label: true
|
||||
i18n:
|
||||
zh-CN: 挂载点
|
||||
en-US: Mounted
|
||||
ja-JP: マウント
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -489,6 +528,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Top10 CPU 进程
|
||||
en-US: Top10 CPU Process
|
||||
ja-JP: トップ10 CPUプロセス
|
||||
priority: 4
|
||||
fields:
|
||||
- field: pid
|
||||
@@ -497,23 +537,27 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程ID
|
||||
en-US: PID
|
||||
ja-JP: プロセスID
|
||||
- field: cpu_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: CPU占用率
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: mem_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存占用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: command
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -543,6 +587,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Top10 内存进程
|
||||
en-US: Top10 Memory Process
|
||||
ja-JP: トップ10 メモリプロセス
|
||||
priority: 5
|
||||
fields:
|
||||
- field: pid
|
||||
@@ -551,23 +596,27 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程ID
|
||||
en-US: PID
|
||||
ja-JP: プロセスID
|
||||
- field: mem_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存占用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: cpu_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: CPU占用率
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: command
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -21,11 +21,13 @@ app: ftp
|
||||
name:
|
||||
zh-CN: FTP服务器
|
||||
en-US: FTP Server
|
||||
ja-JP: FTPサーバー
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 对 FTP 服务器的通用指标进行测量监控。<br>您可以点击 “<i>新建 FTP服务器</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitoring FTP server through general performance metric. You could click the "<i>New FTP server</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 對 FTP 伺服器的通用名額進行量測監控。<br>您可以點擊“<i>新建FTP伺服器</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は FTPサーバーの一般的なメトリクスを監視します。<br>「<i>新規 FTPサーバー</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/ftp
|
||||
en-US: https://hertzbeat.apache.org/docs/help/ftp
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
type: text
|
||||
limit: 50
|
||||
required: false
|
||||
@@ -69,6 +74,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
required: false
|
||||
@@ -77,6 +83,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目录
|
||||
en-US: Direction
|
||||
ja-JP: ディレクション
|
||||
type: text
|
||||
limit: 100
|
||||
required: true
|
||||
@@ -84,6 +91,7 @@ params:
|
||||
name:
|
||||
zh-CN: 超时时间
|
||||
en-US: Timeout
|
||||
ja-JP: タイムアウト
|
||||
type: number
|
||||
range: '[0,100000]'
|
||||
required: true
|
||||
@@ -93,6 +101,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启用SFTP
|
||||
en-US: SFTP
|
||||
ja-JP: SFTP利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -104,6 +113,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 概要
|
||||
en-US: Basic
|
||||
ja-JP: 基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -115,12 +125,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 活动状态
|
||||
en-US: Is Active
|
||||
ja-JP: 活動ステータス
|
||||
- field: responseTime
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 响应时间
|
||||
en-US: Response Time
|
||||
ja-JP: 応答時間
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: ftp
|
||||
# the config content when protocol is ftp
|
||||
|
||||
@@ -21,11 +21,13 @@ app: fullsite
|
||||
name:
|
||||
zh-CN: SiteMap全站
|
||||
en-US: SITE MAP
|
||||
ja-JP: SITE MAP
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: HertzBeat 对网站全部页面的 URL 路径、HTTP 状态码、响应时间及请求反馈进行监测。由于一个网站可能有多个不同服务提供的页面,系统将采集网站暴露的<a class='help_module_content' href='https://en.wikipedia.org/wiki/Site_map'>网站地图(SiteMap)</a>来监控全站。<span class='help_module_span'><br>⚠️注意:此功能需要您的网站支持 XML 和 TXT 格式的 SiteMap。</span>
|
||||
en-US: HertzBeat monitoring all pages of website by URL path, HTTP status code, response times and request feedback. Due to the possibility that a website may have multiple pages provided by different services, Hertzbeat will collect <a class='help_module_content' href='https://en.wikipedia.org/wiki/Site_map'>SiteMap</a> which exposed by the website to monitor the entire site. <span class='help_module_span'><br>⚠️Note:HertzBeat support SiteMap in XML or TXT format.</span>
|
||||
zh-TW: HertzBeat對網站全部頁面的URL路徑、HTTP狀態碼、回應時間及請求迴響進行監測。 由於一個網站可能有多個不同服務提供的頁面,系統將採集網站暴露的<a class='help_ module_ content' href='https://en.wikipedia.org/wiki/Site_map'>網站地圖(SiteMap)</a>來監控全站。<span class='help_ module_ span'> <br>⚠️注意:此功能需要您的網站支持XML和TXT格式的SiteMap。</span>
|
||||
zh-TW: HertzBeat對網站全部頁面的URL路徑、HTTP狀態碼、回應時間及請求迴響進行監測。 由於一個網站可能有多個不同服務提供的頁面,系統將採集網站暴露的<a class='help_module_content' href='https://en.wikipedia.org/wiki/Site_map'>網站地圖(SiteMap)</a>來監控全站。<span class='help_module_span'> <br>⚠️注意:此功能需要您的網站支持XML和TXT格式的SiteMap。</span>
|
||||
ja-JP: HertzBeat はウェブサイトの全てのURL、HTTPステータスコード、応答時間などのメトリクスを監視します。ウェブサイトには、異なるサービスによって提供される複数のページが存在する可能性があるため、システムはウェブサイトによって公開される<a class='help_module_content' href='https://en.wikipedia.org/wiki/Site_map'>SiteMap</a>を収集して監視します。<span class='help_module_span'> <br>⚠️注意:この機能を使用するには、ウェブサイトがXMLおよびTXT形式のSiteMapをサポートしている必要があります。</span>
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/guide/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/guide/
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -58,6 +62,7 @@ params:
|
||||
name:
|
||||
zh-CN: 网站地图
|
||||
en-US: Site Map
|
||||
ja-JP: Site Map
|
||||
type: text
|
||||
limit: 200
|
||||
required: true
|
||||
@@ -66,6 +71,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: HTTPS
|
||||
ja-JP: HTTPS利用
|
||||
# type-param field type(boolean mapping the html switch tag)
|
||||
type: boolean
|
||||
required: true
|
||||
@@ -77,6 +83,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 概要信息
|
||||
en-US: Summary
|
||||
ja-JP: 概要
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -89,22 +96,26 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: URL
|
||||
en-US: URL
|
||||
ja-JP: URL
|
||||
- field: statusCode
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 响应状态码
|
||||
en-US: Status Code
|
||||
ja-JP: ステータスコード
|
||||
- field: responseTime
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 响应时间
|
||||
en-US: Response Time
|
||||
ja-JP: 応答時間
|
||||
- field: errorMsg
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 错误信息
|
||||
en-US: Error Msg
|
||||
ja-JP: エラーメッセージ
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: http
|
||||
# the config content when protocol is http
|
||||
|
||||
@@ -21,11 +21,13 @@ app: greenplum
|
||||
name:
|
||||
zh-CN: GreenPlum 数据库
|
||||
en-US: GreenPlum DB
|
||||
ja-JP: GreenPlum データベース
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: HertzBeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jdbc'> JDBC 协议</a> 通过配置 SQL 对 GreenPlum 数据库的通用性能指标 (basic、state、activity etc) 进行采集监控,支持版本为 GreenPlum 6.23.0+。<br>您可以点击“<i>新建 GreenPlum 数据库</i>”并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jdbc'> JDBC Protocol</a> to configure SQL for collecting general metrics of GreenPlum database (basic、state、activity etc). Supported version is GreenPlum 6.23.0+. <br>You can click "<i>New GreenPlum Database</i>" and configure it, or select "<i>More Action</i>" to import the existing configuration.
|
||||
zh-TW: HertzBeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jdbc'> JDBC 協議</a> 通過配置 SQL 對 GreenPlum 數據庫的通用性能指標 (basic、state、activity etc)進行采集監控,支持版本爲 GreenPlum 6.23.0+。<br>您可以點擊“<i>新建 GreenPlum 數據庫</i>”並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jdbc'> JDBCプロトコルを介して</a> GreenPlum データベース(6.23.0+)の一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 GreenPlum データベース</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/greenplum
|
||||
en-US: https://hertzbeat.apache.org/docs/help/greenplum
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -59,6 +63,7 @@ params:
|
||||
name:
|
||||
zh-CN: 查询超时时间(ms)
|
||||
en-US: Query Timeout(ms)
|
||||
ja-JP: クエリタイムアウト(ms)
|
||||
type: number
|
||||
range: '[400,200000]'
|
||||
required: false
|
||||
@@ -68,6 +73,7 @@ params:
|
||||
name:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
type: text
|
||||
defaultValue: postgres
|
||||
required: false
|
||||
@@ -75,6 +81,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
type: text
|
||||
limit: 50
|
||||
required: false
|
||||
@@ -82,12 +89,14 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
type: password
|
||||
required: false
|
||||
- field: url
|
||||
name:
|
||||
zh-CN: URL
|
||||
en-US: URL
|
||||
ja-JP: URL
|
||||
type: text
|
||||
required: false
|
||||
hide: true
|
||||
@@ -99,6 +108,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 基本信息
|
||||
en-US: Basic Info
|
||||
ja-JP: 基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -111,26 +121,31 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 服务器版本
|
||||
en-US: Server Version
|
||||
ja-JP: サーバーのバージョン
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
- field: server_encoding
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 服务器编码
|
||||
en-US: Server Encoding
|
||||
ja-JP: サーバーのエンコード
|
||||
- field: data_directory
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 数据目录
|
||||
en-US: Data Directory
|
||||
ja-JP: データディレクトリ
|
||||
- field: max_connections
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大连接数
|
||||
en-US: Max Connections
|
||||
ja-JP: 最大接続数
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: jdbc
|
||||
# the config content when protocol is jdbc
|
||||
@@ -155,6 +170,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 状态信息
|
||||
en-US: State Info
|
||||
ja-JP: 状態情報
|
||||
priority: 1
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -163,47 +179,55 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: conflicts
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 冲突次数
|
||||
en-US: Conflicts
|
||||
ja-JP: コンフリクト回数
|
||||
- field: deadlocks
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 死锁次数
|
||||
en-US: Deadlocks
|
||||
ja-JP: デッドロック回数
|
||||
- field: blks_read
|
||||
type: 0
|
||||
unit: blocks per second
|
||||
i18n:
|
||||
zh-CN: 读取块
|
||||
en-US: Blocks Read
|
||||
ja-JP: 読み取られたブロック
|
||||
- field: blks_hit
|
||||
type: 0
|
||||
unit: blocks per second
|
||||
i18n:
|
||||
zh-CN: 命中块
|
||||
en-US: Blocks Hit
|
||||
ja-JP: ヒットブロック
|
||||
- field: blk_read_time
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 读取时间
|
||||
en-US: Read Time
|
||||
ja-JP: 読み取られタイム
|
||||
- field: blk_write_time
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 写入时间
|
||||
en-US: Write Time
|
||||
ja-JP: 書き込まれ時間
|
||||
- field: stats_reset
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 统计重置
|
||||
en-US: Stats Reset
|
||||
ja-JP: 統計リセット
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -221,6 +245,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 活动信息
|
||||
en-US: Activity Info
|
||||
ja-JP: 活動情報
|
||||
priority: 2
|
||||
fields:
|
||||
- field: running
|
||||
@@ -229,6 +254,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 运行中
|
||||
en-US: Running
|
||||
ja-JP: 実行中
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -246,6 +272,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 资源配置
|
||||
en-US: Resource Config
|
||||
ja-JP: リソース設定
|
||||
priority: 3
|
||||
fields:
|
||||
- field: work_mem
|
||||
@@ -254,34 +281,40 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 工作内存
|
||||
en-US: Work Memory
|
||||
ja-JP: ワークメモリ
|
||||
- field: shared_buffers
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 共享缓冲区
|
||||
en-US: Shared Buffers
|
||||
ja-JP: 共有バッファ
|
||||
- field: autovacuum
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 自动清理
|
||||
en-US: Auto Vacuum
|
||||
ja-JP: オートバキューム
|
||||
- field: max_connections
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大连接数
|
||||
en-US: Max Connections
|
||||
ja-JP: 最大接続数
|
||||
- field: effective_cache_size
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 有效缓存大小
|
||||
en-US: Effective Cache Size
|
||||
ja-JP: キャッシュサイズ
|
||||
- field: wal_buffers
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: WAL缓冲区
|
||||
en-US: WAL Buffers
|
||||
ja-JP: WALバッファ
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -299,6 +332,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 连接信息
|
||||
en-US: Connection Info
|
||||
ja-JP: 接続情報
|
||||
priority: 4
|
||||
fields:
|
||||
- field: active
|
||||
@@ -306,6 +340,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 活动连接
|
||||
en-US: Active Connection
|
||||
ja-JP: 活躍的な接続
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -323,6 +358,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 连接状态
|
||||
en-US: Connection State
|
||||
ja-JP: 接続状態
|
||||
priority: 5
|
||||
fields:
|
||||
- field: state
|
||||
@@ -331,11 +367,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: State
|
||||
ja-JP: 状態
|
||||
- field: num
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
en-US: Num
|
||||
ja-JP: 数量
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -353,6 +391,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 连接数据库
|
||||
en-US: Connection Db
|
||||
ja-JP: 接続データベース
|
||||
priority: 6
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -361,11 +400,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: active
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活动连接
|
||||
en-US: Active Connection
|
||||
ja-JP: 活躍的な接続
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -383,6 +424,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 元组信息
|
||||
en-US: Tuple Info
|
||||
ja-JP: 組情報
|
||||
priority: 7
|
||||
fields:
|
||||
- field: fetched
|
||||
@@ -390,26 +432,31 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 获取次数
|
||||
en-US: Fetched
|
||||
ja-JP: フェッチ回数
|
||||
- field: returned
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 返回次数
|
||||
en-US: Returned
|
||||
ja-JP: 戻る回数
|
||||
- field: inserted
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 插入次数
|
||||
en-US: Inserted
|
||||
ja-JP: インサート回数
|
||||
- field: updated
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 更新次数
|
||||
en-US: Updated
|
||||
ja-JP: 更新回数
|
||||
- field: deleted
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 删除次数
|
||||
en-US: Deleted
|
||||
ja-JP: 削除回数
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -427,6 +474,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 临时文件
|
||||
en-US: Temp File
|
||||
ja-JP: 一時ファイル
|
||||
priority: 8
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -435,17 +483,20 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: num
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 次数
|
||||
en-US: Num
|
||||
ja-JP: 数量
|
||||
- field: size
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
zh-CN: 大小
|
||||
en-US: Size
|
||||
ja-JP: サイズ
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -463,6 +514,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 锁信息
|
||||
en-US: Lock Info
|
||||
ja-JP: ロック情報
|
||||
priority: 9
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -471,18 +523,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: conflicts
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 冲突次数
|
||||
en-US: Conflicts
|
||||
ja-JP: コンフリクト回数
|
||||
- field: deadlocks
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 死锁次数
|
||||
en-US: Deadlocks
|
||||
ja-JP: デッドロック回数
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -500,6 +555,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 慢查询
|
||||
en-US: Slow Sql
|
||||
ja-JP: スローSQL
|
||||
priority: 10
|
||||
fields:
|
||||
- field: sql_text
|
||||
@@ -508,28 +564,33 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: SQL语句
|
||||
en-US: SQL Text
|
||||
ja-JP: SQL文のテキスト
|
||||
- field: calls
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 调用次数
|
||||
en-US: Calls
|
||||
ja-JP: コール回数
|
||||
- field: rows
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 行数
|
||||
en-US: Rows
|
||||
ja-JP: 行
|
||||
- field: avg_time
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 平均时间
|
||||
en-US: Avg Time
|
||||
ja-JP: 平均時間
|
||||
- field: total_time
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 总时间
|
||||
en-US: Total Time
|
||||
ja-JP: 合計時間
|
||||
aliasFields:
|
||||
- query
|
||||
- calls
|
||||
@@ -557,6 +618,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 事务信息
|
||||
en-US: Transaction Info
|
||||
ja-JP: トランザクション情報
|
||||
priority: 11
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -565,18 +627,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: commits
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 提交次数
|
||||
en-US: Commits
|
||||
ja-JP: コミット回数
|
||||
- field: rollbacks
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 回滚次数
|
||||
en-US: Rollbacks
|
||||
ja-JP: ロールバック回数
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -594,6 +659,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 冲突信息
|
||||
en-US: Conflicts Info
|
||||
ja-JP: コンフリクト情報
|
||||
priority: 12
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -602,31 +668,37 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: tablespace
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 表空间
|
||||
en-US: Tablespace
|
||||
ja-JP: 表領域
|
||||
- field: lock
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 锁
|
||||
en-US: Lock
|
||||
ja-JP: ロック
|
||||
- field: snapshot
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 快照
|
||||
en-US: Snapshot
|
||||
ja-JP: スナップショット
|
||||
- field: bufferpin
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 缓冲区
|
||||
en-US: Bufferpin
|
||||
ja-JP: バッファ
|
||||
- field: deadlock
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 死锁
|
||||
en-US: Deadlock
|
||||
ja-JP: デッドロック
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -644,6 +716,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 缓存命中率
|
||||
en-US: Cache Hit Ratio
|
||||
ja-JP: キャッシュ命中率
|
||||
priority: 13
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -652,12 +725,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: ratio
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 命中率
|
||||
en-US: Hit Ratio
|
||||
ja-JP: 命中率
|
||||
aliasFields:
|
||||
- blks_hit
|
||||
- blks_read
|
||||
@@ -681,6 +756,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Checkpoint信息
|
||||
en-US: Checkpoint Info
|
||||
ja-JP: チェックポイント情報
|
||||
priority: 14
|
||||
fields:
|
||||
- field: checkpoint_sync_time
|
||||
@@ -689,12 +765,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Checkpoint同步时间
|
||||
en-US: Checkpoint Sync Time
|
||||
ja-JP: チェックポイント同期時間
|
||||
- field: checkpoint_write_time
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: Checkpoint写入时间
|
||||
en-US: Checkpoint Write Time
|
||||
ja-JP: Checkpoint書き込まれた時間
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -712,6 +790,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Buffer信息
|
||||
en-US: Buffer Info
|
||||
ja-JP: バッファ情報
|
||||
priority: 15
|
||||
fields:
|
||||
- field: allocated
|
||||
@@ -719,26 +798,31 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 已分配
|
||||
en-US: Allocated
|
||||
ja-JP: 割り当てバッファ
|
||||
- field: fsync_calls_by_backend
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 后端进程直接执行的文件同步调用次数
|
||||
en-US: Fsync Calls By Backend
|
||||
ja-JP: バックエンド同期コール回数
|
||||
- field: written_directly_by_backend
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 后台写入到数据文件
|
||||
en-US: Written Directly By Backend
|
||||
ja-JP: バックエンドによる直接書き込まれたファイル
|
||||
- field: written_by_background_writer
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 后台写入
|
||||
en-US: Written By Background Writer
|
||||
ja-JP: バックグラウンドライターに書き込まれた
|
||||
- field: written_during_checkpoints
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 检查点期间写入
|
||||
en-US: Written During Checkpoints
|
||||
ja-JP: チェックポイント中の書き込み
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -14,51 +14,44 @@
|
||||
# limitations under the License.
|
||||
|
||||
# The monitoring type category:service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
|
||||
# 监控类型所属类别:service-应用服务 program-应用程序 db-数据库 custom-自定义 os-操作系统 bigdata-大数据 mid-中间件 webserver-web服务器 cache-缓存 cn-云原生 network-网络监控等等
|
||||
category: bigdata
|
||||
# The monitoring type eg: linux windows tomcat mysql aws...
|
||||
# 监控类型 eg: linux windows tomcat mysql aws...
|
||||
app: greptime
|
||||
# The monitoring i18n name
|
||||
# 监控类型国际化名称
|
||||
name:
|
||||
zh-CN: GreptimeDB
|
||||
en-US: GreptimeDB
|
||||
ja-JP: GreptimeDB
|
||||
# The description and help of this monitoring type
|
||||
# 监控类型的帮助描述信息
|
||||
help:
|
||||
zh-CN: HertzBeat 对 GreptimeDB 时序数据库进行监控。<br><span class='help_module_span'><a class='help_module_content' https://docs.greptime.com/user-guide/operations/monitoring'>点击查看开启步骤</a>。</span>
|
||||
en-US: HertzBeat monitors the GreptimeDB time series database. <br><span class='help_module_span'><a class='help_module_content' https://docs.greptime.com/user-guide/operations/monitoring'>Click to view the activation steps</a>. </span>
|
||||
zh-TW: HertzBeat 對 GreptimeDB 時序資料庫進行監控。<br><span class='help_module_span'><a class='help_module_content' https://docs.greptime.com/user-guide/operations/monitoring'>點擊查看開啓步驟</a>。</span>
|
||||
ja-JP: HertzBeat は GreptimeDB 時系列データベースを監視します。<br><span class='help_module_span'><a class='help_module_content' https://docs.greptime.com/user-guide/operations/monitoring'>クリックしてガイドを見ます</a>。</span>
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.com/zh-cn/docs/help/greptimedb
|
||||
en-US: https://hertzbeat.com/docs/help/greptimedb
|
||||
# 监控所需输入参数定义(根据定义渲染页面UI)
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/greptimedb
|
||||
en-US: https://hertzbeat.apache.org/docs/help/greptimedb
|
||||
# Input params define for monitoring(render web ui by the definition)
|
||||
params:
|
||||
# field-param field key
|
||||
# field-变量字段标识符
|
||||
- field: host
|
||||
# name-param field display i18n name
|
||||
# name-参数字段显示名称
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
# type-字段类型,样式(大部分映射input标签type属性)
|
||||
type: host
|
||||
# required-true or false
|
||||
# required-是否是必输项 true-必填 false-可选
|
||||
required: true
|
||||
- field: port
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
# type-字段类型,样式(大部分映射input标签type属性)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
# 当type为number时,用range表示范围
|
||||
range: '[0,65535]'
|
||||
# default value
|
||||
defaultValue: 4000
|
||||
@@ -67,28 +60,28 @@ params:
|
||||
name:
|
||||
zh-CN: 查询超时时间
|
||||
en-US: Query Timeout
|
||||
ja-JP: クエリタイムアウト
|
||||
type: number
|
||||
required: false
|
||||
# hide param-true or false
|
||||
# 是否隐藏字段 true or false
|
||||
hide: true
|
||||
defaultValue: 6000
|
||||
|
||||
# collect metrics config list
|
||||
# 采集指标配置列表
|
||||
metrics:
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_app_version
|
||||
i18n:
|
||||
zh-CN: greptime 应用版本
|
||||
en-US: greptime_app_version
|
||||
ja-JP: greptime応用バージョン
|
||||
priority: 0
|
||||
fields:
|
||||
- field: short_version
|
||||
i18n:
|
||||
zh-CN: 版本
|
||||
en-US: version
|
||||
ja-JP: バージョン
|
||||
type: 1
|
||||
label: true
|
||||
protocol: http
|
||||
@@ -101,17 +94,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_catalog_schema_count
|
||||
i18n:
|
||||
zh-CN: 目录 模式 数量
|
||||
en-US: greptime_catalog_schema_count
|
||||
ja-JP: greptime_catalog_schema_count
|
||||
priority: 1
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
en-US: count
|
||||
ja-JP: 数量
|
||||
type: 1
|
||||
calculates:
|
||||
- name=.name
|
||||
@@ -125,23 +119,25 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_meta_cache_container_cache_get
|
||||
i18n:
|
||||
zh-CN: 缓存容器缓存获取
|
||||
en-US: greptime_meta_cache_container_cache_get
|
||||
ja-JP: キャッシュゲット
|
||||
priority: 2
|
||||
fields:
|
||||
- field: name
|
||||
i18n:
|
||||
zh-CN: 名称
|
||||
en-US: name
|
||||
ja-JP: キー
|
||||
type: 1
|
||||
label: true
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 指标值
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -153,23 +149,25 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_meta_cache_container_cache_miss
|
||||
i18n:
|
||||
zh-CN: 缓存容器缓存未命中
|
||||
en-US: greptime_meta_cache_container_cache_miss
|
||||
ja-JP: キャッシュミス
|
||||
priority: 3
|
||||
fields:
|
||||
- field: name
|
||||
i18n:
|
||||
zh-CN: 名称
|
||||
en-US: name
|
||||
ja-JP: 名前
|
||||
type: 1
|
||||
label: true
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 指标值
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -181,23 +179,25 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_mito_region_count
|
||||
i18n:
|
||||
zh-CN: mito 引擎区域数量
|
||||
en-US: greptime_mito_region_count
|
||||
ja-JP: mitoエンジンのリージョン数量
|
||||
priority: 4
|
||||
fields:
|
||||
- field: worker
|
||||
i18n:
|
||||
zh-CN: 工作线程
|
||||
en-US: worker
|
||||
ja-JP: ワーカースレッド
|
||||
type: 1
|
||||
label: true
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
en-US: count
|
||||
ja-JP: 数量
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -209,23 +209,25 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_mito_write_stall_total
|
||||
i18n:
|
||||
zh-CN: mito 引擎写入延迟总数
|
||||
en-US: greptime_mito_write_stall_total
|
||||
ja-JP: mitoエンジンの書き込み遅延の合計
|
||||
priority: 5
|
||||
fields:
|
||||
- field: worker
|
||||
i18n:
|
||||
zh-CN: 工作线程
|
||||
en-US: worker
|
||||
ja-JP: ワーカースレッド
|
||||
type: 1
|
||||
label: true
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
en-US: total
|
||||
ja-JP: 数量
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -237,17 +239,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_meta_create_catalog_counter
|
||||
i18n:
|
||||
zh-CN: 创建目录计数器
|
||||
en-US: greptime_meta_create_catalog_counter
|
||||
ja-JP: 目録カウンター
|
||||
priority: 6
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 指标值
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -259,22 +262,24 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_runtime_threads_alive
|
||||
i18n:
|
||||
zh-CN: 运行时线程存活
|
||||
en-US: greptime_runtime_threads_alive
|
||||
ja-JP: ランタイムのアライブスレッド
|
||||
priority: 7
|
||||
fields:
|
||||
- field: thread_name
|
||||
i18n:
|
||||
zh-CN: 线程名称
|
||||
en-US: thread_name
|
||||
ja-JP: スレッド名
|
||||
type: 1
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -286,22 +291,24 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_runtime_threads_idle
|
||||
i18n:
|
||||
zh-CN: 运行时线程空闲
|
||||
en-US: greptime_runtime_threads_idle
|
||||
ja-JP: ランタイムのidleスレッド
|
||||
priority: 8
|
||||
fields:
|
||||
- field: thread_name
|
||||
i18n:
|
||||
zh-CN: 线程名称
|
||||
en-US: thread_name
|
||||
ja-JP: スレッド名
|
||||
type: 1
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -313,32 +320,36 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_servers_http_requests_total
|
||||
i18n:
|
||||
zh-CN: greptime 服务 HTTP 请求总数
|
||||
en-US: greptime_servers_http_requests_total
|
||||
ja-JP: HTTPリクエストの合計
|
||||
priority: 9
|
||||
fields:
|
||||
- field: code
|
||||
i18n:
|
||||
zh-CN: code
|
||||
en-US: code
|
||||
ja-JP: コード
|
||||
type: 1
|
||||
- field: method
|
||||
i18n:
|
||||
zh-CN: method
|
||||
en-US: method
|
||||
ja-JP: メソッド
|
||||
type: 1
|
||||
- field: path
|
||||
i18n:
|
||||
zh-CN: path
|
||||
en-US: path
|
||||
ja-JP: パス
|
||||
type: 1
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -350,17 +361,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_servers_mysql_connection_count
|
||||
i18n:
|
||||
zh-CN: greptime 服务 MySQL 连接数
|
||||
en-US: greptime_servers_mysql_connection_count
|
||||
ja-JP: MySQLの接続数
|
||||
priority: 10
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -372,17 +384,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: greptime_servers_postgres_connection_count
|
||||
i18n:
|
||||
zh-CN: greptime 服务 Postgres 连接数
|
||||
en-US: greptime_servers_postgres_connection_count
|
||||
ja-JP: Postgresの接続数
|
||||
priority: 11
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -394,17 +407,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: process_cpu_seconds_total
|
||||
i18n:
|
||||
zh-CN: 进程 CPU 时间总数
|
||||
en-US: process_cpu_seconds_total
|
||||
ja-JP: CPU時間合計
|
||||
priority: 12
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -416,17 +430,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: process_max_fds
|
||||
i18n:
|
||||
zh-CN: 进程最大文件描述符
|
||||
en-US: process_max_fds
|
||||
ja-JP: プロセスの最大ファイル記述子
|
||||
priority: 13
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -438,17 +453,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: process_open_fds
|
||||
i18n:
|
||||
zh-CN: 进程打开文件描述符
|
||||
en-US: process_open_fds
|
||||
ja-JP: プロセスのオープン中ファイル記述子
|
||||
priority: 14
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -460,17 +476,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: process_resident_memory_bytes
|
||||
i18n:
|
||||
zh-CN: 进程常驻内存字节
|
||||
en-US: process_resident_memory_bytes
|
||||
ja-JP: プロセスの常駐メモリバイト
|
||||
priority: 15
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -482,17 +499,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: process_start_time_seconds
|
||||
i18n:
|
||||
zh-CN: 进程启动时间(秒)
|
||||
en-US: process_start_time_seconds
|
||||
ja-JP: プロセスのアップタイム(秒)
|
||||
priority: 16
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -504,17 +522,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: process_threads
|
||||
i18n:
|
||||
zh-CN: 进程线程
|
||||
en-US: process_threads
|
||||
ja-JP: プロセススレッド
|
||||
priority: 17
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -526,17 +545,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: process_virtual_memory_bytes
|
||||
i18n:
|
||||
zh-CN: 进程虚拟内存字节
|
||||
en-US: process_virtual_memory_bytes
|
||||
ja-JP: プロセスの仮想メモリバイト
|
||||
priority: 18
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: value
|
||||
en-US: value
|
||||
ja-JP: 値
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -548,22 +568,24 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: raft_engine_log_entry_count
|
||||
i18n:
|
||||
zh-CN: raft 引擎日志条目数量
|
||||
en-US: raft_engine_log_entry_count
|
||||
ja-JP: raftエンジンのログエントリー数
|
||||
priority: 19
|
||||
fields:
|
||||
- field: type
|
||||
i18n:
|
||||
zh-CN: 类型
|
||||
en-US: type
|
||||
ja-JP: タイプ
|
||||
type: 1
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
en-US: count
|
||||
ja-JP: 数量
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -575,22 +597,24 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: raft_engine_log_file_count
|
||||
i18n:
|
||||
zh-CN: raft 引擎日志文件数量
|
||||
en-US: raft_engine_log_file_count
|
||||
ja-JP: raftエンジンのログファイル数
|
||||
priority: 20
|
||||
fields:
|
||||
- field: type
|
||||
i18n:
|
||||
zh-CN: 类型
|
||||
en-US: type
|
||||
ja-JP: タイプ
|
||||
type: 1
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
en-US: count
|
||||
ja-JP: 数量
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -602,17 +626,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: raft_engine_memory_usage
|
||||
i18n:
|
||||
zh-CN: raft 引擎内存占用
|
||||
en-US: raft_engine_memory_usage
|
||||
ja-JP: raftエンジンのメモリ使用率
|
||||
priority: 21
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 占用
|
||||
en-US: total
|
||||
ja-JP: 使用率
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -624,22 +649,24 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: raft_engine_recycled_file_count
|
||||
i18n:
|
||||
zh-CN: raft 引擎回收文件数量
|
||||
en-US: raft_engine_recycled_file_count
|
||||
ja-JP: raftエンジンのリサイクルファイル数
|
||||
priority: 22
|
||||
fields:
|
||||
- field: type
|
||||
i18n:
|
||||
zh-CN: 类型
|
||||
en-US: type
|
||||
ja-JP: タイプ
|
||||
type: 1
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
en-US: count
|
||||
ja-JP: 数量
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -651,17 +678,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: sys_jemalloc_allocated
|
||||
i18n:
|
||||
zh-CN: jemalloc 分配
|
||||
en-US: sys_jemalloc_allocated
|
||||
ja-JP: jemallocの割り当て
|
||||
priority: 23
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
en-US: value
|
||||
ja-JP: 数量
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
@@ -673,17 +701,18 @@ metrics:
|
||||
parseType: prometheus
|
||||
|
||||
# metrics - cluster_node_status
|
||||
# 监控指标 - cluster_node_status
|
||||
- name: sys_jemalloc_resident
|
||||
i18n:
|
||||
zh-CN: jemalloc 常驻
|
||||
en-US: sys_jemalloc_resident
|
||||
ja-JP: jemallocの常駐
|
||||
priority: 24
|
||||
fields:
|
||||
- field: value
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
en-US: value
|
||||
ja-JP: 数量
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
|
||||
@@ -21,11 +21,13 @@ app: h3c_switch
|
||||
name:
|
||||
zh-CN: 华三通用交换机
|
||||
en-US: H3C Switch
|
||||
ja-JP: H3Cスイッチングハブ
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP 协议</a> 对 华三交换机 的通用指标(可用性,系统信息,端口流量等)进行采集监控。<br>您可以点击 “<i>新建 华三通用交换机</i>” 并进行配置SNMP相关参数添加,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP Protocol</a> to monitoring H3C Switch general performance metrics. <br>You can click the "<i>New H3C Switch</i>" button and config snmp params to add monitor or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP 協議</a> 對 華三交換機 的通用指標(可用性,系統信息,端口流量等)進行采集監控。<br>您可以點擊 “<i>新建 華三通用交換機</i>” 並進行配置SNMP相關參數添加,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP プロトコルを介して</a> H3Cスイッチングハブの一般的なメトリクスを監視します。<br>「<i>新規 H3Cスイッチングハブ</i>」をクリックしてSNMPなどのパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/h3c_switch
|
||||
en-US: https://hertzbeat.apache.org/docs/help/h3c_switch
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: SNMP 版本
|
||||
en-US: SNMP Version
|
||||
ja-JP: SNMPバージョン
|
||||
# type-param field type(radio mapping the html radio tag)
|
||||
type: radio
|
||||
# required-true or false
|
||||
@@ -79,6 +84,7 @@ params:
|
||||
name:
|
||||
zh-CN: SNMP 团体字
|
||||
en-US: SNMP Community
|
||||
ja-JP: SNMPコミュニティ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -98,6 +104,7 @@ params:
|
||||
name:
|
||||
zh-CN: SNMP username
|
||||
en-US: SNMP username
|
||||
ja-JP: SNMPユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -116,6 +123,7 @@ params:
|
||||
name:
|
||||
zh-CN: SNMP contextName
|
||||
en-US: SNMP contextName
|
||||
ja-JP: SNMPコンテキスト名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -134,6 +142,7 @@ params:
|
||||
name:
|
||||
zh-CN: SNMP authPassword
|
||||
en-US: SNMP authPassword
|
||||
ja-JP: SNMP認証パスワード
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -152,6 +161,7 @@ params:
|
||||
name:
|
||||
zh-CN: authPassword 加密方式
|
||||
en-US: authPassword Encryption
|
||||
ja-JP: 認証暗号
|
||||
# type-param field type(radio mapping the html radio tag)
|
||||
type: radio
|
||||
# required-true or false
|
||||
@@ -172,6 +182,7 @@ params:
|
||||
name:
|
||||
zh-CN: SNMP privPassphrase
|
||||
en-US: SNMP privPassphrase
|
||||
ja-JP: SNMPパスワードフレーズ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -190,6 +201,7 @@ params:
|
||||
name:
|
||||
zh-CN: privPassword 加密方式
|
||||
en-US: privPassword Encryption
|
||||
ja-JP: パスワードの暗号
|
||||
# type-param field type(radio mapping the html radio tag)
|
||||
type: radio
|
||||
# required-true or false
|
||||
@@ -210,6 +222,7 @@ params:
|
||||
name:
|
||||
zh-CN: 超时时间(ms)
|
||||
en-US: Timeout(ms)
|
||||
ja-JP: タイムアウト(ms)
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -227,6 +240,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 系统信息
|
||||
en-US: System Info
|
||||
ja-JP: システム情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -238,32 +252,38 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 主机名称
|
||||
en-US: Host Name
|
||||
ja-JP: ホスト名
|
||||
- field: descr
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 描述信息
|
||||
en-US: Description
|
||||
ja-JP: 説明
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 运行时长
|
||||
en-US: Uptime
|
||||
ja-JP: アップタイム
|
||||
- field: location
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 位置
|
||||
en-US: Location
|
||||
ja-JP: 位置
|
||||
- field: contact
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 联系人
|
||||
en-US: Contact
|
||||
ja-JP: 連絡先
|
||||
- field: responseTime
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 响应时间
|
||||
en-US: Response Time
|
||||
ja-JP: 応答時間
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: snmp
|
||||
# the config content when protocol is snmp
|
||||
@@ -305,6 +325,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 接口详情
|
||||
en-US: Interfaces Detail
|
||||
ja-JP: ネットワークカード詳細
|
||||
priority: 1
|
||||
fields:
|
||||
- field: index
|
||||
@@ -312,66 +333,78 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 编号
|
||||
en-US: Index
|
||||
ja-JP: 番号
|
||||
- field: descr
|
||||
type: 1
|
||||
label: true
|
||||
i18n:
|
||||
zh-CN: 接口名称
|
||||
en-US: Interface Name
|
||||
ja-JP: ネットワークカード名
|
||||
- field: mtu
|
||||
type: 0
|
||||
unit: 'byte'
|
||||
i18n:
|
||||
zh-CN: MTU
|
||||
en-US: MTU
|
||||
ja-JP: MTU
|
||||
- field: speed
|
||||
type: 0
|
||||
unit: 'MB/s'
|
||||
i18n:
|
||||
zh-CN: 接口速率
|
||||
en-US: Interface Speed
|
||||
ja-JP: ネットワークカード速度
|
||||
- field: in_octets
|
||||
type: 0
|
||||
unit: 'MByte'
|
||||
i18n:
|
||||
zh-CN: 入流量
|
||||
en-US: In Octets
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: in_discards
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 入丢包数
|
||||
en-US: In Discards
|
||||
ja-JP: 受信されたパケットのロス数
|
||||
- field: in_errors
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 入错包数
|
||||
en-US: In Errors
|
||||
ja-JP: 受信異常パケット数
|
||||
- field: out_octets
|
||||
type: 0
|
||||
unit: 'MByte'
|
||||
i18n:
|
||||
zh-CN: 出流量
|
||||
en-US: Out Octets
|
||||
ja-JP: 転送されたバイト数
|
||||
- field: out_discards
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 出丢包数
|
||||
en-US: Out Discards
|
||||
ja-JP: 転送されたパケットのロス数
|
||||
- field: out_errors
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 出错包数
|
||||
en-US: Out Errors
|
||||
ja-JP: 転送異常パケット数
|
||||
- field: admin_status
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 配置状态
|
||||
en-US: Config Status
|
||||
ja-JP: 設定ステータス
|
||||
- field: oper_status
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 当前状态
|
||||
en-US: Current Status
|
||||
ja-JP: 現在のステータス
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- ifIndex
|
||||
|
||||
@@ -21,11 +21,13 @@ app: hadoop
|
||||
name:
|
||||
zh-CN: Apache Hadoop
|
||||
en-US: Apache Hadoop
|
||||
ja-JP: Apache Hadoop
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: HertzBeat 使用<a class='help_module_content' href='https://baijiahao.baidu.com/s?id=1605937053950156833&wfr=spider&for=pc'> JMX 协议</a>对 Hadoop 的 JVM 虚拟机的通用性能指标(memory pool,限JDK8及以下的code cache、class loading、thread)进行采集监控。<br><span class='help_module_span'>⚠️注意:您需要在 Hadoop 应用开启 JMX 服务, <a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/help/hadoop#hadoop%E5%BA%94%E7%94%A8%E5%BC%80%E5%90%AFjmx%E5%8D%8F%E8%AE%AE%E6%AD%A5%E9%AA%A4'>点击查看开启步骤</a>。</span>
|
||||
en-US: "HertzBeat monitors general performance metrics(memory pool, class loading, thread) of Hadoop VMware through <a class='help_module_content' href='https://zh.wikipedia.org/JMX'>JMX protocol</a>. <br><span class='help_module_span'>⚠️Note: You should enable the JMX service in Hadoop application, and the metric of code cache is only available to JDK8 and below.<a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/hadoop#hadoop%E5%BA%94%E7%94%A8%E5%BC%80%E5%90%AFjmx%E5%8D%8F%E8%AE%AE%E6%AD%A5%E9%AA%A4'>Click here to view the specific steps.</a></span>"
|
||||
zh-TW: HertzBeat使用<a class='help_ module_ content' href='https://baijiahao.baidu.com/s?id=1605937053950156833&wfr=spider&for=pc'> JMX協定</a>對Hadoop的JVM虛擬機器的通用性能指標(memory pool,限JDK8及以下的code cache、class loading、thread)進行採集監控。<br><span class='help_ module_ span'> ⚠️ ️注意:您需要在Hadoop應用開啟JMX服務,<a class='help_ module_ content' href='https://hertzbeat.apache.org/zh-cn/docs/help/hadoop#hadoop%E5%BA%94%E7%94%A8%E5%BC%80%E5%90%AFjmx%E5%8D%8F%E8%AE%AE%E6%AD%A5%E9%AA%A4'>點擊查看開啟步驟</a>。</span>
|
||||
zh-TW: HertzBeat使用<a class='help_module_content' href='https://baijiahao.baidu.com/s?id=1605937053950156833&wfr=spider&for=pc'> JMX協定</a>對Hadoop的JVM虛擬機器的通用性能指標(memory pool,限JDK8及以下的code cache、class loading、thread)進行採集監控。<br><span class='help_module_span'> ⚠️ ️注意:您需要在Hadoop應用開啟JMX服務,<a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/help/hadoop#hadoop%E5%BA%94%E7%94%A8%E5%BC%80%E5%90%AFjmx%E5%8D%8F%E8%AE%AE%E6%AD%A5%E9%AA%A4'>點擊查看開啟步驟</a>。</span>
|
||||
ja-JP: HertzBeatは <a class='help_module_content' href='https://baijiahao.baidu.com/s?id=1605937053950156833&wfr=spider&for=pc'> JMXプロトコルを介して</a> HadoopのJava仮想マシンの一般的なパフォーマンスのメトリクスを監視します。<br><span class='help_module_span'> ⚠️注意:Hadoop で JMX サービスを有効にする必要があります。<a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/hadoop#hadoop%E5%BA%94%E7%94%A8%E5%BC%80%E5%90%AFjmx%E5%8D%8F%E8%AE%AE%E6%AD%A5%E9%AA%A4'>クリックしてガイドを見ます</a>。</span>
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/hadoop/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/hadoop/
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: JMX URL
|
||||
en-US: JMX URL
|
||||
ja-JP: JMX URL
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
@@ -75,6 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -89,6 +95,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -102,6 +109,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 虚拟机基础信息
|
||||
en-US: JVM Basic
|
||||
ja-JP: Java仮想マシン基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -113,22 +121,26 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 名称
|
||||
en-US: Vm Name
|
||||
ja-JP: 仮想マシン名
|
||||
- field: VmVendor
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 厂商
|
||||
en-US: Vm Vendor
|
||||
ja-JP: 仮想マシンベンダー
|
||||
- field: VmVersion
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 版本
|
||||
en-US: Vm Version
|
||||
ja-JP: 仮想マシンバージョン
|
||||
- field: Uptime
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 运行时长
|
||||
en-US: Up time
|
||||
ja-JP: アップタイム
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: jmx
|
||||
# the config content when protocol is jmx
|
||||
@@ -148,6 +160,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 内存池
|
||||
en-US: Memory Pool
|
||||
ja-JP: メモリプール
|
||||
fields:
|
||||
- field: name
|
||||
type: 1
|
||||
@@ -155,30 +168,35 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 指标名称
|
||||
en-US: Name
|
||||
ja-JP: メトリクス名
|
||||
- field: committed
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 已分配内存
|
||||
en-US: Committed
|
||||
ja-JP: コミットされたメモリ
|
||||
- field: init
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 初始化内存
|
||||
en-US: Init
|
||||
ja-JP: イニシャルメモリ
|
||||
- field: max
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 最大内存
|
||||
en-US: Max
|
||||
ja-JP: 最大メモリ
|
||||
- field: used
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 已使用内存
|
||||
en-US: Used
|
||||
ja-JP: 使用したメモリ
|
||||
units:
|
||||
- committed=B->MB
|
||||
- init=B->MB
|
||||
@@ -215,27 +233,32 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 本地代码缓冲区
|
||||
en-US: Code Cache
|
||||
ja-JP: コードキャッシュ
|
||||
fields:
|
||||
- field: committed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 已分配内存
|
||||
en-US: Committed
|
||||
ja-JP: コミットされたメモリ
|
||||
- field: init
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 初始化内存
|
||||
en-US: Init
|
||||
ja-JP: イニシャルメモリ
|
||||
- field: max
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大内存
|
||||
en-US: Max
|
||||
ja-JP: 最大メモリ
|
||||
- field: used
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 已使用内存
|
||||
en-US: Used
|
||||
ja-JP: 使用したメモリ
|
||||
aliasFields:
|
||||
- Usage->committed
|
||||
- Usage->init
|
||||
@@ -262,6 +285,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 类加载信息
|
||||
en-US: Class Loading
|
||||
ja-JP: クラスローディング情報
|
||||
# collect metrics content
|
||||
fields:
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
@@ -270,16 +294,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 当前已加载类数量
|
||||
en-US: Loaded Class Count
|
||||
ja-JP: ロードされたクラス数
|
||||
- field: TotalLoadedClassCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 已加载类总数量
|
||||
en-US: Total Loaded Class Count
|
||||
ja-JP: ロードされたクラス総数
|
||||
- field: UnloadedClassCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 未加载类总数量
|
||||
en-US: Unloaded Class Count
|
||||
ja-JP: アンロードされたクラス総数
|
||||
protocol: jmx
|
||||
jmx:
|
||||
host: ^_^host^_^
|
||||
@@ -294,6 +321,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 线程信息
|
||||
en-US: Thread
|
||||
ja-JP: スレッド情報
|
||||
# collect metrics content
|
||||
fields:
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
@@ -302,33 +330,39 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 已启动线程总数
|
||||
en-US: Total Started Thread Count
|
||||
ja-JP: スレッド総数
|
||||
- field: ThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活跃线程数
|
||||
en-US: Thread Count
|
||||
ja-JP: 活躍スレッド数
|
||||
- field: PeakThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大峰值线程数
|
||||
en-US: Peak Thread Count
|
||||
ja-JP: 最大スレッド数
|
||||
- field: DaemonThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活跃守护线程数
|
||||
en-US: Daemon Thread Count
|
||||
ja-JP: デーモンスレッド数
|
||||
- field: CurrentThreadUserTime
|
||||
type: 0
|
||||
unit: s
|
||||
i18n:
|
||||
zh-CN: 线程占用的CPU时间(用户态)
|
||||
en-US: Current Thread User Time
|
||||
ja-JP: 現在のスレッドユーザー時間
|
||||
- field: CurrentThreadCpuTime
|
||||
type: 0
|
||||
unit: s
|
||||
i18n:
|
||||
zh-CN: 线程占用的CPU时间
|
||||
en-US: Current Thread CPU Time
|
||||
ja-JP: 現在のスレッドシステム時間
|
||||
units:
|
||||
- CurrentThreadUserTime=NS->S
|
||||
- CurrentThreadCpuTime=NS->S
|
||||
|
||||
@@ -21,12 +21,13 @@ app: hbase_master
|
||||
name:
|
||||
zh-CN: Apache Hbase Master
|
||||
en-US: Apache Hbase Master
|
||||
ja-JP: Apache Hbase Master
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 对 Hbase 数据库 Master 节点监控指标进行监控。<br>您可以点击 “<i>新建 Apache Hbase Master</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitors the Master node monitoring indicators of the Hbase database. <br>You can click "<i>New Apache Hbase Master</i>" to configure, or select "<i>More Actions</i>" to import an existing configuration.
|
||||
zh-TW: Hertzbeat 對 Hbase 數據庫 Master 节點監控指標進行監控。<br>您可以點擊 “<i>新建 Apache Hbase Master</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
|
||||
ja-JP: Hertzbeat は HbaseデータベースのMasterノードの一般的なメトリクスを監視します。<br>「<i>新規 Apache Hbase Master</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/hbase_master/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/hbase_master/
|
||||
@@ -38,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -48,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -62,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: 查询超时时间
|
||||
en-US: Query Timeout
|
||||
ja-JP: クエリタイムアウト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# required-true or false
|
||||
@@ -76,6 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: HTTPS
|
||||
ja-JP: HTTPS
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -87,6 +92,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Master服务信息
|
||||
en-US: Master Service Info
|
||||
ja-JP: マスターサービス情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -98,21 +104,25 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 活跃RegionServer数量
|
||||
en-US: numRegionServers
|
||||
ja-JP: 活躍的なRegionServer数
|
||||
- field: numDeadRegionServers
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 异常RegionServer数量
|
||||
en-US: numDeadRegionServers
|
||||
ja-JP: 異常的なRegionServer数
|
||||
- field: averageLoad
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 集群平均负载
|
||||
en-US: averageLoad
|
||||
ja-JP: 平均ロード
|
||||
- field: clusterRequests
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 集群请求数量
|
||||
en-US: clusterRequests
|
||||
ja-JP: クラスターのリクエスト数
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.numRegionServers
|
||||
@@ -137,6 +147,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Region In Transition 信息
|
||||
en-US: Region In Transition Info
|
||||
ja-JP: Region In Transition 情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 1
|
||||
@@ -148,16 +159,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 当前的 RIT 数量
|
||||
en-US: ritCount
|
||||
ja-JP: RIT数
|
||||
- field: ritCountOverThreshold
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 超过阈值的 RIT 数量
|
||||
en-US: ritCountOverThreshold
|
||||
ja-JP: 閾値を超えたRIT数
|
||||
- field: ritOldestAge
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最老的RIT的持续时间
|
||||
en-US: ritOldestAge
|
||||
ja-JP: 最古のRITのスパン
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.ritCount
|
||||
@@ -180,6 +194,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 基础信息
|
||||
en-US: Basic Info
|
||||
ja-JP: 基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 2
|
||||
@@ -191,48 +206,57 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 当前活跃RegionServer列表
|
||||
en-US: liveRegionServers
|
||||
ja-JP: 活躍的なRegionServer
|
||||
- field: deadRegionServers
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 当前离线RegionServer列表
|
||||
en-US: deadRegionServers
|
||||
ja-JP: オフラインRegionServer
|
||||
- field: zookeeperQuorum
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Zookeeper列表
|
||||
en-US: zookeeperQuorum
|
||||
ja-JP: zookeeper定足数
|
||||
- field: masterHostName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Master节点
|
||||
en-US: masterHostName
|
||||
ja-JP: マスターホスト名
|
||||
- field: BalancerCluster_num_ops
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 集群负载均衡次数
|
||||
en-US: BalancerCluster_num_ops
|
||||
ja-JP: クラスターのロードバランシング回数
|
||||
- field: numActiveHandler
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: RPC句柄数
|
||||
en-US: numActiveHandler
|
||||
ja-JP: RPCハンドル数
|
||||
- field: receivedBytes
|
||||
type: 0
|
||||
unit: 'MB'
|
||||
i18n:
|
||||
zh-CN: 集群接收数据量(MB)
|
||||
en-US: receivedBytes
|
||||
ja-JP: 受信されたバイト
|
||||
- field: sentBytes
|
||||
type: 0
|
||||
unit: 'MB'
|
||||
i18n:
|
||||
zh-CN: 集群发送数据量(MB)
|
||||
en-US: sentBytes
|
||||
ja-JP: 転送されたバイト
|
||||
- field: clusterRequests
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 集群总请求数量
|
||||
en-US: clusterRequests
|
||||
ja-JP: クラスターのリクエスト数
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.beans[?(@.name == "Hadoop:service=HBase,name=Master,sub=Server")].['tag.liveRegionServers']
|
||||
|
||||
@@ -21,11 +21,13 @@ app: hbase_regionserver
|
||||
name:
|
||||
zh-CN: Apache Hbase RegionServer
|
||||
en-US: Apache Hbase RegionServer
|
||||
ja-JP: Apache Hbase RegionServer
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 对 Hbase 数据库 RegionServer 节点监控指标进行监控。<br>您可以点击 “<i>新建 Apache Hbase RegionServer</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitors the RegionServer node monitoring indicators of the Hbase database. <br>You can click "<i>New Apache Hbase RegionServer</i>" to configure, or select "<i>More Actions</i>" to import an existing configuration.
|
||||
zh-TW: Hertzbeat 對 Hbase 數據庫 RegionServer 节點監控指標進行監控。<br>您可以點擊 “<i>新建 Apache Hbase RegionServer</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は HbaseデータベースのRegionServerノードの一般的なメトリクスを監視します。<br>「<i>新規 Apache Hbase RegionServer</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/hbase_regionserver/
|
||||
@@ -38,6 +40,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -48,6 +51,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -62,6 +66,7 @@ params:
|
||||
name:
|
||||
zh-CN: 查询超时时间
|
||||
en-US: Query Timeout
|
||||
ja-JP: クエリタイムアウト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# required-true or false
|
||||
@@ -76,6 +81,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: HTTPS
|
||||
ja-JP: HTTPS
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -87,6 +93,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: RegionServer 服务信息
|
||||
en-US: RegionServer Service Info
|
||||
ja-JP: RegionServerサービス情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -98,24 +105,28 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Region数量
|
||||
en-US: regionCount
|
||||
ja-JP: Region数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: readRequestCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 重启集群后的读请求数量
|
||||
en-US: readRequestCount
|
||||
ja-JP: 読み取りリクエスト数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: writeRequestCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 重启集群后的写请求数量
|
||||
en-US: writeRequestCount
|
||||
ja-JP: 書き込みリクエスト数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: averageRegionSize
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 平均Region大小
|
||||
en-US: averageRegionSize
|
||||
ja-JP: Regionの平均サイズ
|
||||
unit: 'MB'
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: totalRequestCount
|
||||
@@ -123,108 +134,126 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 全部请求数量
|
||||
en-US: totalRequestCount
|
||||
ja-JP: リクエスト総数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ScanTime_num_ops
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Scan 请求总量
|
||||
en-US: ScanTime_num_ops
|
||||
ja-JP: Scan操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: Append_num_ops
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Append 请求量
|
||||
en-US: Append_num_ops
|
||||
ja-JP: Append操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: Increment_num_ops
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Increment请求量
|
||||
en-US: Increment_num_ops
|
||||
ja-JP: Increment操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: Get_num_ops
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Get 请求量
|
||||
en-US: Get_num_ops
|
||||
ja-JP: Get操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: Delete_num_ops
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Delete 请求量
|
||||
en-US: Delete_num_ops
|
||||
ja-JP: Delete操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: Put_num_ops
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Put 请求量
|
||||
en-US: Put_num_ops
|
||||
ja-JP: Put操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ScanTime_mean
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 平均 Scan 请求时间
|
||||
en-US: ScanTime_mean
|
||||
ja-JP: Scan操作の平均時間
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ScanTime_min
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最小 Scan 请求时间
|
||||
en-US: ScanTime_min
|
||||
ja-JP: Scan操作の最小時間
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ScanTime_max
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大 Scan 请求时间
|
||||
en-US: ScanTime_max
|
||||
ja-JP: Scan操作の最大時間
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ScanSize_mean
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 平均 Scan 请求大小
|
||||
en-US: ScanSize_mean
|
||||
ja-JP: Scan操作の平均サイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ScanSize_min
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最小 Scan 请求大小
|
||||
en-US: ScanSize_min
|
||||
ja-JP: Scan操作の最小サイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ScanSize_max
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大 Scan 请求大小
|
||||
en-US: ScanSize_max
|
||||
ja-JP: Scan操作の最大サイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: slowPutCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 慢操作次数/Put
|
||||
en-US: slowPutCount
|
||||
ja-JP: スローPut操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: slowGetCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 慢操作次数/Get
|
||||
en-US: slowGetCount
|
||||
ja-JP: スローGet操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: slowAppendCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 慢操作次数/Append
|
||||
en-US: slowAppendCount
|
||||
ja-JP: スローAppend操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: slowIncrementCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 慢操作次数/Increment
|
||||
en-US: slowIncrementCount
|
||||
ja-JP: スローIncrement操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: slowDeleteCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 慢操作次数/Delete
|
||||
en-US: slowDeleteCount
|
||||
ja-JP: スローDelete操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: blockCacheSize
|
||||
type: 0
|
||||
@@ -232,36 +261,42 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 缓存块内存占用大小
|
||||
en-US: blockCacheSize
|
||||
ja-JP: ブロックキャッシュのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: blockCacheCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 缓存块数量_Block Cache 中的 Block 数量
|
||||
en-US: blockCacheCount
|
||||
ja-JP: ブロックキャッシュ数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: blockCacheExpressHitPercent
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 读缓存命中率
|
||||
en-US: blockCacheExpressHitPercent
|
||||
ja-JP: ブロックキャッシュ命中率
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: memStoreSize
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Memstore 大小
|
||||
en-US: memStoreSize
|
||||
ja-JP: Memstoreサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: FlushTime_num_ops
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: RS写磁盘次数/MemStore Flush 写磁盘次数
|
||||
en-US: FlushTime_num_ops
|
||||
ja-JP: MemStore Flush操作回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: flushQueueLength
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Region Flush 队列长度
|
||||
en-US: flushQueueLength
|
||||
ja-JP: Region Flushキューの長さ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: flushedCellsSize
|
||||
type: 0
|
||||
@@ -269,18 +304,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: flush到磁盘大小
|
||||
en-US: flushedCellsSize
|
||||
ja-JP: flushedサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: storeCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Store 个数
|
||||
en-US: storeCount
|
||||
ja-JP: Store数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: storeFileCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Storefile 个数
|
||||
en-US: storeFileCount
|
||||
ja-JP: Storeファイル数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: storeFileSize
|
||||
type: 0
|
||||
@@ -288,36 +326,42 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Storefile 大小
|
||||
en-US: storeFileSize
|
||||
ja-JP: Storeファイルサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: compactionQueueLength
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Compaction 队列长度
|
||||
en-US: compactionQueueLength
|
||||
ja-JP: Compactionキューの長さ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: percentFilesLocal
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Region 的 HFile 位于本地 HDFS data node的比例
|
||||
en-US: percentFilesLocal
|
||||
ja-JP: Regionのローカルファイルのパーセント
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: percentFilesLocalSecondaryRegions
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Region 副本的 HFile 位于本地 HDFS data node的比例
|
||||
en-US: percentFilesLocalSecondaryRegions
|
||||
ja-JP: Secondary Regionのローカルファイルのパーセント
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: hlogFileCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: WAL 文件数量
|
||||
en-US: hlogFileCount
|
||||
ja-JP: WALファイル数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: hlogFileSize
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: WAL 文件大小
|
||||
en-US: hlogFileSize
|
||||
ja-JP: WALファイルサイズ
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.regionCount
|
||||
@@ -414,6 +458,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: RegionServer IPC 信息
|
||||
en-US: RegionServer IPC Info
|
||||
ja-JP: RegionServer IPC 情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 1
|
||||
@@ -425,24 +470,28 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: RPC句柄数
|
||||
en-US: numActiveHandler
|
||||
ja-JP: RPCハンドル数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: NotServingRegionException
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: NotServingRegionException 异常数量
|
||||
en-US: NotServingRegionException
|
||||
ja-JP: NotServingRegionException
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: RegionMovedException
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: RegionMovedException异常数量
|
||||
en-US: RegionMovedException
|
||||
ja-JP: RegionMovedException
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: RegionTooBusyException
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: RegionTooBusyException异常数量
|
||||
en-US: RegionTooBusyException
|
||||
ja-JP: RegionTooBusyException
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.numActiveHandler
|
||||
@@ -468,6 +517,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: RegionServer JVM 信息
|
||||
en-US: RegionServer JVM Info
|
||||
ja-JP: RegionServer Java仮想マシン情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 2
|
||||
@@ -480,6 +530,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程使用的非堆内存大小
|
||||
en-US: MemNonHeapUsedM
|
||||
ja-JP: 使用したノンヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemNonHeapCommittedM
|
||||
type: 0
|
||||
@@ -487,6 +538,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程 commit 的非堆内存大小
|
||||
en-US: MemNonHeapCommittedM
|
||||
ja-JP: コミットされたノンヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemHeapUsedM
|
||||
type: 0
|
||||
@@ -494,6 +546,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程使用的堆内存大小
|
||||
en-US: MemHeapUsedM
|
||||
ja-JP: 使用したヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemHeapCommittedM
|
||||
type: 0
|
||||
@@ -501,6 +554,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程 commit 的堆内存大小
|
||||
en-US: MemHeapCommittedM
|
||||
ja-JP: コミットされたヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemHeapMaxM
|
||||
type: 0
|
||||
@@ -508,6 +562,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程最大的堆内存大小
|
||||
en-US: MemHeapMaxM
|
||||
ja-JP: ヒープメモリサイズの最大値
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemMaxM
|
||||
type: 0
|
||||
@@ -515,12 +570,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程最大内存大小
|
||||
en-US: MemMaxM
|
||||
ja-JP: メモリサイズの最大値
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: GcCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Young GC次数
|
||||
en-US: GcCount
|
||||
ja-JP: GC回数
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.MemNonHeapUsedM
|
||||
|
||||
@@ -21,11 +21,13 @@ app: hdfs_datanode
|
||||
name:
|
||||
zh-CN: Apache HDFS DataNode
|
||||
en-US: Apache HDFS DataNode
|
||||
ja-JP: Apache HDFS DataNode
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 对 HDFS DataNode 节点监控指标进行监控。<br>您可以点击 “<i>新建 Apache HDFS DataNode</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitors the HDFS DataNode metrics. <br>You can click "<i>New Apache HDFS DataNode</i>" to configure, or select "<i>More Actions</i>" to import an existing configuration.
|
||||
zh-TW: Hertzbeat 對 HDFS DataNode 節點監控指標進行監控。<br>您可以點擊 “<i>新建 Apache HDFS DataNode</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は HDFS DataNodeの一般的なメトリクスを監視します。<br>「<i>新規 Apache HDFS DataNode</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/hdfs_datanode/
|
||||
@@ -38,6 +40,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -48,6 +51,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -62,6 +66,7 @@ params:
|
||||
name:
|
||||
zh-CN: 查询超时时间
|
||||
en-US: Query Timeout
|
||||
ja-JP: クエリタイムアウト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# required-true or false
|
||||
@@ -86,6 +91,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: DataNode HDFS使用量
|
||||
en-US: DfsUsed
|
||||
ja-JP: 使用したHDFS容量
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: Remaining
|
||||
type: 0
|
||||
@@ -93,6 +99,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: DataNode HDFS剩余空间
|
||||
en-US: Remaining
|
||||
ja-JP: 使用可能のHDFS容量
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: Capacity
|
||||
type: 0
|
||||
@@ -100,6 +107,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: DataNode HDFS空间总量
|
||||
en-US: Capacity
|
||||
ja-JP: HDFS容量合計
|
||||
units:
|
||||
- DfsUsed=B->GB
|
||||
- Remaining=B->GB
|
||||
@@ -134,60 +142,70 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: JVM 当前已经使用的 NonHeapMemory 的大小
|
||||
en-US: MemNonHeapUsedM
|
||||
ja-JP: 使用したノンヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemNonHeapCommittedM
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 配置的 NonHeapCommittedM 的大小
|
||||
en-US: MemNonHeapCommittedM
|
||||
ja-JP: コミットされたノンヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemHeapUsedM
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 当前已经使用的 HeapMemory 的大小
|
||||
en-US: MemHeapUsedM
|
||||
ja-JP: 使用したヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemHeapCommittedM
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM HeapMemory 提交大小
|
||||
en-US: MemHeapCommittedM
|
||||
ja-JP: コミットされたヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemHeapMaxM
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 配置的 HeapMemory 的大小
|
||||
en-US: MemHeapMaxM
|
||||
ja-JP: 配置のヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemMaxM
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 运行时可以使用的最大内存大小
|
||||
en-US: MemMaxM
|
||||
ja-JP: 最大のヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ThreadsRunnable
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 处于 RUNNABLE 状态的线程数量
|
||||
en-US: ThreadsRunnable
|
||||
ja-JP: 実行中のスレッド数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ThreadsBlocked
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 处于 BLOCKED 状态的线程数量
|
||||
en-US: ThreadsBlocked
|
||||
ja-JP: ブロックされたスレッド数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ThreadsWaiting
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 处于 WAITING 状态的线程数量
|
||||
en-US: ThreadsWaiting
|
||||
ja-JP: 待機中のスレッド数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ThreadsTimedWaiting
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 处于 TIMED WAITING 状态的线程数量
|
||||
en-US: ThreadsTimedWaiting
|
||||
ja-JP: 時間指定の待機中のスレッド数
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.MemNonHeapUsedM
|
||||
@@ -232,6 +250,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 启动时间
|
||||
en-US: StartTime
|
||||
ja-JP: 起動時間
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.beans[?(@.name == "java.lang:type=Runtime")].StartTime
|
||||
|
||||
@@ -21,11 +21,13 @@ app: hdfs_namenode
|
||||
name:
|
||||
zh-CN: Apache HDFS NameNode
|
||||
en-US: Apache HDFS NameNode
|
||||
ja-JP: Apache HDFS NameNode
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 对 HDFS NameNode 节点监控指标进行监控。<br>您可以点击 “<i>新建 Apache HDFS NameNode</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitors the HDFS NameNode metrics. <br>You can click "<i>New Apache HDFS NameNode</i>" to configure, or select "<i>More Actions</i>" to import an existing configuration.
|
||||
zh-TW: Hertzbeat 對 HDFS NameNode 節點監控指標進行監控。<br>您可以點擊 “<i>新建 Apache HDFS NameNode</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は HDFS NameNodeの一般的なメトリクスを監視します。<br>「<i>新規 Apache HDFS NameNode</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/hdfs_namenode/
|
||||
@@ -38,6 +40,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -48,6 +51,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -62,6 +66,7 @@ params:
|
||||
name:
|
||||
zh-CN: 查询超时时间
|
||||
en-US: Query Timeout
|
||||
ja-JP: クエリタイムアウト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# required-true or false
|
||||
@@ -85,6 +90,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 集群存储总容量
|
||||
en-US: CapacityTotal
|
||||
ja-JP: 容量合計
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: CapacityTotalGB
|
||||
type: 0
|
||||
@@ -92,12 +98,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 集群存储总容量
|
||||
en-US: CapacityTotalGB
|
||||
ja-JP: 容量合計(GB)
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: CapacityUsed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 集群存储已使用容量
|
||||
en-US: CapacityUsed
|
||||
ja-JP: 使用した容量
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: CapacityUsedGB
|
||||
type: 0
|
||||
@@ -105,12 +113,14 @@ metrics:
|
||||
zh-CN: 集群存储已使用容量
|
||||
unit: 'GB'
|
||||
en-US: CapacityUsedGB
|
||||
ja-JP: 使用した容量(GB)
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: CapacityRemaining
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 集群存储剩余容量
|
||||
en-US: CapacityRemaining
|
||||
ja-JP: 使用可能の容量
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: CapacityRemainingGB
|
||||
type: 0
|
||||
@@ -118,120 +128,140 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 集群存储剩余容量
|
||||
en-US: CapacityRemainingGB
|
||||
ja-JP: 使用可能の容量(GB)
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: CapacityUsedNonDFS
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 集群非 HDFS 使用容量
|
||||
en-US: CapacityUsedNonDFS
|
||||
ja-JP: 使用したノンHDFS容量
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: TotalLoad
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 整个集群的客户端连接数
|
||||
en-US: TotalLoad
|
||||
ja-JP: クライアントとの接続総数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: FilesTotal
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 集群文件总数量
|
||||
en-US: FilesTotal
|
||||
ja-JP: ファイル総数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: BlocksTotal
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 总 BLOCK 数量
|
||||
en-US: BlocksTotal
|
||||
ja-JP: ブロック総数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: PendingReplicationBlocks
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 等待被备份的块数量
|
||||
en-US: PendingReplicationBlocks
|
||||
ja-JP: 保留中のレプリケーションのブロック数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: UnderReplicatedBlocks
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 副本数不够的块数量
|
||||
en-US: UnderReplicatedBlocks
|
||||
ja-JP: レプリケート中のブロック数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: CorruptBlocks
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 坏块数量
|
||||
en-US: CorruptBlocks
|
||||
ja-JP: 破損ブロック数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ScheduledReplicationBlocks
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 安排要备份的块数量
|
||||
en-US: ScheduledReplicationBlocks
|
||||
ja-JP: スケジュールされたレプリケーションのブロック数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: PendingDeletionBlocks
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 等待被删除的块数量
|
||||
en-US: PendingDeletionBlocks
|
||||
ja-JP: 保留中の削除ブロック数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ExcessBlocks
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 多余的块数量
|
||||
en-US: ExcessBlocks
|
||||
ja-JP: 余剰ブロック数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: PostponedMisreplicatedBlocks
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 被推迟处理的异常块数量
|
||||
en-US: PostponedMisreplicatedBlocks
|
||||
ja-JP: 延期の異常ブロック数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: NumLiveDataNodes
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活的数据节点数量
|
||||
en-US: NumLiveDataNodes
|
||||
ja-JP: ライブのDATANODE数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: NumDeadDataNodes
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 已经标记为 Dead 状态的数据节点数量
|
||||
en-US: NumDeadDataNodes
|
||||
ja-JP: デッドのDATANODE数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: NumDecomLiveDataNodes
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 下线且 Live 的节点数量
|
||||
en-US: NumDecomLiveDataNodes
|
||||
ja-JP: オフラインとライブのDATANODE数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: NumDecomDeadDataNodes
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 下线且 Dead 的节点数量
|
||||
en-US: NumDecomDeadDataNodes
|
||||
ja-JP: オフラインとデッドのDATANODE数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: NumDecommissioningDataNodes
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 正在下线的节点数量
|
||||
en-US: NumDecommissioningDataNodes
|
||||
ja-JP: オフライン中のDATANODE数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: TransactionsSinceLastCheckpoint
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 从上次Checkpoint之后的事务数量
|
||||
en-US: TransactionsSinceLastCheckpoint
|
||||
ja-JP: 前回のチェックポイントからのトランザクション数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: LastCheckpointTime
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 上一次Checkpoint时间
|
||||
en-US: LastCheckpointTime
|
||||
ja-JP: 最終チェックポイント時刻
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: PendingDataNodeMessageCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: DATANODE 的请求被 QUEUE 在 standby namenode 中的个数
|
||||
en-US: PendingDataNodeMessageCount
|
||||
ja-JP: DATANODEで保留中のメッセージ数
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.CapacityTotal
|
||||
@@ -306,18 +336,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 接收数据速率
|
||||
en-US: ReceivedBytes
|
||||
ja-JP: 受信されたバイト
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: SentBytes
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 发送数据速率
|
||||
en-US: SentBytes
|
||||
ja-JP: 転送されたバイト
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: RpcQueueTimeNumOps
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: RPC 调用速率
|
||||
en-US: RpcQueueTimeNumOps
|
||||
ja-JP: RPCスピード
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.ReceivedBytes
|
||||
@@ -336,7 +369,6 @@ metrics:
|
||||
ssl: ^_^ssl^_^
|
||||
parseType: jsonPath
|
||||
parseScript: '$.beans[?(@.name =~ /Hadoop:service=NameNode,name=RpcActivityForPort80\d+/)]'
|
||||
# parseScript: '$.beans[?(@.name == "Hadoop:service=NameNode,name=RpcActivityForPort8020")]'
|
||||
- name: runtime
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
@@ -349,6 +381,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 启动时间
|
||||
en-US: StartTime
|
||||
ja-JP: 起動時間
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.beans[?(@.name == "java.lang:type=Runtime")].StartTime
|
||||
@@ -376,96 +409,112 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: JVM 当前已经使用的 NonHeapMemory 的大小
|
||||
en-US: MemNonHeapUsedM
|
||||
ja-JP: 使用したノンヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemNonHeapCommittedM
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 配置的 NonHeapCommittedM 的大小
|
||||
en-US: MemNonHeapCommittedM
|
||||
ja-JP: コミットされたノンヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemHeapUsedM
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 当前已经使用的 HeapMemory 的大小
|
||||
en-US: MemHeapUsedM
|
||||
ja-JP: 使用したヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemHeapCommittedM
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM HeapMemory 提交大小
|
||||
en-US: MemHeapCommittedM
|
||||
ja-JP: コミットされたヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemHeapMaxM
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 配置的 HeapMemory 的大小
|
||||
en-US: MemHeapMaxM
|
||||
ja-JP: 配置のヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: MemMaxM
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 运行时可以使用的最大内存大小
|
||||
en-US: MemMaxM
|
||||
ja-JP: 最大のヒープメモリのサイズ
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: GcCountParNew
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 新生代GC次数
|
||||
en-US: GcCountParNew
|
||||
ja-JP: 若い領域GC回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: GcTimeMillisParNew
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 新生代GC消耗时间
|
||||
en-US: GcTimeMillisParNew
|
||||
ja-JP: 若い領域GC時間
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: GcCountConcurrentMarkSweep
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 老年代GC次数
|
||||
en-US: GcCountConcurrentMarkSweep
|
||||
ja-JP: 古い領域GC回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: GcTimeMillisConcurrentMarkSweep
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 老年代GC消耗时间
|
||||
en-US: GcTimeMillisConcurrentMarkSweep
|
||||
ja-JP: 古い領域GC時間
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: GcCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: GC次数
|
||||
en-US: GcCount
|
||||
ja-JP: GC回数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: GcTimeMillis
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: GC消耗时间
|
||||
en-US: GcTimeMillis
|
||||
ja-JP: GC時間
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ThreadsRunnable
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 处于 BLOCKED 状态的线程数量
|
||||
zh-CN: 处于 RUNNABLE 状态的线程数量
|
||||
en-US: ThreadsRunnable
|
||||
ja-JP: 実行中のスレッド数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ThreadsBlocked
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 处于 BLOCKED 状态的线程数量
|
||||
en-US: ThreadsBlocked
|
||||
ja-JP: ブロックされたスレッド数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ThreadsWaiting
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 处于 WAITING 状态的线程数量
|
||||
en-US: ThreadsWaiting
|
||||
ja-JP: 待機中のスレッド数
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: ThreadsTimedWaiting
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 处于 TIMED WAITING 状态的线程数量
|
||||
en-US: ThreadsTimedWaiting
|
||||
ja-JP: 時間指定の待機中のスレッド数
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.MemNonHeapUsedM
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user