This is an automated email from the ASF dual-hosted git repository.
gongchao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git
The following commit(s) were added to refs/heads/master by this push:
new 3e567e5be6 [improve]Improve issues related to tag conflicts (#3889)
3e567e5be6 is described below
commit 3e567e5be6cefb486641faf8a407d4a90fe1054e
Author: Duansg <[email protected]>
AuthorDate: Fri Dec 5 22:02:43 2025 +0800
[improve]Improve issues related to tag conflicts (#3889)
---
.../realtime/MetricsRealTimeAlertCalculator.java | 1 -
.../common/constants/HertzBeatKeywordsEnum.java | 43 +++++++++++++++++
.../common/util/HertzBeatKeywordsUtil.java | 51 ++++++++++++++++++++
.../common/util/HertzBeatKeywordsUtilTest.java | 54 ++++++++++++++++++++++
.../manager/service/impl/AppServiceImpl.java | 13 ++----
.../main/resources/define/app-influxdb_promql.yml | 36 +++++++++++++--
.../src/main/resources/define/app-kafka_promql.yml | 19 +++++++-
7 files changed, 200 insertions(+), 17 deletions(-)
diff --git
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/calculate/realtime/MetricsRealTimeAlertCalculator.java
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/calculate/realtime/MetricsRealTimeAlertCalculator.java
index e338126eb0..f28a48a5d2 100644
---
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/calculate/realtime/MetricsRealTimeAlertCalculator.java
+++
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/calculate/realtime/MetricsRealTimeAlertCalculator.java
@@ -205,7 +205,6 @@ public class MetricsRealTimeAlertCalculator {
}
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());
diff --git
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/constants/HertzBeatKeywordsEnum.java
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/constants/HertzBeatKeywordsEnum.java
new file mode 100644
index 0000000000..5f51de2973
--- /dev/null
+++
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/constants/HertzBeatKeywordsEnum.java
@@ -0,0 +1,43 @@
+/*
+ * 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.constants;
+
+/**
+ * HertzBeat Reserved Keywords Enum
+ */
+public enum HertzBeatKeywordsEnum {
+
+ INSTANCE("instance", "metric_instance");
+
+ private final String keyword;
+
+ private final String alias;
+
+ HertzBeatKeywordsEnum(String keyword, String alias) {
+ this.keyword = keyword;
+ this.alias = alias;
+ }
+
+ public String getKeyword() {
+ return keyword;
+ }
+
+ public String getAlias() {
+ return alias;
+ }
+}
\ No newline at end of file
diff --git
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/HertzBeatKeywordsUtil.java
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/HertzBeatKeywordsUtil.java
new file mode 100644
index 0000000000..0549348cec
--- /dev/null
+++
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/HertzBeatKeywordsUtil.java
@@ -0,0 +1,51 @@
+/*
+ * 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.hertzbeat.common.constants.HertzBeatKeywordsEnum;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Validate JEXL rules
+ */
+public class HertzBeatKeywordsUtil {
+
+
+ private static final Map<String, HertzBeatKeywordsEnum> KEYWORDS =
+ Arrays.stream(HertzBeatKeywordsEnum.values())
+
.collect(Collectors.toMap(HertzBeatKeywordsEnum::getKeyword, e -> e));
+
+
+ /**
+ * Verify if the field matches any reserved keywords
+ *
+ * @param field Field name to verify
+ */
+ public static void verifyKeywords(String field) {
+ HertzBeatKeywordsEnum keyword = KEYWORDS.get(field);
+ if (null == keyword) {
+ return;
+ }
+ throw new IllegalArgumentException(
+ String.format("Field matches keyword `%s`, please set alias
`%s`.",
+ keyword.getKeyword(), keyword.getAlias()));
+ }
+}
\ No newline at end of file
diff --git
a/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/util/HertzBeatKeywordsUtilTest.java
b/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/util/HertzBeatKeywordsUtilTest.java
new file mode 100644
index 0000000000..7f23e234f6
--- /dev/null
+++
b/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/util/HertzBeatKeywordsUtilTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.hertzbeat.common.constants.HertzBeatKeywordsEnum;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+/**
+ * Test case for {@link HertzBeatKeywordsUtil}
+ */
+class HertzBeatKeywordsUtilTest {
+
+ @Test
+ void testVerifyKeywords_WithReservedKeyword_Instance() {
+ IllegalArgumentException exception = assertThrows(
+ IllegalArgumentException.class,
+ () -> HertzBeatKeywordsUtil.verifyKeywords("instance")
+ );
+ String expectedMessage = String.format(
+ "Field matches keyword `%s`, please set alias `%s`.",
+ HertzBeatKeywordsEnum.INSTANCE.getKeyword(),
+ HertzBeatKeywordsEnum.INSTANCE.getAlias()
+ );
+ assertEquals(expectedMessage, exception.getMessage());
+ }
+
+ @Test
+ void testVerifyKeywords_WithValidField() {
+ assertDoesNotThrow(() ->
HertzBeatKeywordsUtil.verifyKeywords("cpu_usage"));
+ assertDoesNotThrow(() ->
HertzBeatKeywordsUtil.verifyKeywords("memory_used"));
+ assertDoesNotThrow(() ->
HertzBeatKeywordsUtil.verifyKeywords("response_time"));
+ assertDoesNotThrow(() ->
HertzBeatKeywordsUtil.verifyKeywords("metric_instance"));
+ assertDoesNotThrow(() ->
HertzBeatKeywordsUtil.verifyKeywords(HertzBeatKeywordsEnum.INSTANCE.getAlias()));
+ }
+}
diff --git
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AppServiceImpl.java
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AppServiceImpl.java
index 007092b7f1..f80f60463c 100644
---
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AppServiceImpl.java
+++
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AppServiceImpl.java
@@ -34,6 +34,7 @@ import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.support.SpringContextHolder;
import org.apache.hertzbeat.common.support.exception.CommonException;
import org.apache.hertzbeat.common.util.CommonUtil;
+import org.apache.hertzbeat.common.util.HertzBeatKeywordsUtil;
import org.apache.hertzbeat.common.util.JexlCheckerUtil;
import org.apache.hertzbeat.manager.dao.DefineDao;
import org.apache.hertzbeat.manager.dao.MonitorDao;
@@ -439,24 +440,18 @@ public class AppServiceImpl implements AppService,
InitializingBean {
for (ParamDefine param : app.getParams()) {
CommonUtil.validDefineI18n(param.getName(), param.getField() + "
param");
}
- for (Metrics metric : app.getMetrics()) {
- CommonUtil.validDefineI18n(metric.getI18n(), metric.getName() + "
metric");
- if (metric.getFields() == null){
- continue;
- }
- for (Metrics.Field field : metric.getFields()) {
- CommonUtil.validDefineI18n(field.getI18n(), metric.getName() +
" metric " + field.getField() + " field");
- }
- }
if (!isModify) {
Assert.isNull(appDefines.get(app.getApp().toLowerCase()),
"monitoring template name " + app.getApp() + " already
exists.");
}
Set<String> fieldsSet = new HashSet<>(16);
for (Metrics metrics : app.getMetrics()) {
+ CommonUtil.validDefineI18n(metrics.getI18n(), metrics.getName() +
" metric");
Assert.notEmpty(metrics.getFields(), "monitoring template metrics
fields can not null");
fieldsSet.clear();
for (Metrics.Field field : metrics.getFields()) {
+ CommonUtil.validDefineI18n(field.getI18n(), metrics.getName()
+ " metric " + field.getField() + " field");
+ HertzBeatKeywordsUtil.verifyKeywords(field.getField());
if (fieldsSet.contains(field.getField())) {
throw new IllegalArgumentException(app.getApp() + " " +
metrics.getName() + " "
+ field.getField() + " can not duplicated.");
diff --git
a/hertzbeat-manager/src/main/resources/define/app-influxdb_promql.yml
b/hertzbeat-manager/src/main/resources/define/app-influxdb_promql.yml
index 833fa5999b..a6a3fb4c7c 100644
--- a/hertzbeat-manager/src/main/resources/define/app-influxdb_promql.yml
+++ b/hertzbeat-manager/src/main/resources/define/app-influxdb_promql.yml
@@ -162,7 +162,7 @@ metrics:
# metrics fields list.
fields:
# Metric information includes the following: Field name, Type: 0-number,
1-string, instance: indicates whether the metric is the primary key, unit: the
unit of the metric
- - field: instance
+ - field: metric_instance
type: 1
i18n:
zh-CN: 实例
@@ -180,6 +180,12 @@ metrics:
zh-CN: 值
en-US: Value
ja-JP: 値
+ aliasFields:
+ - instance
+ - timestamp
+ - value
+ calculates:
+ - metric_instance=instance
# Monitoring protocol used for data collection, e.g. sql, ssh, http, telnet,
wmi, snmp, sdk.
protocol: http
# When the protocol is HTTP, the specific collection configuration is as
follows
@@ -201,7 +207,7 @@ metrics:
^_^headers^_^: ^_^headers^_^
# Request parameter content
params:
- ^_^params^_^: ^_^params^_^
+ query: basic_influxdb_memstats_alloc
# authorization
authorization:
# Authentication method: Basic Auth, Digest Auth, Bearer Token
@@ -231,7 +237,7 @@ metrics:
zh-CN: 任务
en-US: Job
ja-JP: タスク
- - field: instance
+ - field: metric_instance
type: 1
i18n:
zh-CN: 实例
@@ -255,6 +261,14 @@ metrics:
zh-CN: 值
en-US: Value
ja-JP: 値
+ aliasFields:
+ - job
+ - instance
+ - database
+ - timestamp
+ - value
+ calculates:
+ - metric_instance=instance
# Monitoring protocol used for data collection, e.g. sql, ssh, http,
telnet, wmi, snmp, sdk.
protocol: http
# When the protocol is HTTP, the specific collection configuration is as
follows
@@ -300,7 +314,7 @@ metrics:
# metrics fields list.
fields:
# Metric information includes the following: Field name, Type: 0-number,
1-string, instance: indicates whether the metric is the primary key, unit: the
unit of the metric
- - field: instance
+ - field: metric_instance
type: 1
i18n:
zh-CN: 实例
@@ -318,6 +332,12 @@ metrics:
zh-CN: 值
en-US: Value
ja-JP: 値
+ aliasFields:
+ - instance
+ - timestamp
+ - value
+ calculates:
+ - metric_instance=instance
# Monitoring protocol used for data collection, e.g. sql, ssh, http,
telnet, wmi, snmp, sdk.
protocol: http
# When the protocol is HTTP, the specific collection configuration is as
follows
@@ -364,7 +384,7 @@ metrics:
# metrics fields list.
fields:
# Metric information includes the following: Field name, Type: 0-number,
1-string, instance: indicates whether the metric is the primary key, unit: the
unit of the metric
- - field: instance
+ - field: metric_instance
type: 1
i18n:
zh-CN: 实例
@@ -382,6 +402,12 @@ metrics:
zh-CN: 值
en-US: Value
ja-JP: 値
+ aliasFields:
+ - instance
+ - timestamp
+ - value
+ calculates:
+ - metric_instance=instance
# Monitoring protocol used for data collection, e.g. sql, ssh, http,
telnet, wmi, snmp, sdk.
protocol: http
# When the protocol is HTTP, the specific collection configuration is as
follows
diff --git a/hertzbeat-manager/src/main/resources/define/app-kafka_promql.yml
b/hertzbeat-manager/src/main/resources/define/app-kafka_promql.yml
index 52344d5a8a..01f09b9c6c 100644
--- a/hertzbeat-manager/src/main/resources/define/app-kafka_promql.yml
+++ b/hertzbeat-manager/src/main/resources/define/app-kafka_promql.yml
@@ -166,7 +166,7 @@ metrics:
zh-CN: 名称
en-US: Name
ja-JP: 名前
- - field: instance
+ - field: metric_instance
type: 1
i18n:
zh-CN: 实例
@@ -184,6 +184,13 @@ metrics:
zh-CN: 数值
en-US: Value
ja-JP: 値
+ aliasFields:
+ - __name__
+ - instance
+ - timestamp
+ - value
+ calculates:
+ - metric_instance=instance
# The protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp,
sdk
protocol: http
# The config content when protocol is http
@@ -295,7 +302,7 @@ metrics:
# 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
- - field: instance
+ - field: metric_instance
type: 1
i18n:
zh-CN: 实例
@@ -325,6 +332,14 @@ metrics:
zh-CN: 数值
en-US: Value
ja-JP: 値
+ aliasFields:
+ - instance
+ - job
+ - topic
+ - timestamp
+ - value
+ calculates:
+ - metric_instance=instance
# The protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp,
sdk
protocol: http
# The specific collection configuration when the protocol is http
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]