Compare commits

..
207 changed files with 1416 additions and 2056 deletions
+1 -1
View File
@@ -16,7 +16,7 @@
#
github:
description: Real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
description: Apache HertzBeat(incubating) is a real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
homepage: https://hertzbeat.apache.org/
labels:
- monitoring
+10
View File
@@ -0,0 +1,10 @@
Apache HertzBeat (incubating) is an effort undergoing incubation at the Apache
Software Foundation (ASF), sponsored by the Apache Incubator PMC.
Incubation is required of all newly accepted projects until a further review
indicates that the infrastructure, communications, and decision making process
have stabilized in a manner consistent with other successful ASF projects.
While incubation status is not necessarily a reflection of the completeness
or stability of the code, it does indicate that the project has yet to be
fully endorsed by the ASF.
+1 -1
View File
@@ -1,4 +1,4 @@
Apache HertzBeat
Apache HertzBeat (incubating)
Copyright 2024-2025 The Apache Software Foundation
This product includes software developed at
+1 -1
View File
@@ -28,7 +28,7 @@
## 🎡 <font color="green">Introduction</font>
[Apache HertzBeat](https://github.com/apache/hertzbeat) is an easy-to-use, open source, real-time monitoring system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
[Apache HertzBeat](https://github.com/apache/hertzbeat) (incubating) is an easy-to-use, open source, real-time monitoring system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
### Features
+1 -1
View File
@@ -28,7 +28,7 @@
## 🎡 <font color="green">介绍</font>
[Apache HertzBeat](https://github.com/apache/hertzbeat) 是一个易用友好的开源实时监控告警系统,无需 Agent,高性能集群,兼容 Prometheus,提供强大的自定义监控和状态页构建能力。
[Apache HertzBeat](https://github.com/apache/hertzbeat) incubating是一个易用友好的开源实时监控告警系统,无需 Agent,高性能集群,兼容 Prometheus,提供强大的自定义监控和状态页构建能力。
### 特点
@@ -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.
*/
package org.apache.hertzbeat.common.constants;
/**
* Enum representing the possible statuses of a collector.
*/
public enum CollectorStatus {
ONLINE, OFFLINE;
}
-15
View File
@@ -293,21 +293,6 @@
</descriptors>
</configuration>
</execution>
<execution>
<id>make-docker-zip</id>
<!--Bound maven operation-->
<phase>package</phase>
<!--Run once-->
<goals>
<goal>single</goal>
</goals>
<configuration>
<outputDirectory>../dist</outputDirectory>
<descriptors>
<descriptor>../script/assembly/server/assembly-docker.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>make-docker-compose-script</id>
<!--Bound maven operation-->
@@ -18,6 +18,8 @@
package org.apache.hertzbeat.manager;
import javax.annotation.PostConstruct;
import org.apache.hertzbeat.common.constants.ConfigConstants;
import org.apache.hertzbeat.manager.nativex.HertzbeatRuntimeHintsRegistrar;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -36,10 +38,10 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableJpaAuditing
@EnableJpaRepositories(basePackages = {"org.apache.hertzbeat"})
@EntityScan(basePackages = {"org.apache.hertzbeat"})
@ComponentScan(basePackages = {"org.apache.hertzbeat"})
@ConfigurationPropertiesScan(basePackages = {"org.apache.hertzbeat"})
@EnableJpaRepositories(basePackages = {ConfigConstants.PkgConstant.PKG})
@EntityScan(basePackages = {ConfigConstants.PkgConstant.PKG})
@ComponentScan(basePackages = {ConfigConstants.PkgConstant.PKG})
@ConfigurationPropertiesScan(basePackages = {ConfigConstants.PkgConstant.PKG})
@ImportRuntimeHints(HertzbeatRuntimeHintsRegistrar.class)
@EnableAsync
@EnableScheduling
@@ -40,7 +40,7 @@ import org.apache.hertzbeat.common.entity.manager.Monitor;
import org.apache.hertzbeat.common.entity.manager.StatusPageComponent;
import org.apache.hertzbeat.common.entity.manager.StatusPageHistory;
import org.apache.hertzbeat.common.entity.manager.StatusPageOrg;
import org.apache.hertzbeat.manager.config.StatusProperties;
import org.apache.hertzbeat.manager.properties.StatusProperties;
import org.apache.hertzbeat.manager.dao.MonitorDao;
import org.apache.hertzbeat.manager.dao.StatusPageComponentDao;
import org.apache.hertzbeat.manager.dao.StatusPageHistoryDao;
@@ -18,8 +18,8 @@
package org.apache.hertzbeat.manager.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.manager.scheduler.ConsistentHash;
import org.apache.hertzbeat.manager.scheduler.SchedulerProperties;
import org.apache.hertzbeat.manager.scheduler.ConsistentHashCollectorKeeper;
import org.apache.hertzbeat.manager.properties.SchedulerProperties;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -33,8 +33,8 @@ import org.springframework.context.annotation.Configuration;
public class SchedulerConfig {
@Bean
public ConsistentHash consistentHasInstance() {
return new ConsistentHash();
public ConsistentHashCollectorKeeper consistentHasInstance() {
return new ConsistentHashCollectorKeeper();
}
}
@@ -19,7 +19,6 @@
package org.apache.hertzbeat.manager.nativex;
import java.lang.reflect.Constructor;
import java.util.Set;
import org.apache.sshd.common.channel.ChannelListener;
import org.apache.sshd.common.forward.PortForwardingEventListener;
@@ -28,7 +27,6 @@ import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory;
import org.apache.sshd.common.session.SessionListener;
import org.apache.sshd.common.util.security.bouncycastle.BouncyCastleSecurityProviderRegistrar;
import org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderRegistrar;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
@@ -60,11 +58,4 @@ public class HertzbeatRuntimeHintsRegistrar implements RuntimeHintsRegistrar {
TypeReference.of(PortForwardingEventListener.class), TypeReference.of(SessionListener.class));
}
}
private void registerConstructor(RuntimeHints hints, Class<?> clazz) {
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
hints.reflection().registerConstructor(declaredConstructor, ExecutableMode.INVOKE);
}
}
}
@@ -0,0 +1,156 @@
/*
* 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.manager.pojo;
import lombok.Data;
import org.apache.hertzbeat.common.constants.CollectorStatus;
import org.apache.hertzbeat.manager.scheduler.AssignJobs;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Collector Node
*/
@Data
public class CollectorNode {
/**
* Default number of VM nodes
*/
private static final byte VIRTUAL_NODE_DEFAULT_SIZE = 10;
/**
* collector identity
*/
private final String identity;
/**
* collector mode: public or private
*/
private String mode;
/**
* ip
*/
private String ip;
/**
* collector On-line time stamp
*/
private long uptime;
/**
* collector's own performance service quality score 0 - 127
* The number of virtual nodes will be calculated based on this service quality score
*
*/
private Byte quality;
private CollectorStatus collectorStatus;
/**
* use this collector's collect job ID list
* jobId,jobVersion
*/
private AssignJobs assignJobs;
/**
* the collection task ID list mapped by each virtual node corresponding to this node
* Long[] [0]-jobId, [1]-dispatchHash
*/
private Map<Integer, Set<Long[]>> virtualNodeMap;
public CollectorNode(String identity, String mode, String ip, long uptime, Byte quality) {
this.identity = identity;
this.mode = mode;
this.ip = ip;
this.uptime = uptime;
this.quality = quality;
assignJobs = new AssignJobs();
virtualNodeMap = new ConcurrentHashMap<>(VIRTUAL_NODE_DEFAULT_SIZE);
}
public synchronized void addJob(Integer virtualNodeKey, Integer dispatchHash, Long jobId, boolean isFlushed) {
if (virtualNodeMap == null) {
virtualNodeMap = new ConcurrentHashMap<>(VIRTUAL_NODE_DEFAULT_SIZE);
}
if (assignJobs == null) {
assignJobs = new AssignJobs();
}
Set<Long[]> virtualNodeJob = virtualNodeMap.computeIfAbsent(virtualNodeKey, k -> ConcurrentHashMap.newKeySet(16));
virtualNodeJob.add(new Long[]{jobId, dispatchHash.longValue()});
if (isFlushed) {
assignJobs.addAssignJob(jobId);
} else {
assignJobs.addAddingJob(jobId);
}
}
/**
* obtain the collection task routed by the specified virtual node according to virtualNodeKey
* @param virtualNodeKey virtualNodeKey
* @return collection task
*/
public Set<Long[]> clearVirtualNodeJobs(Integer virtualNodeKey) {
if (virtualNodeMap == null || virtualNodeMap.isEmpty()) {
return null;
}
Set<Long[]> virtualNodeJobs = virtualNodeMap.remove(virtualNodeKey);
virtualNodeMap.put(virtualNodeKey, ConcurrentHashMap.newKeySet(16));
return virtualNodeJobs;
}
public void addVirtualNodeJobs(Integer virtualHashKey, Set<Long[]> reDispatchJobs) {
if (reDispatchJobs == null) {
return;
}
if (virtualNodeMap == null) {
virtualNodeMap = new ConcurrentHashMap<>(16);
}
virtualNodeMap.computeIfPresent(virtualHashKey, (k, v) -> {
reDispatchJobs.addAll(v);
return v;
});
virtualNodeMap.put(virtualHashKey, reDispatchJobs);
}
public void removeVirtualNodeJob(Long jobId) {
if (jobId == null || virtualNodeMap == null) {
return;
}
for (Set<Long[]> jobSet : virtualNodeMap.values()) {
Optional<Long[]> optional = jobSet.stream().filter(item -> Objects.equals(item[0], jobId)).findFirst();
if (optional.isPresent()) {
jobSet.remove(optional.get());
break;
}
}
}
public void destroy() {
if (assignJobs != null) {
assignJobs.clear();
}
if (virtualNodeMap != null) {
virtualNodeMap.clear();
}
}
}
@@ -0,0 +1,53 @@
/*
* 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.manager.pojo;
import org.apache.hertzbeat.common.entity.job.Job;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Utility class for caching {@link Job} objects in memory.
* <p>
* This class provides static methods to store, retrieve, and remove {@code Job} instances
* using a thread-safe {@link ConcurrentHashMap}. It is intended to be used as a simple
* in-memory cache for job data within the manager component.
* <p>
* Usage:
* <pre>
* JobCache.put(job);
* Job job = JobCache.get(jobId);
* JobCache.remove(jobId);
* </pre>
*/
public class JobCache {
private static final Map<Long, Job> jobContentCache = new ConcurrentHashMap<>(16);
public static Job get(Long jobId) {
return jobContentCache.get(jobId);
}
public static void put(Job job) {
jobContentCache.put(job.getId(), job);
}
public static void remove(Long jobId) {
jobContentCache.remove(jobId);
}
}
@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.hertzbeat.manager.scheduler;
package org.apache.hertzbeat.manager.properties;
import lombok.Getter;
import lombok.Setter;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.hertzbeat.manager.config;
package org.apache.hertzbeat.manager.properties;
import lombok.Getter;
import lombok.Setter;
@@ -29,6 +29,7 @@ import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Data
public class AssignJobs {
private static final Integer DEFAULT_CAPACITY = 16;
/**
* current assign jobIds
@@ -51,10 +52,10 @@ public class AssignJobs {
private Set<Long> pinnedJobs;
public AssignJobs() {
jobs = ConcurrentHashMap.newKeySet(16);
addingJobs = ConcurrentHashMap.newKeySet(16);
removingJobs = ConcurrentHashMap.newKeySet(16);
pinnedJobs = ConcurrentHashMap.newKeySet(16);
jobs = ConcurrentHashMap.newKeySet(DEFAULT_CAPACITY);
addingJobs = ConcurrentHashMap.newKeySet(DEFAULT_CAPACITY);
removingJobs = ConcurrentHashMap.newKeySet(DEFAULT_CAPACITY);
pinnedJobs = ConcurrentHashMap.newKeySet(DEFAULT_CAPACITY);
}
public void addAssignJob(Long jobId) {
@@ -29,11 +29,14 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectJobService;
import org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectResponseEventListener;
import org.apache.hertzbeat.common.constants.CollectorStatus;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.dto.CollectorInfo;
import org.apache.hertzbeat.common.entity.dto.ServerInfo;
@@ -53,6 +56,10 @@ import org.apache.hertzbeat.manager.dao.CollectorDao;
import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
import org.apache.hertzbeat.manager.dao.MonitorDao;
import org.apache.hertzbeat.manager.dao.ParamDao;
import org.apache.hertzbeat.manager.pojo.CollectorNode;
import org.apache.hertzbeat.manager.pojo.JobCache;
import org.apache.hertzbeat.manager.properties.SchedulerProperties;
import org.apache.hertzbeat.manager.scheduler.collector.CollectorKeeper;
import org.apache.hertzbeat.manager.scheduler.netty.ManageServer;
import org.apache.hertzbeat.manager.service.AppService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -65,9 +72,7 @@ import org.springframework.stereotype.Component;
@Component
@AutoConfigureAfter(value = {SchedulerProperties.class})
@Slf4j
public class CollectorJobScheduler implements CollectorScheduling, CollectJobScheduling {
private final Map<Long, Job> jobContentCache = new ConcurrentHashMap<>(16);
public class CollectorJobScheduler implements CollectorOperation, CollectorOperationReceiver, JobOperation {
private final Map<Long, CollectResponseEventListener> eventListeners = new ConcurrentHashMap<>(16);
@@ -77,9 +82,6 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
@Autowired
private CollectorMonitorBindDao collectorMonitorBindDao;
@Autowired
private ConsistentHash consistentHash;
@Autowired
private CollectJobService collectJobService;
@@ -92,6 +94,10 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
@Autowired
private ParamDao paramDao;
@Autowired
private CollectorKeeper collectorKeeper;
@Setter
private ManageServer manageServer;
@Override
@@ -125,15 +131,18 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
.build();
}
collectorDao.save(collector);
ConsistentHash.Node node = new ConsistentHash.Node(identity, collector.getMode(),
collector.getIp(), System.currentTimeMillis(), null);
consistentHash.addNode(node);
reBalanceCollectorAssignJobs();
CollectorNode node = new CollectorNode(identity, collector.getMode(), collector.getIp(), System.currentTimeMillis(), null);
collectorKeeper.addNode(node);
collectorKeeper.changeStatus(identity, CollectorStatus.ONLINE);
collectorKeeper.rebalanceJobs(this::doRebalanceJobs);
// Read database The fixed collection tasks at this collector are delivered
List<CollectorMonitorBind> binds = collectorMonitorBindDao.findCollectorMonitorBindsByCollector(identity);
if (CollectionUtils.isEmpty(binds)){
return;
}
List<Monitor> monitors = monitorDao.findMonitorsByIdIn(binds.stream().map(CollectorMonitorBind::getMonitorId).collect(Collectors.toSet()));
for (Monitor monitor : monitors) {
if (Objects.isNull(monitor) || monitor.getStatus() == CommonConstants.MONITOR_PAUSED_CODE) {
@@ -189,56 +198,10 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
}
collector.setStatus(CommonConstants.COLLECTOR_STATUS_OFFLINE);
collectorDao.save(collector);
consistentHash.removeNode(identity);
reBalanceCollectorAssignJobs();
log.info("the collector: {} go offline success.", identity);
}
@Override
public void reBalanceCollectorAssignJobs() {
consistentHash.getAllNodes().entrySet().parallelStream().forEach(entry -> {
String collectorName = entry.getKey();
AssignJobs assignJobs = entry.getValue().getAssignJobs();
if (StringUtils.isBlank(collectorName) || Objects.isNull(assignJobs)) {
return;
}
if (CollectionUtils.isNotEmpty(assignJobs.getAddingJobs())) {
Set<Long> addedJobIds = new HashSet<>(8);
for (Long addingJobId : assignJobs.getAddingJobs()) {
Job job = jobContentCache.get(addingJobId);
if (Objects.isNull(job)) {
log.error("assigning job {} content is null.", addingJobId);
continue;
}
addedJobIds.add(addingJobId);
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorName)) {
collectJobService.addAsyncCollectJob(job);
} else {
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
.setDirection(ClusterMsg.Direction.REQUEST)
.setType(ClusterMsg.MessageType.ISSUE_CYCLIC_TASK)
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(job)))
.build();
this.manageServer.sendMsg(collectorName, message);
}
}
assignJobs.addAssignJobs(addedJobIds);
assignJobs.removeAddingJobs(addedJobIds);
}
if (CollectionUtils.isNotEmpty(assignJobs.getRemovingJobs())) {
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorName)) {
assignJobs.getRemovingJobs().forEach(jobId -> collectJobService.cancelAsyncCollectJob(jobId));
} else {
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
.setDirection(ClusterMsg.Direction.REQUEST)
.setType(ClusterMsg.MessageType.DELETE_CYCLIC_TASK)
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(assignJobs.getRemovingJobs())))
.build();
this.manageServer.sendMsg(collectorName, message);
}
assignJobs.clearRemovingJobs();
}
});
collectorKeeper.changeStatus(identity, CollectorStatus.OFFLINE);
collectorKeeper.rebalanceJobs(this::doRebalanceJobs);
log.info("the collector: {} go offline success.", identity);
}
@Override
@@ -285,56 +248,11 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
return true;
}
@Override
public List<CollectRep.MetricsData> collectSyncJobData(Job job) {
// todo dispatchKey ip+port or id
String dispatchKey = String.valueOf(job.getMonitorId());
ConsistentHash.Node node = consistentHash.preDispatchJob(dispatchKey);
if (Objects.isNull(node)) {
log.error("there is no collector online to assign job.");
CollectRep.MetricsData metricsData = CollectRep.MetricsData.newBuilder()
.setCode(CollectRep.Code.FAIL)
.setMsg("no collector online to assign job")
.build();
return Collections.singletonList(metricsData);
}
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(node.getIdentity())) {
return collectJobService.collectSyncJobData(job);
} else {
List<CollectRep.MetricsData> metricsData = new LinkedList<>();
CountDownLatch countDownLatch = new CountDownLatch(1);
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
.setType(ClusterMsg.MessageType.ISSUE_ONE_TIME_TASK)
.setDirection(ClusterMsg.Direction.REQUEST)
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(job)))
.build();
boolean result = this.manageServer.sendMsg(node.getIdentity(), message);
if (result) {
CollectResponseEventListener listener = new CollectResponseEventListener() {
@Override
public void response(List<CollectRep.MetricsData> responseMetrics) {
if (responseMetrics != null) {
metricsData.addAll(responseMetrics);
}
countDownLatch.countDown();
}
};
eventListeners.put(job.getMonitorId(), listener);
}
try {
countDownLatch.await(120, TimeUnit.SECONDS);
} catch (Exception e) {
log.info("The sync task runs for 120 seconds with no response and returns");
}
return metricsData;
}
}
@Override
public List<CollectRep.MetricsData> collectSyncJobData(Job job, String collector) {
ConsistentHash.Node node = consistentHash.getNode(collector);
CollectorNode node = StringUtils.isBlank(collector)
? collectorKeeper.determineNode(job.getMonitorId())
: collectorKeeper.getNode(collector);
if (Objects.isNull(node)) {
log.error("there is no collector online to assign job.");
CollectRep.MetricsData metricsData = CollectRep.MetricsData.newBuilder()
@@ -343,9 +261,11 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
.build();
return Collections.singletonList(metricsData);
}
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(node.getIdentity())) {
return collectJobService.collectSyncJobData(job);
}
List<CollectRep.MetricsData> metricsData = new LinkedList<>();
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
.setType(ClusterMsg.MessageType.ISSUE_ONE_TIME_TASK)
@@ -378,25 +298,10 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
public long addAsyncCollectJob(Job job, String collector) {
long jobId = SnowFlakeIdGenerator.generateId();
job.setId(jobId);
jobContentCache.put(jobId, job);
ConsistentHash.Node node;
if (StringUtils.isBlank(collector)) {
// todo dispatchKey ip+port or id
String dispatchKey = String.valueOf(job.getMonitorId());
node = consistentHash.dispatchJob(dispatchKey, jobId);
if (node == null) {
log.error("there is no collector online to assign job.");
return jobId;
}
} else {
node = consistentHash.getNode(collector);
if (node == null) {
log.error("there is no collector name: {} online to assign job.", collector);
return jobId;
}
node.getAssignJobs().addPinnedJob(jobId);
}
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(node.getIdentity())) {
CollectorNode collectorNode = collectorKeeper.addJob(job, collector);
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorNode.getIdentity())) {
collectJobService.addAsyncCollectJob(job);
} else {
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
@@ -404,27 +309,16 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
.setDirection(ClusterMsg.Direction.REQUEST)
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(job)))
.build();
this.manageServer.sendMsg(node.getIdentity(), message);
this.manageServer.sendMsg(collectorNode.getIdentity(), message);
}
return jobId;
}
@Override
public long updateAsyncCollectJob(Job modifyJob) {
// delete and add
long preJobId = modifyJob.getId();
long newJobId = addAsyncCollectJob(modifyJob, null);
jobContentCache.remove(preJobId);
cancelAsyncCollectJob(preJobId);
return newJobId;
}
@Override
public long updateAsyncCollectJob(Job modifyJob, String collector) {
// delete and add
long preJobId = modifyJob.getId();
long newJobId = addAsyncCollectJob(modifyJob, collector);
jobContentCache.remove(preJobId);
cancelAsyncCollectJob(preJobId);
return newJobId;
}
@@ -434,24 +328,21 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
if (jobId == null) {
return;
}
jobContentCache.remove(jobId);
for (ConsistentHash.Node node : consistentHash.getAllNodes().values()) {
AssignJobs assignJobs = node.getAssignJobs();
if (assignJobs.getPinnedJobs().remove(jobId)
|| assignJobs.getJobs().remove(jobId) || assignJobs.getAddingJobs().remove(jobId)) {
node.removeVirtualNodeJob(jobId);
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(node.getIdentity())) {
collectJobService.cancelAsyncCollectJob(jobId);
} else {
ClusterMsg.Message deleteMessage = ClusterMsg.Message.newBuilder()
.setType(ClusterMsg.MessageType.DELETE_CYCLIC_TASK)
.setDirection(ClusterMsg.Direction.REQUEST)
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(List.of(jobId))))
.build();
this.manageServer.sendMsg(node.getIdentity(), deleteMessage);
}
// break; if is there jod exist in multi collector?
}
CollectorNode collectorNode = collectorKeeper.removeJob(jobId);
if (collectorNode == null) {
return;
}
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorNode.getIdentity())) {
collectJobService.cancelAsyncCollectJob(jobId);
} else {
ClusterMsg.Message deleteMessage = ClusterMsg.Message.newBuilder()
.setType(ClusterMsg.MessageType.DELETE_CYCLIC_TASK)
.setDirection(ClusterMsg.Direction.REQUEST)
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(List.of(jobId))))
.build();
this.manageServer.sendMsg(collectorNode.getIdentity(), deleteMessage);
}
}
@@ -468,7 +359,55 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
}
}
public void setManageServer(ManageServer manageServer) {
this.manageServer = manageServer;
private void doRebalanceJobs(AssignJobs assignJobs, String collectorName) {
handleAddingJobs(assignJobs, collectorName);
handleRemovingJobs(assignJobs, collectorName);
}
private void handleAddingJobs(AssignJobs assignJobs, String collectorName) {
if (CollectionUtils.isEmpty(assignJobs.getAddingJobs())) {
return;
}
Set<Long> addedJobIds = new HashSet<>(8);
for (Long addingJobId : assignJobs.getAddingJobs()) {
Job job = JobCache.get(addingJobId);
if (Objects.isNull(job)) {
log.error("assigning job {} content is null.", addingJobId);
continue;
}
addedJobIds.add(addingJobId);
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorName)) {
collectJobService.addAsyncCollectJob(job);
} else {
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
.setDirection(ClusterMsg.Direction.REQUEST)
.setType(ClusterMsg.MessageType.ISSUE_CYCLIC_TASK)
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(job)))
.build();
this.manageServer.sendMsg(collectorName, message);
}
}
assignJobs.addAssignJobs(addedJobIds);
assignJobs.removeAddingJobs(addedJobIds);
}
private void handleRemovingJobs(AssignJobs assignJobs, String collectorName) {
if (CollectionUtils.isEmpty(assignJobs.getRemovingJobs())) {
return;
}
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorName)) {
assignJobs.getRemovingJobs().forEach(jobId -> collectJobService.cancelAsyncCollectJob(jobId));
} else {
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
.setDirection(ClusterMsg.Direction.REQUEST)
.setType(ClusterMsg.MessageType.DELETE_CYCLIC_TASK)
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(assignJobs.getRemovingJobs())))
.build();
this.manageServer.sendMsg(collectorName, message);
}
assignJobs.clearRemovingJobs();
}
}
@@ -0,0 +1,46 @@
/*
* 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.manager.scheduler;
/**
* Interface defining operations for managing collector.
* Implementations of this interface provide functionality to control the operation state
* of collectors in the system.
*/
public interface CollectorOperation {
/**
* Takes a collector offline by stopping its collection operations.
* This is typically used for maintenance, updates, or when the collector is no longer needed.
*
* @param identity The unique identifier of the collector to be taken offline
* @return true if the collector was successfully taken offline,
* false if the operation failed or the collector wasn't found
*/
boolean offlineCollector(String identity);
/**
* Brings a collector online by starting its collection operations.
* This is used to activate a collector that was previously offline.
*
* @param identity The unique identifier of the collector to be brought online
* @return true if the collector was successfully brought online,
* false if the operation failed or the collector wasn't found
*/
boolean onlineCollector(String identity);
}
@@ -20,39 +20,25 @@ package org.apache.hertzbeat.manager.scheduler;
import org.apache.hertzbeat.common.entity.dto.CollectorInfo;
/**
* slave collector service
* Interface defining operations for receiving collector status updates from remote collectors.
* This interface serves as a callback mechanism for handling collector online/offline events.
*/
public interface CollectorScheduling {
public interface CollectorOperationReceiver {
/**
* register collector go online
* @param identity collector identity name
* @param collectorInfo collector information
* Notifies the system when a collector comes online.
* This method should be called when a collector establishes connection and becomes available.
*
* @param identity The unique identifier of the collector (e.g., hostname, IP, or custom ID)
* @param collectorInfo Detailed information about the collector including capabilities,
* configuration, and status metadata
*/
void collectorGoOnline(String identity, CollectorInfo collectorInfo);
/**
* register collector go offline
* @param identity collector identity name
*/
void collectorGoOffline(String identity);
/**
* reBalance dispatch monitoring jobs when collector go online or offline or timeout
*/
void reBalanceCollectorAssignJobs();
/**
* offline collector(stop collector collect operation)
* @param identity collector identity name
* @return true/false
*/
boolean offlineCollector(String identity);
/**
* online collector(start collector collect operation)
* @param identity collector identity name
* @return true/false
* Notifies the system when a collector goes offline.
* This method should be called when a collector disconnects or becomes unavailable.
*
* @param identity The unique identifier of the collector to be marked as offline
*/
boolean onlineCollector(String identity);
void collectorGoOffline(String identity);
}
@@ -23,46 +23,149 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.hertzbeat.common.constants.CollectorStatus;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.job.Job;
import org.apache.hertzbeat.manager.pojo.CollectorNode;
import org.apache.hertzbeat.manager.pojo.JobCache;
import org.apache.hertzbeat.manager.scheduler.collector.CollectorKeeper;
/**
* Collector and task mapping scheduling implemented by consistent hashing
*/
@Slf4j
public class ConsistentHash {
public class ConsistentHashCollectorKeeper implements CollectorKeeper {
/**
* consistent hash circle
*/
private final ConcurrentTreeMap<Integer, Node> hashCircle;
private final ConcurrentTreeMap<Integer, CollectorNode> hashCircle = new ConcurrentTreeMap<>();
/**
* collector node
*/
private final Map<String, Node> existNodeMap;
private final Map<String, CollectorNode> existNodeMap = new ConcurrentHashMap<>(16);
/**
* not dispatched job cache
* not dispatched job cache, in order to obtain the cached collection scheduling task
*/
private final List<DispatchJob> dispatchJobCache;
@Getter
private final List<DispatchJob> dispatchJobCache = Collections.synchronizedList(new LinkedList<>());
/**
* Default number of VM nodes
*/
private static final byte VIRTUAL_NODE_DEFAULT_SIZE = 10;
public ConsistentHash() {
hashCircle = new ConcurrentTreeMap<>();
existNodeMap = new ConcurrentHashMap<>(16);
dispatchJobCache = Collections.synchronizedList(new LinkedList<>());
/**
* add collector node
* @param newNode node
*/
@Override
public void addNode(CollectorNode newNode) {
// when mode is cluster public, need reBalance dispatch jobs. else not when is cloud-edge private
if (!CommonConstants.MODE_PRIVATE.equals(newNode.getMode())) {
byte virtualNodeNum = newNode.getQuality() == null ? VIRTUAL_NODE_DEFAULT_SIZE : newNode.getQuality();
for (byte i = 0; i < virtualNodeNum; i++) {
addVirtualNode(newNode, newNode.getIdentity() + i);
}
}
existNodeMap.put(newNode.getIdentity(), newNode);
dispatchJobInCache();
}
@Override
public CollectorNode addJob(Job job, String collectorId) {
JobCache.put(job);
CollectorNode collectorNode;
if (StringUtils.isBlank(collectorId)) {
// todo dispatchKey ip+port or id
String dispatchKey = String.valueOf(job.getMonitorId());
collectorNode = this.dispatchJob(dispatchKey, job.getId());
if (collectorNode == null) {
log.error("there is no collector online to assign job.");
}
} else {
collectorNode = getNode(collectorId);
if (collectorNode == null) {
log.error("there is no collector name: {} online to assign job.", collectorId);
return null;
}
collectorNode.getAssignJobs().addPinnedJob(job.getId());
}
return collectorNode;
}
/**
* get node
* @param collectorName collector name
* @return node
*/
@Override
public CollectorNode getNode(String collectorName) {
return existNodeMap.get(collectorName);
}
@Override
public CollectorNode determineNode(Long jobId) {
String dispatchKey = String.valueOf(jobId);
if (dispatchKey == null || StringUtils.isBlank(dispatchKey)) {
log.error("The dispatch key can not null.");
return null;
}
int dispatchHash = hash(dispatchKey);
return preDispatchJob(dispatchHash);
}
@Override
public void changeStatus(String collectorId, CollectorStatus collectorStatus) {
switch (collectorStatus) {
case ONLINE -> this.getNode(collectorId).setCollectorStatus(collectorStatus);
case OFFLINE -> this.removeNode(collectorId);
default -> {}
}
}
@Override
public void rebalanceJobs(BiConsumer<AssignJobs, String> assignJobCollectorConsumer) {
existNodeMap.entrySet().parallelStream().forEach(entry -> {
String collectorName = entry.getKey();
AssignJobs assignJobs = entry.getValue().getAssignJobs();
if (StringUtils.isBlank(collectorName) || Objects.isNull(assignJobs)) {
return;
}
assignJobCollectorConsumer.accept(assignJobs, collectorName);
});
}
@Override
public CollectorNode removeJob(Long jobId) {
JobCache.remove(jobId);
for (CollectorNode node : existNodeMap.values()) {
AssignJobs assignJobs = node.getAssignJobs();
if (assignJobs.getPinnedJobs().remove(jobId)
|| assignJobs.getJobs().remove(jobId) || assignJobs.getAddingJobs().remove(jobId)) {
node.removeVirtualNodeJob(jobId);
return node;
// break; if is there jod exist in multi collector?
}
}
return null;
}
/**
@@ -70,15 +173,15 @@ public class ConsistentHash {
* @param newNode node
* @param identity virtual node identity
*/
public synchronized void addVirtualNode(Node newNode, String identity){
private synchronized void addVirtualNode(CollectorNode newNode, String identity){
int virtualHashKey = hash(identity);
hashCircle.put(virtualHashKey, newNode);
newNode.addVirtualNodeJobs(virtualHashKey, ConcurrentHashMap.newKeySet(16));
Map.Entry<Integer, Node> higherVirtualNode = hashCircle.higherOrFirstEntry(virtualHashKey);
Map.Entry<Integer, CollectorNode> higherVirtualNode = hashCircle.higherOrFirstEntry(virtualHashKey);
// Reassign tasks that are routed to the higherVirtualNode virtual node
// Tasks are either on the original virtual node or on the new virtual node
Integer higherVirtualNodeKey = higherVirtualNode.getKey();
Node higherNode = higherVirtualNode.getValue();
CollectorNode higherNode = higherVirtualNode.getValue();
Set<Long[]> dispatchJobs = higherNode.clearVirtualNodeJobs(higherVirtualNodeKey);
if (dispatchJobs != null && !dispatchJobs.isEmpty()) {
Set<Long[]> reDispatchJobs = ConcurrentHashMap.newKeySet(dispatchJobs.size());
@@ -91,53 +194,37 @@ public class ConsistentHash {
iterator.remove();
}
}
higherNode.virtualNodeMap.put(higherVirtualNodeKey, dispatchJobs);
higherNode.getVirtualNodeMap().put(higherVirtualNodeKey, dispatchJobs);
Set<Long> jobIds = reDispatchJobs.stream().map(item -> item[0]).collect(Collectors.toSet());
newNode.addVirtualNodeJobs(virtualHashKey, reDispatchJobs);
if (higherNode != newNode) {
higherNode.assignJobs.removeAssignJobs(jobIds);
higherNode.assignJobs.addRemovingJobs(jobIds);
newNode.assignJobs.addAddingJobs(jobIds);
higherNode.getAssignJobs().removeAssignJobs(jobIds);
higherNode.getAssignJobs().addRemovingJobs(jobIds);
newNode.getAssignJobs().addAddingJobs(jobIds);
}
}
}
/**
* add collector node
* @param newNode node
*/
public void addNode(Node newNode) {
// when mode is cluster public, need reBalance dispatch jobs. else not when is cloud-edge private
if (!CommonConstants.MODE_PRIVATE.equals(newNode.mode)) {
byte virtualNodeNum = newNode.quality == null ? VIRTUAL_NODE_DEFAULT_SIZE : newNode.quality;
for (byte i = 0; i < virtualNodeNum; i++) {
addVirtualNode(newNode, newNode.identity + i);
}
}
existNodeMap.put(newNode.identity, newNode);
dispatchJobInCache();
}
/**
* remove virtual node
* @param deletedNode node
* @param virtualNodeHash virtual node hash key
*/
public synchronized void removeVirtualNode(Node deletedNode, Integer virtualNodeHash) {
Set<Long[]> removeJobHashSet = deletedNode.virtualNodeMap.get(virtualNodeHash);
private synchronized void removeVirtualNode(CollectorNode deletedNode, Integer virtualNodeHash) {
Set<Long[]> removeJobHashSet = deletedNode.getVirtualNodeMap().get(virtualNodeHash);
// Migrate the virtualNodeEntry collection task to the nearest virtual node that is larger than it
hashCircle.remove(virtualNodeHash);
if (removeJobHashSet == null || removeJobHashSet.isEmpty()) {
return;
}
Map.Entry<Integer, Node> higherVirtualEntry = hashCircle.higherOrFirstEntry(virtualNodeHash);
Map.Entry<Integer, CollectorNode> higherVirtualEntry = hashCircle.higherOrFirstEntry(virtualNodeHash);
if (higherVirtualEntry == null || higherVirtualEntry.getValue() == deletedNode) {
higherVirtualEntry = null;
}
// jobId
Set<Long> removeJobIds = removeJobHashSet.stream().map(item -> item[0]).collect(Collectors.toSet());
deletedNode.assignJobs.removeAssignJobs(removeJobIds);
deletedNode.assignJobs.addRemovingJobs(removeJobIds);
deletedNode.getAssignJobs().removeAssignJobs(removeJobIds);
deletedNode.getAssignJobs().addRemovingJobs(removeJobIds);
if (higherVirtualEntry == null) {
// jobId-dispatchHash
removeJobHashSet.forEach(value -> {
@@ -150,9 +237,9 @@ public class ConsistentHash {
}
});
} else {
Node higherVirtualNode = higherVirtualEntry.getValue();
CollectorNode higherVirtualNode = higherVirtualEntry.getValue();
higherVirtualNode.addVirtualNodeJobs(higherVirtualEntry.getKey(), removeJobHashSet);
higherVirtualNode.assignJobs.addAddingJobs(removeJobIds);
higherVirtualNode.getAssignJobs().addAddingJobs(removeJobIds);
}
}
@@ -160,20 +247,19 @@ public class ConsistentHash {
* deleted collector node
* @param name collector name
*/
public Node removeNode(String name) {
Node deletedNode = existNodeMap.remove(name);
private void removeNode(String name) {
CollectorNode deletedNode = existNodeMap.remove(name);
if (deletedNode == null) {
return null;
}
for (Integer virtualNodeHash : deletedNode.virtualNodeMap.keySet()) {
removeVirtualNode(deletedNode, virtualNodeHash);
return;
}
deletedNode.getVirtualNodeMap().keySet()
.forEach(virtualNodeHash -> removeVirtualNode(deletedNode, virtualNodeHash));
deletedNode.destroy();
dispatchJobInCache();
return deletedNode;
}
public synchronized void dispatchJobInCache() {
private synchronized void dispatchJobInCache() {
if (!dispatchJobCache.isEmpty()) {
int size = dispatchJobCache.size();
for (int index = 0; index < size; index++) {
@@ -183,31 +269,6 @@ public class ConsistentHash {
}
}
/**
* get all collector nodes
* @return nodes
*/
public Map<String, Node> getAllNodes() {
return existNodeMap;
}
/**
* get node
* @param collectorName collector name
* @return node
*/
public Node getNode(String collectorName) {
return existNodeMap.get(collectorName);
}
/**
* Obtain the cached collection scheduling task
* @return cache task
*/
public List<DispatchJob> getDispatchJobCache() {
return dispatchJobCache;
}
/**
* obtain the collector node according to the collection task information
*
@@ -215,7 +276,7 @@ public class ConsistentHash {
* @param jobId jobId
* @return collector node
*/
public Node dispatchJob(String dispatchKey, Long jobId) {
private CollectorNode dispatchJob(String dispatchKey, Long jobId) {
if (dispatchKey == null || StringUtils.isBlank(dispatchKey)) {
log.error("The dispatch key can not null.");
return null;
@@ -224,38 +285,23 @@ public class ConsistentHash {
return dispatchJob(dispatchHash, jobId, true);
}
/**
* The collector node to which the collector is assigned is obtained in advance based on the collection task information
*
* @param dispatchKey collector task route key: ip+appId
* @return collector node
*/
public Node preDispatchJob(String dispatchKey) {
if (dispatchKey == null || StringUtils.isBlank(dispatchKey)) {
log.error("The dispatch key can not null.");
return null;
}
int dispatchHash = hash(dispatchKey);
return preDispatchJob(dispatchHash);
}
/**
* Obtain the collector node to which the collector is assigned based on the collection task information
*
* @param dispatchHash The task route hash is collected
* @param jobId jobId
* @param isFlushed is has flush this job or wait to dispatch
* @param isFlushed if it has flushed this job or wait to dispatch
* @return collector node
*/
public Node dispatchJob(Integer dispatchHash, Long jobId, boolean isFlushed) {
private CollectorNode dispatchJob(Integer dispatchHash, Long jobId, boolean isFlushed) {
if (dispatchHash == null || hashCircle == null || hashCircle.isEmpty()) {
log.warn("There is no available collector registered. Cache the job {}.", jobId);
dispatchJobCache.add(new DispatchJob(dispatchHash, jobId));
return null;
}
Map.Entry<Integer, Node> ceilEntry = hashCircle.ceilingOrFirstEntry(dispatchHash);
Map.Entry<Integer, CollectorNode> ceilEntry = hashCircle.ceilingOrFirstEntry(dispatchHash);
int virtualKey = ceilEntry.getKey();
Node curNode = ceilEntry.getValue();
CollectorNode curNode = ceilEntry.getValue();
curNode.addJob(virtualKey, dispatchHash, jobId, isFlushed);
return curNode;
@@ -267,25 +313,15 @@ public class ConsistentHash {
* @param dispatchHash The task route hash is collected
* @return collector node
*/
public Node preDispatchJob(Integer dispatchHash) {
private CollectorNode preDispatchJob(Integer dispatchHash) {
if (dispatchHash == null || hashCircle == null || hashCircle.isEmpty()) {
log.warn("There is no available collector registered.");
return null;
}
Map.Entry<Integer, Node> ceilEntry = hashCircle.ceilingOrFirstEntry(dispatchHash);
Map.Entry<Integer, CollectorNode> ceilEntry = hashCircle.ceilingOrFirstEntry(dispatchHash);
return ceilEntry.getValue();
}
/**
* hash long
* @param key long value
* @return hash value
*/
private int hash(long key) {
String keyStr = String.valueOf(key);
return hash(keyStr);
}
/**
* FNV1_32_HASH algorithm
* @param key the key
@@ -314,7 +350,7 @@ public class ConsistentHash {
* dispatch job summary
*/
@AllArgsConstructor
public static class DispatchJob {
private static class DispatchJob {
/**
* dispatch task route key
@@ -327,130 +363,4 @@ public class ConsistentHash {
@Getter
private Long jobId;
}
/**
* collector node machine address
*/
public static class Node {
/**
* collector identity
*/
@Getter
private final String identity;
/**
* collector mode: public or private
*/
private final String mode;
/**
* ip
*/
private final String ip;
/**
* collector On-line time stamp
*/
private final long uptime;
/**
* collector's own performance service quality score 0 - 127
* The number of virtual nodes will be calculated based on this service quality score
*
*/
private final Byte quality;
/**
* use this collector's collect job ID list
* jobId,jobVersion
*/
private AssignJobs assignJobs;
/**
* the collection task ID list mapped by each virtual node corresponding to this node
* Long[] [0]-jobId, [1]-dispatchHash
*/
private Map<Integer, Set<Long[]>> virtualNodeMap;
public Node(String identity, String mode, String ip, long uptime, Byte quality) {
this.identity = identity;
this.mode = mode;
this.ip = ip;
this.uptime = uptime;
this.quality = quality;
assignJobs = new AssignJobs();
virtualNodeMap = new ConcurrentHashMap<>(VIRTUAL_NODE_DEFAULT_SIZE);
}
private synchronized void addJob(Integer virtualNodeKey, Integer dispatchHash, Long jobId, boolean isFlushed) {
if (virtualNodeMap == null) {
virtualNodeMap = new ConcurrentHashMap<>(VIRTUAL_NODE_DEFAULT_SIZE);
}
if (assignJobs == null) {
assignJobs = new AssignJobs();
}
Set<Long[]> virtualNodeJob = virtualNodeMap.computeIfAbsent(virtualNodeKey, k -> ConcurrentHashMap.newKeySet(16));
virtualNodeJob.add(new Long[]{jobId, dispatchHash.longValue()});
if (isFlushed) {
assignJobs.addAssignJob(jobId);
} else {
assignJobs.addAddingJob(jobId);
}
}
/**
* obtain the collection task routed by the specified virtual node according to virtualNodeKey
* @param virtualNodeKey virtualNodeKey
* @return collection task
*/
private Set<Long[]> clearVirtualNodeJobs(Integer virtualNodeKey) {
if (virtualNodeMap == null || virtualNodeMap.isEmpty()) {
return null;
}
Set<Long[]> virtualNodeJobs = virtualNodeMap.remove(virtualNodeKey);
virtualNodeMap.put(virtualNodeKey, ConcurrentHashMap.newKeySet(16));
return virtualNodeJobs;
}
private void addVirtualNodeJobs(Integer virtualHashKey, Set<Long[]> reDispatchJobs) {
if (reDispatchJobs == null) {
return;
}
if (virtualNodeMap == null) {
virtualNodeMap = new ConcurrentHashMap<>(16);
}
virtualNodeMap.computeIfPresent(virtualHashKey, (k, v) -> {
reDispatchJobs.addAll(v);
return v;
});
virtualNodeMap.put(virtualHashKey, reDispatchJobs);
}
public void removeVirtualNodeJob(Long jobId) {
if (jobId == null || virtualNodeMap == null) {
return;
}
for (Set<Long[]> jobSet : virtualNodeMap.values()) {
Optional<Long[]> optional = jobSet.stream().filter(item -> Objects.equals(item[0], jobId)).findFirst();
if (optional.isPresent()) {
jobSet.remove(optional.get());
break;
}
}
}
public AssignJobs getAssignJobs() {
return assignJobs;
}
public void destroy() {
if (assignJobs != null) {
assignJobs.clear();
}
if (virtualNodeMap != null) {
virtualNodeMap.clear();
}
}
}
}
@@ -24,15 +24,8 @@ import org.apache.hertzbeat.common.entity.message.CollectRep;
/**
* Collection job management provides api interface
*/
public interface CollectJobScheduling {
public interface JobOperation {
/**
* Execute a one-time collection task and get the collected data response
* @param job Collect task details
* @return Collection results
*/
List<CollectRep.MetricsData> collectSyncJobData(Job job);
/**
* Execute a one-time collection task and get the collected data response
* @param job Collect task details
@@ -49,13 +42,6 @@ public interface CollectJobScheduling {
*/
long addAsyncCollectJob(Job job, String collector);
/**
* Update the periodic asynchronous collection tasks that have been delivered
* @param modifyJob Collect task details
* @return long Job ID
*/
long updateAsyncCollectJob(Job modifyJob);
/**
* Update the periodic asynchronous collection tasks that have been delivered
* @param modifyJob Collect task details
@@ -52,10 +52,10 @@ import org.springframework.util.StringUtils;
public class SchedulerInit implements CommandLineRunner {
@Autowired
private CollectorScheduling collectorScheduling;
private CollectorOperationReceiver collectorOperationReceiver;
@Autowired
private CollectJobScheduling collectJobScheduling;
private JobOperation jobOperation;
private static final String MAIN_COLLECTOR_NODE_IP = "127.0.0.1";
private static final String DEFAULT_COLLECTOR_VERSION = "DEBUG";
@@ -91,7 +91,7 @@ public class SchedulerInit implements CommandLineRunner {
.ip(MAIN_COLLECTOR_NODE_IP)
.version(DEFAULT_COLLECTOR_VERSION)
.build();
collectorScheduling.collectorGoOnline(CommonConstants.MAIN_COLLECTOR_NODE, collectorInfo);
collectorOperationReceiver.collectorGoOnline(CommonConstants.MAIN_COLLECTOR_NODE, collectorInfo);
// init jobs
List<Monitor> monitors = monitorDao.findMonitorsByStatusNotInAndJobIdNotNull(List.of(CommonConstants.MONITOR_PAUSED_CODE));
List<CollectorMonitorBind> monitorBinds = collectorMonitorBindDao.findAll();
@@ -136,7 +136,7 @@ public class SchedulerInit implements CommandLineRunner {
});
appDefine.setConfigmap(configmaps);
String collector = monitorIdCollectorMap.get(monitor.getId());
long jobId = collectJobScheduling.addAsyncCollectJob(appDefine, collector);
long jobId = jobOperation.addAsyncCollectJob(appDefine, collector);
monitor.setJobId(jobId);
monitorDao.save(monitor);
} catch (Exception e) {
@@ -0,0 +1,82 @@
/*
* 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.manager.scheduler.collector;
import org.apache.hertzbeat.common.constants.CollectorStatus;
import org.apache.hertzbeat.common.entity.job.Job;
import org.apache.hertzbeat.manager.pojo.CollectorNode;
import org.apache.hertzbeat.manager.scheduler.AssignJobs;
import java.util.function.BiConsumer;
/**
* Interface for managing collector nodes and their associated jobs.
* Maintains all collector information and provides operations for managing collectors and job assignments.
*/
public interface CollectorKeeper {
/**
* Adds a new collector node to the keeper's management pool.
* @param newNode The collector node to be added to the management system
*/
void addNode(CollectorNode newNode);
/**
* Assigns a monitoring job to a specific collector node.
* @param job The monitoring job to be assigned
* @param collectorId The unique identifier of the target collector node
* @return The collector node that received the job assignment
*/
CollectorNode addJob(Job job, String collectorId);
/**
* Retrieves a collector node by its unique identifier.
* @param collectorId The unique identifier of the collector node
* @return The collector node matching the given ID, or null if not found
*/
CollectorNode getNode(String collectorId);
/**
* Determines the most appropriate collector node for a given job based on scheduling logic.
* @param jobId The unique identifier of the job to be assigned
* @return The collector node selected to handle this job
*/
CollectorNode determineNode(Long jobId);
/**
* Updates the operational status of a collector node.
* @param collectorId The unique identifier of the collector node
* @param collectorStatus The new status to assign to the collector
*/
void changeStatus(String collectorId, CollectorStatus collectorStatus);
/**
* Rebalances job assignments across collector nodes, typically triggered by status changes.
* Uses a callback mechanism to handle job reassignments.
* @param assignJobCollectorConsumer A biconsumer that handles the job reassignment process,
* taking the job assignment logic and collector ID as parameters
*/
void rebalanceJobs(BiConsumer<AssignJobs, String> assignJobCollectorConsumer);
/**
* Removes a job from whichever collector node it is currently assigned to.
* @param jobId The unique identifier of the job to be removed
* @return The collector node from which the job was removed, or null if job wasn't found
*/
CollectorNode removeJob(Long jobId);
}
@@ -28,7 +28,7 @@ import org.apache.hertzbeat.alert.calculate.CollectorAlertHandler;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
import org.apache.hertzbeat.common.support.CommonThreadPool;
import org.apache.hertzbeat.manager.scheduler.CollectorJobScheduler;
import org.apache.hertzbeat.manager.scheduler.SchedulerProperties;
import org.apache.hertzbeat.manager.properties.SchedulerProperties;
import org.apache.hertzbeat.manager.scheduler.netty.process.CollectCyclicDataResponseProcessor;
import org.apache.hertzbeat.manager.scheduler.netty.process.CollectCyclicServiceDiscoveryDataResponseProcessor;
import org.apache.hertzbeat.manager.scheduler.netty.process.CollectOneTimeDataResponseProcessor;
@@ -45,6 +45,8 @@ import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
/**
* manage server
*/
@@ -112,6 +114,7 @@ public class ManageServer implements CommandLineRunner {
}, 10, 3, TimeUnit.SECONDS);
}
@PreDestroy
public void shutdown() {
this.remotingServer.shutdown();
@@ -31,8 +31,9 @@ import org.apache.hertzbeat.common.support.exception.CommonException;
import org.apache.hertzbeat.common.util.IpDomainUtil;
import org.apache.hertzbeat.manager.dao.CollectorDao;
import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
import org.apache.hertzbeat.manager.pojo.CollectorNode;
import org.apache.hertzbeat.manager.scheduler.AssignJobs;
import org.apache.hertzbeat.manager.scheduler.ConsistentHash;
import org.apache.hertzbeat.manager.scheduler.ConsistentHashCollectorKeeper;
import org.apache.hertzbeat.manager.scheduler.netty.ManageServer;
import org.apache.hertzbeat.manager.service.CollectorService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -57,7 +58,7 @@ public class CollectorServiceImpl implements CollectorService {
private CollectorMonitorBindDao collectorMonitorBindDao;
@Autowired
private ConsistentHash consistentHash;
private ConsistentHashCollectorKeeper consistentHashCollectorKeeper;
@Autowired(required = false)
private ManageServer manageServer;
@@ -81,7 +82,7 @@ public class CollectorServiceImpl implements CollectorService {
List<CollectorSummary> collectorSummaryList = new LinkedList<>();
for (Collector collector : collectors.getContent()) {
CollectorSummary.CollectorSummaryBuilder summaryBuilder = CollectorSummary.builder().collector(collector);
ConsistentHash.Node node = consistentHash.getNode(collector.getName());
CollectorNode node = consistentHashCollectorKeeper.getNode(collector.getName());
if (node != null && node.getAssignJobs() != null) {
AssignJobs assignJobs = node.getAssignJobs();
summaryBuilder.pinMonitorNum(assignJobs.getPinnedJobs().size());
@@ -60,7 +60,7 @@ import org.apache.hertzbeat.manager.dao.MonitorDao;
import org.apache.hertzbeat.manager.dao.ParamDao;
import org.apache.hertzbeat.manager.pojo.dto.AppCount;
import org.apache.hertzbeat.manager.pojo.dto.MonitorDto;
import org.apache.hertzbeat.manager.scheduler.CollectJobScheduling;
import org.apache.hertzbeat.manager.scheduler.JobOperation;
import org.apache.hertzbeat.manager.service.AppService;
import org.apache.hertzbeat.manager.service.ImExportService;
import org.apache.hertzbeat.manager.service.LabelService;
@@ -113,7 +113,7 @@ public class MonitorServiceImpl implements MonitorService {
@Autowired
private AppService appService;
@Autowired
private CollectJobScheduling collectJobScheduling;
private JobOperation jobOperation;
@Autowired
private MonitorDao monitorDao;
@Autowired
@@ -193,11 +193,10 @@ public class MonitorServiceImpl implements MonitorService {
return new Configmap(param.getField(), param.getParamValue(), param.getType());
}).collect(Collectors.toList());
appDefine.setConfigmap(configmaps);
long jobId = collector == null ? collectJobScheduling.addAsyncCollectJob(appDefine, null) :
collectJobScheduling.addAsyncCollectJob(appDefine, collector);
try {
detectMonitor(monitor, params, collector);
} catch (Exception ignored) {}
long jobId = jobOperation.addAsyncCollectJob(appDefine, collector);
detectMonitorSafely(monitor, params, collector);
try {
if (collector != null) {
@@ -217,7 +216,7 @@ public class MonitorServiceImpl implements MonitorService {
paramDao.saveAll(params);
} catch (Exception e) {
log.error("Error while adding monitor: {}", e.getMessage(), e);
collectJobScheduling.cancelAsyncCollectJob(jobId);
jobOperation.cancelAsyncCollectJob(jobId);
throw new MonitorDatabaseException(e.getMessage());
}
}
@@ -510,18 +509,11 @@ public class MonitorServiceImpl implements MonitorService {
List<Configmap> configmaps = params.stream().map(param ->
new Configmap(param.getField(), param.getParamValue(), param.getType())).collect(Collectors.toList());
appDefine.setConfigmap(configmaps);
long newJobId;
if (collector == null) {
newJobId = collectJobScheduling.updateAsyncCollectJob(appDefine);
} else {
newJobId = collectJobScheduling.updateAsyncCollectJob(appDefine, collector);
}
long newJobId = jobOperation.updateAsyncCollectJob(appDefine, collector);
monitor.setJobId(newJobId);
// execute only in non paused status
try {
detectMonitor(monitor, params, collector);
} catch (Exception ignored) {}
detectMonitorSafely(monitor, params, collector);
}
// After the update is successfully released, refresh the database
@@ -548,7 +540,7 @@ public class MonitorServiceImpl implements MonitorService {
} catch (Exception e) {
log.error(e.getMessage(), e);
// Repository brushing abnormally cancels the previously delivered task
collectJobScheduling.cancelAsyncCollectJob(monitor.getJobId());
jobOperation.cancelAsyncCollectJob(monitor.getJobId());
throw new MonitorDatabaseException(e.getMessage());
}
}
@@ -578,7 +570,7 @@ public class MonitorServiceImpl implements MonitorService {
for (Monitor monitor : monitors) {
monitorBindDao.deleteByMonitorId(monitor.getId());
collectorMonitorBindDao.deleteCollectorMonitorBindsByMonitorId(monitor.getId());
collectJobScheduling.cancelAsyncCollectJob(monitor.getJobId());
jobOperation.cancelAsyncCollectJob(monitor.getJobId());
applicationContext.publishEvent(new MonitorDeletedEvent(applicationContext, monitor.getId()));
}
}
@@ -692,17 +684,17 @@ public class MonitorServiceImpl implements MonitorService {
// The jobId is not deleted, and the jobId is reused again after the management is started.
Set<Long> subMonitorIds = monitorBindDao.findMonitorBindsByBizIdIn(ids).stream().map(MonitorBind::getMonitorId).collect(Collectors.toSet());
ids.addAll(subMonitorIds);
List<Monitor> managedMonitors = monitorDao.findMonitorsByIdIn(ids)
.stream().filter(monitor ->
monitor.getStatus() != CommonConstants.MONITOR_PAUSED_CODE)
List<Monitor> managedMonitors = monitorDao.findMonitorsByIdIn(ids).stream()
.filter(monitor -> monitor.getStatus() != CommonConstants.MONITOR_PAUSED_CODE)
.peek(monitor -> monitor.setStatus(CommonConstants.MONITOR_PAUSED_CODE))
.collect(Collectors.toList());
if (!CollectionUtils.isEmpty(managedMonitors)) {
for (Monitor monitor : managedMonitors) {
collectJobScheduling.cancelAsyncCollectJob(monitor.getJobId());
}
monitorDao.saveAll(managedMonitors);
if (CollectionUtils.isEmpty(managedMonitors)) {
return;
}
managedMonitors.forEach(monitor -> jobOperation.cancelAsyncCollectJob(monitor.getJobId()));
monitorDao.saveAll(managedMonitors);
}
@Override
@@ -710,9 +702,8 @@ public class MonitorServiceImpl implements MonitorService {
// Update monitoring status Add corresponding monitoring periodic task
Set<Long> subMonitorIds = monitorBindDao.findMonitorBindsByBizIdIn(ids).stream().map(MonitorBind::getMonitorId).collect(Collectors.toSet());
ids.addAll(subMonitorIds);
List<Monitor> unManagedMonitors = monitorDao.findMonitorsByIdIn(ids)
.stream().filter(monitor ->
monitor.getStatus() == CommonConstants.MONITOR_PAUSED_CODE)
List<Monitor> unManagedMonitors = monitorDao.findMonitorsByIdIn(ids).stream()
.filter(monitor -> monitor.getStatus() == CommonConstants.MONITOR_PAUSED_CODE)
.peek(monitor -> monitor.setStatus(CommonConstants.MONITOR_UP_CODE))
.collect(Collectors.toList());
if (unManagedMonitors.isEmpty()) {
@@ -757,13 +748,11 @@ public class MonitorServiceImpl implements MonitorService {
Optional<CollectorMonitorBind> bindOptional =
collectorMonitorBindDao.findCollectorMonitorBindByMonitorId(monitor.getId());
String collector = bindOptional.map(CollectorMonitorBind::getCollector).orElse(null);
long newJobId = collectJobScheduling.addAsyncCollectJob(appDefine, collector);
long newJobId = jobOperation.addAsyncCollectJob(appDefine, collector);
monitor.setJobId(newJobId);
applicationContext.publishEvent(new MonitorDeletedEvent(applicationContext, monitor.getId()));
try {
detectMonitor(monitor, params, collector);
} catch (Exception ignored) {
}
detectMonitorSafely(monitor, params, collector);
}
monitorDao.saveAll(unManagedMonitors);
}
@@ -852,7 +841,7 @@ public class MonitorServiceImpl implements MonitorService {
// if is pinned collector
String collector = monitorIdCollectorMap.get(monitor.getId());
// Delivering a collection task
long newJobId = collectJobScheduling.updateAsyncCollectJob(appDefine, collector);
long newJobId = jobOperation.updateAsyncCollectJob(appDefine, collector);
monitor.setJobId(newJobId);
monitorDao.save(monitor);
} catch (Exception e) {
@@ -932,12 +921,8 @@ public class MonitorServiceImpl implements MonitorService {
new Configmap(param.getField(), param.getParamValue(), param.getType())).collect(Collectors.toList());
appDefine.setConfigmap(configmaps);
appDefine.setSd(true);
List<CollectRep.MetricsData> collectRep;
if (collector != null) {
collectRep = collectJobScheduling.collectSyncJobData(appDefine, collector);
} else {
collectRep = collectJobScheduling.collectSyncJobData(appDefine);
}
List<CollectRep.MetricsData> collectRep = jobOperation.collectSyncJobData(appDefine, collector);
monitor.setStatus(CommonConstants.MONITOR_UP_CODE);
// If the detection result fails, a detection exception is thrown
if (collectRep == null || collectRep.isEmpty()) {
@@ -975,12 +960,7 @@ public class MonitorServiceImpl implements MonitorService {
List<Metrics> availableMetrics = appDefine.getMetrics().stream()
.filter(item -> item.getPriority() == 0).collect(Collectors.toList());
appDefine.setMetrics(availableMetrics);
List<CollectRep.MetricsData> collectRep;
if (collector != null) {
collectRep = collectJobScheduling.collectSyncJobData(appDefine, collector);
} else {
collectRep = collectJobScheduling.collectSyncJobData(appDefine);
}
List<CollectRep.MetricsData> collectRep = jobOperation.collectSyncJobData(appDefine, collector);
monitor.setStatus(CommonConstants.MONITOR_UP_CODE);
// If the detection result fails, a detection exception is thrown
@@ -994,4 +974,10 @@ public class MonitorServiceImpl implements MonitorService {
}
collectRep.forEach(CollectRep.MetricsData::close);
}
private void detectMonitorSafely(Monitor monitor, List<Param> params, String collector) {
try {
detectMonitor(monitor, params, collector);
} catch (Exception ignored) {}
}
}
@@ -21,12 +21,10 @@ app: dolphinscheduler
name:
zh-CN: Apache DolphinScheduler
en-US: Apache DolphinScheduler
ja-JP: Apache DolphinScheduler
# The description and help of this monitoring type
help:
zh-CN: Hertzbeat 对 Apache DolphinScheduler (支持v3.3.0或更高版本)通用指标进行测量监控。<br>您可以点击 “<i>新建 Apache DolphinScheduler</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
en-US: Hertzbeat measures and monitors the general metrics of Apache DolphinScheduler (support v3.3.0 or later).<br>You can click on “<i>Create New Apache DolphinScheduler</i>” to configure it, or select “<i>More Actions</i>” to import an existing configuration.
ja-JP: Hertzbeat は Apache DolphinSchedulerv3.3.0+)の一般的なメトリクスを監視します。<br>「<i>新規 Apache DolphinScheduler</i>」をクリックしてパラメタを設定した後、新規することができます。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/dolphinscheduler
en-US: https://hertzbeat.apache.org/docs/help/dolphinscheduler
@@ -38,7 +36,6 @@ 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
@@ -49,7 +46,6 @@ 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
@@ -64,7 +60,6 @@ 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
@@ -79,7 +74,6 @@ params:
name:
zh-CN: 启用HTTPS
en-US: SSL
ja-JP: SSL
# type-param field type(boolean mapping the html h tag)
type: boolean
# required-true or false
@@ -89,7 +83,6 @@ params:
name:
zh-CN: 令牌
en-US: Token
ja-JP: トークン
type: text
limit: 100
required: true
@@ -100,7 +93,6 @@ metrics:
i18n:
zh-CN: Master
en-US: Master
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
@@ -112,90 +104,76 @@ metrics:
i18n:
zh-CN: 主机地址
en-US: Host
ja-JP: ホスト
- field: port
type: 1
i18n:
zh-CN: 端口
en-US: Port
ja-JP: ポート
- field: serverStatus
type: 1
i18n:
zh-CN: 状态
en-US: Server Status
ja-JP: サーバーステータス
- field: processId
type: 1
i18n:
zh-CN: 进程 ID
en-US: Process Id
ja-JP: プロセスID
- field: runningTime
type: 0
i18n:
zh-CN: 运行时间
en-US: Up Time
ja-JP: アップタイム
en-US: Running Time
- field: cpuUsage
type: 0
unit: '%'
i18n:
zh-CN: 处理器使用量
en-US: CPU Usage
ja-JP: CPU使用率
- field: memoryUsage
type: 0
unit: '%'
i18n:
zh-CN: 内存使用量
en-US: Memory Usage
ja-JP: メモリ使用率
- field: diskUsage
type: 0
unit: '%'
i18n:
zh-CN: 磁盘使用量
en-US: Disk Usage
ja-JP: ディスク使用率
- field: jvmCpuUsage
type: 0
unit: '%'
i18n:
zh-CN: JVM CPU 使用量
en-US: JVM CPU Usage
ja-JP: Java仮想マシンのCPU使用率
- field: jvmMemoryUsage
type: 0
unit: '%'
i18n:
zh-CN: JVM 内存 使用量
en-US: JVM Memory Usage
ja-JP: Java仮想マシンのメモリ使用率
- field: jvmHeapUsed
type: 0
i18n:
zh-CN: JVM 已使用的堆内存大小
en-US: JVM Heap Used
ja-JP: Java仮想マシンが使用したヒープメモリのサイズ
- field: jvmNonHeapUsed
type: 0
i18n:
zh-CN: JVM 已使用的非堆内存大小
en-US: JVM NonHeap Used
ja-JP: Java仮想マシンが使用したノンヒープメモリのサイズ
- field: jvmHeapMax
type: 0
i18n:
zh-CN: JVM 配置的最大堆内存大小
en-US: JVM Heap Max
ja-JP: Java仮想マシンのヒープメモリの最大値
- field: jvmNonHeapMax
type: 0
i18n:
zh-CN: JVM 配置的最大非堆内存大小
en-US: JVM NonHeap Max
ja-JP: Java仮想マシンのノンヒープメモリの最大値
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
aliasFields:
- $.heartBeatInfo
@@ -241,7 +219,6 @@ metrics:
i18n:
zh-CN: Worker
en-US: Worker
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
@@ -253,109 +230,92 @@ metrics:
i18n:
zh-CN: 主机地址
en-US: Host
ja-JP: ホスト
- field: port
type: 1
i18n:
zh-CN: 端口
en-US: Port
ja-JP: ポート
- field: serverStatus
type: 1
i18n:
zh-CN: 状态
en-US: Server Status
ja-JP: サーバーステータス
- field: processId
type: 1
i18n:
zh-CN: 进程 ID
en-US: Process Id
ja-JP: プロセスID
- field: runningTime
type: 0
i18n:
zh-CN: 运行时间
en-US: Up Time
ja-JP: アップタイム
en-US: Running Time
- field: cpuUsage
type: 0
unit: '%'
i18n:
zh-CN: 处理器使用量
en-US: CPU Usage
ja-JP: CPU使用率
- field: memoryUsage
type: 0
unit: '%'
i18n:
zh-CN: 内存使用量
en-US: Memory Usage
ja-JP: メモリ使用率
- field: diskUsage
type: 0
unit: '%'
i18n:
zh-CN: 磁盘使用量
en-US: Disk Usage
ja-JP: ディスク使用率
- field: jvmCpuUsage
type: 0
unit: '%'
i18n:
zh-CN: JVM CPU 使用量
en-US: JVM CPU Usage
ja-JP: Java仮想マシンのCPU使用率
- field: jvmMemoryUsage
type: 0
unit: '%'
i18n:
zh-CN: JVM 内存 使用量
en-US: JVM Memory Usage
ja-JP: Java仮想マシンのメモリ使用率
- field: jvmHeapUsed
type: 0
i18n:
zh-CN: JVM 已使用的堆内存大小
en-US: JVM Heap Used
ja-JP: Java仮想マシンが使用したヒープメモリのサイズ
- field: jvmNonHeapUsed
type: 0
i18n:
zh-CN: JVM 已使用的非堆内存大小
en-US: JVM NonHeap Used
ja-JP: Java仮想マシンが使用したノンヒープメモリのサイズ
- field: jvmHeapMax
type: 0
i18n:
zh-CN: JVM 配置的最大堆内存大小
en-US: JVM Heap Max
ja-JP: Java仮想マシンのヒープメモリの最大値
- field: jvmNonHeapMax
type: 0
i18n:
zh-CN: JVM 配置的最大非堆内存大小
en-US: JVM NonHeap Max
ja-JP: Java仮想マシンのノンヒープメモリの最大値
- field: workerHostWeight
type: 0
i18n:
zh-CN: 权重
en-US: Weight
ja-JP: ウェイト
- field: threadPoolUsage
type: 0
unit: '%'
i18n:
zh-CN: 线程池使用量
en-US: Thread Pool Usage
ja-JP: スレッドプールの使用率
en-US: Thread Pool Usage
- field: workerGroup
type: 1
i18n:
zh-CN: Worker 组
en-US: Worker Group
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:
- $.heartBeatInfo
@@ -404,7 +364,6 @@ metrics:
i18n:
zh-CN: Alert Server
en-US: Alert Server
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
@@ -416,90 +375,76 @@ metrics:
i18n:
zh-CN: 主机地址
en-US: Host
ja-JP: ホスト
- field: port
type: 1
i18n:
zh-CN: 端口
en-US: Port
ja-JP: ポート
- field: serverStatus
type: 1
i18n:
zh-CN: 状态
en-US: Server Status
ja-JP: サーバーステータス
- field: processId
type: 1
i18n:
zh-CN: 进程 ID
en-US: Process Id
ja-JP: プロセスID
- field: runningTime
type: 0
i18n:
zh-CN: 运行时间
en-US: Up Time
ja-JP: アップタイム
en-US: Running Time
- field: cpuUsage
type: 0
unit: '%'
i18n:
zh-CN: 处理器使用量
en-US: CPU Usage
ja-JP: CPU使用率
- field: memoryUsage
type: 0
unit: '%'
i18n:
zh-CN: 内存使用量
en-US: Memory Usage
ja-JP: メモリ使用率
- field: diskUsage
type: 0
unit: '%'
i18n:
zh-CN: 磁盘使用量
en-US: Disk Usage
ja-JP: ディスク使用率
- field: jvmCpuUsage
type: 0
unit: '%'
i18n:
zh-CN: JVM CPU 使用量
en-US: JVM CPU Usage
ja-JP: Java仮想マシンのCPU使用率
- field: jvmMemoryUsage
type: 0
unit: '%'
i18n:
zh-CN: JVM 内存 使用量
en-US: JVM Memory Usage
ja-JP: Java仮想マシンのメモリ使用率
- field: jvmHeapUsed
type: 0
i18n:
zh-CN: JVM 已使用的堆内存大小
en-US: JVM Heap Used
ja-JP: Java仮想マシンが使用したヒープメモリのサイズ
- field: jvmNonHeapUsed
type: 0
i18n:
zh-CN: JVM 已使用的非堆内存大小
en-US: JVM NonHeap Used
ja-JP: Java仮想マシンが使用したノンヒープメモリのサイズ
- field: jvmHeapMax
type: 0
i18n:
zh-CN: JVM 配置的最大堆内存大小
en-US: JVM Heap Max
ja-JP: Java仮想マシンのヒープメモリの最大値
- field: jvmNonHeapMax
type: 0
i18n:
zh-CN: JVM 配置的最大非堆内存大小
en-US: JVM NonHeap Max
ja-JP: Java仮想マシンのノンヒープメモリの最大値
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
aliasFields:
- $.heartBeatInfo
@@ -545,7 +490,6 @@ metrics:
i18n:
zh-CN: 数据库
en-US: Database
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
@@ -557,31 +501,26 @@ metrics:
i18n:
zh-CN: 数据库类型
en-US: Database Type
ja-JP: データベースのタイプ
- field: state
type: 1
i18n:
zh-CN: 状态
en-US: State
ja-JP: 状態
- field: maxConnections
type: 0
i18n:
zh-CN: 最大连接数
en-US: Max Connections
ja-JP: 最大接続数
- field: threadsConnections
type: 0
i18n:
zh-CN: 当前连接数
en-US: Threads Connections
ja-JP: 現在接続数
- field: threadsRunningConnections
type: 0
i18n:
zh-CN: 当前活跃连接数
en-US: Threads Running Connections
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:
- dbType
@@ -62,7 +62,6 @@ params:
type: number
required: false
hide: true
defaultValue: 6000
- field: authType
name:
zh-CN: 认证方式
@@ -126,7 +125,7 @@ metrics:
zh-CN: 状态
en-US: Status
ja-JP: ステータス
- field: Size
- field: size
type: 0
i18n:
zh-CN: 数量
@@ -138,18 +137,6 @@ metrics:
zh-CN: 可用数量
en-US: Available Size
ja-JP: 利用可能なサイズ
aliasFields:
- $.app
- $.category
- $.status
- $.size
- $.availableSize
calculates:
- app=$.app
- category=$.category
- status=$.status
- Size=$.size
- availableSize=$.availableSize
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk, we use HTTP protocol here
protocol: http
# the config content when protocol is http
@@ -241,7 +228,7 @@ metrics:
priority: 1
fields:
- field: state
type: 1
type: 2
i18n:
zh-CN: 状态
en-US: State
@@ -160,7 +160,7 @@ metrics:
zh-CN: 状态
en-US: Status
ja-JP: ステータス
- field: Size
- field: size
type: 0
i18n:
zh-CN: 数量
@@ -172,18 +172,6 @@ metrics:
zh-CN: 可用数量
en-US: Available Size
ja-JP: 利用可能なサイズ
aliasFields:
- $.app
- $.category
- $.status
- $.size
- $.availableSize
calculates:
- app=$.app
- category=$.category
- status=$.status
- Size=$.size
- availableSize=$.availableSize
protocol: http
http:
host: ^_^host^_^
@@ -651,7 +651,7 @@ metrics:
zh-CN: 次数
en-US: Num
ja-JP: 数量
- field: Size
- field: size
type: 0
unit: B
i18n:
@@ -21,13 +21,11 @@ app: redis_sentinel
name:
zh-CN: Redis Sentinel
en-US: Redis Sentinel
ja-JP: Redis Sentinel
# The description and help of this monitoring type
help:
zh-CN: Hertzbeat 对 Redis Sentinel 的通用指标进行采集监控。<br>您可以点击 “<i>新建 Redis Sentinel</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
en-US: Hertzbeat monitors Redis Database Sentinel's general performance metrics. You could click the "<i>New Redis Sentinel</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: Hertzbeat 對 Redis Sentinel 的通用指標進行采集監控。<br>您可以點擊 “<i>新建 Redis Sentinel</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
ja-JP: Hertzbeat は Redis Sentinel の一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Redis Sentinel</i>」をクリックしてパラメタを設定した後、新規することができます。
zh-CN: Hertzbeat 对 Redis Sentinel 的通用指标进行采集监控。<br>您可以点击 “<i>新建 Redis Cluster</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
en-US: Hertzbeat monitors Redis Database Sentinel's general performance metrics. You could click the "<i>New Redis Cluster</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: Hertzbeat 對 Redis Sentinel 的通用指標進行采集監控。<br>您可以點擊 “<i>新建 Redis Cluster</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/influxdb_promql
en-US: https://hertzbeat.apache.org/docs/help/influxdb_promql
@@ -39,7 +37,6 @@ 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
@@ -49,7 +46,6 @@ 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
@@ -64,7 +60,6 @@ params:
name:
zh-CN: 查询超时时间(ms)
en-US: Query Timeout(ms)
ja-JP: クエリタイムアウト(ms)
# type-param field type(most mapping the html input type)
type: number
# when type is number, range is required
@@ -79,7 +74,6 @@ 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
@@ -92,7 +86,6 @@ 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
@@ -103,7 +96,6 @@ params:
name:
zh-CN: 模式
en-US: Pattern
ja-JP: パターン
# type-param field type(most mapping the html input type)
type: number
# required-true or false
@@ -116,7 +108,6 @@ params:
name:
zh-CN: 是否启用SSH隧道
en-US: Enable SSH Tunnel
ja-JP: SSHトンネルの有効化
type: boolean
required: true
hide: true
@@ -124,7 +115,6 @@ params:
name:
zh-CN: SSH Host
en-US: SSH Host
ja-JP: SSHホスト
type: text
required: false
placeholder: 'When Enable SSH Tunnel'
@@ -133,7 +123,6 @@ params:
name:
zh-CN: SSH端口
en-US: SSH Port
ja-JP: SSHポート
type: number
range: '[0,65535]'
required: false
@@ -144,7 +133,6 @@ params:
name:
zh-CN: SSH超时时间(ms)
en-US: SSH Timeout(ms)
ja-JP: SSHタイムアウト(ms)
type: number
required: false
range: '[400,200000]'
@@ -154,7 +142,6 @@ params:
name:
zh-CN: SSH用户名
en-US: SSH Username
ja-JP: SSHユーザー名
type: text
required: false
placeholder: 'When Enable SSH tunnel'
@@ -163,7 +150,6 @@ params:
name:
zh-CN: SSH密码
en-US: SSH Password
ja-JP: SSHパスワード
type: password
required: false
hide: true
@@ -171,7 +157,6 @@ params:
name:
zh-CN: 是否共享SSH连接
en-US: Share SSH Connection
ja-JP: SSH接続共有
type: boolean
required: true
defaultValue: true
@@ -180,7 +165,6 @@ params:
name:
zh-CN: SSH私钥
en-US: SSH PrivateKey
ja-JP: SSH秘密鍵
type: textarea
placeholder: -----BEGIN RSA PRIVATE KEY-----
required: false
@@ -189,7 +173,6 @@ params:
name:
zh-CN: SSH密钥短语
en-US: SSH PrivateKey PassPhrase
ja-JP: SSH秘密鍵フレーズ
type: password
required: false
hide: true
@@ -198,7 +181,6 @@ metrics:
i18n:
zh-CN: 服务器
en-US: Server
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
@@ -209,145 +191,121 @@ metrics:
i18n:
zh-CN: 标识
en-US: Identity
ja-JP: ID
- field: redis_version
type: 1
i18n:
zh-CN: Redis 版本
en-US: Redis Version
ja-JP: Redisバージョン
- field: redis_git_sha1
type: 0
i18n:
zh-CN: Redis Git SHA1
en-US: Redis Git SHA1
ja-JP: Redis Git SHA1
- field: redis_git_dirty
type: 0
i18n:
zh-CN: Redis Git Dirty
en-US: Redis Git Dirty
ja-JP: RedisサーバーのGitリポジトリ状態
- field: redis_build_id
type: 1
i18n:
zh-CN: Redis Build ID
en-US: Redis Build ID
ja-JP: Redis ビルド Id
- field: redis_mode
type: 1
i18n:
zh-CN: Redis 模式
en-US: Redis Mode
ja-JP: Redis モード
- field: os
type: 1
i18n:
zh-CN: 操作系统
en-US: Operating System
ja-JP: オーエス
- field: arch_bits
type: 0
i18n:
zh-CN: 架构位数
en-US: Architecture Bits
ja-JP: アーキテクチャ
- field: multiplexing_api
type: 1
i18n:
zh-CN: 多路复用 API
en-US: Multiplexing API
ja-JP: IO多重化API
- field: atomicvar_api
type: 1
i18n:
zh-CN: 原子变量 API
en-US: Atomicvar API
ja-JP: 原子操作API
- field: gcc_version
type: 1
i18n:
zh-CN: GCC 版本
en-US: GCC Version
ja-JP: GCC バージョン
- field: process_id
type: 0
i18n:
zh-CN: 进程 ID
en-US: Process ID
ja-JP: プロセスID
- field: process_supervised
type: 1
i18n:
zh-CN: 进程监控
en-US: Process Supervised
ja-JP: プロセスの監視方法
- field: run_id
type: 1
i18n:
zh-CN: 运行 ID
en-US: Run ID
ja-JP: Run ID
- field: tcp_port
type: 0
i18n:
zh-CN: TCP 端口
en-US: TCP Port
ja-JP: TCP ポート
- field: server_time_usec
type: 0
i18n:
zh-CN: 基于纪元的系统时间
en-US: Server Time Usec
ja-JP: サーバーのタイムスタンプ
- field: uptime_in_seconds
type: 0
i18n:
zh-CN: 运行时间(秒)
en-US: Uptime In Seconds
ja-JP: アップタイム(秒)
- field: uptime_in_days
type: 0
i18n:
zh-CN: 运行时间(天)
en-US: Uptime In Days
ja-JP: アップタイム(日)
- field: hz
type: 0
i18n:
zh-CN: 定时器频率
en-US: Hz
ja-JP: イベントの実行頻度
- field: configured_hz
type: 0
i18n:
zh-CN: 配置定时器频率
en-US: Configured Hz
ja-JP: 設定されたイベントの実行頻度
- field: lru_clock
type: 0
i18n:
zh-CN: LRU 时钟
en-US: LRU Clock
ja-JP: LRU クロック
- field: executable
type: 1
i18n:
zh-CN: 可执行文件
en-US: Executable
ja-JP: サーバーの実行パス
- field: config_file
type: 1
i18n:
zh-CN: 配置文件
en-US: Config File
ja-JP: 設定されたサーバーの実行ファイル
- field: io_threads_active
type: 0
i18n:
zh-CN: 活动 IO 线程
en-US: IO Threads Active
ja-JP: 活動中のスレッド数
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: redis
# the config content when protocol is redis
@@ -378,7 +336,6 @@ metrics:
i18n:
zh-CN: 客户端
en-US: Clients
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
@@ -389,49 +346,41 @@ metrics:
i18n:
zh-CN: 已连接客户端
en-US: Connected Clients
ja-JP: 現在接続されているクライアントの数
- field: cluster_connections
type: 0
i18n:
zh-CN: 集群连接
en-US: Cluster Connections
ja-JP: クラスター内の接続数
- field: maxclients
type: 0
i18n:
zh-CN: 最大客户端数
en-US: Maxclients
ja-JP: 最大クライアント数
- field: client_recent_max_input_buffer
type: 0
i18n:
zh-CN: 客户端最近最大输入缓冲区
en-US: Client Recent Max Input Buffer
ja-JP: クライアントの最近の最大入力バッファサイズ
- field: client_recent_max_output_buffer
type: 0
i18n:
zh-CN: 客户端最近最大输出缓冲区
en-US: Client Recent Max Output Buffer
ja-JP: クライアントの最近の最大出力バッファサイズ
- field: blocked_clients
type: 0
i18n:
zh-CN: 阻塞客户端
en-US: Blocked Clients
ja-JP: ブロックされたクライアント数
- field: tracking_clients
type: 0
i18n:
zh-CN: 跟踪客户端
en-US: Tracking Clients
ja-JP: トラッキングを使用するクライアントの数
- field: clients_in_timeout_table
type: 0
i18n:
zh-CN: 超时表中的客户端
en-US: Clients In Timeout Table
ja-JP: タイムアウトテーブル内のクライアント数
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: redis
# the config content when protocol is redis
@@ -462,7 +411,6 @@ metrics:
i18n:
zh-CN: 统计
en-US: Stats
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
@@ -473,229 +421,191 @@ metrics:
i18n:
zh-CN: 收到总连接数
en-US: Total Connections Received
ja-JP: サーバーの起動後に受信された合計接続数
- field: total_commands_processed
type: 0
i18n:
zh-CN: 处理总命令数
en-US: Total Commands Processed
ja-JP: サーバーの起動後に処理した総コマンド数
- field: instantaneous_ops_per_sec
type: 0
i18n:
zh-CN: 瞬时每秒操作数
en-US: Instantaneous Ops Per Sec
ja-JP: 1秒当たりに処理されたコマンドの数
- field: total_net_input_bytes
type: 0
i18n:
zh-CN: 总网络输入字节
en-US: Total Net Input Bytes
ja-JP: 受信されたネットワークバイトの合計数
- field: total_net_output_bytes
type: 0
i18n:
zh-CN: 总网络输出字节
en-US: Total Net Output Bytes
ja-JP: 転送されたネットワークバイトの合計数
- field: instantaneous_input_kbps
type: 0
i18n:
zh-CN: 瞬时的输入 kbps
en-US: Instantaneous Input Kbps
ja-JP: 瞬間入力速度(kbps)
- field: instantaneous_output_kbps
type: 0
i18n:
zh-CN: 瞬时输出 kbps
en-US: Instantaneous Output Kbps
ja-JP: 瞬間出力速度(kbps)
- field: rejected_connections
type: 0
i18n:
zh-CN: 拒绝连接数
en-US: Rejected Connections
ja-JP: maxclients制限で拒否された接続数
- field: sync_full
type: 0
i18n:
zh-CN: 全量同步
en-US: Sync Full
ja-JP: 完全同期の回数
- field: sync_partial_ok
type: 0
i18n:
zh-CN: 部分同步成功
en-US: Sync Partial Ok
ja-JP: 部分同期の回数
- field: sync_partial_err
type: 0
i18n:
zh-CN: 部分同步失败
en-US: Sync Partial Err
ja-JP: 部分同期のエラー回数
- field: expired_keys
type: 0
i18n:
zh-CN: 过期键
en-US: Expired Keys
ja-JP: expireコマンドで削除されたキーの数
- field: expired_stale_perc
type: 0
i18n:
zh-CN: 过期key占比
en-US: Expired Stale Perc
ja-JP: 期限切れのステイルキーの比率
- field: expired_time_cap_reached_count
type: 0
i18n:
zh-CN: 达到过期时间上限计数
en-US: Expired Time Cap Reached Count
ja-JP: 満了時間の制限に達した回数
- field: expire_cycle_cpu_milliseconds
type: 0
i18n:
zh-CN: 过期周期 CPU 毫秒
en-US: Expire Cycle CPU Milliseconds
ja-JP: 満了サイクルでかかったCPU時間(ms)
- field: evicted_keys
type: 0
i18n:
zh-CN: 逐出键
en-US: Evicted Keys
ja-JP: メモリ不足で追放されたキーの数
- field: keyspace_hits
type: 0
i18n:
zh-CN: 命中键
en-US: Keyspace Hits
ja-JP: キースペースのヒット数
- field: keyspace_misses
type: 0
i18n:
zh-CN: 未命中键
en-US: Keyspace Misses
ja-JP: キースペースのミス数
- field: pubsub_channels
type: 0
i18n:
zh-CN: 发布订阅频道
en-US: Pubsub Channels
ja-JP: 有効になっているPub/Subチャネルに接続されているチャネルの数
- field: pubsub_patterns
type: 0
i18n:
zh-CN: 发布订阅模式
en-US: Pubsub Patterns
ja-JP: 有効になっているPub/Subパターンで接続されたパターンチャネルの数
- field: latest_fork_usec
type: 0
i18n:
zh-CN: 最新 fork 毫秒
en-US: Latest Fork Usec
ja-JP: 最後のフォーク作業にかかった時間
- field: total_forks
type: 0
i18n:
zh-CN: 总 fork 数
en-US: Total Forks
ja-JP: 実行されたフォーク作業の合計数
- field: migrate_cached_sockets
type: 0
i18n:
zh-CN: 迁移缓存套接字
en-US: Migrate Cached Sockets
ja-JP: マイグレーションされたソケット数
- field: slave_expires_tracked_keys
type: 0
i18n:
zh-CN: 从节点过期跟踪键
en-US: Slave Expires Tracked Keys
ja-JP: スレーブで満了した、トラッキングされたキーの数
- field: active_defrag_hits
type: 0
i18n:
zh-CN: 活跃碎片整理命中
en-US: Active Defrag Hits
ja-JP: アクティブなデフラグ操作中に発生したヒットの数
- field: active_defrag_misses
type: 0
i18n:
zh-CN: 活跃碎片整理未命中
en-US: Active Defrag Misses
ja-JP: アクティブなデフラグ操作中に見逃したヒットの数
- field: active_defrag_key_hits
type: 0
i18n:
zh-CN: 活跃碎片整理键命中
en-US: Active Defrag Key Hits
ja-JP: デフラグ操作でヒットしたキーの数
- field: active_defrag_key_misses
type: 0
i18n:
zh-CN: 活跃碎片整理键未命中
en-US: Active Defrag Key Misses
ja-JP: デフラグ操作で見逃したキーの数
- field: tracking_total_keys
type: 0
i18n:
zh-CN: 跟踪键总数
en-US: Tracking Total Keys
ja-JP: トラッキングされたキーの合計数
- field: tracking_total_items
type: 0
i18n:
zh-CN: 跟踪项总数
en-US: Tracking Total Items
ja-JP: トラッキングされたアイテムの合計数
- field: tracking_total_prefixes
type: 0
i18n:
zh-CN: 跟踪前缀总数
en-US: Tracking Total Prefixes
ja-JP: トラッキングされたプレフィックスの合計数
- field: unexpected_error_replies
type: 0
i18n:
zh-CN: 意外错误回复
en-US: Unexpected Error Replies
ja-JP: 予期しないエラー応答の数
- field: total_error_replies
type: 0
i18n:
zh-CN: 总错误回复
en-US: Total Error Replies
ja-JP: 発生したエラーの合計応答の数
- field: dump_payload_sanitizations
type: 0
i18n:
zh-CN: 转储有效负载深度完整性验证的总数
en-US: Dump Payload Sanitizations
ja-JP: ダンプペイロードで実行された整理作業の数
- field: total_reads_processed
type: 0
i18n:
zh-CN: 总读取处理
en-US: Total Reads Processed
ja-JP: 処理された読み取り作業の合計数
- field: total_writes_processed
type: 0
i18n:
zh-CN: 总写入处理
en-US: Total Writes Processed
ja-JP: 処理された書き込み作業の合計数
- field: io_threaded_reads_processed
type: 0
i18n:
zh-CN: IO 线程读取处理
en-US: Io Threaded Reads Processed
ja-JP: I/Oスレッドで処理された読み取り作業の数
- field: io_threaded_writes_processed
type: 0
i18n:
zh-CN: IO 线程写入处理
en-US: Io Threaded Writes Processed
ja-JP: I/Oスレッドで処理された書き込み作業の数
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: redis
# the config content when protocol is redis
@@ -726,7 +636,6 @@ metrics:
i18n:
zh-CN: CPU
en-US: CPU
ja-JP: CPU情報
# 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: 3
@@ -737,37 +646,31 @@ metrics:
i18n:
zh-CN: 系统已使用 CPU
en-US: Sys CPU Used
ja-JP: システムモードで使用されたCPUの合計時間
- field: used_cpu_user
type: 0
i18n:
zh-CN: 用户已使用 CPU
en-US: User CPU Used
ja-JP: ユーザーモードで使用されたCPUの合計時間
- field: used_cpu_sys_children
type: 0
i18n:
zh-CN: Sys 子进程已使用 CPU
en-US: Sys Children CPU Used
ja-JP: 子プロセスがシステムモードで使用したCPU時間
- field: used_cpu_user_children
type: 0
i18n:
zh-CN: 用户子进程已使用 CPU
en-US: User Children CPU Used
ja-JP: 子プロセスがユーザーモードで使用したCPU時間
- field: used_cpu_sys_main_thread
type: 0
i18n:
zh-CN: 系统主线程已使用 CPU
en-US: Sys Main Thread CPU Used
ja-JP: プロセスがシステムモードで使用したCPU時間
- field: used_cpu_user_main_thread
type: 0
i18n:
zh-CN: 用户主线程已使用 CPU
en-US: User Main Thread CPU Used
ja-JP: プロセスがユーザーモードで使用したCPU時間
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: redis
# the config content when protocol is redis
@@ -798,7 +701,6 @@ metrics:
i18n:
zh-CN: 哨兵
en-US: Sentinel
ja-JP: Sentinel
# 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: 4
@@ -809,31 +711,26 @@ metrics:
i18n:
zh-CN: 主节点
en-US: Masters
ja-JP: マスターノード
- field: sentinel_tilt
type: 1
i18n:
zh-CN: 倾斜
en-US: Tilt
ja-JP: マスターをダウン状態としてマークする前の待機時間
- field: sentinel_running_scripts
type: 1
i18n:
zh-CN: 运行脚本
en-US: Running Scripts
ja-JP: 実行するスクリプト
- field: sentinel_scripts_queue_length
type: 1
i18n:
zh-CN: 脚本队列长度
en-US: Scripts Queue Length
ja-JP: 実行するスクリプトのキューの長さ
- field: sentinel_simulate_failure_flags
type: 1
i18n:
zh-CN: 模拟失败标志
en-US: Simulate Failure Flags
ja-JP: フェイルオーバー機能をテスト用のフラグ
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: redis
# the config content when protocol is redis
@@ -19,15 +19,15 @@ category: mid
app: spring_gateway
# The monitoring i18n name
name:
zh-CN: Spring Cloud Gateway
en-US: Spring Cloud Gateway
ja-JP: Spring Cloud Gateway
zh-CN: SpringGateway
en-US: SpringGateway
ja-JP: SpringGateway
# The description and help of this monitoring type
help:
zh-CN: HertzBeat 对 <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a> 暴露的通用性能指标(globalfilters、routefilters、refresh、routes)进行采集监控。<span class='help_module_span'>注意⚠️:如果要监控 Spring Cloud Gateway 中的信息,需要您的 Spring Cloud Gateway 应用集成并开启 SpringBoot Actuator, <a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>点击查看具体步骤</a>。</span>
en-US: HertzBeat collect and monitors SpringGateway through general performance metric that exposed by the SpringBoot Actuator. <br><span class='help_module_span'><br>Note⚠️:You should make sure that your Spring Cloud Gateway application have already integrated and enabled the SpringBoot Actuator, <a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>click here to see the specific steps.</a></span>
zh-TW: HertzBeat 對 <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a>暴露的通用性能指標(globalfilters、routefilters、refresh、routes)進行採集監控。<span class='help_module_span'>注意⚠️:如果要監控 Spring Cloud Gateway 中的指標,需要您的 Spring Cloud Gateway 應用集成並開啟SpringBoot Actuator<a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>點擊查看具體步驟</a>。</span>
ja-JP: HertzBeat は <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a> の一般的なパフォーマンスのメトリクスを監視します。<span class='help_module_span'>⚠️注意:Spring Cloud Gateway で SpringBoot Actuatorを有効にする必要があります。<a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>クリックしてガイドを見ます</a>。</span>
zh-CN: HertzBeat 对 <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a> 暴露的通用性能指标(globalfilters、routefilters、refresh、routes)进行采集监控。<span class='help_module_span'>注意⚠️:如果要监控 SpringGateway 中的信息,需要您的 SpringGateway 应用集成并开启 SpringBoot Actuator, <a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>点击查看具体步骤</a>。</span>
en-US: HertzBeat collect and monitors SpringGateway through general performance metric that exposed by the SpringBoot Actuator. <br><span class='help_module_span'><br>Note⚠️:You should make sure that your SpringGateway application have already integrated and enabled the SpringBoot Actuator, <a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>click here to see the specific steps.</a></span>
zh-TW: HertzBeat 對 <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a>暴露的通用性能指標(globalfilters、routefilters、refresh、routes)進行採集監控。<span class='help_module_span'>注意⚠️:如果要監控SpringGateway中的指標,需要您的SpringGateway應用集成並開啟SpringBoot Actuator<a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>點擊查看具體步驟</a>。</span>
ja-JP: HertzBeat は <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a> の一般的なパフォーマンスのメトリクスを監視します。<span class='help_module_span'>⚠️注意:SpringGateway で SpringBoot Actuatorを有効にする必要があります。<a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>クリックしてガイドを見ます</a>。</span>
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/spring_gateway
en-US: https://hertzbeat.apache.org/docs/help/spring_gateway
@@ -284,7 +284,7 @@ metrics:
en-US: State
ja-JP: 状態
label: true
- field: Size
- field: size
type: 0
i18n:
zh-CN: 数量
@@ -294,7 +294,7 @@ metrics:
- $.measurements[?(@.statistic == "VALUE")].value
calculates:
- state='^o^state^o^'
- Size=$.measurements[?(@.statistic == "VALUE")].value
- size=$.measurements[?(@.statistic == "VALUE")].value
protocol: http
http:
host: ^_^host^_^
@@ -316,7 +316,7 @@ metrics:
type: 0
i18n:
zh-CN: 编号
en-US: Index
en-US: 编号
- field: hrSWInstalledName
type: 1
i18n:
@@ -357,14 +357,14 @@ metrics:
type: 0
i18n:
zh-CN: 编号
en-US: Index
en-US: 编号
- field: descr
type: 1
i18n:
zh-CN: 存储描述
en-US: Storage Description
label: true
- field: Size
- field: size
i18n:
zh-CN: 存储大小
en-US: Storage Size
@@ -400,7 +400,7 @@ metrics:
calculates:
- index=hrStorageIndex
- descr=hrStorageDescr
- Size=hrStorageSize * hrStorageAllocationUnits
- size=hrStorageSize * hrStorageAllocationUnits
- free=(hrStorageSize - hrStorageUsed) * hrStorageAllocationUnits
- used=hrStorageUsed * hrStorageAllocationUnits
- usage= hrStorageUsed / hrStorageSize * 100
@@ -29,6 +29,7 @@ import org.apache.hertzbeat.manager.dao.CollectorDao;
import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
import org.apache.hertzbeat.manager.dao.MonitorDao;
import org.apache.hertzbeat.manager.dao.ParamDao;
import org.apache.hertzbeat.manager.pojo.CollectorNode;
import org.apache.hertzbeat.manager.scheduler.netty.ManageServer;
import org.apache.hertzbeat.manager.service.AppService;
import org.junit.jupiter.api.BeforeEach;
@@ -63,7 +64,7 @@ public class CollectorJobSchedulerTest {
@InjectMocks
private CollectorJobScheduler collectorJobScheduler;
@Mock
private ConsistentHash consistentHash;
private ConsistentHashCollectorKeeper consistentHashCollectorKeeper;
@Mock
private CollectorDao collectorDao;
@Mock
@@ -85,8 +86,8 @@ public class CollectorJobSchedulerTest {
public void testCollectSyncJobData() {
assertDoesNotThrow(() -> {
Job job = new Job();
when(consistentHash.preDispatchJob(any(String.class))).thenReturn(null);
List<?> list = collectorJobScheduler.collectSyncJobData(job);
when(consistentHashCollectorKeeper.determineNode(any(Long.class))).thenReturn(null);
List<?> list = collectorJobScheduler.collectSyncJobData(job, null);
assertEquals(1, list.size());
});
}
@@ -127,9 +128,8 @@ public class CollectorJobSchedulerTest {
appDefine.setParams(Collections.emptyList());
when(appService.getAppDefine(anyString())).thenReturn(appDefine);
ConsistentHash.Node node = new ConsistentHash.Node(identity, collector.getMode(),
collector.getIp(), System.currentTimeMillis(), null);
when(consistentHash.getNode("collector-1")).thenReturn(node);
CollectorNode node = new CollectorNode(identity, collector.getMode(), collector.getIp(), System.currentTimeMillis(), null);
when(consistentHashCollectorKeeper.addJob(appDefine, identity)).thenReturn(node);
ManageServer manageServer = mock(ManageServer.class);
collectorJobScheduler.setManageServer(manageServer);
@@ -138,7 +138,7 @@ public class CollectorJobSchedulerTest {
// Capture the parameters of sendMsg
ArgumentCaptor<ClusterMsg.Message> msgCaptor = ArgumentCaptor.forClass(ClusterMsg.Message.class);
verify(manageServer, atLeastOnce()).sendMsg(eq("collector-1"), msgCaptor.capture());
verify(manageServer, atLeastOnce()).sendMsg(eq(identity), msgCaptor.capture());
ClusterMsg.Message message = msgCaptor.getValue();
Job job = JsonUtil.fromJson(message.getMsg().toStringUtf8(), Job.class);
@@ -0,0 +1,101 @@
/*
* 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.manager.scheduler;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.hertzbeat.common.constants.CollectorStatus;
import org.apache.hertzbeat.common.entity.job.Job;
import org.apache.hertzbeat.common.util.SnowFlakeIdGenerator;
import org.apache.hertzbeat.manager.pojo.CollectorNode;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test case for {@link ConsistentHashCollectorKeeper}
*/
public class ConsistentHashCollectorKeeperTest {
private ConsistentHashCollectorKeeper consistentHashCollectorKeeper;
@BeforeEach
void setUp() {
consistentHashCollectorKeeper = new ConsistentHashCollectorKeeper();
}
@Test
void testAddNode() {
long jobId1 = SnowFlakeIdGenerator.generateId();
long jobId2 = SnowFlakeIdGenerator.generateId();
long jobId3 = SnowFlakeIdGenerator.generateId();
CollectorNode node1 = new CollectorNode("node1", "public", "192.168.0.1", System.currentTimeMillis(), (byte) 10);
CollectorNode node2 = new CollectorNode("node2", "public", "192.168.0.2", System.currentTimeMillis(), (byte) 10);
consistentHashCollectorKeeper.addNode(node1);
consistentHashCollectorKeeper.determineNode(jobId1);
consistentHashCollectorKeeper.determineNode(jobId2);
consistentHashCollectorKeeper.determineNode(jobId3);
consistentHashCollectorKeeper.addNode(node2);
assertTrue(node2.getAssignJobs().getAddingJobs().containsAll(node1.getAssignJobs().getRemovingJobs()));
assertTrue(node2.getAssignJobs().getAddingJobs().containsAll(node2.getAssignJobs().getRemovingJobs()));
assertSame(consistentHashCollectorKeeper.getNode("node1"), node1);
assertSame(consistentHashCollectorKeeper.getNode("node2"), node2);
}
@Test
void testDispatchJob() {
long jobId1 = SnowFlakeIdGenerator.generateId();
CollectorNode res1 = consistentHashCollectorKeeper.determineNode(jobId1);
assertNull(res1);
CollectorNode node1 = new CollectorNode("node1", "public", "192.168.0.1", System.currentTimeMillis(), (byte) 10);
consistentHashCollectorKeeper.addNode(node1);
long jobId2 = SnowFlakeIdGenerator.generateId();
CollectorNode res2 = consistentHashCollectorKeeper.determineNode(jobId2);
assertSame(res2, node1);
assertTrue(consistentHashCollectorKeeper.getDispatchJobCache().isEmpty());
}
@Test
void testRemoveNode() {
CollectorNode node1 = new CollectorNode("node1", "public", "192.168.0.1", System.currentTimeMillis(), (byte) 10);
CollectorNode node2 = new CollectorNode("node2", "public", "192.168.0.2", System.currentTimeMillis(), (byte) 10);
consistentHashCollectorKeeper.addNode(node1);
consistentHashCollectorKeeper.addNode(node2);
long jobId1 = SnowFlakeIdGenerator.generateId();
long jobId2 = SnowFlakeIdGenerator.generateId();
long jobId3 = SnowFlakeIdGenerator.generateId();
long jobId4 = SnowFlakeIdGenerator.generateId();
consistentHashCollectorKeeper.addJob(Job.builder().id(jobId1).monitorId(jobId1).build(), null);
consistentHashCollectorKeeper.addJob(Job.builder().id(jobId2).monitorId(jobId2).build(), null);
consistentHashCollectorKeeper.addJob(Job.builder().id(jobId3).monitorId(jobId3).build(), null);
consistentHashCollectorKeeper.addJob(Job.builder().id(jobId4).monitorId(jobId4).build(), null);
consistentHashCollectorKeeper.changeStatus(node2.getIdentity(), CollectorStatus.OFFLINE);
assertTrue(node1.getAssignJobs().getAddingJobs().containsAll(node2.getAssignJobs().getRemovingJobs()));
assertSame(consistentHashCollectorKeeper.getNode("node1"), node1);
assertNull(consistentHashCollectorKeeper.getNode("node2"));
consistentHashCollectorKeeper.changeStatus(node1.getIdentity(), CollectorStatus.OFFLINE);
assertEquals(4, consistentHashCollectorKeeper.getDispatchJobCache().size());
}
}
@@ -1,100 +0,0 @@
/*
* 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.manager.scheduler;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.hertzbeat.common.util.SnowFlakeIdGenerator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test case for {@link ConsistentHash}
*/
public class ConsistentHashTest {
private ConsistentHash consistentHash;
@BeforeEach
void setUp() {
consistentHash = new ConsistentHash();
}
@Test
void testAddNode() {
String job1 = "job1";
long jobId1 = SnowFlakeIdGenerator.generateId();
String job2 = "job2";
long jobId2 = SnowFlakeIdGenerator.generateId();
String job3 = "job3";
long jobId3 = SnowFlakeIdGenerator.generateId();
ConsistentHash.Node node1 = new ConsistentHash.Node("node1", "public", "192.168.0.1", System.currentTimeMillis(), (byte) 10);
ConsistentHash.Node node2 = new ConsistentHash.Node("node2", "public", "192.168.0.2", System.currentTimeMillis(), (byte) 10);
consistentHash.addNode(node1);
consistentHash.dispatchJob(job1, jobId1);
consistentHash.dispatchJob(job2, jobId2);
consistentHash.dispatchJob(job3, jobId3);
consistentHash.addNode(node2);
assertTrue(node2.getAssignJobs().getAddingJobs().containsAll(node1.getAssignJobs().getRemovingJobs()));
assertTrue(node2.getAssignJobs().getAddingJobs().containsAll(node2.getAssignJobs().getRemovingJobs()));
assertSame(consistentHash.getNode("node1"), node1);
assertSame(consistentHash.getNode("node2"), node2);
}
@Test
void testDispatchJob() {
String job1 = "job1";
long jobId1 = SnowFlakeIdGenerator.generateId();
ConsistentHash.Node res1 = consistentHash.dispatchJob(job1, jobId1);
assertNull(res1);
ConsistentHash.Node node1 = new ConsistentHash.Node("node1", "public", "192.168.0.1", System.currentTimeMillis(), (byte) 10);
consistentHash.addNode(node1);
String job2 = "job2";
long jobId2 = SnowFlakeIdGenerator.generateId();
ConsistentHash.Node res2 = consistentHash.dispatchJob(job2, jobId2);
assertSame(res2, node1);
assertTrue(consistentHash.getDispatchJobCache().isEmpty());
}
@Test
void testRemoveNode() {
String job1 = "job1";
long jobId1 = SnowFlakeIdGenerator.generateId();
String job2 = "job2";
long jobId2 = SnowFlakeIdGenerator.generateId();
String job3 = "job3";
long jobId3 = SnowFlakeIdGenerator.generateId();
ConsistentHash.Node node1 = new ConsistentHash.Node("node1", "public", "192.168.0.1", System.currentTimeMillis(), (byte) 10);
ConsistentHash.Node node2 = new ConsistentHash.Node("node2", "public", "192.168.0.2", System.currentTimeMillis(), (byte) 10);
consistentHash.addNode(node1);
consistentHash.addNode(node2);
consistentHash.dispatchJob(job1, jobId1);
consistentHash.dispatchJob(job2, jobId2);
consistentHash.dispatchJob(job3, jobId3);
consistentHash.removeNode(node2.getIdentity());
assertTrue(node1.getAssignJobs().getAddingJobs().containsAll(node2.getAssignJobs().getRemovingJobs()));
assertSame(consistentHash.getNode("node1"), node1);
assertNull(consistentHash.getNode("node2"));
consistentHash.removeNode(node1.getIdentity());
assertEquals(3, consistentHash.getDispatchJobCache().size());
}
}
@@ -32,7 +32,7 @@ import org.apache.hertzbeat.common.entity.manager.Collector;
import org.apache.hertzbeat.common.support.exception.CommonException;
import org.apache.hertzbeat.manager.dao.CollectorDao;
import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
import org.apache.hertzbeat.manager.scheduler.ConsistentHash;
import org.apache.hertzbeat.manager.scheduler.ConsistentHashCollectorKeeper;
import org.apache.hertzbeat.manager.scheduler.netty.ManageServer;
import org.apache.hertzbeat.manager.service.impl.CollectorServiceImpl;
import org.junit.jupiter.api.Test;
@@ -60,7 +60,7 @@ public class CollectorServiceTest {
private CollectorDao collectorDao;
@Mock
private ConsistentHash consistentHash;
private ConsistentHashCollectorKeeper consistentHashCollectorKeeper;
@Mock
private CollectorMonitorBindDao collectorMonitorBindDao;
@@ -46,7 +46,7 @@ import org.apache.hertzbeat.manager.dao.MonitorDao;
import org.apache.hertzbeat.manager.dao.ParamDao;
import org.apache.hertzbeat.manager.pojo.dto.AppCount;
import org.apache.hertzbeat.manager.pojo.dto.MonitorDto;
import org.apache.hertzbeat.manager.scheduler.CollectJobScheduling;
import org.apache.hertzbeat.manager.scheduler.CollectorJobScheduler;
import org.apache.hertzbeat.manager.service.impl.MonitorServiceImpl;
import org.apache.hertzbeat.manager.support.exception.MonitorDatabaseException;
import org.apache.hertzbeat.manager.support.exception.MonitorDetectException;
@@ -105,7 +105,7 @@ class MonitorServiceTest {
private LabelService tagService;
@Mock
private CollectJobScheduling collectJobScheduling;
private CollectorJobScheduler jobOperation;
@Mock
private AlertDefineBindDao alertDefineBindDao;
@@ -143,7 +143,7 @@ class MonitorServiceTest {
when(appService.getAppDefine(monitor.getApp())).thenReturn(job);
List<CollectRep.MetricsData> collectRep = new ArrayList<>();
when(collectJobScheduling.collectSyncJobData(job)).thenReturn(collectRep);
when(jobOperation.collectSyncJobData(job, null)).thenReturn(collectRep);
List<Param> params = Collections.singletonList(new Param());
assertThrows(MonitorDetectException.class, () -> monitorService.detectMonitor(monitor, params, null));
@@ -170,7 +170,7 @@ class MonitorServiceTest {
CollectRep.MetricsData failCode = CollectRep.MetricsData.newBuilder()
.setCode(CollectRep.Code.TIMEOUT).setMsg("collect timeout").build();
collectRep.add(failCode);
when(collectJobScheduling.collectSyncJobData(job)).thenReturn(collectRep);
when(jobOperation.collectSyncJobData(job, null)).thenReturn(collectRep);
List<Param> params = Collections.singletonList(new Param());
assertThrows(MonitorDetectException.class, () -> monitorService.detectMonitor(monitor, params, null));
@@ -186,7 +186,7 @@ class MonitorServiceTest {
.build();
Job job = new Job();
when(appService.getAppDefine(monitor.getApp())).thenReturn(job);
when(collectJobScheduling.addAsyncCollectJob(job, null)).thenReturn(1L);
when(jobOperation.addAsyncCollectJob(job, null)).thenReturn(1L);
when(monitorDao.save(monitor)).thenReturn(monitor);
List<Param> params = Collections.singletonList(new Param());
when(paramDao.saveAll(params)).thenReturn(params);
@@ -203,7 +203,7 @@ class MonitorServiceTest {
.build();
Job job = new Job();
when(appService.getAppDefine(monitor.getApp())).thenReturn(job);
when(collectJobScheduling.addAsyncCollectJob(job, null)).thenReturn(1L);
when(jobOperation.addAsyncCollectJob(job, null)).thenReturn(1L);
List<Param> params = Collections.singletonList(new Param());
when(monitorDao.save(monitor)).thenThrow(RuntimeException.class);
assertThrows(MonitorDatabaseException.class, () -> monitorService.addMonitor(monitor, params, null, null));
+1 -1
View File
@@ -22,7 +22,7 @@ We warmly welcome everyone to join the HertzBeat community. The community accept
## What is HertzBeat
[Apache HertzBeat](https://github.com/apache/hertzbeat) is an easy-to-use, open source, real-time monitoring system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
[Apache HertzBeat](https://github.com/apache/hertzbeat) (incubating) is an easy-to-use, open source, real-time monitoring system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
### Features
+3 -3
View File
@@ -8,9 +8,9 @@ tags: [opensource, practice]
keywords: [open source, monitoring, alerting]
---
**Hi guys, We are excited to announce that Apache HertzBeat has released its first Apache version v1.6.0! 🎉.**
**Hi guys, We are excited to announce that Apache HertzBeat (incubating) has released its first Apache version v1.6.0! 🎉.**
Through nearly five months of community development iteration and two months of Apache Incubator incubation process, Apache HertzBeat v1.6.0 is finally out.
Through nearly five months of community development iteration and two months of Apache Incubator incubation process, Apache HertzBeat (incubating) v1.6.0 is finally out.
In this version, we added monitoring for OpenAi, Redfish protocol servers, plugin mechanism, and support for NebulaGraph, Apache Yarn, HDFS, Hbase, Storm, and more functional features.
Due to license compatibility issues, we replaced multiple dependencies at the bottom layer, Hibernate -> EclipseLink, which is also a rare migration pitfall practice in the JPA ecosystem.
At the same time, some bugs were fixed and some functions were optimized, and more complete documents. Welcome everyone to try to use, put forward valuable opinions and suggestions, and promote the development of HertzBeat together.
@@ -23,7 +23,7 @@ Upgrade Guide: <https://hertzbeat.apache.org/blog/2024/06/11/hertzbeat-v1.6.0-up
## What is HertzBeat?
[Apache HertzBeat](https://github.com/apache/hertzbeat) is an easy-to-use, open source, real-time monitoring system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
[Apache HertzBeat](https://github.com/apache/hertzbeat) (incubating) is an easy-to-use, open source, real-time monitoring system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
## Features
+1 -1
View File
@@ -4,7 +4,7 @@ title: Quick Tutorial Customize and adapt a monitoring based on HTTP protocol
sidebar_label: Tutorial Case
---
Through this tutorial, we describe step by step how to customize and adapt a monitoring type based on the http protocol under the Apache HertzBeat.
Through this tutorial, we describe step by step how to customize and adapt a monitoring type based on the http protocol under the Apache HertzBeat (incubating).
Before reading this tutorial, we hope that you are familiar with how to customize types, metrics, protocols, etc. from [Custom Monitoring](extend-point) and [Http Protocol Customization](extend-http).
+41 -41
View File
@@ -213,9 +213,9 @@ mvn clean package -Pcluster
The release package are here:
- `dist/apache-hertzbeat-{version}-bin.tar.gz`
- `dist/apache-hertzbeat-collector-{version}-bin.tar.gz`
- `dist/apache-hertzbeat-{version}-docker-compose.tar.gz`
- `dist/apache-hertzbeat-{version}-incubating-bin.tar.gz`
- `dist/apache-hertzbeat-collector-{version}-incubating-bin.tar.gz`
- `dist/apache-hertzbeat-{version}-incubating-docker-compose.tar.gz`
#### 3.4 Package the source code
@@ -224,12 +224,12 @@ The release package are here:
```shell
git archive \
--format=tar.gz \
--output="dist/apache-hertzbeat-1.6.0-src.tar.gz" \
--prefix=apache-hertzbeat-1.6.0-src/ \
--output="dist/apache-hertzbeat-1.6.0-incubating-src.tar.gz" \
--prefix=apache-hertzbeat-1.6.0-incubating-src/ \
release-1.6.0-rc1
```
The archive package is here `dist/apache-hertzbeat-1.6.0-src.tar.gz`
The archive package is here `dist/apache-hertzbeat-1.6.0-incubating-src.tar.gz`
### Sign package
@@ -252,18 +252,18 @@ for i in *.tar.gz; do echo $i; sha512sum $i > $i.sha512 ; done
> The final file list is as follows
```text
apache-hertzbeat-1.6.0-src.tar.gz
apache-hertzbeat-1.6.0-src.tar.gz.asc
apache-hertzbeat-1.6.0-src.tar.gz.sha512
apache-hertzbeat-1.6.0-bin.tar.gz
apache-hertzbeat-1.6.0-bin.tar.gz.asc
apache-hertzbeat-1.6.0-bin.tar.gz.sha512
apache-hertzbeat-1.6.0-docker-compose.tar.gz
apache-hertzbeat-1.6.0-docker-compose.tar.gz.asc
apache-hertzbeat-1.6.0-docker-compose.tar.gz.sha512
apache-hertzbeat-collector-1.6.0-bin.tar.gz
apache-hertzbeat-collector-1.6.0-bin.tar.gz.asc
apache-hertzbeat-collector-1.6.0-bin.tar.gz.sha512
apache-hertzbeat-1.6.0-incubating-src.tar.gz
apache-hertzbeat-1.6.0-incubating-src.tar.gz.asc
apache-hertzbeat-1.6.0-incubating-src.tar.gz.sha512
apache-hertzbeat-1.6.0-incubating-bin.tar.gz
apache-hertzbeat-1.6.0-incubating-bin.tar.gz.asc
apache-hertzbeat-1.6.0-incubating-bin.tar.gz.sha512
apache-hertzbeat-1.6.0-incubating-docker-compose.tar.gz
apache-hertzbeat-1.6.0-incubating-docker-compose.tar.gz.asc
apache-hertzbeat-1.6.0-incubating-docker-compose.tar.gz.sha512
apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz
apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz.asc
apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz.sha512
```
#### 3.6 Verify signature
@@ -274,15 +274,15 @@ $ cd dist
# Verify signature
$ for i in *.tar.gz; do echo $i; gpg --verify $i.asc $i ; done
apache-hertzbeat-1.6.0-src.tar.gz
apache-hertzbeat-1.6.0-incubating-src.tar.gz
gpg: Signature made Tue May 2 12:16:35 2023 CST
gpg: using RSA key 85778A4CE4DD04B7E07813ABACFB69E705016886
gpg: Good signature from "muchunjin (apache key) <muchunjin@apache.org>" [ultimate]
apache-hertzbeat_2.11-1.6.0-bin.tar.gz
apache-hertzbeat_2.11-1.6.0-incubating-bin.tar.gz
gpg: Signature made Tue May 2 12:16:36 2023 CST
gpg: using RSA key 85778A4CE4DD04B7E07813ABACFB69E705016886
gpg: Good signature from "muchunjin (apache key) <muchunjin@apache.org>" [ultimate]
apache-hertzbeat_2.12-1.6.0-bin.tar.gz
apache-hertzbeat_2.12-1.6.0-incubating-bin.tar.gz
gpg: Signature made Tue May 2 12:16:37 2023 CST
gpg: using RSA key 85778A4CE4DD04B7E07813ABACFB69E705016886
gpg: BAD signature from "muchunjin (apache key) <muchunjin@apache.org>" [ultimate]
@@ -290,14 +290,14 @@ gpg: BAD signature from "muchunjin (apache key) <muchunjin@apache.org>" [ultimat
# Verify SHA512
$ for i in *.tar.gz; do echo $i; sha512sum --check $i.sha512; done
apache-hertzbeat-1.6.0-src.tar.gz
apache-hertzbeat-1.6.0-src.tar.gz: OK
apache-hertzbeat-1.6.0-bin.tar.gz
apache-hertzbeat-1.6.0-bin.tar.gz: OK
apache-hertzbeat-1.6.0-docker-compose.tar.gz
apache-hertzbeat-1.6.0-docker-compose.tar.gz: OK
apache-hertzbeat-collector-1.6.0-bin.tar.gz
apache-hertzbeat-collector-1.6.0-bin.tar.gz: OK
apache-hertzbeat-1.6.0-incubating-src.tar.gz
apache-hertzbeat-1.6.0-incubating-src.tar.gz: OK
apache-hertzbeat-1.6.0-incubating-bin.tar.gz
apache-hertzbeat-1.6.0-incubating-bin.tar.gz: OK
apache-hertzbeat-1.6.0-incubating-docker-compose.tar.gz
apache-hertzbeat-1.6.0-incubating-docker-compose.tar.gz: OK
apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz
apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz: OK
```
#### 3.7 Publish the dev directory of the Apache SVN material package
@@ -350,13 +350,13 @@ svn commit -m "release for HertzBeat 1.6.0"
Send a voting email in the community requires at least three `+1` and no `-1`.
> `Send to`: <dev@hertzbeat.apache.org> <br />
> `Title`: [VOTE] Release Apache HertzBeat 1.6.0 rc1 <br />
> `Title`: [VOTE] Release Apache HertzBeat (incubating) 1.6.0 rc1 <br />
> `Body`:
```text
Hello HertzBeat Community:
This is a call for vote to release Apache HertzBeat version release-1.6.0-RC1.
This is a call for vote to release Apache HertzBeat (incubating) version release-1.6.0-RC1.
Apache HertzBeat - a real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
@@ -406,13 +406,13 @@ Thanks!
After 72 hours, the voting results will be counted, and the voting result email will be sent, as follows.
> `Send to`: <dev@hertzbeat.apache.org> <br />
> `Title`: [RESULT]\[VOTE\] Release Apache HertzBeat 1.6.0-rc1 <br />
> `Title`: [RESULT]\[VOTE\] Release Apache HertzBeat (incubating) 1.6.0-rc1 <br />
> `Body`:
```text
Dear HertzBeat community,
Thanks for your review and vote for "Release Apache HertzBeat 1.6.0-rc1"
Thanks for your review and vote for "Release Apache HertzBeat (incubating) 1.6.0-rc1"
I'm happy to announce the vote has passed:
---
4 binding +1, from:
@@ -441,14 +441,14 @@ One item of the email content is `Vote thread`, and the link is obtained here: <
Send a voting email in the incubator community requires at least three `+1` and no `-1`.
> `Send to`: <general@incubator.apache.org> <br />
> `Title`: [VOTE] Release Apache HertzBeat 1.6.0-rc1 <br />
> `Title`: [VOTE] Release Apache HertzBeat (incubating) 1.6.0-rc1 <br />
> `Body`:
```text
Hello Incubator Community:
This is a call for a vote to release Apache HertzBeat version 1.6.0-RC1.
The Apache HertzBeat community has voted on and approved a proposal to release Apache HertzBeat version 1.6.0-RC1.
This is a call for a vote to release Apache HertzBeat (incubating) version 1.6.0-RC1.
The Apache HertzBeat community has voted on and approved a proposal to release Apache HertzBeat (incubating) version 1.6.0-RC1.
We now kindly request the Incubator PPMC members review and vote on this incubator release.
Apache HertzBeat, a real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
@@ -486,7 +486,7 @@ https://hertzbeat.apache.org/docs/community/development/#build-hertzbeat-binary-
---
Thanks,
On behalf of Apache HertzBeat community
On behalf of Apache HertzBeat (incubating) community
---
Best,
ChunJin Mu
@@ -507,13 +507,13 @@ Chunjin Mu
Then the voting results will be counted, and the voting result email will be sent, as follows.
> `Send to`: <general@incubator.apache.org> <br />
> `Title`: [RESULT]\[VOTE\] Release Apache HertzBeat 1.6.0-rc1 <br />
> `Title`: [RESULT]\[VOTE\] Release Apache HertzBeat (incubating) 1.6.0-rc1 <br />
> `Body`:
```text
Hi Incubator Community,
The vote to release Apache HertzBeat 1.6.0-rc4 has passed with 3 +1 binding and no +0 or -1 votes.
The vote to release Apache HertzBeat (incubating) 1.6.0-rc4 has passed with 3 +1 binding and no +0 or -1 votes.
3 binding votes, no +0 or -1 votes.
@@ -584,13 +584,13 @@ The rename the release-1.6.0-rc1 branch to release-1.6.0.
> `Send to`: <general@incubator.apache.org> <br />
> `cc`: <dev@hertzbeat.apache.org> <br />
> `Title`: [ANNOUNCE] Apache HertzBeat 1.6.0 released <br />
> `Title`: [ANNOUNCE] Apache HertzBeat (incubating) 1.6.0 released <br />
> `Body`:
```text
Hi Community,
We are glad to announce the release of Apache HertzBeat 1.6.0.
We are glad to announce the release of Apache HertzBeat (incubating) 1.6.0.
Thanks again for your help.
Apache HertzBeat (https://hertzbeat.apache.org/) - a real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
+8 -5
View File
@@ -91,7 +91,7 @@ check result
> If something like the following appears, it means the signature is correct. Keyword: **`Good signature`**
```shell
apache-hertzbeat-xxx-src.tar.gz
apache-hertzbeat-xxx-incubating-src.tar.gz
gpg: Signature made XXXX
gpg: using RSA key XXXXX
gpg: Good signature from "xxx @apache.org>"
@@ -105,16 +105,18 @@ for i in *.tar.gz; do echo $i; sha512sum --check $i.sha512; done
#### 2.4 Check the binary package
unzip `apache-hertzbeat-${release.version}-bin.tar.gz`
unzip `apache-hertzbeat-${release.version}-incubating-bin.tar.gz`
```shell
tar -xzvf apache-hertzbeat-${release.version}-bin.tar.gz
tar -xzvf apache-hertzbeat-${release.version}-incubating-bin.tar.gz
```
check as follows:
- [ ] Check whether the source package contains unnecessary files, which makes the tar package too large
- [ ] Folder contains the word `incubating`
- [ ] There are `LICENSE` and `NOTICE` files
- [ ] There is a `DISCLAIMER` or `DISCLAIMER-WIP` file
- [ ] The year in the `NOTICE` file is correct
- [ ] Only text files exist, not binary files
- [ ] All files have ASF license at the beginning
@@ -125,10 +127,10 @@ check as follows:
> If the binary/web-binary package is uploaded, check the binary package.
Unzip `apache-hertzbeat-${release_version}-src.tar.gz`
Unzip `apache-hertzbeat-${release_version}-incubating-src.tar.gz`
```shell
cd apache-hertzbeat-${release_version}-src
cd apache-hertzbeat-${release_version}-incubating-src
```
compile the source code: [Build HertzBeat Binary Package](https://hertzbeat.apache.org/docs/community/development/#build-hertzbeat-binary-package)
@@ -136,6 +138,7 @@ compile the source code: [Build HertzBeat Binary Package](https://hertzbeat.apac
and check as follows:
- [ ] There are `LICENSE` and `NOTICE` files
- [ ] There is a `DISCLAIMER` or `DISCLAIMER-WIP` file
- [ ] The year in the `NOTICE` file is correct
- [ ] All text files have ASF license at the beginning
- [ ] Check the third-party dependent license:
+1 -1
View File
@@ -273,7 +273,7 @@ Subject: [ANNOUNCE] New committer: ${NEW_COMMITTER_NAME}
```text
Hello Community,
The Podling Project Management Committee (PPMC) for Apache HertzBeat
The Podling Project Management Committee (PPMC) for Apache HertzBeat (incubating)
has invited ${NEW_COMMITTER_NAME} to become a committer and we are pleased to
announce that he has accepted.
@@ -280,5 +280,5 @@ submission process. This should enable better productivity.
A PPMC member helps manage and guide the direction of the project.
Thanks,
On behalf of the Apache HertzBeat PPMC
On behalf of the Apache HertzBeat (incubating) PPMC
```
+2 -2
View File
@@ -1,10 +1,10 @@
---
id: download
title: Download Apache HertzBeat
title: Download Apache HertzBeat (incubating)
sidebar_label: Download
---
> **Here is the Apache HertzBeat official download page.**
> **Here is the Apache HertzBeat (incubating) official download page.**
> **Please choose version to download from the following tables. It is recommended use the latest.**
:::tip
+1 -1
View File
@@ -5,7 +5,7 @@ sidebar_label: Collector
keywords: [monitoring, observability, collector, metrics]
---
> HertzBeat Collector is a lightweight data collection module that enables metrics collection, high availability deployments, and cloud-edge collaboration in Apache HertzBeat.
> HertzBeat Collector is a lightweight data collection module that enables metrics collection, high availability deployments, and cloud-edge collaboration in Apache HertzBeat (incubating).
## Introduction
+2 -3
View File
@@ -15,7 +15,6 @@ This page explains how connect to the HertzBeat MCP SSE server. The MCP server a
### Connect to the MCP server
Make sure that hertzbeat server is up and running. If you are using any other port than 1157, replace the following accordingly
- URL: `http://localhost:1157/api/sse`
### Authentication
@@ -24,10 +23,10 @@ You must authenticate each request using one of the following methods:
- JWT bearer token
- Header: `Authorization: Bearer <your-jwt-token>`
- Header: `Authorization: Bearer <your-jwt-token>`
- Basic authentication
- Header: `Authorization: Basic <base64(username:password)>`
- Header: `Authorization: Basic <base64(username:password)>`
### Cursor MCP configuration
+16 -17
View File
@@ -1,15 +1,15 @@
---
id: spring_gateway
Title: Monitoring Spring Cloud Gateway
sidebar_label: Spring Cloud Gateway
keywords: [open source monitoring tool, open source Spring Cloud Gateway monitoring tool, monitoring Spring Cloud Gateway metrics]
Title: Monitoring Spring Gateway
sidebar_label: Spring Gateway
keywords: [open source monitoring tool, open source spring gateway monitoring tool, monitoring spring gateway metrics]
---
> Collect and monitor the general performance metrics exposed by the SpringBoot actuator.
## Pre-monitoring operations
If you want to monitor information in `Spring Cloud Gateway` with this monitoring type, you need to integrate your `Spring Cloud Gateway` application and enable the SpringBoot Actuator.
If you want to monitor information in 'Spring Gateway' with this monitoring type, you need to integrate your SpringBoot application and enable the SpringBoot Actuator.
**1、Add POM .XML dependencies:**
@@ -26,26 +26,25 @@ If you want to monitor information in `Spring Cloud Gateway` with this monitorin
management:
endpoint:
gateway:
enabled: true
env:
show-values: ALWAYS
enabled: true # default value
endpoints:
web:
exposure:
include: "*"
include: '*'
enabled-by-default: on
```
### Configure parameters
| Parameter name | Parameter Help describes the |
|-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Monitor Host | THE MONITORED PEER IPV4, IPV6 OR DOMAIN NAME. Note ⚠️ that there are no protocol headers (eg: https://, http://). |
| Monitoring Name | A name that identifies this monitoring that needs to be unique. |
| Port | The default port provided by the database is 8080. |
| Enable HTTPS | Whether to access the website through HTTPS, please note that ⚠️ when HTTPS is enabled, the default port needs to be changed to 443 |
| The acquisition interval is | Monitor the periodic data acquisition interval, in seconds, and the minimum interval that can be set is 30 seconds |
| Whether to probe the | Whether to check the availability of the monitoring before adding a monitoring is successful, and the new modification operation will continue only if the probe is successful |
| Description Comment | For more information identifying and describing the remarks for this monitoring, users can remark the information here |
| Parameter name | Parameter Help describes the |
|-----------------------------|-------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
| Monitor Host | THE MONITORED PEER IPV4, IPV6 OR DOMAIN NAME. Note ⚠️ that there are no protocol headers (eg: https://, http://). |
| Monitoring Name | A name that identifies this monitoring that needs to be unique. |
| Port | The default port provided by the database is 8080. |
| Enable HTTPS | Whether to access the website through HTTPS, please note that ⚠️ when HTTPS is enabled, the default port needs to be changed to 443 |
| The acquisition interval is | Monitor the periodic data acquisition interval, in seconds, and the minimum interval that can be set is 30 seconds |
| Whether to probe the | Whether to check the availability of the monitoring before adding a monitoring is successful, and the new modification operation | will continue only if the probe is successful |
| Description Comment | For more information identifying and describing the remarks for this monitoring, users can remark the information here |
### Collect metrics
+1 -1
View File
@@ -16,7 +16,7 @@ The fields that need to be filled in are as follows:
| Field Name | Field Description | Example |
|--------------------------|----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Organization Name | Name of the organization | HertzBeat |
| Organization Description | Detailed description of the organization | Apache HertzBeat is an easy-to-use and user-friendly open-source real-time monitoring and alerting system, no agent required, high-performance cluster, compatible with Prometheus, providing powerful custom monitoring and status page building capabilities. |
| Organization Description | Detailed description of the organization | Apache HertzBeat (incubating) is an easy-to-use and user-friendly open-source real-time monitoring and alerting system, no agent required, high-performance cluster, compatible with Prometheus, providing powerful custom monitoring and status page building capabilities. |
| Website Link | URL of the organization's website for more information | <https://hertzbeat.apache.org/> |
| Logo Image | Path or URL of the organization's official logo image, preferably in .svg format | <https://hertzbeat.apache.org/zh-cn/img/hertzbeat-logo.svg> |
| Feedback Address | Address to receive feedback | <https://github.com/apache/hertzbeat/issues> |
+2 -2
View File
@@ -1,6 +1,6 @@
---
id: introduce
title: Apache HertzBeat
title: Apache HertzBeat (incubating)
sidebar_label: Introduce
slug: /
---
@@ -11,7 +11,7 @@ slug: /
## 🎡 <font color="green">Introduction</font>
[Apache HertzBeat](https://github.com/apache/hertzbeat) is an easy-to-use, open source, real-time monitoring system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
[Apache HertzBeat](https://github.com/apache/hertzbeat) (incubating) is an easy-to-use, open source, real-time monitoring system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
### Features
+1 -1
View File
@@ -6,7 +6,7 @@ sidebar_label: Update Account Secret
## Update Account
Apache HertzBeat default built-in three user accounts, respectively admin/hertzbeat tom/hertzbeat guest/hertzbeat
Apache HertzBeat (incubating) default built-in three user accounts, respectively admin/hertzbeat tom/hertzbeat guest/hertzbeat
If you need add, delete or modify account or password, configure `sureness.yml`. Ignore this step without this demand.
Modify the following **part parameters** in sureness.yml**[Note⚠️Other default sureness configuration parameters should be retained]**
+1 -1
View File
@@ -4,7 +4,7 @@ title: Use aaPanel Deploy HertzBeat
sidebar_label: Install via aaPanel
---
Apache HertzBeat supports one-click deployment in the `Docker` application store of the aaPanel.
Apache HertzBeat (incubating) supports one-click deployment in the `Docker` application store of the aaPanel.
## Prerequisites
+4 -4
View File
@@ -15,13 +15,13 @@ Run the `docker compose version` command to check if you have a Docker Compose e
1. Download the startup script package
Download the installation script package `apache-hertzbeat-xxx-docker-compose.tar.gz` from the [download](/docs/download)
Download the installation script package `apache-hertzbeat-xxx-incubating-docker-compose.tar.gz` from the [download](/docs/download)
2. Choose to use the HertzBeat + PostgreSQL + VictoriaMetrics solution
:::tip
- `apache-hertzbeat-xxx-docker-compose.tar.gz` contains multiple deployment solutions after decompression. Here we recommend choosing the `hertzbeat-postgresql-victoria-metrics` solution.
- `apache-hertzbeat-xxx-incubating-docker-compose.tar.gz` contains multiple deployment solutions after decompression. Here we recommend choosing the `hertzbeat-postgresql-victoria-metrics` solution.
- Other deployment methods, please read the README.md file of each deployment solution in detail. The MySQL solution requires you to prepare the MySQL driver package yourself.
:::
@@ -29,13 +29,13 @@ Run the `docker compose version` command to check if you have a Docker Compose e
- Unzip the script package
```shell
tar zxvf apache-hertzbeat-1.6.0-docker-compose.tar.gz
tar zxvf apache-hertzbeat-1.6.0-incubating-docker-compose.tar.gz
```
- Enter the decompression directory and select `HertzBeat + PostgreSQL + VictoriaMetrics` for one-click deployment
```shell
cd apache-hertzbeat-1.6.0-docker-compose
cd apache-hertzbeat-1.6.0-incubating-docker-compose
cd hertzbeat-postgresql-victoria-metrics
```
+1 -1
View File
@@ -4,7 +4,7 @@ title: Use Time Series Database Greptime to Store Metrics Data (Recommended)
sidebar_label: Metrics Store Greptime (Recommended)
---
Apache HertzBeat's historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
Apache HertzBeat (incubating)'s historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
> It is recommended to use Greptime as metrics storage.
+1 -1
View File
@@ -4,7 +4,7 @@ title: Use Time Series Database InfluxDB to Store Metrics Data (Optional)
sidebar_label: Metrics Store InfluxDB
---
Apache HertzBeat's historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
Apache HertzBeat (incubating)'s historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
> It is recommended to use VictoriaMetrics as metrics storage.
+1 -1
View File
@@ -4,7 +4,7 @@ title: Use Time Series Database IoTDB to Store Metrics Data (Optional)
sidebar_label: Metrics Store IoTDB
---
Apache HertzBeat's historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
Apache HertzBeat (incubating)'s historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
> It is recommended to use VictoriaMetrics as metrics storage.
+1 -1
View File
@@ -4,7 +4,7 @@ title: Use MYSQL Replace H2 Database to Store Metadata(Optional)
sidebar_label: Meta Store MYSQL
---
MYSQL is a reliable relational database. In addition to default built-in H2 database, Apache HertzBeat allow you to use MYSQL to store structured relational data such as monitoring information, alarm information and configuration information.
MYSQL is a reliable relational database. In addition to default built-in H2 database, Apache HertzBeat (incubating) allow you to use MYSQL to store structured relational data such as monitoring information, alarm information and configuration information.
> If you already have a MySQL environment and the MySQL version meets the requirements, you can skip directly to the database creation step.
+5 -5
View File
@@ -5,7 +5,7 @@ sidebar_label: Install via Package
---
:::tip
You can install and run Apache HertzBeat on Linux Windows Mac system, and CPU supports X86/ARM64.
You can install and run Apache HertzBeat (incubating) on Linux Windows Mac system, and CPU supports X86/ARM64.
Since version 1.6.0 uses `Java 17` and the installation package no longer provides a built-in JDK version, use the new Hertzbeat according to the following situations:
- When the default environment variable on your server is `Java 17`, you do not need to take any action for this step.
@@ -18,7 +18,7 @@ Since version 1.6.0 uses `Java 17` and the installation package no longer provid
1. Download installation package
Download installation package `apache-hertzbeat-xxx-bin.tar.gz` corresponding to your system environment
Download installation package `apache-hertzbeat-xxx-incubating-bin.tar.gz` corresponding to your system environment
- [Download Page](/docs/download)
2. Configure HertzBeat's configuration file(optional)
@@ -26,7 +26,7 @@ Since version 1.6.0 uses `Java 17` and the installation package no longer provid
Unzip the installation package to the host eg: /opt/hertzbeat
```shell
tar zxvf apache-hertzbeat-xxx-bin.tar.gz
tar zxvf apache-hertzbeat-xxx-incubating-bin.tar.gz
```
:::tip
@@ -68,7 +68,7 @@ Deploying multiple HertzBeat Collectors can achieve high availability, load bala
1. Download installation package
Download installation package `apache-hertzbeat-collector-xxx-bin.tar.gz` corresponding to your system environment
Download installation package `apache-hertzbeat-collector-xxx-incubating-bin.tar.gz` corresponding to your system environment
- [Download Page](/docs/download)
2. Configure the collector configuration file
@@ -76,7 +76,7 @@ Deploying multiple HertzBeat Collectors can achieve high availability, load bala
Unzip the installation package to the host eg: /opt/hertzbeat-collector
```shell
tar zxvf apache-hertzbeat-collector-xxx-bin.tar.gz
tar zxvf apache-hertzbeat-collector-xxx-incubating-bin.tar.gz
```
Configure the collector configuration yml file `config/application.yml`: unique `identity` name, running `mode` (public or private), hertzbeat `manager-host`, hertzbeat `manager-port`
+1 -1
View File
@@ -4,7 +4,7 @@ title: Use PostgreSQL Replace H2 Database to Store Metadata(Recommended)
sidebar_label: Meta Store PostgreSQL (Recommended)
---
PostgreSQL is a RDBMS emphasizing extensibility and SQL compliance. In addition to default built-in H2 database, Apache HertzBeat allow you to use PostgreSQL to store structured relational data such as monitoring information, alarm information and configuration information.
PostgreSQL is a RDBMS emphasizing extensibility and SQL compliance. In addition to default built-in H2 database, Apache HertzBeat (incubating) allow you to use PostgreSQL to store structured relational data such as monitoring information, alarm information and configuration information.
> If you have the PostgreSQL environment, can be directly to database creation step.
+2 -2
View File
@@ -6,11 +6,11 @@ sidebar_label: Quick Start
### 🐕 Quick Start
- If you wish to deploy Apache HertzBeat locally, please refer to the following Deployment Documentation for instructions.
- If you wish to deploy Apache HertzBeat (incubating) locally, please refer to the following Deployment Documentation for instructions.
#### 🍞 Install HertzBeat
> Apache HertzBeat supports installation through source code, docker or package, cpu support X86/ARM64.
> Apache HertzBeat (incubating) supports installation through source code, docker or package, cpu support X86/ARM64.
##### 1Install quickly via docker
+1 -1
View File
@@ -4,7 +4,7 @@ title: Use Rainbond Deploy HertzBeat
sidebar_label: Install via Rainbond
---
If you are unfamiliar with Kubernetes, and want to install Apache HertzBeat in Kubernetes, you can use Rainbond to deploy. Rainbond is a cloud-native application management platform built on Kubernetes and simplifies the application deployment to Kubernetes.
If you are unfamiliar with Kubernetes, and want to install Apache HertzBeat (incubating) in Kubernetes, you can use Rainbond to deploy. Rainbond is a cloud-native application management platform built on Kubernetes and simplifies the application deployment to Kubernetes.
## Rainbond Cloud deployment
+1 -1
View File
@@ -4,7 +4,7 @@ title: Use Time Series Database TDengine to Store Metrics Data (Optional)
sidebar_label: Metrics Store TDengine
---
Apache HertzBeat's historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
Apache HertzBeat (incubating)'s historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
> It is recommended to use VictoriaMetrics as metrics storage.
+1 -1
View File
@@ -10,7 +10,7 @@ sidebar_label: Version Upgrade Guide
- [Github Release](https://github.com/apache/hertzbeat/releases)
- [DockerHub Release](https://hub.docker.com/r/apache/hertzbeat/tags)
Apache HertzBeat's metadata information is stored in H2 or Mysql, PostgreSQL relational databases, and the collected metric data is stored in time series databases such as TDengine and IotDB.
Apache HertzBeat (incubating)'s metadata information is stored in H2 or Mysql, PostgreSQL relational databases, and the collected metric data is stored in time series databases such as TDengine and IotDB.
**You need to save and back up the data files of the database and monitoring templates yml files before upgrading**
+1 -1
View File
@@ -30,7 +30,7 @@ The production environment recommends a complete deployment method, refer [Insta
### 1. Click Add Linux Operating System Monitor
> HertzBeat Page -> Monitors -> New Monitor -> OS Monitor -> Add OS Linux
> HertzBeat Page -> Monitors Menu -> New Monitor -> OS Monitor -> Add OS Linux
![HertzBeat](/img/docs/start/linux-os-practice-1.png)
@@ -14,7 +14,7 @@ This article introduces an integrated solution using the HertzBeat monitoring sy
## What is HertzBeat
Apache HertzBeat is a real-time monitoring tool with powerful custom monitoring capabilities without Agent. Website monitoring, PING connectivity, port availability, database, operating system, middleware, API monitoring, threshold alarms, alarm notification (email, WeChat, Ding Ding Feishu).
Apache HertzBeat (incubating) is a real-time monitoring tool with powerful custom monitoring capabilities without Agent. Website monitoring, PING connectivity, port availability, database, operating system, middleware, API monitoring, threshold alarms, alarm notification (email, WeChat, Ding Ding Feishu).
**github: <https://github.com/apache/hertzbeat>**
+2 -2
View File
@@ -12,7 +12,7 @@ This article introduces how to use the hertzbeat monitoring tool to detect the v
## What is HertzBeat
Apache HertzBeat is a real-time monitoring tool with powerful custom monitoring capabilities without Agent. Website monitoring, PING connectivity, port availability, database, operating system, middleware, API monitoring, threshold alarms, alarm notification (email, WeChat, Ding Ding Feishu).
Apache HertzBeat (incubating) is a real-time monitoring tool with powerful custom monitoring capabilities without Agent. Website monitoring, PING connectivity, port availability, database, operating system, middleware, API monitoring, threshold alarms, alarm notification (email, WeChat, Ding Ding Feishu).
github: <https://github.com/apache/hertzbeat>
@@ -32,7 +32,7 @@ The production environment recommends a complete deployment method, refer <https
1. Click Add SSL Certificate Monitor
> HertzBeat Page -> Monitors -> New Monitor -> Service Monitor -> Add SSL Certificate
> HertzBeat Page -> Monitors Menu -> New Monitor -> Service Monitor -> Add SSL Certificate
![HertzBeat](/img/docs/start/ssl_1.png)
+1 -1
View File
@@ -4,7 +4,7 @@ title: Use Time Series Database VictoriaMetrics to Store Metrics Data (Recommend
sidebar_label: Metrics Store VictoriaMetrics (Recommended)
---
Apache HertzBeat's historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
Apache HertzBeat (incubating)'s historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
> It is recommended to use VictoriaMetrics as metrics storage.
+1 -1
View File
@@ -4,7 +4,7 @@ title: Monitoring Template Here
sidebar_label: Monitoring Template
---
> Apache HertzBeat is an open source, real-time monitoring tool with custom-monitor and agentLess.
> Apache HertzBeat (incubating) is an open source, real-time monitoring tool with custom-monitor and agentLess.
>
> We make protocols such as `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` configurable, and you only need to configure `YML` online to collect any metrics you want.
> Do you believe that you can immediately adapt a new monitoring type such as K8s or Docker just by configuring online?
+7 -7
View File
@@ -2,7 +2,7 @@ const path = require('path')
const organizationName = 'apache' // Usually your GitHub name.
const projectName = 'hertzbeat' // Usually your repo name.
const deploymentBranch = 'asf-site'
const deploymentBranch = 'asf-site'
const branch = 'master'
const repoUrl = `https://github.com/apache/${projectName}`
const cdnUrl = null
@@ -16,8 +16,8 @@ module.exports = {
onBrokenMarkdownLinks: 'throw',
favicon: '/img/hertzbeat-logo.svg',
organizationName,
projectName,
deploymentBranch,
projectName,
deploymentBranch,
customFields: {
repoUrl,
cdnUrl,
@@ -206,22 +206,22 @@ module.exports = {
{
type: 'localeDropdown',
position: 'right',
},
},
{
href: repoUrl,
position: 'right',
className: 'header-github-link'
},
},
{
href: 'https://x.com/hertzbeat1024',
position: 'right',
className: 'header-twitter-link'
},
},
{
href: 'https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow',
position: 'right',
className: 'header-youtube-link'
},
},
{
href: 'https://discord.gg/Fb6M73htGr',
position: 'right',
+3 -3
View File
@@ -263,13 +263,13 @@
"message": "Makes protocols such as Http, Jmx, Ssh, Snmp, Jdbc configurable, you can collect any metrics by simply configuring the yml online. {br} High performance, supports horizontal expansion of multi-collector clusters, multi-isolated network monitoring and cloud-edge collaboration. {br} Flexible threshold rules and timely notifications delivered via discord slack email webhook more."
},
"opensource-content": {
"message": "Apache HertzBeat is open source, has an inclusive and open community. Unlimited and anyone who are interested in it are very welcome to contribute. No matter how small the contribution is, whether it is a code document or a typo, respect everyone and grow together. {br} Our code is being deployed on thousands of machines worldwide.{github}"
"message": "Apache HertzBeat (incubating) is open source, has an inclusive and open community. Unlimited and anyone who are interested in it are very welcome to contribute. No matter how small the contribution is, whether it is a code document or a typo, respect everyone and grow together. {br} Our code is being deployed on thousands of machines worldwide.{github}"
},
"slogan": {
"message": "Open Source Real-time Monitoring System"
},
"Who uses HertzBeat?": {
"message": "Who uses Apache HertzBeat?"
"message": "Who uses Apache HertzBeat (incubating)?"
},
"theme.admonition.note": {
"message": "note",
@@ -490,7 +490,7 @@
"description": "The title of the tag list page"
},
"team.name": {
"message": "Apache HertzBeat Team"
"message": "Apache HertzBeat (incubating) Team"
},
"team.desc": {
"message": "The HertzBeat team is composed of contributors from various fields around the world. We embrace the community philosophy of openness and collaboration, welcoming👏 more people to join us and grow together with the community."
+3 -3
View File
@@ -437,7 +437,7 @@
"message": "将 Http,Jmx,Ssh,Snmp,Jdbc 等协议规范可配置模板化,只需在线配置YML就可自定义监控指标。{br} 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。{br}灵活的告警阈值规则,邮箱,短信,钉钉,企业微信,飞书,Webhook等消息及时送达。{br} 您相信只需配置下就能适配新K8s监控类型吗?"
},
"opensource-content": {
"message": "Apache HertzBeat 是开源的,拥有一个包容开放的社区。{br}欢迎任何对此有兴趣的同学参与其中,无论是代码文档或者错别字,尊重社区的每一位,一起进步成长。{br}我们的代码正被部署到全球成千上万机器上。{github}"
"message": "Apache HertzBeat (incubating) 是开源的,拥有一个包容开放的社区。{br}欢迎任何对此有兴趣的同学参与其中,无论是代码文档或者错别字,尊重社区的每一位,一起进步成长。{br}我们的代码正被部署到全球成千上万机器上。{github}"
},
"slogan": {
"message": "易用友好的开源实时监控系统"
@@ -464,7 +464,7 @@
"message": "快速开始"
},
"Who uses HertzBeat?": {
"message": "谁在使用 Apache HertzBeat"
"message": "谁在使用 Apache HertzBeat (incubating)"
},
"Support HertzBeat": {
"message": "Support HertzBeat"
@@ -493,7 +493,7 @@
"description": "The title of the tag list page"
},
"team.name": {
"message": "Apache HertzBeat 团队"
"message": "Apache HertzBeat (incubating) 团队"
},
"team.desc": {
"message": "HertzBeat 团队由来自全球各个领域的贡献者组成。践行 开放,协作 的社区理念,欢迎👏更多的人加入我们,和社区一同成长。"
@@ -36,7 +36,7 @@ gitee: <https://gitee.com/hertzbeat/hertzbeat>
1. 点击新增SSL证书监控
> 系统页面 -> 监控中心 -> SSL证书 -> 新增SSL证书
> 系统页面 -> 监控菜单 -> SSL证书 -> 新增SSL证书
![HertzBeat](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bd53f343a5b54feab62e71458d076441~tplv-k3u1fbpfcp-zoom-1.image)
@@ -8,9 +8,9 @@ tags: [opensource, practice]
keywords: [open source, monitoring, alerting]
---
**Hi 朋友们,我们很高兴地宣布,Apache HertzBeat 的了第一个Apache版本 v1.6.0 发布啦!🎉.**
**Hi 朋友们,我们很高兴地宣布,Apache HertzBeat (incubating) 的了第一个Apache版本 v1.6.0 发布啦!🎉.**
经过近五个月的社区开发迭代贡献和两个月的Apache Incubator孵化过程,Apache HertzBeat v1.6.0 终于出来了。
经过近五个月的社区开发迭代贡献和两个月的Apache Incubator孵化过程,Apache HertzBeat (incubating) v1.6.0 终于出来了。
这个版本我们增加了对OpenAi监控,Redfish协议服务器,插件机制,支持了NebulaGraph, Apache Yarn, HDFS, Hbase, Storm等更多功能特性。
由于License兼容问题,我们在底层替换了ORM框架,计算框架等多个依赖,Hibernate -> EclipseLink, 这也算是JPA生态下为数不多的迁移踩坑实践。
同时修复了一些bug和优化了一些功能,更完善的文档。欢迎大家尝试使用,提出宝贵意见和建议,共同推动HertzBeat的发展。🎉
@@ -4,7 +4,7 @@ title: HTTP协议系统默认解析方式
sidebar_label: 系统默认解析方式
---
> HTTP接口调用获取响应数据后,用 Apache HertzBeat 默认的解析方式去解析响应数据。
> HTTP接口调用获取响应数据后,用 Apache HertzBeat (incubating) 默认的解析方式去解析响应数据。
**此需接口响应数据结构符合HertzBeat指定的数据结构规则**
@@ -4,7 +4,7 @@ title: 教程一:适配一款基于HTTP协议的监控类型
sidebar_label: 教程一:适配一款HTTP协议监控
---
通过此教程我们一步一步描述如何在 Apache HertzBeat 监控系统下新增适配一款基于http协议的监控类型。
通过此教程我们一步一步描述如何在 Apache HertzBeat (incubating) 监控系统下新增适配一款基于http协议的监控类型。
阅读此教程前我们希望您已经从[自定义监控](extend-point)和[http协议自定义](extend-http)了解熟悉了怎么自定义类型,指标,协议等。
@@ -8,7 +8,7 @@ sidebar_label: JsonPath解析方式
注意⚠️ 响应数据为JSON格式
**使用JsonPath脚本将响应数据解析成符合 Apache HertzBeat 指定的数据结构规则的数据**
**使用JsonPath脚本将响应数据解析成符合 Apache HertzBeat (incubating) 指定的数据结构规则的数据**
#### JsonPath操作符
@@ -4,7 +4,7 @@ title: 自定义适配一款基于HTTP协议的新监控类型
sidebar_label: 教程案例
---
通过此教程我们一步一步描述如何在 Apache HertzBeat 系统下自定义新增适配一款基于 http 协议的监控类型。
通过此教程我们一步一步描述如何在 Apache HertzBeat (incubating) 系统下自定义新增适配一款基于 http 协议的监控类型。
阅读此教程前我们希望您已经从[自定义监控](extend-point)和[http协议自定义](extend-http)了解熟悉了怎么自定义类型,指标,协议等。
@@ -350,13 +350,13 @@ svn commit -m "release for HertzBeat 1.6.0-RC1"
发送社区投票邮件需要至少三个`+1`,且无`-1`
> `Send to`: <dev@hertzbeat.apache.org> <br />
> `Title`: [VOTE] Release Apache HertzBeat 1.6.0 rc1 <br />
> `Title`: [VOTE] Release Apache HertzBeat (incubating) 1.6.0 rc1 <br />
> `Body`:
```text
Hello HertzBeat Community:
This is a call for vote to release Apache HertzBeat version release-1.6.0-RC1.
This is a call for vote to release Apache HertzBeat (incubating) version release-1.6.0-RC1.
Apache HertzBeat - a real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
@@ -406,13 +406,13 @@ Thanks!
在72小时后,将统计投票结果,并发送投票结果邮件,如下所示。
> `Send to`: <dev@hertzbeat.apache.org> <br />
> `Title`: [RESULT]\[VOTE\] Release Apache HertzBeat 1.6.0-rc1 <br />
> `Title`: [RESULT]\[VOTE\] Release Apache HertzBeat (incubating) 1.6.0-rc1 <br />
> `Body`:
```text
Dear HertzBeat community,
Thanks for your review and vote for "Release Apache HertzBeat 1.6.0-rc1"
Thanks for your review and vote for "Release Apache HertzBeat (incubating) 1.6.0-rc1"
I'm happy to announce the vote has passed:
---
4 binding +1, from:
@@ -441,14 +441,14 @@ ChunJin Mu
发送孵化社区投票邮件需要至少三个`+1`,且无`-1`
> `Send to`: <general@incubator.apache.org> <br />
> `Title`: [VOTE] Release Apache HertzBeat 1.6.0-rc1 <br />
> `Title`: [VOTE] Release Apache HertzBeat (incubating) 1.6.0-rc1 <br />
> `Body`:
```text
Hello Incubator Community:
This is a call for a vote to release Apache HertzBeat version 1.6.0-RC1.
The Apache HertzBeat community has voted on and approved a proposal to release Apache HertzBeat version 1.6.0-RC1.
This is a call for a vote to release Apache HertzBeat (incubating) version 1.6.0-RC1.
The Apache HertzBeat community has voted on and approved a proposal to release Apache HertzBeat (incubating) version 1.6.0-RC1.
We now kindly request the Incubator PPMC members review and vote on this incubator release.
Apache HertzBeat, a real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
@@ -486,7 +486,7 @@ https://hertzbeat.apache.org/docs/community/development/#build-hertzbeat-binary-
---
Thanks,
On behalf of Apache HertzBeat community
On behalf of Apache HertzBeat (incubating) community
---
Best,
ChunJin Mu
@@ -507,13 +507,13 @@ Chunjin Mu
然后将统计投票结果,并发送投票结果邮件,如下所示。
> `Send to`: <general@incubator.apache.org> <br />
> `Title`: [RESULT]\[VOTE\] Release Apache HertzBeat 1.6.0-rc1 <br />
> `Title`: [RESULT]\[VOTE\] Release Apache HertzBeat (incubating) 1.6.0-rc1 <br />
> `Body`:
```text
Hi Incubator Community,
The vote to release Apache HertzBeat 1.6.0-rc4 has passed with 3 +1 binding and no +0 or -1 votes.
The vote to release Apache HertzBeat (incubating) 1.6.0-rc4 has passed with 3 +1 binding and no +0 or -1 votes.
3 binding votes, no +0 or -1 votes.
@@ -584,13 +584,13 @@ release note: xxx
> `Send to`: <general@incubator.apache.org> <br />
> `cc`: <dev@hertzbeat.apache.org> <br />
> `Title`: [ANNOUNCE] Apache HertzBeat 1.6.0 released <br />
> `Title`: [ANNOUNCE] Apache HertzBeat (incubating) 1.6.0 released <br />
> `Body`:
```text
Hi Community,
We are glad to announce the release of Apache HertzBeat 1.6.0.
We are glad to announce the release of Apache HertzBeat (incubating) 1.6.0.
Thanks again for your help.
Apache HertzBeat (https://hertzbeat.apache.org/) - a real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
@@ -110,7 +110,9 @@ tar -xzvf apache-hertzbeat-${release.version}-incubating-bin.tar.gz
进行如下检查:
- [ ] 文件夹包含单词`incubating`
- [ ] 存在`LICENSE``NOTICE`文件
- [ ] 存在`DISCLAIMER``DISCLAIMER-WIP`文件
- [ ] `NOTICE`文件中的年份正确
- [ ] 所有文本文件开头都有ASF许可证
- [ ] 检查第三方依赖许可证:
@@ -134,7 +136,9 @@ cd apache-hertzbeat-${release_version}-incubating-src
进行如下检查:
- [ ] 检查源码包是否包含由于包含不必要文件,致使tar包过于庞大
- [ ] 文件夹包含单词`incubating`
- [ ] 存在`LICENSE``NOTICE`文件
- [ ] 存在`DISCLAIMER``DISCLAIMER-WIP`文件
- [ ] `NOTICE`文件中的年份正确
- [ ] 只存在文本文件,不存在二进制文件
- [ ] 所有文件的开头都有ASF许可证
@@ -270,7 +270,7 @@ Subject: [ANNOUNCE] New committer: ${NEW_COMMITTER_NAME}
```text
Hello Community,
The Podling Project Management Committee (PPMC) for Apache HertzBeat
The Podling Project Management Committee (PPMC) for Apache HertzBeat (incubating)
has invited ${NEW_COMMITTER_NAME} to become a committer and we are pleased to
announce that he has accepted.
@@ -281,5 +281,5 @@ submission process. This should enable better productivity.
A PPMC member helps manage and guide the direction of the project.
Thanks,
On behalf of the Apache HertzBeat PPMC
On behalf of the Apache HertzBeat (incubating) PPMC
```
@@ -1,10 +1,10 @@
---
id: download
title: 下载 Apache HertzBeat
title: 下载 Apache HertzBeat (incubating)
sidebar_label: Download
---
> **这里是 Apache HertzBeat 官方下载页面。**
> **这里是 Apache HertzBeat (incubating) 官方下载页面。**
> **请在下方表中选择版本下载,推荐使用最新版本。**
:::tip
@@ -1,15 +1,15 @@
---
id: spring_gateway
Title: 监控 Spring Cloud Gateway
sidebar_label: Spring Cloud Gateway
keywords: [开源监控工具, 开源 Spring Cloud Gateway 监控工具, 监控 Spring Cloud Gateway 指标]
Title: 监控 Spring Gateway
sidebar_label: Spring Gateway
keywords: [开源监控工具, 开源 Spring Gateway 监控工具, 监控 Spring Gateway 指标]
---
> 收集和监控 SpringBoot Actuator 提供的常规性能指标。
## 监控前操作
如果您想使用此监控类型监控 `Spring Cloud Gateway` 的信息,您需要集成您的 `Spring Cloud Gateway` 应用程序并启用 SpringBoot Actuator。
如果您想使用此监控类型监控 'Spring Gateway' 的信息,您需要集成您的 SpringBoot 应用程序并启用 SpringBoot Actuator。
**1、添加 POM .XML 依赖:**
@@ -26,25 +26,24 @@ keywords: [开源监控工具, 开源 Spring Cloud Gateway 监控工具, 监控
management:
endpoint:
gateway:
enabled: true
env:
show-values: ALWAYS
enabled: true # default value
endpoints:
web:
exposure:
include: "*"
include: '*'
enabled-by-default: on
```
### 配置参数
| 参数名称 | 参数描述 |
|----------|--------------------------------------------------------|
| 参数名称 | 参数描述 |
|----------|--------------------------------------------------------|-----------------------------------------------|
| 监控主机 | 被监控的目标 IPV4、IPV6 或域名。注意⚠️不要包含协议头(例如:https://http://)。 |
| 监控名称 | 用于标识此监控的名称,需要保证唯一性。 |
| 端口 | 数据库提供的默认端口为 8080。 |
| 启用 HTTPS | 是否通过 HTTPS 访问网站,请注意⚠️当启用 HTTPS 时,需要将默认端口更改为 443 |
| 采集间隔 | 监控周期性采集数据的时间间隔,单位为秒,最小间隔为 30 秒。 |
| 是否探测 | 在新增监控前是否先进行可用性探测,只有探测成功才会继续新增或修改操作。 |
| 是否探测 | 在新增监控前是否先进行可用性探测,只有探测成功才会继续新增或修改操作。 | will continue only if the probe is successful |
| 描述备注 | 用于添加关于监控的额外标识和描述信息。 |
### 采集指标
@@ -16,7 +16,7 @@ keywords: [开源监控系统, 开源网站监控, 状态页面]
| 字段名称 | 字段说明 | 举例 |
|------|----------------------------------------|---------------------------------------------------------------------------------------------------|
| 组织名称 | 组织的名称 | HertzBeat |
| 组织介绍 | 组织的详细介绍 | Apache HertzBeat 是一个易用友好的开源实时监控告警系统,无需 Agent,高性能集群,兼容 Prometheus,提供强大的自定义监控和状态页构建能力。 |
| 组织介绍 | 组织的详细介绍 | Apache HertzBeat (incubating) 是一个易用友好的开源实时监控告警系统,无需 Agent,高性能集群,兼容 Prometheus,提供强大的自定义监控和状态页构建能力。 |
| 网站链接 | 组织网站的 URL,便于访问者获取更多信息 | <https://hertzbeat.apache.org/> |
| 标志图片 | 组织官方标志或 Logo 的图片文件路径或 URL,建议使用 .svg 格式 | <https://hertzbeat.apache.org/zh-cn/img/hertzbeat-logo.svg> |
| 反馈地址 | 接收问题反馈的地址 | <https://github.com/apache/hertzbeat/issues> |
@@ -1,6 +1,6 @@
---
id: introduce
title: Apache HertzBeat
title: Apache HertzBeat (incubating)
sidebar_label: 介绍
slug: /
---
@@ -6,7 +6,7 @@ sidebar_label: 更新账户和密钥
## 更新账户
Apache HertzBeat 默认内置三个用户账户,分别为 admin/hertzbeat tom/hertzbeat guest/hertzbeat
Apache HertzBeat (incubating) 默认内置三个用户账户,分别为 admin/hertzbeat tom/hertzbeat guest/hertzbeat
若需要新增删除修改账户或密码,可以通过配置 `sureness.yml` 实现,若无此需求可忽略此步骤
修改位于安装目录下的 `/hertzbeat/config/sureness.yml` 的配置文件,docker环境目录为`opt/hertzbeat/config/sureness.yml`,建议提前挂载映射
配置文件内容参考如下
@@ -4,7 +4,7 @@ title: 使用 宝塔面板 部署 HertzBeat
sidebar_label: 基于宝塔面板部署
---
Apache HertzBeat 支持在宝塔面板的 `Docker` 应用商店一键部署。
Apache HertzBeat (incubating) 支持在宝塔面板的 `Docker` 应用商店一键部署。
## 前提
@@ -4,7 +4,7 @@ title: 依赖时序数据库服务 Greptime 安装初始化 (推荐)
sidebar_label: 指标数据存储 Greptime (推荐)
---
Apache HertzBeat 的历史数据存储依赖时序数据库,任选其一安装初始化即可,也可不安装(注意⚠️但强烈建议生产环境配置)
Apache HertzBeat (incubating) 的历史数据存储依赖时序数据库,任选其一安装初始化即可,也可不安装(注意⚠️但强烈建议生产环境配置)
> 我们推荐使用并长期支持 Greptime 作为存储。
@@ -4,7 +4,7 @@ title: 依赖时序数据库服务InfluxDB安装初始化(可选)
sidebar_label: 指标数据存储InfluxDB
---
Apache HertzBeat 的历史数据存储依赖时序数据库,任选其一安装初始化即可,也可不安装(注意⚠️但强烈建议生产环境配置)
Apache HertzBeat (incubating) 的历史数据存储依赖时序数据库,任选其一安装初始化即可,也可不安装(注意⚠️但强烈建议生产环境配置)
> 我们推荐使用并长期支持 VictoriaMetrics 作为存储。
@@ -4,7 +4,7 @@ title: 依赖时序数据库服务IoTDB安装初始化(可选)
sidebar_label: 指标数据存储IoTDB
---
Apache HertzBeat 的历史数据存储依赖时序数据库,任选其一安装初始化即可,也可不安装(注意⚠️但强烈建议生产环境配置)
Apache HertzBeat (incubating) 的历史数据存储依赖时序数据库,任选其一安装初始化即可,也可不安装(注意⚠️但强烈建议生产环境配置)
> 我们推荐使用并长期支持 VictoriaMetrics 作为存储。
@@ -4,7 +4,7 @@ title: 关系型数据库使用 Mysql 替换依赖的 H2 存储系统元数据(
sidebar_label: 元数据存储Mysql
---
MYSQL是一款值得信赖的关系型数据库,Apache HertzBeat 除了支持使用默认内置的H2数据库外,还可以切换为使用MYSQL存储监控信息,告警信息,配置信息等结构化关系数据。
MYSQL是一款值得信赖的关系型数据库,Apache HertzBeat (incubating) 除了支持使用默认内置的H2数据库外,还可以切换为使用MYSQL存储监控信息,告警信息,配置信息等结构化关系数据。
注意⚠️ 使用外置MySQL数据库替换内置H2数据库为可选项,但建议生产环境配置,以提供更好的性能
@@ -5,7 +5,7 @@ sidebar_label: 安装包方式安装
---
:::tip
Apache HertzBeat 支持在Linux Windows Mac系统安装运行,CPU支持X86/ARM64。
Apache HertzBeat (incubating) 支持在Linux Windows Mac系统安装运行,CPU支持X86/ARM64。
由于1.6.0及以后版本使用 `Java 17` ,且安装包不再提供内置jdk的版本,参考以下情况使用新版Hertzbeat。
- 当你的服务器中默认环境变量为 `Java 17` 时,这一步你无需任何操作。
@@ -4,7 +4,7 @@ title: 关系型数据库使用 PostgreSQL 替换依赖的 H2 存储系统元数
sidebar_label: 元数据存储PostgreSQL(推荐)
---
PostgreSQL 是一个功能强大,开源的关系型数据库管理系统(RDBMS)。Apache HertzBeat 除了支持使用默认内置的 H2 数据库外,还可以切换为使用 PostgreSQL 存储监控信息,告警信息,配置信息等结构化关系数据。
PostgreSQL 是一个功能强大,开源的关系型数据库管理系统(RDBMS)。Apache HertzBeat (incubating) 除了支持使用默认内置的 H2 数据库外,还可以切换为使用 PostgreSQL 存储监控信息,告警信息,配置信息等结构化关系数据。
注意⚠️ 使用外置 PostgreSQL 数据库替换内置 H2 数据库为可选项,但建议生产环境配置,以提供更好的性能
@@ -6,7 +6,7 @@ sidebar_label: 快速开始
### 🐕 开始使用
- 如果您是想将 Apache HertzBeat 部署到本地搭建监控系统,请参考下面的部署文档进行操作。
- 如果您是想将 Apache HertzBeat (incubating) 部署到本地搭建监控系统,请参考下面的部署文档进行操作。
### 🍞 HertzBeat安装
@@ -4,7 +4,7 @@ title: 使用 Rainbond 部署 HertzBeat
sidebar_label: 基于Rainbond部署
---
如果你不熟悉 Kubernetes,想在 Kubernetes 中安装 Apache HertzBeat,可以使用 Rainbond 来部署。Rainbond 是一个基于 Kubernetes 构建的云原生应用管理平台,可以很简单的将你的应用部署到 Kubernetes中。
如果你不熟悉 Kubernetes,想在 Kubernetes 中安装 Apache HertzBeat (incubating),可以使用 Rainbond 来部署。Rainbond 是一个基于 Kubernetes 构建的云原生应用管理平台,可以很简单的将你的应用部署到 Kubernetes中。
## Rainbond Cloud 部署
@@ -4,7 +4,7 @@ title: 依赖时序数据库服务TDengine安装初始化(可选)
sidebar_label: 指标数据存储TDengine
---
Apache HertzBeat 的历史数据存储依赖时序数据库,任选其一安装初始化即可,也可不安装(注意⚠️但强烈建议生产环境配置)
Apache HertzBeat (incubating) 的历史数据存储依赖时序数据库,任选其一安装初始化即可,也可不安装(注意⚠️但强烈建议生产环境配置)
> 我们推荐使用并长期支持 VictoriaMetrics 作为存储。
@@ -4,7 +4,7 @@ title: HertzBeat 新版本更新指引
sidebar_label: 版本更新指引
---
**Apache HertzBeat 的发布版本列表**
**Apache HertzBeat (incubating) 的发布版本列表**
- [下载页面](https://hertzbeat.apache.org/docs/download)
- [Github Release](https://github.com/apache/hertzbeat/releases)
@@ -14,7 +14,7 @@ sidebar_label: SpringBoot Web应用监控案例
## HertzBeat 是什么
Apache HertzBeat 一个拥有强大自定义监控能力,无需Agent的实时监控工具。网站监测,PING连通性,端口可用性,数据库,操作系统,中间件,API监控,阈值告警,告警通知(邮件微信钉钉飞书)。
Apache HertzBeat (incubating) 一个拥有强大自定义监控能力,无需Agent的实时监控工具。网站监测,PING连通性,端口可用性,数据库,操作系统,中间件,API监控,阈值告警,告警通知(邮件微信钉钉飞书)。
**github: <https://github.com/apache/hertzbeat>**
@@ -12,7 +12,7 @@ sidebar_label: SSL 证书过期监控案例
## HertzBeat 是什么
Apache HertzBeat 一个拥有强大自定义监控能力,无需Agent的实时监控工具。网站监测,PING连通性,端口可用性,数据库,操作系统,中间件,API监控,阈值告警,告警通知(邮件微信钉钉飞书)。
Apache HertzBeat (incubating) 一个拥有强大自定义监控能力,无需Agent的实时监控工具。网站监测,PING连通性,端口可用性,数据库,操作系统,中间件,API监控,阈值告警,告警通知(邮件微信钉钉飞书)。
github: <https://github.com/apache/hertzbeat>
@@ -32,7 +32,7 @@ github: <https://github.com/apache/hertzbeat>
1. 新增 SSL 证书监控
> 系统页面 -> 监控中心 -> 新增监控 -> 应用服务监控 -> SSL 证书 -> 新增 SSL 证书
> 系统页面 -> 监控菜单 -> 新增监控 -> 服务监控 -> SSL 证书 -> 新增 SSL 证书
![HertzBeat](/img/docs/start/ssl_1.png)

Some files were not shown because too many files have changed in this diff Show More