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 caf13c09b [feature] Support custom refresh intervals for each group of 
metrics (#2718)
caf13c09b is described below

commit caf13c09bd2651e3e67929c2f62676561dfb9074
Author: Zhang Yuxuan <[email protected]>
AuthorDate: Sat Nov 9 13:41:31 2024 +0800

    [feature] Support custom refresh intervals for each group of metrics (#2718)
    
    Co-authored-by: tomsun28 <[email protected]>
    Co-authored-by: shown <[email protected]>
    Co-authored-by: aias00 <[email protected]>
    Co-authored-by: crossoverJie <[email protected]>
---
 .../collector/dispatch/timer/TimerDispatcher.java  |  19 ++--
 .../collector/dispatch/timer/WheelTimerTask.java   |   1 +
 .../apache/hertzbeat/common/entity/job/Job.java    | 110 ++++++++++++++++++---
 .../hertzbeat/common/entity/job/Metrics.java       |   9 ++
 .../manager/scheduler/CollectorJobScheduler.java   |   2 +-
 .../hertzbeat/manager/scheduler/SchedulerInit.java |   2 +-
 .../manager/service/impl/MonitorServiceImpl.java   |  10 +-
 home/blog/2023-02-10-new-committer.md              |  22 ++---
 home/docs/advanced/extend-point.md                 |   6 ++
 ...24-05-09-hertzbeat-ospp-subject-introduction.md |   6 +-
 .../current/advanced/extend-point.md               |   7 ++
 11 files changed, 153 insertions(+), 41 deletions(-)

diff --git 
a/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/timer/TimerDispatcher.java
 
b/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/timer/TimerDispatcher.java
index ce094e581..a63b6ca62 100644
--- 
a/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/timer/TimerDispatcher.java
+++ 
b/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/timer/TimerDispatcher.java
@@ -17,19 +17,20 @@
 
 package org.apache.hertzbeat.collector.dispatch.timer;
 
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 import lombok.extern.slf4j.Slf4j;
 import 
org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectResponseEventListener;
 import org.apache.hertzbeat.common.entity.job.Job;
+import org.apache.hertzbeat.common.entity.job.Metrics;
 import org.apache.hertzbeat.common.entity.message.CollectRep;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.stereotype.Component;
 
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 /**
  * job timer dispatcher
  */
@@ -83,7 +84,11 @@ public class TimerDispatcher implements TimerDispatch, 
DisposableBean {
             Timeout timeout = wheelTimer.newTimeout(timerJob, 
addJob.getInterval(), TimeUnit.SECONDS);
             currentCyclicTaskMap.put(addJob.getId(), timeout);
         } else {
-            Timeout timeout = wheelTimer.newTimeout(timerJob, 0, 
TimeUnit.SECONDS);
+            for (Metrics metric : addJob.getMetrics()) {
+                metric.setInterval(0L);
+            }
+            addJob.setIntervals(new LinkedList<>(List.of(0L)));
+            Timeout timeout = wheelTimer.newTimeout(timerJob, 
addJob.getInterval(), TimeUnit.SECONDS);
             currentTempTaskMap.put(addJob.getId(), timeout);
             eventListeners.put(addJob.getId(), eventListener);
         }
diff --git 
a/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/timer/WheelTimerTask.java
 
b/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/timer/WheelTimerTask.java
index 5f0a7875f..96d74eeac 100644
--- 
a/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/timer/WheelTimerTask.java
+++ 
b/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/timer/WheelTimerTask.java
@@ -84,6 +84,7 @@ public class WheelTimerTask implements TimerTask {
             metricsTmp.add(metric);
         }
         job.setMetrics(metricsTmp);
+        job.initIntervals();
     }
 
 
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Job.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Job.java
index 10299a5d6..0a0ca4c7d 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Job.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Job.java
@@ -37,6 +37,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.common.entity.manager.ParamDefine;
 import org.apache.hertzbeat.common.entity.message.CollectRep;
 import org.apache.hertzbeat.common.util.JsonUtil;
+import org.springframework.util.CollectionUtils;
 
 /**
  * Collect task details
@@ -94,9 +95,13 @@ public class Job {
      */
     private long timestamp;
     /**
-     * Task collection time interval (unit: second) eg: 30,60,600
+     * Default task collection time interval (unit: second) eg: 30,60,600
      */
-    private long interval = 600L;
+    private long defaultInterval = 600L;
+    /**
+     * Refresh time list for one cycle of the job
+     */
+    private LinkedList<Long> intervals;
     /**
      * Whether it is a recurring periodic task true is yes, false is no
      */
@@ -151,17 +156,19 @@ public class Job {
      */
     public synchronized void constructPriorMetrics() {
         Map<Byte, List<Metrics>> map = metrics.stream()
-                .peek(metric -> {
-                    // Determine whether to configure aliasFields If not, 
configure the default
-                    if ((metric.getAliasFields() == null || 
metric.getAliasFields().isEmpty()) && metric.getFields() != null) {
-                        
metric.setAliasFields(metric.getFields().stream().map(Metrics.Field::getField).collect(Collectors.toList()));
-                    }
-                    // Set the default metrics execution priority, if not 
filled, the default last priority
-                    if (metric.getPriority() == null) {
-                        metric.setPriority(Byte.MAX_VALUE);
-                    }
-                })
-                .collect(Collectors.groupingBy(Metrics::getPriority));
+            .filter(metrics -> (System.currentTimeMillis() >= 
metrics.getCollectTime() + metrics.getInterval() * 1000))
+            .peek(metric -> {
+                metric.setCollectTime(System.currentTimeMillis());
+                // Determine whether to configure aliasFields If not, 
configure the default
+                if ((metric.getAliasFields() == null || 
metric.getAliasFields().isEmpty()) && metric.getFields() != null) {
+                    
metric.setAliasFields(metric.getFields().stream().map(Metrics.Field::getField).collect(Collectors.toList()));
+                }
+                // Set the default metrics execution priority, if not filled, 
the default last priority
+                if (metric.getPriority() == null) {
+                    metric.setPriority(Byte.MAX_VALUE);
+                }
+            })
+            .collect(Collectors.groupingBy(Metrics::getPriority));
         // Construct a linked list of task execution order of the metrics
         priorMetrics = new LinkedList<>();
         map.values().forEach(metric -> {
@@ -247,4 +254,81 @@ public class Job {
         // deep clone
         return JsonUtil.fromJson(JsonUtil.toJson(this), getClass());
     }
+
+    public void initIntervals() {
+        List<Long> metricsIntervals = new LinkedList<>();
+        for (Metrics metrics: getMetrics()) {
+            metrics.setCollectTime(System.currentTimeMillis());
+            if (metrics.getInterval() <= 0) {
+                metrics.setInterval(defaultInterval);
+            }
+            if (!metricsIntervals.contains(metrics.getInterval())) {
+                metricsIntervals.add(metrics.getInterval());
+            }
+        }
+        generateMetricsIntervals(metricsIntervals);
+    }
+
+    /**
+     * The greatest common divisor
+     */
+    public static long gcd(long a, long b) {
+        while (b != 0) {
+            long temp = b;
+            b = a % b;
+            a = temp;
+        }
+        return a;
+    }
+
+    /**
+     * The least common multiple
+     */
+    public static long lcm(List<Long> array) {
+        if (array != null) {
+            long result = array.get(0);
+            for (int i = 1; i < array.size(); i++) {
+                result = (result * array.get(i)) / gcd(result, array.get(i));
+            }
+            return result;
+        }
+        return 0;
+    }
+
+    /**
+     *
+     * @param metricsIntervals A unique list composed of intervals for all 
metrics
+     * Generate a list of refresh intervals for metric collection
+     */
+    public void generateMetricsIntervals(List<Long> metricsIntervals) {
+        // 1. To find the least common multiple (LCM) of all metric refresh 
intervals
+        long lcm = lcm(metricsIntervals);
+        List<Long> refreshTimes = new LinkedList<>();
+        // 2. Calculate all possible refresh intervals in one round
+        for (long interval : metricsIntervals) {
+            for (long t = interval; t <= lcm; t += interval) {
+                if (!refreshTimes.contains(t)) {
+                    refreshTimes.add(t);
+                }
+            }
+        }
+        // 3. Sort from smallest to largest
+        Collections.sort(refreshTimes);
+        // 4. Calculate the refresh interval list for Job's cycle
+        LinkedList<Long> intervals = new LinkedList<>();
+        intervals.add(refreshTimes.get(0));
+        for (int i = 1; i < refreshTimes.size(); i++) {
+            intervals.add(refreshTimes.get(i) - refreshTimes.get(i - 1));
+        }
+        setIntervals(intervals);
+    }
+
+    public long getInterval() {
+        if (!CollectionUtils.isEmpty(getIntervals())) {
+            long interval = getIntervals().remove();
+            getIntervals().add(interval);
+            return interval;
+        }
+        return getDefaultInterval();
+    }
 }
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
index d39e9165c..3f1131360 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
@@ -93,6 +93,15 @@ public class Metrics {
      * the subsequent metrics tasks will only be scheduled after the 
availability is collected successfully.
      */
     private Byte priority;
+    /**
+     * The latest collect time
+     */
+    private long collectTime;
+    /**
+     * Customize interval of metrics
+     * If not set, the collection interval set in the front-end page will be 
used by default
+     */
+    private long interval;
     /**
      * Is it visible true or false
      * if false, web ui will not see this metrics.
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/CollectorJobScheduler.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/CollectorJobScheduler.java
index a935061d0..c53bd411e 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/CollectorJobScheduler.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/CollectorJobScheduler.java
@@ -143,7 +143,7 @@ public class CollectorJobScheduler implements 
CollectorScheduling, CollectJobSch
                     appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + 
monitor.getName());
                 }
                 appDefine.setMonitorId(monitor.getId());
-                appDefine.setInterval(monitor.getIntervals());
+                appDefine.setDefaultInterval(monitor.getIntervals());
                 appDefine.setCyclic(true);
                 appDefine.setTimestamp(System.currentTimeMillis());
                 List<Param> params = 
paramDao.findParamsByMonitorId(monitor.getId());
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/SchedulerInit.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/SchedulerInit.java
index 34d2d9d02..f9f4cd283 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/SchedulerInit.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/SchedulerInit.java
@@ -102,7 +102,7 @@ public class SchedulerInit implements CommandLineRunner {
                 }
                 appDefine.setId(monitor.getJobId());
                 appDefine.setMonitorId(monitor.getId());
-                appDefine.setInterval(monitor.getIntervals());
+                appDefine.setDefaultInterval(monitor.getIntervals());
                 appDefine.setCyclic(true);
                 appDefine.setTimestamp(System.currentTimeMillis());
                 List<Param> params = 
paramDao.findParamsByMonitorId(monitor.getId());
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
index 8105d13df..a2ed1a6a1 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
@@ -210,7 +210,7 @@ public class MonitorServiceImpl implements MonitorService {
             appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + 
monitor.getName());
         }
         appDefine.setMonitorId(monitorId);
-        appDefine.setInterval(monitor.getIntervals());
+        appDefine.setDefaultInterval(monitor.getIntervals());
         appDefine.setCyclic(true);
         appDefine.setTimestamp(System.currentTimeMillis());
         List<Configmap> configmaps = params.stream().map(param -> {
@@ -272,7 +272,7 @@ public class MonitorServiceImpl implements MonitorService {
         List<Metrics> realMetrics = metricsDefine.stream().filter(m -> 
metrics.contains(m.getName())).collect(Collectors.toList());
         appDefine.setMetrics(realMetrics);
         appDefine.setMonitorId(monitorId);
-        appDefine.setInterval(monitor.getIntervals());
+        appDefine.setDefaultInterval(monitor.getIntervals());
         appDefine.setCyclic(true);
         appDefine.setTimestamp(System.currentTimeMillis());
         List<Configmap> configmaps = params.stream().map(param -> {
@@ -543,7 +543,7 @@ public class MonitorServiceImpl implements MonitorService {
             }
             appDefine.setId(preMonitor.getJobId());
             appDefine.setMonitorId(monitorId);
-            appDefine.setInterval(monitor.getIntervals());
+            appDefine.setDefaultInterval(monitor.getIntervals());
             appDefine.setCyclic(true);
             appDefine.setTimestamp(System.currentTimeMillis());
             if (params != null) {
@@ -759,7 +759,7 @@ public class MonitorServiceImpl implements MonitorService {
                     appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + 
monitor.getName());
                 }
                 appDefine.setMonitorId(monitor.getId());
-                appDefine.setInterval(monitor.getIntervals());
+                appDefine.setDefaultInterval(monitor.getIntervals());
                 appDefine.setCyclic(true);
                 appDefine.setTimestamp(System.currentTimeMillis());
                 List<Param> params = 
paramDao.findParamsByMonitorId(monitor.getId());
@@ -865,7 +865,7 @@ public class MonitorServiceImpl implements MonitorService {
                 }
                 appDefine.setId(monitor.getJobId());
                 appDefine.setMonitorId(monitor.getId());
-                appDefine.setInterval(monitor.getIntervals());
+                appDefine.setDefaultInterval(monitor.getIntervals());
                 appDefine.setCyclic(true);
                 appDefine.setTimestamp(System.currentTimeMillis());
                 List<Param> params = 
paramDao.findParamsByMonitorId(monitor.getId());
diff --git a/home/blog/2023-02-10-new-committer.md 
b/home/blog/2023-02-10-new-committer.md
index 35154e321..3706d4763 100644
--- a/home/blog/2023-02-10-new-committer.md
+++ b/home/blog/2023-02-10-new-committer.md
@@ -80,16 +80,16 @@ From the first `PR` to the present, I have participated in 
the `hertzbeat` open
 
 **contribute:**
 
-* 1. Realize the monitoring of docker containers.
-* 2. Complete the domestic database DM monitoring
-* 3. Write a single test for the corresponding business.
-* 4. English translation of some annotations.
+1. Realize the monitoring of docker containers.
+2. Complete the domestic database DM monitoring
+3. Write a single test for the corresponding business.
+4. English translation of some annotations.
 
 **reward:**
 
-* 1. The technical ability has been further improved.
-* 2. Broaden your horizons.
-* 3. Learned a lot from the bosses.
+1. The technical ability has been further improved.
+2. Broaden your horizons.
+3. Learned a lot from the bosses.
 
 ### 🌻 Thanks to the community partners
 
@@ -99,10 +99,10 @@ Thanks to the friends who have helped me or inspired me for 
free (in no particul
 
 First of all, I am also a newcomer to Novice Village, but I can share some of 
my experience with you, hoping to help you.
 
-* 1. Don't be too impatient, and calm down to understand the general 
implementation logic of each module.
-* 2. Use different functions and debug to see the underlying implementation 
principle of each function.
-* 3. Slowly try to read the source code and understand it.
-* 4. If you encounter a bug, you can directly report it to issues, or you can 
try to solve it yourself.
+1. Don't be too impatient, and calm down to understand the general 
implementation logic of each module.
+2. Use different functions and debug to see the underlying implementation 
principle of each function.
+3. Slowly try to read the source code and understand it.
+4. If you encounter a bug, you can directly report it to issues, or you can 
try to solve it yourself.
 
 ## What is Hertz Beat?
 
diff --git a/home/docs/advanced/extend-point.md 
b/home/docs/advanced/extend-point.md
index 018e67deb..25e273711 100644
--- a/home/docs/advanced/extend-point.md
+++ b/home/docs/advanced/extend-point.md
@@ -11,6 +11,10 @@ sidebar_label: Custom Monitoring
 
 **HertzBeat Dashboard** -> **Monitoring Templates** -> **New Template** -> 
**Config Monitoring Template Yml** -> **Save and Apply** -> **Add A Monitoring 
with The New Monitoring Type**
 
+### Custom Monitoring Metrics Refresh Interval
+
+HertzBeat now supports setting different refresh intervals for various groups 
of monitoring metrics. This can be configured in the monitoring template under 
the `metrics` section by setting the `interval` field, with the unit being 
seconds. If not set, the default refresh interval specified during the creation 
of the monitoring will be used.
+
 -------
 
 Configuration usages of the monitoring templates yml are detailed below.
@@ -111,6 +115,8 @@ metrics:
     # 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
+    # refresh interval for this metrics group
+    interval: 600
     # collect metrics content
     fields:
       # field-metric name, type-metric type(0-number,1-string), unit-metric 
unit('%','ms','MB'), label-if is metrics label
diff --git 
a/home/i18n/zh-cn/docusaurus-plugin-content-blog/2024-05-09-hertzbeat-ospp-subject-introduction.md
 
b/home/i18n/zh-cn/docusaurus-plugin-content-blog/2024-05-09-hertzbeat-ospp-subject-introduction.md
index cb7c0af9d..ae4643ec2 100644
--- 
a/home/i18n/zh-cn/docusaurus-plugin-content-blog/2024-05-09-hertzbeat-ospp-subject-introduction.md
+++ 
b/home/i18n/zh-cn/docusaurus-plugin-content-blog/2024-05-09-hertzbeat-ospp-subject-introduction.md
@@ -60,9 +60,9 @@
 
 **产出:**
 
-- 1. 特性代码能以PR的形式合入HertzBeat仓库。
-- 2. 完成 HertzBeat官方模板市场
-- 3. 更新相关帮助文档
+1. 特性代码能以PR的形式合入HertzBeat仓库。
+2. 完成 HertzBeat官方模板市场
+3. 更新相关帮助文档
 
 **联系导师:** 赵青然 [[email protected]](mailto:[email protected])
 
diff --git 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/advanced/extend-point.md
 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/advanced/extend-point.md
index 8d16dec60..43fd90a16 100644
--- 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/advanced/extend-point.md
+++ 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/advanced/extend-point.md
@@ -13,6 +13,10 @@ sidebar_label: 自定义监控
 
 ![HertzBeat](/img/docs/advanced/extend-point-1.png)
 
+### 自定义监控指标刷新时间
+
+现在,HertzBeat支持为每组监控指标设置不同的刷新时间。您可以在监控模板的 `metrics` 部分通过设置 `interval` 
字段来实现,单位为秒。若不进行设置,则使用创建监控时设置的默认刷新时间。
+
 -------
 
 ### 监控模版YML
@@ -146,6 +150,9 @@ metrics:
     # 指标采集调度优先级(0->127)->(优先级高->低) 优先级低的指标会等优先级高的指标采集完成后才会被调度, 相同优先级的指标会并行调度采集
     # 优先级为0的指标为可用性指标,即它会被首先调度,采集成功才会继续调度其它指标,采集失败则中断调度
     priority: 0
+    # refresh interval for this metrics group
+    # 该指标组刷新时间
+    interval: 10
     # collect metrics content
     # 具体监控指标列表
     fields:


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to