Compare commits

...
Author SHA1 Message Date
tomsun28 b65d57b492 Merge branch 'master' into update-doc-342 2025-05-23 08:46:03 +08:00
Calvin f31c835181 [doc] japanese clickhouse (#3390) 2025-05-23 08:42:33 +08:00
tomsun28 33d9764631 [doc] update 2025-05-23 08:37:07 +08:00
tomsun28 5d1b1eade7 [doc] update 2025-05-23 08:34:58 +08:00
tomsun28 26f9e66143 [doc] new contributor and committer
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-05-23 08:32:11 +08:00
tomsun28 dca55b6d99 Update @xiaomizhou2 as a contributor 2025-05-23 08:31:00 +08:00
tomsun28 48b1e52585 Add @xiaomizhou2 as a contributor 2025-05-23 08:30:17 +08:00
tomsun28 2a20150d7c Add @Duansg as a contributor 2025-05-23 08:28:43 +08:00
Logicandtomsun28 552554b96d [fix](warehouse): improve GreptimeDB data storage and querying (#3387)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-22 23:31:06 +08:00
zhangyaxiandtomsun28 4adcfd2a4e [test] Add unit tests for HttpSdCollectImpl (#3386)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-22 23:29:23 +08:00
Calvin e630beecb4 [doc] japanese cisco switch (#3389) 2025-05-22 22:46:53 +08:00
Duansgandtomsun28 6c2b38e180 [doc] modify supplement related documentation (#3383)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-21 23:17:50 +08:00
84986dd1bf [feature] support auto nacos service discovery (#3324)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Signed-off-by: zhangyaxi <yaxi.zhang950408@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-05-21 22:01:09 +08:00
af868e083a [Task] Batch import metrics data in victoria-metrics (#3337)
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-05-20 23:56:56 +08:00
be3e2f3558 [doc] modify chinese words (#3380)
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-20 21:42:37 +08:00
d32818e8ef [feat] Support Zookeeper Service Discovery (#3377)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-20 21:30:48 +08:00
10b283522c [improve] add path validation for pluginservice (#3375)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2025-05-20 12:32:24 +08:00
138 changed files with 1765 additions and 346 deletions
+19
View File
@@ -2485,6 +2485,25 @@
"contributions": [
"code"
]
},
{
"login": "Duansg",
"name": "Duansg",
"avatar_url": "https://avatars.githubusercontent.com/u/112607719?v=4",
"profile": "https://github.com/Duansg",
"contributions": [
"doc"
]
},
{
"login": "xiaomizhou2",
"name": "zhangyaxi",
"avatar_url": "https://avatars.githubusercontent.com/u/47807926?v=4",
"profile": "https://github.com/xiaomizhou2",
"contributions": [
"code",
"test"
]
}
],
"contributorsPerLine": 7,
+4
View File
@@ -523,6 +523,10 @@ Thanks to these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boyucjz"><img src="https://avatars.githubusercontent.com/u/18730041?v=4?s=100" width="100px;" alt="boyucjz"/><br /><sub><b>boyucjz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=boyucjz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Cyanty"><img src="https://avatars.githubusercontent.com/u/153884653?v=4?s=100" width="100px;" alt="Cyanty"/><br /><sub><b>Cyanty</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KevinLLF"><img src="https://avatars.githubusercontent.com/u/85452733?v=4?s=100" width="100px;" alt="Jay丿167"/><br /><sub><b>Jay丿167</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=KevinLLF" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Duansg"><img src="https://avatars.githubusercontent.com/u/112607719?v=4?s=100" width="100px;" alt="Duansg"/><br /><sub><b>Duansg</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Duansg" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaomizhou2"><img src="https://avatars.githubusercontent.com/u/47807926?v=4?s=100" width="100px;" alt="zhangyaxi"/><br /><sub><b>zhangyaxi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaomizhou2" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xiaomizhou2" title="Tests">⚠️</a></td>
</tr>
</tbody>
</table>
+8 -4
View File
@@ -34,7 +34,7 @@
-**监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web 服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 兼容 `Prometheus` 的系统生态并且更多,只需页面操作就可以监控 `Prometheus` 所能监控的。
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
@@ -59,8 +59,8 @@
## ⛄ 已支持
> 我们将监控采集类型(mysql,jvm,k8s)都定义为 `yml` 监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
> 我们将监控采集类型(mysql,jvm,k8s)都定义为 `yml` 监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
- [Website](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-website.yml), [Port Telnet](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-port.yml),
[Http Api](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-api.yml), [Ping Connect](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ping.yml),
@@ -98,7 +98,7 @@
- [CiscoSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-cisco_switch.yml), [HpeSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-hpe_switch.yml),
[HuaweiSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-huawei_switch.yml), [TpLinkSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-tplink_switch.yml),
[H3cSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-h3c_switch.yml)
- 和更多自定义监控模
- 和更多自定义监控模
- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱`
## 🐕 快速开始
@@ -521,6 +521,10 @@ Thanks these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boyucjz"><img src="https://avatars.githubusercontent.com/u/18730041?v=4?s=100" width="100px;" alt="boyucjz"/><br /><sub><b>boyucjz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=boyucjz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Cyanty"><img src="https://avatars.githubusercontent.com/u/153884653?v=4?s=100" width="100px;" alt="Cyanty"/><br /><sub><b>Cyanty</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KevinLLF"><img src="https://avatars.githubusercontent.com/u/85452733?v=4?s=100" width="100px;" alt="Jay丿167"/><br /><sub><b>Jay丿167</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=KevinLLF" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Duansg"><img src="https://avatars.githubusercontent.com/u/112607719?v=4?s=100" width="100px;" alt="Duansg"/><br /><sub><b>Duansg</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Duansg" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaomizhou2"><img src="https://avatars.githubusercontent.com/u/47807926?v=4?s=100" width="100px;" alt="zhangyaxi"/><br /><sub><b>zhangyaxi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaomizhou2" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xiaomizhou2" title="Tests">⚠️</a></td>
</tr>
</tbody>
</table>
@@ -164,5 +164,11 @@
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-sftp</artifactId>
</dependency>
<!-- Zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper.version}</version>
</dependency>
</dependencies>
</project>
@@ -179,7 +179,7 @@ public class PrometheusAutoCollectImpl {
builder.addField(CollectRep.Field.newBuilder().setName(label.getName())
.setType(CommonConstants.TYPE_STRING).setLabel(true).build());
});
builder.addField(CollectRep.Field.newBuilder().setName("value")
builder.addField(CollectRep.Field.newBuilder().setName("metric_value")
.setType(CommonConstants.TYPE_NUMBER).setLabel(false).build());
}
Map<String, String> labelMap = metric.getLabels()
@@ -0,0 +1,114 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.sd;
import java.util.List;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.collector.collect.registry.constant.DiscoveryClientInstance;
import org.apache.hertzbeat.collector.collect.registry.discovery.DiscoveryClient;
import org.apache.hertzbeat.collector.collect.registry.discovery.DiscoveryClientManagement;
import org.apache.hertzbeat.collector.collect.registry.discovery.entity.ServiceInstance;
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.RegistryProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.springframework.util.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
/**
* Nacos Service Discovery Collector
* This collector integrates with Nacos to discover registered services
*/
@Slf4j
public class NacosSdCollectImpl extends AbstractCollect {
/**
* Client management to interact with discovery services
*/
private final DiscoveryClientManagement discoveryClientManagement = new DiscoveryClientManagement();
@Override
public void preCheck(Metrics metrics) throws IllegalArgumentException {
// Validate the required configuration is present
if (metrics == null || metrics.getNacos_sd() == null) {
throw new IllegalArgumentException("Nacos service discovery monitoring, the config is null");
}
if (metrics.getNacos_sd().isInvalid()) {
throw new IllegalArgumentException("Nacos service discovery monitoring, the config is invalid");
}
}
@Override
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
// Create Registry protocol from NacosSd protocol
RegistryProtocol registryProtocol = RegistryProtocol.builder()
.host(metrics.getNacos_sd().getHost())
.port(metrics.getNacos_sd().getPort())
.discoveryClientTypeName(DiscoveryClientInstance.NACOS.name())
.build();
DiscoveryClient discoveryClient = null;
try {
// Use the existing NacosDiscoveryClient through DiscoveryClientManagement
discoveryClient = discoveryClientManagement.getClient(registryProtocol);
if (discoveryClient == null) {
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("Failed to get Nacos discovery client");
return;
}
// Get all services registered in Nacos
List<ServiceInstance> services = discoveryClient.getServices();
if (CollectionUtils.isEmpty(services)) {
return;
}
// Populate the response data with service information
services.forEach(service -> {
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
valueRowBuilder.addColumn(service.getAddress());
valueRowBuilder.addColumn(String.valueOf(service.getPort()));
valueRowBuilder.addColumn(service.getServiceName());
valueRowBuilder.addColumn(service.getHealthStatus());
builder.addValueRow(valueRowBuilder.build());
});
} catch (Exception e) {
String errorMsg = CommonUtil.getMessageFromThrowable(e);
log.warn("Failed to fetch services from Nacos: {}", errorMsg);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
} finally {
// Close the discovery client to release resources
if (discoveryClient != null) {
try {
discoveryClient.close();
} catch (Exception e) {
log.warn("Failed to close Nacos discovery client: {}", CommonUtil.getMessageFromThrowable(e));
}
}
}
}
@Override
public String supportProtocol() {
return DispatchConstants.PROTOCOL_NACOS_SD;
}
}
@@ -0,0 +1,95 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.sd;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.entity.job.protocol.ZookeeperSdProtocol;
import org.apache.hertzbeat.common.entity.sd.ConnectionConfig;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.hertzbeat.common.util.CommonUtil;
import java.io.IOException;
import java.util.List;
/**
* zookeeper sd collector
*/
@Slf4j
public class ZookeeperSdCollectImpl extends AbstractCollect {
private static int TIMEOUT = 30000;
@Override
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
ZookeeperSdProtocol zookeeperSdProtocol = metrics.getZookeeper_sd();
String url = zookeeperSdProtocol.getUrl();
String pathPrefix = zookeeperSdProtocol.getPathPrefix();
try (ZooKeeper zk = new ZooKeeper(url, TIMEOUT, event -> {})){
List<String> children = zk.getChildren(pathPrefix, false);
List<ConnectionConfig> connectionConfigs = children.stream().map(node -> {
String[] split = node.split(":");
if (split.length != 2) log.warn("Node format is incorrect: {}, expected format is 'host:port'", node);
return new ConnectionConfig(split[0], split[1]);
}).toList();
connectionConfigs.forEach(config -> {
CollectRep.ValueRow valueRow = CollectRep.ValueRow.newBuilder()
.addColumn(config.getHost())
.addColumn(config.getPort())
.build();
builder.addValueRow(valueRow);
});
} catch (IOException e){
String errorMsg = CommonUtil.getMessageFromThrowable(e);
log.error("Failed to connect to Zookeeper: {}", errorMsg);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
} catch (InterruptedException e) {
String errorMsg = CommonUtil.getMessageFromThrowable(e);
log.error("Zookeeper connection interrupted: {}", errorMsg);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
} catch (KeeperException e) {
String errorMsg = CommonUtil.getMessageFromThrowable(e);
log.error("Zookeeper operation failed: {}", errorMsg);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
}
}
@Override
public void preCheck(Metrics metrics) throws IllegalArgumentException {
if (metrics.getZookeeper_sd() == null) {
throw new IllegalArgumentException("Zookeeper SD configuration cannot be null");
}
if (metrics.getZookeeper_sd().getUrl() == null || metrics.getZookeeper_sd().getUrl().isEmpty()) {
throw new IllegalArgumentException("Zookeeper URL cannot be null or empty");
}
if (metrics.getZookeeper_sd().getPathPrefix() == null || metrics.getZookeeper_sd().getPathPrefix().isEmpty()) {
throw new IllegalArgumentException("Zookeeper path prefix cannot be null or empty");
}
}
@Override
public String supportProtocol() {
return "zookeeper_sd";
}
}
@@ -0,0 +1,198 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.sd;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import lombok.SneakyThrows;
import org.apache.hertzbeat.collector.collect.common.http.CommonHttpClient;
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.HttpProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.entity.sd.ServiceDiscoveryResponseEntity;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.apache.http.HttpEntity;
import org.apache.http.ProtocolVersion;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicStatusLine;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
/**
* Test case for {@link HttpSdCollectImpl}
*/
@ExtendWith(MockitoExtension.class)
class HttpSdCollectImplTest {
@InjectMocks
private HttpSdCollectImpl httpSdCollectImpl;
@Mock
private CloseableHttpClient httpClient;
@Mock
private CloseableHttpResponse httpResponse;
private Metrics metrics;
private HttpProtocol httpProtocol;
private CollectRep.MetricsData.Builder builder;
@BeforeEach
void setUp() {
httpProtocol = HttpProtocol.builder()
.url("http://localhost:8080/services")
.build();
metrics = Metrics.builder()
.http_sd(httpProtocol)
.build();
builder = CollectRep.MetricsData.newBuilder();
}
@Test
void testCollectSuccess() throws IOException {
List<ServiceDiscoveryResponseEntity> responseEntities = new ArrayList<>();
ServiceDiscoveryResponseEntity entity1 = new ServiceDiscoveryResponseEntity();
entity1.setTarget(Arrays.asList("192.168.1.10:8080", "192.168.1.11:8081"));
ServiceDiscoveryResponseEntity entity2 = new ServiceDiscoveryResponseEntity();
entity2.setTarget(Arrays.asList("192.168.1.12:8082"));
responseEntities.add(entity1);
responseEntities.add(entity2);
String jsonResponse = JsonUtil.toJson(responseEntities);
try (MockedStatic<CommonHttpClient> mockedHttpClient = Mockito.mockStatic(CommonHttpClient.class)) {
mockedHttpClient.when(CommonHttpClient::getHttpClient).thenReturn(httpClient);
when(httpClient.execute(any(HttpUriRequest.class))).thenReturn(httpResponse);
StatusLine statusLine = new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK");
when(httpResponse.getStatusLine()).thenReturn(statusLine);
HttpEntity entity = new StringEntity(jsonResponse, ContentType.APPLICATION_JSON);
when(httpResponse.getEntity()).thenReturn(entity);
httpSdCollectImpl.collect(builder, metrics);
assertEquals(3, builder.getValuesCount());
CollectRep.ValueRow firstRow = builder.getValues(0);
assertEquals("192.168.1.10", firstRow.getColumns(0));
assertEquals("8080", firstRow.getColumns(1));
CollectRep.ValueRow secondRow = builder.getValues(1);
assertEquals("192.168.1.11", secondRow.getColumns(0));
assertEquals("8081", secondRow.getColumns(1));
CollectRep.ValueRow thirdRow = builder.getValues(2);
assertEquals("192.168.1.12", thirdRow.getColumns(0));
assertEquals("8082", thirdRow.getColumns(1));
}
}
@Test
void testCollectWithNon200Status() throws IOException {
try (MockedStatic<CommonHttpClient> mockedHttpClient = Mockito.mockStatic(CommonHttpClient.class)) {
mockedHttpClient.when(CommonHttpClient::getHttpClient).thenReturn(httpClient);
when(httpClient.execute(any(HttpUriRequest.class))).thenReturn(httpResponse);
StatusLine statusLine = new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 404, "Not Found");
when(httpResponse.getStatusLine()).thenReturn(statusLine);
httpSdCollectImpl.collect(builder, metrics);
assertEquals(CollectRep.Code.FAIL, builder.getCode());
assertEquals("StatusCode 404", builder.getMsg());
}
}
@SneakyThrows
@Test
void testCollectWithException() {
String exceptionMessage = "Connection refused";
IOException testException = new IOException(exceptionMessage);
try (MockedStatic<CommonHttpClient> mockedHttpClient = Mockito.mockStatic(CommonHttpClient.class);
MockedStatic<CommonUtil> mockedCommonUtil = Mockito.mockStatic(CommonUtil.class)) {
mockedHttpClient.when(CommonHttpClient::getHttpClient).thenReturn(httpClient);
when(httpClient.execute(any(HttpUriRequest.class))).thenThrow(testException);
mockedCommonUtil.when(() -> CommonUtil.getMessageFromThrowable(any(Throwable.class)))
.thenReturn(exceptionMessage);
httpSdCollectImpl.collect(builder, metrics);
assertEquals(CollectRep.Code.FAIL, builder.getCode());
assertEquals(exceptionMessage, builder.getMsg());
}
}
@Test
void testCollectWithEmptyServiceList() throws IOException {
List<ServiceDiscoveryResponseEntity> emptyList = Collections.emptyList();
String jsonResponse = JsonUtil.toJson(emptyList);
try (MockedStatic<CommonHttpClient> mockedHttpClient = Mockito.mockStatic(CommonHttpClient.class)) {
mockedHttpClient.when(CommonHttpClient::getHttpClient).thenReturn(httpClient);
when(httpClient.execute(any(HttpUriRequest.class))).thenReturn(httpResponse);
StatusLine statusLine = new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK");
when(httpResponse.getStatusLine()).thenReturn(statusLine);
HttpEntity entity = new StringEntity(jsonResponse, ContentType.APPLICATION_JSON);
when(httpResponse.getEntity()).thenReturn(entity);
httpSdCollectImpl.collect(builder, metrics);
assertEquals(0, builder.getValuesCount());
}
}
@Test
void testSupportProtocol() {
assertEquals(DispatchConstants.PROTOCOL_HTTP_SD, httpSdCollectImpl.supportProtocol());
}
}
@@ -0,0 +1,233 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.sd;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import lombok.SneakyThrows;
import org.apache.hertzbeat.collector.collect.registry.discovery.DiscoveryClient;
import org.apache.hertzbeat.collector.collect.registry.discovery.DiscoveryClientManagement;
import org.apache.hertzbeat.collector.collect.registry.discovery.entity.ServiceInstance;
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.NacosSdProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.RegistryProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
/**
* Test case for {@link NacosSdCollectImpl}
*/
@ExtendWith(MockitoExtension.class)
class NacosSdCollectImplTest {
@InjectMocks
private NacosSdCollectImpl nacosSdCollectImpl;
@Mock
private DiscoveryClientManagement discoveryClientManagement;
@Mock
private DiscoveryClient discoveryClient;
private Metrics metrics;
private NacosSdProtocol nacosSdProtocol;
private CollectRep.MetricsData.Builder builder;
@BeforeEach
void setUp() {
nacosSdProtocol = NacosSdProtocol.builder()
.host("localhost")
.port("8848")
.username("nacos")
.password("nacos")
.build();
metrics = Metrics.builder()
.nacos_sd(nacosSdProtocol)
.build();
builder = CollectRep.MetricsData.newBuilder();
ReflectionTestUtils.setField(nacosSdCollectImpl, "discoveryClientManagement", discoveryClientManagement);
}
@Test
void testPreCheckWithNullMetrics() {
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
() -> nacosSdCollectImpl.preCheck(null));
assertEquals("Nacos service discovery monitoring, the config is null", exception.getMessage());
}
@Test
void testPreCheckWithNullNacosSdConfig() {
Metrics metricsWithoutNacosSd = Metrics.builder().build();
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
() -> nacosSdCollectImpl.preCheck(metricsWithoutNacosSd));
assertEquals("Nacos service discovery monitoring, the config is null", exception.getMessage());
}
@Test
void testPreCheckWithInvalidNacosSdConfig() {
NacosSdProtocol invalidNacosSdProtocol = NacosSdProtocol.builder()
.host("")
.port("8848")
.build();
Metrics metricsWithInvalidNacosSd = Metrics.builder()
.nacos_sd(invalidNacosSdProtocol)
.build();
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
() -> nacosSdCollectImpl.preCheck(metricsWithInvalidNacosSd));
assertEquals("Nacos service discovery monitoring, the config is invalid", exception.getMessage());
NacosSdProtocol portInvalidNacosSdProtocol = NacosSdProtocol.builder()
.host("localhost")
.port("")
.build();
Metrics portMetricsWithInvalidNacosSd = Metrics.builder()
.nacos_sd(portInvalidNacosSdProtocol)
.build();
exception = assertThrows(IllegalArgumentException.class,
() -> nacosSdCollectImpl.preCheck(portMetricsWithInvalidNacosSd));
assertEquals("Nacos service discovery monitoring, the config is invalid", exception.getMessage());
}
@Test
void testPreCheckWithValidConfig() {
assertDoesNotThrow(() -> nacosSdCollectImpl.preCheck(metrics));
}
@Test
void testCollectSuccess() throws Exception {
List<ServiceInstance> services = new ArrayList<>();
services.add(ServiceInstance.builder()
.serviceId("service-1")
.serviceName("user-service")
.address("192.168.1.10")
.port(8080)
.healthStatus("UP")
.build());
services.add(ServiceInstance.builder()
.serviceId("service-2")
.serviceName("order-service")
.address("192.168.1.11")
.port(8081)
.healthStatus("UP")
.build());
when(discoveryClientManagement.getClient(any(RegistryProtocol.class))).thenReturn(discoveryClient);
when(discoveryClient.getServices()).thenReturn(services);
nacosSdCollectImpl.collect(builder, metrics);
verify(discoveryClient, times(1)).close();
assertEquals(2, builder.getValuesCount());
CollectRep.ValueRow firstRow = builder.getValues(0);
assertEquals("192.168.1.10", firstRow.getColumns(0));
assertEquals("8080", firstRow.getColumns(1));
assertEquals("user-service", firstRow.getColumns(2));
assertEquals("UP", firstRow.getColumns(3));
CollectRep.ValueRow secondRow = builder.getValues(1);
assertEquals("192.168.1.11", secondRow.getColumns(0));
assertEquals("8081", secondRow.getColumns(1));
assertEquals("order-service", secondRow.getColumns(2));
assertEquals("UP", secondRow.getColumns(3));
}
@Test
void testCollectClientNull() {
when(discoveryClientManagement.getClient(any(RegistryProtocol.class))).thenReturn(null);
nacosSdCollectImpl.collect(builder, metrics);
assertEquals(CollectRep.Code.FAIL, builder.getCode());
assertEquals("Failed to get Nacos discovery client", builder.getMsg());
}
@SneakyThrows
@Test
void testCollectWithException() {
String exceptionMessage = "Connection refused";
Exception testException = new RuntimeException(exceptionMessage);
when(discoveryClientManagement.getClient(any(RegistryProtocol.class))).thenReturn(discoveryClient);
when(discoveryClient.getServices()).thenThrow(testException);
try (MockedStatic<CommonUtil> mockedCommonUtil = Mockito.mockStatic(CommonUtil.class)) {
mockedCommonUtil.when(() -> CommonUtil.getMessageFromThrowable(any(Throwable.class)))
.thenReturn(exceptionMessage);
nacosSdCollectImpl.collect(builder, metrics);
assertEquals(CollectRep.Code.FAIL, builder.getCode());
assertEquals(exceptionMessage, builder.getMsg());
verify(discoveryClient, times(1)).close();
}
}
@Test
void testCollectWithEmptyServiceList() throws Exception {
when(discoveryClientManagement.getClient(any(RegistryProtocol.class))).thenReturn(discoveryClient);
when(discoveryClient.getServices()).thenReturn(Collections.emptyList());
nacosSdCollectImpl.collect(builder, metrics);
assertEquals(0, builder.getValuesCount());
verify(discoveryClient, times(1)).close();
}
@Test
void testSupportProtocol() {
assertEquals(DispatchConstants.PROTOCOL_NACOS_SD, nacosSdCollectImpl.supportProtocol());
}
}
@@ -0,0 +1,113 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.sd;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.ZookeeperSdProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.zookeeper.ZooKeeper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class ZookeeperSdCollectImplTest {
private ZookeeperSdCollectImpl zookeeperSdCollect;
private Metrics metrics;
private ZookeeperSdProtocol protocol;
private CollectRep.MetricsData.Builder builder;
@BeforeEach
void setUp() {
zookeeperSdCollect = new ZookeeperSdCollectImpl();
protocol = ZookeeperSdProtocol.builder()
.url("localhost:2181")
.pathPrefix("/services")
.build();
metrics = Metrics.builder()
.zookeeper_sd(protocol)
.build();
builder = CollectRep.MetricsData.newBuilder();
}
@Test
void testPreCheckWithNullConfig() {
Metrics invalid = Metrics.builder().build();
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
() -> zookeeperSdCollect.preCheck(invalid));
assertEquals("Zookeeper SD configuration cannot be null", e.getMessage());
}
@Test
void testPreCheckWithEmptyUrl() {
ZookeeperSdProtocol badProtocol = ZookeeperSdProtocol.builder().url("").pathPrefix("/path").build();
Metrics m = Metrics.builder().zookeeper_sd(badProtocol).build();
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
() -> zookeeperSdCollect.preCheck(m));
assertEquals("Zookeeper URL cannot be null or empty", e.getMessage());
}
@Test
void testPreCheckWithEmptyPath() {
ZookeeperSdProtocol badProtocol = ZookeeperSdProtocol.builder().url("host").pathPrefix("").build();
Metrics m = Metrics.builder().zookeeper_sd(badProtocol).build();
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
() -> zookeeperSdCollect.preCheck(m));
assertEquals("Zookeeper path prefix cannot be null or empty", e.getMessage());
}
@Test
void testPreCheckValid() {
assertDoesNotThrow(() -> zookeeperSdCollect.preCheck(metrics));
}
@Test
void testSupportProtocol() {
assertEquals("zookeeper_sd", zookeeperSdCollect.supportProtocol());
}
@Test
void testCollectSuccess() throws Exception {
try (MockedConstruction<ZooKeeper> mocked = Mockito.mockConstruction(ZooKeeper.class,
(mock, context) -> Mockito.when(mock.getChildren("/services", false)).thenReturn(List.of("host1:8080", "host2:9090")))) {
zookeeperSdCollect.collect(builder, metrics);
assertEquals(2, builder.getValuesCount());
assertEquals("host1", builder.getValues(0).getColumns(0));
assertEquals("8080", builder.getValues(0).getColumns(1));
assertEquals("host2", builder.getValues(1).getColumns(0));
assertEquals("9090", builder.getValues(1).getColumns(1));
}
}
}
@@ -28,7 +28,7 @@ import java.util.concurrent.ScheduledExecutorService;
import org.apache.hertzbeat.collector.dispatch.CollectorInfoProperties;
import org.apache.hertzbeat.collector.dispatch.DispatchProperties;
import org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectJobService;
import org.apache.hertzbeat.collector.dispatch.timer.TimerDispatch;
import org.apache.hertzbeat.collector.timer.TimerDispatch;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
import org.apache.hertzbeat.common.support.CommonThreadPool;
import org.apache.hertzbeat.remoting.RemotingClient;
@@ -32,7 +32,7 @@ import java.util.concurrent.CountDownLatch;
import org.apache.hertzbeat.collector.dispatch.DispatchProperties;
import org.apache.hertzbeat.collector.dispatch.WorkerPool;
import org.apache.hertzbeat.collector.dispatch.entrance.CollectServer;
import org.apache.hertzbeat.collector.dispatch.timer.TimerDispatch;
import org.apache.hertzbeat.collector.timer.TimerDispatch;
import org.apache.hertzbeat.common.entity.job.Job;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
import org.apache.hertzbeat.common.entity.message.CollectRep;
@@ -23,9 +23,9 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectJobService;
import org.apache.hertzbeat.collector.dispatch.timer.Timeout;
import org.apache.hertzbeat.collector.dispatch.timer.TimerDispatch;
import org.apache.hertzbeat.collector.dispatch.timer.WheelTimerTask;
import org.apache.hertzbeat.common.timer.Timeout;
import org.apache.hertzbeat.collector.timer.TimerDispatch;
import org.apache.hertzbeat.collector.timer.WheelTimerTask;
import org.apache.hertzbeat.collector.dispatch.unit.UnitConvert;
import org.apache.hertzbeat.collector.util.CollectUtil;
import org.apache.hertzbeat.common.entity.job.Configmap;
@@ -23,8 +23,8 @@ import org.apache.commons.jexl3.JexlExpression;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.collector.collect.prometheus.PrometheusAutoCollectImpl;
import org.apache.hertzbeat.collector.collect.strategy.CollectStrategyFactory;
import org.apache.hertzbeat.collector.dispatch.timer.Timeout;
import org.apache.hertzbeat.collector.dispatch.timer.WheelTimerTask;
import org.apache.hertzbeat.common.timer.Timeout;
import org.apache.hertzbeat.collector.timer.WheelTimerTask;
import org.apache.hertzbeat.collector.dispatch.unit.UnitConvert;
import org.apache.hertzbeat.collector.util.CollectUtil;
import org.apache.hertzbeat.common.constants.CommonConstants;
@@ -29,6 +29,7 @@ org.apache.hertzbeat.collector.collect.mqtt.MqttCollectImpl
org.apache.hertzbeat.collector.collect.ipmi2.IpmiCollectImpl
org.apache.hertzbeat.collector.collect.kafka.KafkaCollectImpl
org.apache.hertzbeat.collector.collect.sd.HttpSdCollectImpl
org.apache.hertzbeat.collector.collect.sd.NacosSdCollectImpl
org.apache.hertzbeat.collector.collect.sd.DnsSdCollectImpl
org.apache.hertzbeat.collector.collect.sd.EurekaSdCollectImpl
org.apache.hertzbeat.collector.collect.sd.ConsulSdCollectImpl
@@ -17,7 +17,7 @@
package org.apache.hertzbeat.collector.dispatch;
import org.apache.hertzbeat.collector.dispatch.timer.Timeout;
import org.apache.hertzbeat.common.timer.Timeout;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.message.CollectRep;
@@ -127,6 +127,10 @@ public interface DispatchConstants {
* protocol http sd
*/
String PROTOCOL_HTTP_SD = "http_sd";
/**
* protocol nacos sd
*/
String PROTOCOL_NACOS_SD = "nacos_sd";
/**
* protocol dns sd
*/
@@ -17,7 +17,7 @@
package org.apache.hertzbeat.collector.dispatch;
import org.apache.hertzbeat.collector.dispatch.timer.Timeout;
import org.apache.hertzbeat.common.timer.Timeout;
/**
* Metrics collection task scheduler interface
@@ -31,7 +31,7 @@ import org.apache.hertzbeat.collector.dispatch.entrance.processor.GoCloseProcess
import org.apache.hertzbeat.collector.dispatch.entrance.processor.GoOfflineProcessor;
import org.apache.hertzbeat.collector.dispatch.entrance.processor.GoOnlineProcessor;
import org.apache.hertzbeat.collector.dispatch.entrance.processor.HeartbeatProcessor;
import org.apache.hertzbeat.collector.dispatch.timer.TimerDispatch;
import org.apache.hertzbeat.collector.timer.TimerDispatch;
import org.apache.hertzbeat.common.entity.dto.CollectorInfo;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
import org.apache.hertzbeat.common.support.CommonThreadPool;
@@ -22,7 +22,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.dispatch.DispatchProperties;
import org.apache.hertzbeat.collector.dispatch.WorkerPool;
import org.apache.hertzbeat.collector.dispatch.entrance.CollectServer;
import org.apache.hertzbeat.collector.dispatch.timer.TimerDispatch;
import org.apache.hertzbeat.collector.timer.TimerDispatch;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.job.Job;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
@@ -20,7 +20,7 @@ package org.apache.hertzbeat.collector.dispatch.entrance.processor;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.dispatch.entrance.CollectServer;
import org.apache.hertzbeat.collector.dispatch.timer.TimerDispatch;
import org.apache.hertzbeat.collector.timer.TimerDispatch;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
import org.apache.hertzbeat.common.support.SpringContextHolder;
@@ -20,7 +20,7 @@ package org.apache.hertzbeat.collector.dispatch.entrance.processor;
import com.google.protobuf.ByteString;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.dispatch.timer.TimerDispatch;
import org.apache.hertzbeat.collector.timer.TimerDispatch;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
import org.apache.hertzbeat.common.support.SpringContextHolder;
@@ -20,7 +20,7 @@ package org.apache.hertzbeat.collector.dispatch.entrance.processor;
import com.google.protobuf.ByteString;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.dispatch.timer.TimerDispatch;
import org.apache.hertzbeat.collector.timer.TimerDispatch;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
import org.apache.hertzbeat.common.support.SpringContextHolder;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.hertzbeat.collector.dispatch.timer;
package org.apache.hertzbeat.collector.timer;
import org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectResponseEventListener;
import org.apache.hertzbeat.common.entity.job.Job;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.hertzbeat.collector.dispatch.timer;
package org.apache.hertzbeat.collector.timer;
import java.util.List;
import java.util.Map;
@@ -28,6 +28,9 @@ import org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectResponse
import org.apache.hertzbeat.common.entity.job.Job;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.timer.HashedWheelTimer;
import org.apache.hertzbeat.common.timer.Timeout;
import org.apache.hertzbeat.common.timer.Timer;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.hertzbeat.collector.dispatch.timer;
package org.apache.hertzbeat.collector.timer;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
@@ -28,6 +28,8 @@ import org.apache.hertzbeat.common.entity.job.Configmap;
import org.apache.hertzbeat.common.entity.job.Job;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.support.SpringContextHolder;
import org.apache.hertzbeat.common.timer.Timeout;
import org.apache.hertzbeat.common.timer.TimerTask;
import org.apache.hertzbeat.common.util.AesUtil;
import java.util.ArrayList;
@@ -36,6 +36,7 @@ import org.apache.hertzbeat.common.entity.job.protocol.HttpProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.EurekaSdProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.ConsulSdProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.ModbusProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.NacosSdProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.PlcProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.RegistryProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.IcmpProtocol;
@@ -66,11 +67,12 @@ import org.apache.hertzbeat.common.entity.job.protocol.TelnetProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.UdpProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.WebsocketProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.entity.job.protocol.ZookeeperSdProtocol;
/**
* Details of the monitoring metrics collected
* eg: cpu | memory | health
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@@ -278,6 +280,14 @@ public class Metrics {
* consul sd protocol
*/
private ConsulSdProtocol consul_sd;
/**
* nacos sd protocol
*/
private NacosSdProtocol nacos_sd;
/*
* zookeeper sd protocol
*/
private ZookeeperSdProtocol zookeeper_sd;
/**
* Monitoring configuration information using the public plc protocol
*/
@@ -0,0 +1,63 @@
/*
* 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.entity.job.protocol;
import org.apache.commons.lang3.StringUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Nacos Service Discovery Protocol
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class NacosSdProtocol implements Protocol {
/**
* Nacos server host
*/
private String host;
/**
* Nacos server port
*/
private String port;
/**
* Nacos namespace
*/
private String namespace;
/**
* Nacos username for authentication
*/
private String username;
/**
* Nacos password for authentication
*/
private String password;
/**
* Check if the essential protocol parameters are invalid
* @return true if essential parameters are missing
*/
public boolean isInvalid() {
return StringUtils.isAnyBlank(host, port);
}
}
@@ -0,0 +1,37 @@
/*
* 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.entity.job.protocol;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
/**
* Zookeeper service discovery protocol
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ZookeeperSdProtocol implements Protocol{
private String url;
private String pathPrefix;
}
@@ -77,7 +77,7 @@ public class Monitor {
@Size(max = 100)
private String app;
@Schema(title = "Scrape type: static | http_sd | dns_sd", example = "static", accessMode = READ_WRITE)
@Schema(title = "Scrape type: static | http_sd | dns_sd | zookeeper_sd", example = "static", accessMode = READ_WRITE)
@Size(max = 100)
private String scrape;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.hertzbeat.collector.dispatch.timer;
package org.apache.hertzbeat.common.timer;
import org.apache.hertzbeat.common.util.NetworkUtil;
import org.slf4j.Logger;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.hertzbeat.collector.dispatch.timer;
package org.apache.hertzbeat.common.timer;
/**
* Derived from Apache Dubbo org.apache.dubbo.common.timer.Timeout
@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.hertzbeat.collector.dispatch.timer;
package org.apache.hertzbeat.common.timer;
import java.util.Set;
import java.util.concurrent.RejectedExecutionException;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.hertzbeat.collector.dispatch.timer;
package org.apache.hertzbeat.common.timer;
import java.util.concurrent.TimeUnit;
@@ -20,8 +20,8 @@ package org.apache.hertzbeat.collector.collect;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.dispatch.CollectDataDispatch;
import org.apache.hertzbeat.collector.dispatch.MetricsCollect;
import org.apache.hertzbeat.collector.dispatch.timer.Timeout;
import org.apache.hertzbeat.collector.dispatch.timer.WheelTimerTask;
import org.apache.hertzbeat.common.timer.Timeout;
import org.apache.hertzbeat.collector.timer.WheelTimerTask;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.job.Job;
import org.apache.hertzbeat.common.entity.job.Metrics;
@@ -224,7 +224,9 @@ public class PluginServiceImpl implements PluginService {
List<PluginItem> pluginItems = new ArrayList<>();
AtomicInteger pluginImplementationCount = new AtomicInteger(0);
try {
validateFilePath(jarFile);
URL jarUrl = new URL("file:" + jarFile.getAbsolutePath());
validateJarUrl(jarUrl);
try (URLClassLoader classLoader = new URLClassLoader(new URL[]{jarUrl}, this.getClass().getClassLoader());
JarFile jar = new JarFile(jarFile)) {
Enumeration<JarEntry> entries = jar.entries();
@@ -272,6 +274,35 @@ public class PluginServiceImpl implements PluginService {
return metadata;
}
/**
* Validate that the file resides within the expected directory.
*
* @param file the file to validate
*/
private void validateFilePath(File file) {
try {
String canonicalPath = file.getCanonicalPath();
String expectedDir = new File("plugin-lib").getCanonicalPath();
if (!canonicalPath.startsWith(expectedDir)) {
throw new CommonException("File is outside the allowed directory: " + canonicalPath);
}
} catch (IOException e) {
log.error("Error validating file path: {}", file.getAbsolutePath(), e);
throw new CommonException("Error validating file path: " + file.getAbsolutePath());
}
}
/**
* Validate that the URL uses the 'file:' protocol and does not point to an external resource.
*
* @param url the URL to validate
*/
private void validateJarUrl(URL url) {
if (!"file".equals(url.getProtocol())) {
throw new CommonException("Invalid URL protocol: " + url.getProtocol());
}
}
private void validateMetadata(PluginMetadata metadata) {
if (metadataDao.countPluginMetadataByName(metadata.getName()) != 0) {
throw new CommonException("A plugin named " + metadata.getName() + " already exists");
@@ -60,6 +60,9 @@ warehouse:
url: http://localhost:8428
username: root
password: root
insert:
buffer-size: 1000
flush-interval: 3
td-engine:
enabled: false
driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
@@ -137,6 +137,9 @@ warehouse:
url: http://localhost:8428
username: root
password: root
insert:
buffer-size: 1000
flush-interval: 3
cluster:
enabled: false
select:
@@ -147,6 +150,8 @@ warehouse:
url: http://localhost:8480
username: root
password: root
buffer-size: 1000
flush-interval: 3
td-engine:
enabled: false
driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
@@ -27,7 +27,7 @@ help:
zh-CN: HertzBeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMX 协议</a> 对 Apache ActiveMQ 消息中间件的运行状态,节点,Topic等相关指标(broker、topic、memory pool、class loading、thread)进行监测。<br><span class='help_module_span'>⚠️注意:您需要在 ActiveMQ 开启 JMX 服务。<a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>点击查看开启步骤</a>。</span>
en-US: "HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMX protocol</a> to monitor the running status, nodes, topics, and other metrics of Apache ActiveMQ message-oriented middleware. <br><span class='help_module_span'>⚠️Note: You should enable the JMX service in ActiveMQ. <a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/activemq'>Click here to view the specific steps.</a></span>"
zh-TW: HertzBeat使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMX 協定</a> 對 Apache ActiveMQ 消息中介軟體的運行狀態,節點,Topic 等相關名額(broker、topic、memory pool、class loading、thread)進行監測。<br><span class='help_module_span'> ⚠️注意:您需要在 ActiveMQ 開啟 JMX 服務。<a class='help_module_content' href=' https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>點擊查看開啟步驟</a>。</span>
ja-JP: HertzBeatは <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMXプロトコルを介して</a> Apache ActiveMQメッセージングシステムのランタイムステータス、ノード、トピック、その他の関連指標を監視します。<br><span class='help_module_span'> ⚠️注意:ActiveMQ で JMX サービスを有効にする必要があります。<a class='help_module_content' href=' https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>クリックしてガイドを見ます</a>。</span>
ja-JP: HertzBeatは <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMXプロトコルを介して</a> Apache ActiveMQメッセージングシステムのランタイムステータス、ノード、トピック、その他の関連メトリックを監視します。<br><span class='help_module_span'> ⚠️注意:ActiveMQ で JMX サービスを有効にする必要があります。<a class='help_module_content' href=' https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>クリックしてガイドを見ます</a>。</span>
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/activemq
en-US: https://hertzbeat.apache.org/docs/help/activemq
@@ -27,7 +27,7 @@ help:
zh-CN: Hertzbeat 对 Apache Airflow 通用性能指标(airflow health、airflow version)进行采集监控。<br>您可以点击“<i>新建 Apache Airflow </i>”并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
en-US: HertzBeat monitors Apache Airflow through general performance metrics such as airflow health and airflow version. You could click the "<i>New Apache Airflow</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: Hertzbeat對Apache Airflow通用性能指標(airflow health、airflow version)進行採集監控。<br>您可以點擊“<i>新建 Apache Airflow</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
ja-JP: Hertzbeatは、Apache Airflowの一般的なパフォーマンス指標を監視します。 <br><i>新規Apache Airflow</i>をクリックして設定しましょう。
ja-JP: Hertzbeatは、Apache Airflowの一般的なパフォーマンスのメトリックを監視します。 <br><i>新規Apache Airflow</i>をクリックして設定しましょう。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/airflow/
en-US: https://hertzbeat.apache.org/docs/help/airflow/
@@ -27,7 +27,7 @@ help:
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 AlmaLinux 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 AlmaLinux</i>”并配置HOST端口账户等相关参数进行添加,支持SSH账户密码或密钥认证。或者选择“<i>更多操作</i>”,导入已有配置。
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH protocol</a> to monitors AlmaLinux operating system's general performance metrics such as cpu, memory, disk, basic, interface, disk_free, top_process etc. <br>You can click the "<i>New AlmaLinux</i>" and config host port and other related params to add, auth support password or secretKey. Or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 AlmaLinux 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建AlmaLinux</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> AlmaLinuxシステムの一般的なパフォーマンス指標監視します。<br>「<i>新規 AlmaLinux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> AlmaLinuxシステムの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 AlmaLinux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/almalinux
en-US: https://hertzbeat.apache.org/docs/help/almalinux
@@ -27,7 +27,7 @@ help:
zh-CN: Hertzbeat 将调用 HTTP API 接口,查看接口是否可用,并以 ms 为指标单位对其响应时间等指标进行监测。您可以先点击“新增 HTTP API”按钮并进行配置,或在“更多操作”中导入已有配置。
en-US: The platform will invoke an HTTP API endpoint to verify its accessibility and monitor various metrics, including response time, measured in milliseconds (ms). <br>To set up this functionality, you could click the "Add HTTP API" button and proceed with the configuration or import an existing setup through the "More Actions" menu.
zh-TW: Hertzbeat將調用HTTP API介面,查看介面是否可用,並以ms為名額組織對其回應時間等名額進行監測。 您可以先點擊“新增HTTP API”按鈕並進行配寘,或在“更多操作”中導入已有配寘。
ja-JP: Hertzbeatは、HTTP APIを呼び出して利用可能かどうかを確認し、応答時間(ms)などのメトリクを監視します。「新規HTTP API」をクリックして設定しましょう。
ja-JP: Hertzbeatは、HTTP APIを呼び出して利用可能かどうかを確認し、応答時間(ms)などのメトリクを監視します。「新規HTTP API」をクリックして設定しましょう。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/api
en-US: https://hertzbeat.apache.org/docs/help/api
@@ -27,7 +27,7 @@ help:
zh-CN: 监控 HTTP API 接口,对 API 返回的业务自定义状态码(非 Http 状态码)进行监控。此需通过配置 JsonPath 来解析您 API 的业务状态码路径。<br>您可以点击 “<i>新建 API Code</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
en-US: Monitor HTTP API to monitor business-defined status codes (non-HTTP status codes) returned by API. To do this, you need to configure JsonPath to resolve the business status code path of your API. <br>You could click the "<i>New API Codes</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: 監控 HTTP API 接口,對 API 返回的業務自定義狀態碼(非 Http 狀態碼)進行監控。此需通過配置 JsonPath 來解析您 API 的業務狀態碼路徑。<br>您可以點擊“<i>新建API Code</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
ja-JP: Hertzbeatは、HTTP APIを呼び出して利用可能かどうかを確認し、ビジネスステータスコード(HTTPステータスコードではない)のメトリクを監視します。これには、API のビジネスステータスコードのパスを解析するように JsonPath を構成する必要があります。「新規API Code」をクリックして設定しましょう。
ja-JP: Hertzbeatは、HTTP APIを呼び出して利用可能かどうかを確認し、ビジネスステータスコード(HTTPステータスコードではない)のメトリクを監視します。これには、API のビジネスステータスコードのパスを解析するように JsonPath を構成する必要があります。「新規API Code」をクリックして設定しましょう。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/api_code
en-US: https://hertzbeat.apache.org/docs/help/api_code
@@ -27,7 +27,7 @@ help:
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 Centos 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 Centos</i>”并配置HOST端口账户等相关参数进行添加,支持SSH账户密码或密钥认证。或者选择“<i>更多操作</i>”,导入已有配置。
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH protocol</a> to monitors Centos operating system's general performance metrics such as cpu, memory, disk, basic, interface, disk_free, top_process etc. <br>You can click the "<i>New Centos</i>" and config host port and other related params to add, auth support password or secretKey. Or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 Centos 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 Centos</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Centosシステムの一般的なパフォーマンス指標監視します。<br>「<i>新規 Centos Linux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Centosシステムの一般的なパフォーマンスのメトリック監視します。<br>「<i>新規 Centos Linux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/centos/
en-US: https://hertzbeat.apache.org/docs/help/centos/
@@ -21,11 +21,13 @@ app: cisco_switch
name:
zh-CN: 思科通用交换机
en-US: Cisco Switch
ja-JP: シスコ・スイッチングハブ
# The description and help of this monitoring type
help:
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP 协议</a> 对 思科交换机 的通用指标(可用性,系统信息,端口流量等)进行采集监控。<br>您可以点击 “<i>新建 思科通用交换机</i>” 并进行配置SNMP相关参数添加,或者选择“<i>更多操作</i>”,导入已有配置。
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP Protocol</a> to monitoring Cisco Switch general performance metrics. <br>You can click the "<i>New Cisco Switch</i>" button and config snmp params to add monitor or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP 協議</a> 對 思科交換機 的通用指標(可用性,系統信息,端口流量等)進行采集監控。<br>您可以點擊 “<i>新建 思科通用交換機</i>” 並進行配置SNMP相關參數添加,或者選擇“<i>更多操作</i>”,導入已有配置。
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP プロトコルを介して</a> シスコ・スイッチングハブの一般的なメトリック監視します。<br>「<i>新規 シスコ・スイッチングハブ</i>」をクリックしてSNMPなどのパラメタを設定した後、新規することができます。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/cisco_switch
en-US: https://hertzbeat.apache.org/docs/help/cisco_switch
@@ -37,6 +39,7 @@ params:
name:
zh-CN: 目标Host
en-US: Target Host
ja-JP: 目標ホスト
# type-param field type(most mapping the html input type)
type: host
# required-true or false
@@ -47,6 +50,7 @@ params:
name:
zh-CN: 端口
en-US: Port
ja-JP: ポート
# type-param field type(most mapping the html input type)
type: number
# when type is number, range is required
@@ -61,6 +65,7 @@ params:
name:
zh-CN: SNMP 版本
en-US: SNMP Version
ja-JP: SNMPバージョン
# type-param field type(radio mapping the html radio tag)
type: radio
# required-true or false
@@ -79,6 +84,7 @@ params:
name:
zh-CN: SNMP 团体字
en-US: SNMP Community
ja-JP: SNMPコミュニティ
# type-param field type(most mapping the html input type)
type: text
# when type is text, use limit to limit string length
@@ -98,6 +104,7 @@ params:
name:
zh-CN: SNMP username
en-US: SNMP username
ja-JP: SNMPユーザー名
# type-param field type(most mapping the html input type)
type: text
# when type is text, use limit to limit string length
@@ -116,6 +123,7 @@ params:
name:
zh-CN: SNMP contextName
en-US: SNMP contextName
ja-JP: SNMPコンテキスト名
# type-param field type(most mapping the html input type)
type: text
# when type is text, use limit to limit string length
@@ -134,6 +142,7 @@ params:
name:
zh-CN: SNMP authPassword
en-US: SNMP authPassword
ja-JP: SNMP認証パスワード
# type-param field type(most mapping the html input type)
type: text
# when type is text, use limit to limit string length
@@ -152,6 +161,7 @@ params:
name:
zh-CN: authPassword 加密方式
en-US: authPassword Encryption
ja-JP: 認証暗号
# type-param field type(radio mapping the html radio tag)
type: radio
# required-true or false
@@ -172,6 +182,7 @@ params:
name:
zh-CN: SNMP privPassphrase
en-US: SNMP privPassphrase
ja-JP: SNMPパスワードフレーズ
# type-param field type(most mapping the html input type)
type: text
# when type is text, use limit to limit string length
@@ -190,6 +201,7 @@ params:
name:
zh-CN: privPassword 加密方式
en-US: privPassword Encryption
ja-JP: パスワードの暗号
# type-param field type(radio mapping the html radio tag)
type: radio
# required-true or false
@@ -210,6 +222,7 @@ params:
name:
zh-CN: 超时时间(ms)
en-US: Timeout(ms)
ja-JP: タイムアウト(ms)
# type-param field type(most mapping the html input type)
type: number
# when type is number, range is required
@@ -228,6 +241,7 @@ metrics:
i18n:
zh-CN: 系统信息
en-US: System Info
ja-JP: システム情報
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
priority: 0
@@ -239,32 +253,38 @@ metrics:
i18n:
zh-CN: 主机名称
en-US: Host Name
ja-JP: ホスト名
- field: descr
type: 1
i18n:
zh-CN: 描述信息
en-US: Description
ja-JP: 説明
- field: uptime
type: 1
i18n:
zh-CN: 运行时长
en-US: Uptime
ja-JP: アップタイム
- field: location
type: 1
i18n:
zh-CN: 位置
en-US: Location
ja-JP: 位置
- field: contact
type: 1
i18n:
zh-CN: 联系人
en-US: Contact
ja-JP: 連絡先
- field: responseTime
type: 0
unit: ms
i18n:
zh-CN: 响应时间
en-US: Response Time
ja-JP: 応答時間
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: snmp
# the config content when protocol is snmp
@@ -305,6 +325,7 @@ metrics:
i18n:
zh-CN: 接口详情
en-US: Interfaces Detail
ja-JP: ネットワークカード詳細
priority: 1
fields:
- field: index
@@ -312,68 +333,79 @@ metrics:
i18n:
zh-CN: 编号
en-US: Index
ja-JP: 番号
- field: descr
type: 1
label: true
i18n:
zh-CN: 接口名称
en-US: Interface Name
ja-JP: ネットワークカード名
- field: mtu
type: 0
unit: 'byte'
i18n:
zh-CN: MTU
en-US: MTU
ja-JP: MTU
- field: speed
type: 0
unit: 'MB/s'
i18n:
zh-CN: 接口速率
en-US: Interface Speed
ja-JP: ネットワークカード速度
- field: in_octets
type: 0
unit: 'MByte'
i18n:
zh-CN: 入流量
en-US: In Octets
ja-JP: 受信バイト数
- field: in_discards
type: 0
i18n:
zh-CN: 入丢包数
en-US: In Discards
ja-JP: 受信パケットロス数
- field: in_errors
type: 0
i18n:
zh-CN: 入错包数
en-US: In Errors
ja-JP: 受信異常パケット数
- field: out_octets
type: 0
unit: 'MByte'
i18n:
zh-CN: 出流量
en-US: Out Octets
ja-JP: 送信バイト数
- field: out_discards
type: 0
i18n:
zh-CN: 出丢包数
en-US: Out Discards
ja-JP: 送信パケットロス数
- field: out_errors
type: 0
i18n:
zh-CN: 出错包数
en-US: Out Errors
ja-JP: 送信異常パケット数
- field: admin_status
type: 1
i18n:
zh-CN: 配置状态
en-US: Config Status
en-US: Config Status
ja-JP: 設定ステータス
- field: oper_status
type: 1
i18n:
zh-CN: 当前状态
en-US: Current Status
ja-JP: ステータス
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
# (可选)监控指标别名, 做为中间字段与采集数据字段和指标字段映射转换
aliasFields:
- ifIndex
- ifDescr
@@ -21,11 +21,13 @@ app: clickhouse
name:
zh-CN: ClickHouse
en-US: ClickHouse
ja-JP: ClickHouse
# The description and help of this monitoring type
help:
zh-CN: Hertzbeat 对 ClickHouse 数据库监控通用指标进行测量监控。<br>您可以点击 “<i>新建 ClickHouse 数据库</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
en-US: Hertzbeat monitors the status codes which returned by the API. You could click the "<i>New ClickHouse Database</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: Hertzbeat 對 ClickHouse 資料庫監控通用名額進行量測監控。<br>您可以點擊 “<i>新建ClickHouse資料庫</i>” 並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
ja-JP: Hertzbeat は ClickHouse データベースの一般的なメトリック監視します。<br>「<i>新規 ClickHouse データベース</i>」をクリックしてパラメタを設定した後、新規することができます。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/clickhouse
en-US: https://hertzbeat.apache.org/docs/help/clickhouse
@@ -37,6 +39,7 @@ params:
name:
zh-CN: 目标Host
en-US: Target Host
ja-JP: 目標ホスト
# type-param field type(most mapping the html input type)
type: host
# required-true or false
@@ -47,6 +50,7 @@ params:
name:
zh-CN: HTTP端口
en-US: HTTP Port
ja-JP: HTTPポート
# type-param field type(most mapping the html input type)
type: number
# when type is number, range is required
@@ -61,6 +65,7 @@ params:
name:
zh-CN: 查询超时时间(ms)
en-US: Query Timeout(ms)
ja-JP: クエリタイムアウト(ms)
# type-param field type(most mapping the html input type)
type: number
# required-true or false
@@ -75,6 +80,7 @@ params:
name:
zh-CN: 数据库名称
en-US: Database Name
ja-JP: データベース名
# type-param field type(most mapping the html input type)
type: text
# required-true or false
@@ -85,6 +91,7 @@ params:
name:
zh-CN: 用户名
en-US: Username
ja-JP: ユーザー名
# type-param field type(most mapping the html input type)
type: text
# when type is text, use limit to limit string length
@@ -97,6 +104,7 @@ params:
name:
zh-CN: 密码
en-US: Password
ja-JP: パスワード
# type-param field type(most mapping the html input type)
type: password
# required-true or false
@@ -108,6 +116,7 @@ metrics:
i18n:
zh-CN: ping的可用性
en-US: ping_available
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
@@ -120,6 +129,7 @@ metrics:
i18n:
zh-CN: 响应时间
en-US: Response Time
ja-JP: 応答時間
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: http
# the config content when protocol is http
@@ -143,6 +153,7 @@ metrics:
i18n:
zh-CN: system.metrics表的数据
en-US: Data in the system.metrics table
ja-JP: system.metricsデータ
fields:
- field: metric
type: 1
@@ -150,16 +161,19 @@ metrics:
i18n:
zh-CN: 指标名称
en-US: metric
ja-JP: メトリック名
- field: value
type: 0
i18n:
zh-CN: 指标值
en-US: value
ja-JP: メトリック値
- field: description
type: 1
i18n:
zh-CN: 说明
en-US: description
ja-JP: メトリック説明
protocol: jdbc
jdbc:
host: ^_^host^_^
@@ -176,6 +190,7 @@ metrics:
i18n:
zh-CN: system.events表的数据
en-US: Data for the system.events table
ja-JP: system.eventsデータ
fields:
- field: event
type: 1
@@ -183,16 +198,19 @@ metrics:
i18n:
zh-CN: 事件信息
en-US: event
ja-JP: イベント名
- field: value
type: 0
i18n:
zh-CN:
en-US: value
ja-JP: 発生したイベントの数
- field: description
type: 1
i18n:
zh-CN: 说明
en-US: description
ja-JP: イベントの説明
protocol: jdbc
jdbc:
host: ^_^host^_^
@@ -210,6 +228,7 @@ metrics:
i18n:
zh-CN: system.asynchronous_metrics表的数据
en-US: Data from the system.asynchronous_metrics table
ja-JP: system.asynchronous_metricsデータ
fields:
- field: metric
type: 1
@@ -217,16 +236,19 @@ metrics:
i18n:
zh-CN: 指标名称
en-US: metric
ja-JP: メトリック名
- field: value
type: 0
i18n:
zh-CN: 指标值
en-US: value
ja-JP: メトリック値
- field: description
type: 1
i18n:
zh-CN: 说明
en-US: description
ja-JP: メトリック説明
protocol: jdbc
jdbc:
host: ^_^host^_^
@@ -0,0 +1,90 @@
# 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.
# The monitoring type category: service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
category: __system__
# Monitoring application type name (consistent with file name) eg: linux windows tomcat mysql aws...
app: nacos_sd
# The monitoring i18n name
name:
zh-CN: Nacos 服务发现
en-US: Nacos Service Discovery
# Input params define for app api(render web ui by the definition)
params:
# field-param field key
- field: __nacos_sd_host__
# name-param field display i18n name
name:
zh-CN: Nacos 服务发现 Host
en-US: Nacos Service Discovery Host
# type-param field type(most mapping the html input type)
type: text
# required-true or false
required: true
- field: __nacos_sd_port__
name:
zh-CN: Nacos 服务发现 Port
en-US: Nacos Service Discovery Port
type: number
required: true
# - field: __nacos_namespace__
# name:
# zh-CN: Nacos 命名空间
# en-US: Nacos Namespace
# type: text
# required: false
# - field: __nacos_username__
# name:
# zh-CN: Nacos 用户名
# en-US: Nacos Username
# type: text
# required: false
# - field: __nacos_password__
# name:
# zh-CN: Nacos 密码
# en-US: Nacos Password
# type: password
# required: false
metrics:
- name: target
i18n:
zh-CN: 监控目标
en-US: Monitor Target
# 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
# collect metrics content
fields:
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
- field: host
type: 1
i18n:
zh-CN: Host
en-US: Host
- field: port
type: 1
i18n:
zh-CN: Port
en-US: Port
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: nacos_sd
# the config content when protocol is nacos_sd
nacos_sd:
host: ^_^__nacos_sd_host__^_^
port: ^_^__nacos_sd_port__^_^
# namespace: ^_^__nacos_namespace__^_^
# username: ^_^__nacos_username__^_^
# password: ^_^__nacos_password__^_^
@@ -0,0 +1,70 @@
# 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.
# The monitoring type categoryservice-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
category: __system__
# Monitoring application type name (consistent with file name) eg: linux windows tomcat mysql aws...
app: zookeeper_sd
# The app api i18n name
name:
zh-CN: Zookeeper Service Discovery
en-US: Zookeeper Service Discovery
# Input params define for app api(render web ui by the definition)
params:
# field-param field key
- field: __sd_url__
# name-param field display i18n name
name:
zh-CN: 服务发现地址
en-US: Service Discovery Url
# type-param field type(most mapping the html input type)
type: text
# required-true or false
required: true
- field: __sd_path_prefix__
name:
zh-CN: 服务发现路径前缀
en-US: Service Discovery Path Prefix
type: text
required: true
metrics:
- name: target
i18n:
zh-CN: 监控目标
en-US: Monitor Target
# 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
# collect metrics content
fields:
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
- field: host
type: 1
i18n:
zh-CN: Host
en-US: Host
- field: port
type: 1
i18n:
zh-CN: Port
en-US: Port
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: zookeeper_sd
# the config content when protocol is zookeeper_sd
zookeeper_sd:
url: ^_^__sd_url__^_^
pathPrefix: ^_^__sd_path_prefix__^_^
@@ -37,7 +37,7 @@ import org.apache.hertzbeat.collector.dispatch.DispatchProperties;
import org.apache.hertzbeat.collector.dispatch.MetricsCollectorQueue;
import org.apache.hertzbeat.collector.dispatch.WorkerPool;
import org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectJobService;
import org.apache.hertzbeat.collector.dispatch.timer.TimerDispatcher;
import org.apache.hertzbeat.collector.timer.TimerDispatcher;
import org.apache.hertzbeat.collector.dispatch.unit.impl.DataSizeConvert;
import org.apache.hertzbeat.common.config.CommonConfig;
import org.apache.hertzbeat.common.config.CommonProperties;
@@ -126,7 +126,7 @@ public class GreptimeDbDataStorage extends AbstractHistoryDataStorage {
return;
}
String monitorId = String.valueOf(metricsData.getId());
String tableName = getTableName(metricsData.getApp(), metricsData.getMetrics());
String tableName = getTableName(metricsData.getId(), metricsData.getMetrics());
TableSchema.Builder tableSchemaBuilder = TableSchema.newBuilder(tableName);
tableSchemaBuilder.addTag("instance", DataType.String)
@@ -194,7 +194,7 @@ public class GreptimeDbDataStorage extends AbstractHistoryDataStorage {
@Override
public Map<String, List<Value>> getHistoryMetricData(Long monitorId, String app, String metrics, String metric,
String label, String history) {
String name = getTableName(app, metrics);
String name = getTableName(monitorId, metrics);
String timeSeriesSelector = LABEL_KEY_NAME + "=\"" + name + "\""
+ "," + LABEL_KEY_INSTANCE + "=\"" + monitorId + "\"";
if (!CommonConstants.PROMETHEUS.equals(app)) {
@@ -227,6 +227,7 @@ public class GreptimeDbDataStorage extends AbstractHistoryDataStorage {
log.error("history time error: {}. use default: 6h", e.getMessage());
start = now.minus(6, ChronoUnit.HOURS).getEpochSecond();
}
long end = now.getEpochSecond();
String step = "60s";
if (end - start < Duration.ofDays(7).getSeconds() && end - start > Duration.ofDays(1).getSeconds()) {
@@ -234,13 +235,15 @@ public class GreptimeDbDataStorage extends AbstractHistoryDataStorage {
} else if (end - start >= Duration.ofDays(7).getSeconds()) {
step = "4h";
}
HttpEntity<Void> httpEntity = new HttpEntity<>(headers);
URI uri = UriComponentsBuilder.fromHttpUrl(greptimeProperties.httpEndpoint() + QUERY_RANGE_PATH)
URI uri = UriComponentsBuilder.fromUriString(greptimeProperties.httpEndpoint() + QUERY_RANGE_PATH)
.queryParam(URLEncoder.encode("query", StandardCharsets.UTF_8), URLEncoder.encode("{" + timeSeriesSelector + "}", StandardCharsets.UTF_8))
.queryParam("start", start)
.queryParam("end", end)
.queryParam("step", step)
.build(true).toUri();
ResponseEntity<PromQlQueryContent> responseEntity = restTemplate.exchange(uri,
HttpMethod.GET, httpEntity, PromQlQueryContent.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
@@ -258,7 +261,6 @@ public class GreptimeDbDataStorage extends AbstractHistoryDataStorage {
for (Object[] valueArr : content.getValues()) {
long timestamp = ((Double) valueArr[0]).longValue();
String value = new BigDecimal(String.valueOf(valueArr[1])).setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
// read timestamp here is s unit
valueList.add(new Value(value, timestamp * 1000));
}
}
@@ -273,8 +275,8 @@ public class GreptimeDbDataStorage extends AbstractHistoryDataStorage {
return instanceValuesMap;
}
private String getTableName(String app, String metrics) {
return app + SPILT + metrics;
private String getTableName(Long monitorId, String metrics) {
return "hzb" + SPILT + monitorId + SPILT + metrics;
}
@Override
@@ -38,6 +38,7 @@ package org.apache.hertzbeat.warehouse.store.history.vm;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -28,6 +28,7 @@ import java.time.Duration;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAmount;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -35,6 +36,9 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -52,6 +56,9 @@ import org.apache.hertzbeat.common.constants.SignConstants;
import org.apache.hertzbeat.common.entity.arrow.RowWrapper;
import org.apache.hertzbeat.common.entity.dto.Value;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.timer.HashedWheelTimer;
import org.apache.hertzbeat.common.timer.Timeout;
import org.apache.hertzbeat.common.timer.TimerTask;
import org.apache.hertzbeat.common.util.Base64Util;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.apache.hertzbeat.common.util.JsonUtil;
@@ -93,12 +100,19 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
private static final String SPILT = "_";
private static final String MONITOR_METRICS_KEY = "__metrics__";
private static final String MONITOR_METRIC_KEY = "__metric__";
private static final long MAX_WAIT_MS = 500L;
private static final int MAX_RETRIES = 3;
private final VictoriaMetricsClusterProperties vmClusterProps;
private final VictoriaMetricsInsertProperties vmInsertProps;
private final VictoriaMetricsSelectProperties vmSelectProps;
private final RestTemplate restTemplate;
private final BlockingQueue<VictoriaMetricsDataStorage.VictoriaMetricsContent> metricsBufferQueue;
private HashedWheelTimer metricsFlushTimer = null;
private MetricsFlushTask metricsFlushtask = null;
private boolean isBatchImportEnabled = false;
public VictoriaMetricsClusterDataStorage(VictoriaMetricsClusterProperties vmClusterProps,
RestTemplate restTemplate) {
@@ -111,6 +125,21 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
this.vmInsertProps = vmClusterProps.insert();
this.vmSelectProps = vmClusterProps.select();
serverAvailable = checkVictoriaMetricsDatasourceAvailable();
metricsBufferQueue = new LinkedBlockingQueue<>(vmInsertProps.bufferSize());
isBatchImportEnabled = vmInsertProps.flushInterval() != 0 && vmInsertProps.bufferSize() != 0;
if (isBatchImportEnabled){
initializeFlushTimer();
}
}
private void initializeFlushTimer() {
this.metricsFlushTimer = new HashedWheelTimer(r -> {
Thread thread = new Thread(r, "victoria-metrics-flush-timer");
thread.setDaemon(true);
return thread;
}, 1, TimeUnit.SECONDS, 512);
metricsFlushtask = new MetricsFlushTask();
this.metricsFlushTimer.newTimeout(metricsFlushtask, 0, TimeUnit.SECONDS);
}
private boolean checkVictoriaMetricsDatasourceAvailable() {
@@ -228,46 +257,25 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
});
}
if (contentList.isEmpty()) {
log.info("[warehouse victoria-metrics] flush metrics data {} is empty, ignore.", metricsData.getId());
return;
}
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
if (StringUtils.hasText(vmInsertProps.username())
&& StringUtils.hasText(vmInsertProps.password())) {
String authStr = vmInsertProps.username() + ":" + vmInsertProps.password();
String encodedAuth = Base64Util.encode(authStr);
headers.add(HttpHeaders.AUTHORIZATION, NetworkConstants.BASIC + SignConstants.BLANK + encodedAuth);
}
StringBuilder stringBuilder = new StringBuilder();
for (VictoriaMetricsDataStorage.VictoriaMetricsContent content : contentList) {
stringBuilder.append(JsonUtil.toJson(content)).append("\n");
}
HttpEntity<String> httpEntity = new HttpEntity<>(stringBuilder.toString(), headers);
String importUrl = vmClusterProps.insert().url() + VM_INSERT_BASE_PATH.formatted(vmClusterProps.accountID(), IMPORT_PATH);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(importUrl,
httpEntity, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
log.debug("insert metrics data to victoria-metrics success.");
} else {
log.error("insert metrics data to victoria-metrics failed. {}", responseEntity.getBody());
}
} catch (Exception e){
log.error("flush metrics data to victoria-metrics error: {}.", e.getMessage(), e);
if (!isBatchImportEnabled){
doSaveData(contentList);
return;
}
sendVictoriaMetrics(contentList);
} catch (Exception e) {
log.error("flush metrics data to victoria-metrics error: {}.", e.getMessage(), e);
}
}
@Override
public void destroy() {
if (metricsFlushTimer != null && !metricsFlushTimer.isStop()) {
metricsFlushTimer.stop();
}
}
@Override
@@ -555,6 +563,109 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
return instanceValuesMap;
}
/**
* Save metric data to victoria-metric via HTTP call
*/
public void doSaveData(List<VictoriaMetricsDataStorage.VictoriaMetricsContent> contentList){
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
if (StringUtils.hasText(vmInsertProps.username())
&& StringUtils.hasText(vmInsertProps.password())) {
String authStr = vmInsertProps.username() + ":" + vmInsertProps.password();
String encodedAuth = Base64Util.encode(authStr);
headers.add(HttpHeaders.AUTHORIZATION, NetworkConstants.BASIC + SignConstants.BLANK + encodedAuth);
}
StringBuilder stringBuilder = new StringBuilder();
for (VictoriaMetricsDataStorage.VictoriaMetricsContent content : contentList) {
stringBuilder.append(JsonUtil.toJson(content)).append("\n");
}
HttpEntity<String> httpEntity = new HttpEntity<>(stringBuilder.toString(), headers);
String importUrl = vmClusterProps.insert().url() + VM_INSERT_BASE_PATH.formatted(vmClusterProps.accountID(), IMPORT_PATH);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(importUrl,
httpEntity, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
log.debug("insert metrics data to victoria-metrics success.");
} else {
log.error("insert metrics data to victoria-metrics failed. {}", responseEntity.getBody());
}
} catch (Exception e){
log.error("flush metrics data to victoria-metrics error: {}.", e.getMessage(), e);
}
}
/**
* add victoriaMetricsContent to buffer
* @param contentList victoriaMetricsContent List
*/
private void sendVictoriaMetrics(List<VictoriaMetricsDataStorage.VictoriaMetricsContent> contentList) {
for (VictoriaMetricsDataStorage.VictoriaMetricsContent content : contentList) {
boolean offered = false;
int retryCount = 0;
while (!offered && retryCount < MAX_RETRIES) {
try {
// Attempt to add to the queue for a limited time
offered = metricsBufferQueue.offer(content, MAX_WAIT_MS, TimeUnit.MILLISECONDS);
if (!offered) {
// If the queue is still full, trigger an immediate refresh to free up space
if (retryCount == 0) {
log.debug("victoria metrics buffer queue is full, triggering immediate flush");
triggerImmediateFlush();
}
retryCount++;
// The short sleep allows the queue to clear out
if (retryCount < MAX_RETRIES) {
Thread.sleep(100L * retryCount);
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("[Victoria Metrics] Interrupted while offering metrics to buffer queue", e);
break;
}
}
// When the maximum number of retries is reached, if it still cannot be added to the queue, the data is saved directly
if (!offered) {
log.warn("[Victoria Metrics] Failed to add metrics to buffer after {} retries, saving directly", MAX_RETRIES);
try {
doSaveData(contentList);
} catch (Exception e) {
log.error("[Victoria Metrics] Failed to save metrics directly: {}", e.getMessage(), e);
}
}
// Refresh in advance to avoid waiting
if (metricsBufferQueue.size() >= vmInsertProps.bufferSize() * 0.8) {
triggerImmediateFlush();
}
}
}
private void triggerImmediateFlush() {
metricsFlushTimer.newTimeout(metricsFlushtask, 0, TimeUnit.MILLISECONDS);
}
/**
* Regularly refresh the buffer queue to the vm
*/
private class MetricsFlushTask implements TimerTask {
@Override
public void run(Timeout timeout) {
try {
List<VictoriaMetricsDataStorage.VictoriaMetricsContent> batch = new ArrayList<>(vmInsertProps.bufferSize());
metricsBufferQueue.drainTo(batch, vmInsertProps.bufferSize());
if (!batch.isEmpty()) {
doSaveData(batch);
log.debug("[Victoria Metrics] Flushed {} metrics items", batch.size());
}
if (metricsFlushTimer != null && !metricsFlushTimer.isStop()) {
metricsFlushTimer.newTimeout(this, vmInsertProps.flushInterval(), TimeUnit.SECONDS);
}
} catch (Exception e) {
log.error("[VictoriaMetrics] flush task error: {}", e.getMessage(), e);
}
}
}
/**
* victoria metrics content
*/
@@ -25,12 +25,16 @@ import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAmount;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
@@ -46,6 +50,9 @@ import org.apache.hertzbeat.common.constants.SignConstants;
import org.apache.hertzbeat.common.entity.arrow.RowWrapper;
import org.apache.hertzbeat.common.entity.dto.Value;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.timer.HashedWheelTimer;
import org.apache.hertzbeat.common.timer.Timeout;
import org.apache.hertzbeat.common.timer.TimerTask;
import org.apache.hertzbeat.common.util.Base64Util;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.apache.hertzbeat.common.util.JsonUtil;
@@ -87,10 +94,16 @@ public class VictoriaMetricsDataStorage extends AbstractHistoryDataStorage {
private static final String SPILT = "_";
private static final String MONITOR_METRICS_KEY = "__metrics__";
private static final String MONITOR_METRIC_KEY = "__metric__";
private static final long MAX_WAIT_MS = 500L;
private static final int MAX_RETRIES = 3;
private final VictoriaMetricsProperties victoriaMetricsProp;
private final RestTemplate restTemplate;
private final BlockingQueue<VictoriaMetricsDataStorage.VictoriaMetricsContent> metricsBufferQueue;
private boolean isBatchImportEnabled = false;
private HashedWheelTimer metricsFlushTimer = null;
private MetricsFlushTask metricsFlushtask = null;
public VictoriaMetricsDataStorage(VictoriaMetricsProperties victoriaMetricsProperties, RestTemplate restTemplate) {
if (victoriaMetricsProperties == null) {
@@ -100,6 +113,22 @@ public class VictoriaMetricsDataStorage extends AbstractHistoryDataStorage {
this.restTemplate = restTemplate;
victoriaMetricsProp = victoriaMetricsProperties;
serverAvailable = checkVictoriaMetricsDatasourceAvailable();
serverAvailable = checkVictoriaMetricsDatasourceAvailable();
metricsBufferQueue = new LinkedBlockingQueue<>(victoriaMetricsProperties.insert().bufferSize());
isBatchImportEnabled = victoriaMetricsProperties.insert().flushInterval() != 0 && victoriaMetricsProperties.insert().bufferSize() != 0;
if (isBatchImportEnabled){
initializeFlushTimer();
}
}
private void initializeFlushTimer() {
this.metricsFlushTimer = new HashedWheelTimer(r -> {
Thread thread = new Thread(r, "victoria-metrics-cluster-flush-timer");
thread.setDaemon(true);
return thread;
}, 1, TimeUnit.SECONDS, 512);
metricsFlushtask = new MetricsFlushTask();
this.metricsFlushTimer.newTimeout(metricsFlushtask, 0, TimeUnit.SECONDS);
}
private boolean checkVictoriaMetricsDatasourceAvailable() {
@@ -135,7 +164,7 @@ public class VictoriaMetricsDataStorage extends AbstractHistoryDataStorage {
return;
}
if (metricsData.getValues().isEmpty()) {
log.info("[warehouse victoria-metrics] flush metrics data {} {} {} is null, ignore.",
log.info("[warehouse victoria-metrics] flush metrics data {} {} {} is null, ignore.",
metricsData.getId(), metricsData.getApp(), metricsData.getMetrics());
return;
}
@@ -215,36 +244,20 @@ public class VictoriaMetricsDataStorage extends AbstractHistoryDataStorage {
log.info("[warehouse victoria-metrics] flush metrics data {} is empty, ignore.", metricsData.getId());
return;
}
if (!isBatchImportEnabled){
doSaveData(contentList);
return;
}
sendVictoriaMetrics(contentList);
}
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
if (StringUtils.hasText(victoriaMetricsProp.username())
&& StringUtils.hasText(victoriaMetricsProp.password())) {
String authStr = victoriaMetricsProp.username() + ":" + victoriaMetricsProp.password();
String encodedAuth = Base64Util.encode(authStr);
headers.add(HttpHeaders.AUTHORIZATION, NetworkConstants.BASIC + SignConstants.BLANK + encodedAuth);
}
StringBuilder stringBuilder = new StringBuilder();
for (VictoriaMetricsContent content : contentList) {
stringBuilder.append(JsonUtil.toJson(content)).append("\n");
}
HttpEntity<String> httpEntity = new HttpEntity<>(stringBuilder.toString(), headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(victoriaMetricsProp.url() + IMPORT_PATH,
httpEntity, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
log.debug("insert metrics data to victoria-metrics success.");
} else {
log.error("insert metrics data to victoria-metrics failed. {}", responseEntity.getBody());
}
} catch (Exception e){
log.error("flush metrics data to victoria-metrics error: {}.", e.getMessage(), e);
@Override
public void destroy() {
if (metricsFlushTimer != null && !metricsFlushTimer.isStop()) {
metricsFlushTimer.stop();
}
}
@Override
public void destroy() {}
@Override
public Map<String, List<Value>> getHistoryMetricData(Long monitorId, String app, String metrics, String metric, String label, String history) {
String labelName = metrics + SPILT + metric;
@@ -388,7 +401,7 @@ public class VictoriaMetricsDataStorage extends AbstractHistoryDataStorage {
long timestamp = Long.parseLong(String.valueOf(valueArr[0]));
String value = new BigDecimal(String.valueOf(valueArr[1])).setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
// read timestamp here is s unit
valueList.add(new Value(value, timestamp * 1000));
valueList.add(new Value(value, timestamp * 1000));
}
}
}
@@ -532,4 +545,107 @@ public class VictoriaMetricsDataStorage extends AbstractHistoryDataStorage {
*/
private Long[] timestamps;
}
/**
* add victoriaMetricsContent to buffer
* @param contentList victoriaMetricsContent List
*/
private void sendVictoriaMetrics(List<VictoriaMetricsDataStorage.VictoriaMetricsContent> contentList) {
for (VictoriaMetricsDataStorage.VictoriaMetricsContent content : contentList) {
boolean offered = false;
int retryCount = 0;
while (!offered && retryCount < MAX_RETRIES) {
try {
// Attempt to add to the queue for a limited time
offered = metricsBufferQueue.offer(content, MAX_WAIT_MS, TimeUnit.MILLISECONDS);
if (!offered) {
// If the queue is still full, trigger an immediate refresh to free up space
if (retryCount == 0) {
log.debug("victoria metrics buffer queue is full, triggering immediate flush");
triggerImmediateFlush();
}
retryCount++;
// The short sleep allows the queue to clear out
if (retryCount < MAX_RETRIES) {
Thread.sleep(100L * retryCount);
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("[Victoria Metrics] Interrupted while offering metrics to buffer queue", e);
break;
}
}
// When the maximum number of retries is reached, if it still cannot be added to the queue, the data is saved directly
if (!offered) {
log.warn("[Victoria Metrics] Failed to add metrics to buffer after {} retries, saving directly", MAX_RETRIES);
try {
doSaveData(contentList);
} catch (Exception e) {
log.error("[Victoria Metrics] Failed to save metrics directly: {}", e.getMessage(), e);
}
}
// Refresh in advance to avoid waiting
if (metricsBufferQueue.size() >= victoriaMetricsProp.insert().bufferSize() * 0.8) {
triggerImmediateFlush();
}
}
}
private void triggerImmediateFlush() {
metricsFlushTimer.newTimeout(metricsFlushtask, 0, TimeUnit.MILLISECONDS);
}
/**
* Regularly refresh the buffer queue to the vm
*/
private class MetricsFlushTask implements TimerTask {
@Override
public void run(Timeout timeout) {
try {
List<VictoriaMetricsDataStorage.VictoriaMetricsContent> batch = new ArrayList<>(victoriaMetricsProp.insert().bufferSize());
metricsBufferQueue.drainTo(batch, victoriaMetricsProp.insert().bufferSize());
if (!batch.isEmpty()) {
doSaveData(batch);
log.debug("[Victoria Metrics] Flushed {} metrics items", batch.size());
}
if (metricsFlushTimer != null && !metricsFlushTimer.isStop()) {
metricsFlushTimer.newTimeout(this, victoriaMetricsProp.insert().flushInterval(), TimeUnit.SECONDS);
}
} catch (Exception e) {
log.error("[VictoriaMetrics] flush task error: {}", e.getMessage(), e);
}
}
}
/**
* Save metric data to victoria-metric via HTTP call
*/
private void doSaveData(List<VictoriaMetricsContent> contentList) {
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
if (StringUtils.hasText(victoriaMetricsProp.username())
&& StringUtils.hasText(victoriaMetricsProp.password())) {
String authStr = victoriaMetricsProp.username() + ":" + victoriaMetricsProp.password();
String encodedAuth = Base64Util.encode(authStr);
headers.add(HttpHeaders.AUTHORIZATION, NetworkConstants.BASIC + SignConstants.BLANK + encodedAuth);
}
StringBuilder stringBuilder = new StringBuilder();
for (VictoriaMetricsContent content : contentList) {
stringBuilder.append(JsonUtil.toJson(content)).append("\n");
}
HttpEntity<String> httpEntity = new HttpEntity<>(stringBuilder.toString(), headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(victoriaMetricsProp.url() + IMPORT_PATH,
httpEntity, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
log.debug("insert metrics data to victoria-metrics success.");
} else {
log.error("insert metrics data to victoria-metrics failed. {}", responseEntity.getBody());
}
} catch (Exception e){
log.error("flush metrics data to victoria-metrics error: {}.", e.getMessage(), e);
}
}
}
@@ -17,12 +17,16 @@
package org.apache.hertzbeat.warehouse.store.history.vm;
import org.springframework.boot.context.properties.bind.DefaultValue;
/**
* vminsert configuration information
*/
public record VictoriaMetricsInsertProperties(
String url,
String username,
String password
String password,
@DefaultValue("1000") int bufferSize,
@DefaultValue("3") int flushInterval
) {
}
@@ -27,13 +27,15 @@ import org.springframework.boot.context.properties.bind.DefaultValue;
* Victoria metrics configuration information.
*/
@ConfigurationProperties(prefix = ConfigConstants.FunctionModuleConstants.WAREHOUSE
+ SignConstants.DOT
+ WarehouseConstants.STORE
+ SignConstants.DOT
+ WarehouseConstants.HistoryName.VM)
@ConfigurationProperties(prefix = ConfigConstants.FunctionModuleConstants.WAREHOUSE + SignConstants.DOT + WarehouseConstants.STORE + SignConstants.DOT + WarehouseConstants.HistoryName.VM)
public record VictoriaMetricsProperties(@DefaultValue("false") boolean enabled,
@DefaultValue("http://localhost:8428") String url,
String username,
String password) {
String password,
InsertConfig insert) {
record InsertConfig(@DefaultValue("1000") int bufferSize,
@DefaultValue("3") int flushInterval) {
}
}
+1 -1
View File
@@ -118,7 +118,7 @@ Detailed config refer to [Install HertzBeat via Docker](https://hertzbeat.com/do
* Update app-zookeeper.yml by @hurenjie1 in <https://github.com/apache/hertzbeat/pull/1458>
* add hurenjie1 as a contributor for code by @allcontributors in <https://github.com/apache/hertzbeat/pull/1459>
* update dashboard ui, remove ssh custom SignatureFactories, update app name by @tomsun28 in <https://github.com/apache/hertzbeat/pull/1460>
* [Task] Monitoring Template Yml Metrics I18n | 监控模指标国际化任务认领 #1212 by @tslj1024 in <https://github.com/apache/hertzbeat/pull/1461>
* [Task] Monitoring Template Yml Metrics I18n | 监控模指标国际化任务认领 #1212 by @tslj1024 in <https://github.com/apache/hertzbeat/pull/1461>
* add tslj1024 as a contributor for code by @allcontributors in <https://github.com/apache/hertzbeat/pull/1462>
* Add alarm trigger time for alarm restore by @Calvin979 in <https://github.com/apache/hertzbeat/pull/1464>
* bugfix history range query not work when victoria-metrics store by @tomsun28 in <https://github.com/apache/hertzbeat/pull/1463>
+2 -2
View File
@@ -96,9 +96,9 @@ name:
en-US: EXAMPLE APP
# The description and help of this monitoring type
help:
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
en-US: "HertzBeat supports custom monitoring, and you only need to configure the monitoring template YML to adapt to a custom monitoring type. <br>Definition process as follow: HertzBeat Pages -> Main Menu -> Monitor Template -> edit and save -> apply this template."
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-point/
en-US: https://hertzbeat.apache.org/docs/advanced/extend-point/
+2 -2
View File
@@ -45,9 +45,9 @@ name:
en-US: EXAMPLE APP
# The description and help of this monitoring type
help:
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
en-US: "HertzBeat supports custom monitoring, and you only need to configure the monitoring template YML to adapt to a custom monitoring type. <br>Definition process as follow: HertzBeat Pages -> Main Menu -> Monitor Template -> edit and save -> apply this template."
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-point/
en-US: https://hertzbeat.apache.org/docs/advanced/extend-point/
+2 -2
View File
@@ -40,9 +40,9 @@ name:
en-US: EXAMPLE WEBSITE
# The description and help of this monitoring type
help:
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
en-US: "HertzBeat supports custom monitoring, and you only need to configure the monitoring template YML to adapt to a custom monitoring type. <br>Definition process as follow: HertzBeat Pages -> Main Menu -> Monitor Template -> edit and save -> apply this template."
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-point/
en-US: https://hertzbeat.apache.org/docs/advanced/extend-point/
-1
View File
@@ -441,7 +441,6 @@ 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 />
> `cc`: <dev@hertzbeat.apache.org>、<private@hertzbeat.apache.org> <br />
> `Title`: [VOTE] Release Apache HertzBeat (incubating) 1.6.0-rc1 <br />
> `Body`:
+1 -1
View File
@@ -434,7 +434,7 @@
"message": "{docker} {br}集监控-告警-通知为一体,支持应用服务,Web,数据库,缓存,操作系统,中间件,大数据,云原生,网络等监控阈值告警通知一步到位。{br} 易用友好,无需Agent,全WEB页面操作,鼠标点一点就能监控告警,零上手学习成本。{br}安全是最重要的,数据密钥全链路加密。"
},
"custom-multi-support-content": {
"message": "将 Http,Jmx,Ssh,Snmp,Jdbc 等协议规范可配置模化,只需在线配置YML就可自定义监控指标。{br} 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。{br}自由的告警阈值规则,邮箱,短信,钉钉,企业微信,飞书,Webhook等消息及时送达。{br} 您相信只需配置下就能适配新K8s监控类型吗?"
"message": "将 Http,Jmx,Ssh,Snmp,Jdbc 等协议规范可配置模化,只需在线配置YML就可自定义监控指标。{br} 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。{br}自由的告警阈值规则,邮箱,短信,钉钉,企业微信,飞书,Webhook等消息及时送达。{br} 您相信只需配置下就能适配新K8s监控类型吗?"
},
"opensource-content": {
"message": "Apache HertzBeat (incubating) 是开源的,拥有一个包容开放的社区。{br}欢迎任何对此有兴趣的同学参与其中,无论是代码文档或者错别字,尊重社区的每一位,一起进步成长。{br}我们的代码正被部署到全球成千上万机器上。{github}"
@@ -60,7 +60,7 @@ Online <https://console.tancloud.cn>.
> 当然,我们也提供了对应的[SAAS云监控版本](https://console.tancloud.cn),中小团队和个人无需再为了监控自己的网站资源,而去部署一套繁琐的监控系统,[登录即可免费开始](https://console.tancloud.cn)监控之旅。
> HertzBeat 支持自定义监控,只用通过配置YML文件我们就可以自定义需要的监控类型和指标,来满足常见的个性化需求。
> HertzBeat 模块化,`manager, collector, scheduler, warehouse, alerter` 各个模块解耦合,方便理解与定制开发。
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模,邮件钉钉微信飞书等及时通知送达
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模,邮件钉钉微信飞书等及时通知送达
> 欢迎登录 HertzBeat 的 [云环境TanCloud](https://console.tancloud.cn) 试用发现更多。
> 我们正在快速迭代中,欢迎参与加入共建项目开源生态。
>
@@ -61,7 +61,7 @@ Have Fun!
> 当然,我们也提供了对应的[SAAS云监控版本](https://console.tancloud.cn),中小团队和个人无需再为了监控自己的网站资源,而去部署一套繁琐的监控系统,[登录即可免费开始](https://console.tancloud.cn)监控之旅。
> HertzBeat 支持自定义监控,只用通过配置YML文件我们就可以自定义需要的监控类型和指标,来满足常见的个性化需求。
> HertzBeat 模块化,`manager, collector, scheduler, warehouse, alerter` 各个模块解耦合,方便理解与定制开发。
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模,邮件钉钉微信飞书等及时通知送达
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模,邮件钉钉微信飞书等及时通知送达
> 欢迎登录 HertzBeat 的 [云环境TanCloud](https://console.tancloud.cn) 试用发现更多。
> 我们正在快速迭代中,欢迎参与加入共建项目开源生态。
>
@@ -61,7 +61,7 @@ Have Fun!
> 当然,我们也提供了对应的[SAAS云监控版本](https://console.tancloud.cn),中小团队和个人无需再为了监控自己的网站资源,而去部署一套繁琐的监控系统,[登录即可免费开始](https://console.tancloud.cn)监控之旅。
> HertzBeat 支持自定义监控,只用通过配置YML文件我们就可以自定义需要的监控类型和指标,来满足常见的个性化需求。
> HertzBeat 模块化,`manager, collector, scheduler, warehouse, alerter` 各个模块解耦合,方便理解与定制开发。
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模,邮件钉钉微信飞书等及时通知送达
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模,邮件钉钉微信飞书等及时通知送达
> 欢迎登录 HertzBeat 的 [云环境TanCloud](https://console.tancloud.cn) 试用发现更多。
> 我们正在快速迭代中,欢迎参与加入共建项目开源生态。
>
@@ -50,7 +50,7 @@ Have Fun!
> 当然,我们也提供了对应的[SAAS云监控版本](https://console.tancloud.cn),中小团队和个人无需再为了监控自己的网站资源,而去部署一套繁琐的监控系统,[登录即可免费开始](https://console.tancloud.cn)监控之旅。
> HertzBeat 支持自定义监控,只用通过配置YML文件我们就可以自定义需要的监控类型和指标,来满足常见的个性化需求。
> HertzBeat 模块化,`manager, collector, scheduler, warehouse, alerter` 各个模块解耦合,方便理解与定制开发。
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模,邮件钉钉微信飞书等及时通知送达
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模,邮件钉钉微信飞书等及时通知送达
> 欢迎登录 HertzBeat 的 [云环境TanCloud](https://console.tancloud.cn) 试用发现更多。
> 我们正在快速迭代中,欢迎参与加入共建项目开源生态。
>
@@ -61,7 +61,7 @@ gitee: <https://gitee.com/hertzbeat/hertzbeat>
![HertzBeat](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8d6205172d43463aa34e534477f132f1~tplv-k3u1fbpfcp-zoom-1.image)
> 配置阈值,选择SSL证书指标对象,配置告警表达式-当指标`expired`为`true`触发,即`equals(expired,"true")` , 设置告警级别通知模信息等。
> 配置阈值,选择SSL证书指标对象,配置告警表达式-当指标`expired`为`true`触发,即`equals(expired,"true")` , 设置告警级别通知模信息等。
![HertzBeat](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/83d17b381d994f26a6240e01915b2001~tplv-k3u1fbpfcp-zoom-1.image)
@@ -39,7 +39,7 @@ githubgcdd1993 (进击的阿晨)
* 实现了对`Redis`数据库的指标监控
* 优化`spring.factories` 配置项
* 实现支持了 `Telegram``Discord``Slack` 的消息通知渠道
* 使用 `Thymeleaf` 重构了告警文本,告警通知模更规范化
* 使用 `Thymeleaf` 重构了告警文本,告警通知模更规范化
### 感谢社区小伙伴
@@ -49,8 +49,8 @@ COMMIT;
## ⛄ 已支持
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
- Website, Port Telnet, Http Api, Ping Connect, Jvm, SiteMap, Ssl Certificate, SpringBoot2, FTP Server, SpringBoot3
- Mysql, PostgreSQL, MariaDB, Redis, ElasticSearch, SqlServer, Oracle, MongoDB, DM, OpenGauss, ClickHouse, IoTDB, Redis Cluster, Redis Sentinel
@@ -58,7 +58,7 @@ COMMIT;
- Tomcat, Nacos, Zookeeper, RabbitMQ, Flink, Kafka, ShenYu, DynamicTp, Jetty, ActiveMQ
- Kubernetes, Docker
- CiscoSwitch, HpeSwitch, HuaweiSwitch, TpLinkSwitch, H3cSwitch
- 和更多自定义监控模
- 和更多自定义监控模
- 通知支持 Discord Slack Telegram 邮件 钉钉 微信 飞书 短信 Webhook。
---
@@ -27,7 +27,7 @@ Cloud: **[GreptimePlay](https://greptime.com/playground)**
-**监控+告警+通知** All in one,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web服务器,云原生,网络,自定义等监控,阈值告警通知一步到位。
- 更自由化的阈值规则(计算表达式)`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` 等方式及时送达。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus`等协议规范可配置化,只需在浏览器配置`YML`监控模就能使用这些协议去自定义采集想要的指标。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus`等协议规范可配置化,只需在浏览器配置`YML`监控模就能使用这些协议去自定义采集想要的指标。
> `HertzBeat`的强大自定义,多类型支持,易扩展,低耦合,希望能帮助开发者和中小团队快速搭建自有监控系统。
@@ -51,8 +51,8 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
## ⛄ 已支持
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
- Website, Port Telnet, Http Api, Ping Connect, Jvm, SiteMap, Ssl Certificate, SpringBoot2, FTP Server, SpringBoot3
- Mysql, PostgreSQL, MariaDB, Redis, ElasticSearch, SqlServer, Oracle, MongoDB, DM, OpenGauss, ClickHouse, IoTDB, Redis Cluster, Redis Sentinel
@@ -60,7 +60,7 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
- Tomcat, Nacos, Zookeeper, RabbitMQ, Flink, Kafka, ShenYu, DynamicTp, Jetty, ActiveMQ
- Kubernetes, Docker
- CiscoSwitch, HpeSwitch, HuaweiSwitch, TpLinkSwitch, H3cSwitch
- 和更多自定义监控模
- 和更多自定义监控模
- 通知支持 Discord Slack Telegram 邮件 钉钉 微信 飞书 短信 Webhook。
---
@@ -18,7 +18,7 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
-**监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` 等方式消息及时送达。
@@ -65,7 +65,7 @@ HertzBeat 提供云边协同能力,可以在多个隔离网络部署边缘采
- 用户流量。开源项目免费提供给用户和开发者,吸引用户使用,宣传等方面都有优势。
- 用户信任。开源的产品天生容易获取用户的信任和使用耐心,或者说降低用户的信任门槛。
- 社区协作。开源的产品可以吸引到顶级贡献者一起贡献,接收用户的反馈issue,pr贡献等,在社区的驱动下使开源项目越来越好,正向反馈后也会有更多人参与和使用。社区协作我觉得这是开源的意义,而且这样不仅仅只是程序员之间的贡献代码协作,用户都是协作对象(比如我们这个项目有大量的运维朋友贡献代码和文档),如果是仅仅代码开源而不社区协作,那还不如放个安装包给别人免费使用下载就好。
- 产品生态。这对一些需要生态的产品是需要的,比如hertzbeat,需要支持对接各种类型协议的监控类型,大量的监控模。一个好的开源项目生态才能吸引到其它贡献者贡献和分享,在生态中互通有无,最终大家在生态中都受益。这在闭源程序中是很难做到的。
- 产品生态。这对一些需要生态的产品是需要的,比如hertzbeat,需要支持对接各种类型协议的监控类型,大量的监控模。一个好的开源项目生态才能吸引到其它贡献者贡献和分享,在生态中互通有无,最终大家在生态中都受益。这在闭源程序中是很难做到的。
上面几点,重在社区协作和产品生态,这也是开源集群版的原因,只有卷开源产品卷自己到更强的产品力,比如集群这一技术特性天生会吸引到开发者(而且集群本身就是我们社区协作的产物),会吸引到更多的用户和贡献者使用反馈大家一起迭代,社区驱动进而正向促进开源项目和满足用户功能体验。
而对于开源商业化,开源商业化的前提是得有个真正好的,受欢迎,被广泛使用的开源产品,然后在此基础上做商业化挣钱。
@@ -155,8 +155,8 @@ HertzBeat 提供云边协同能力,可以在多个隔离网络部署边缘采
## ⛄ 已支持
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
- Site Monitor, Port Availability, Http Api, Ping Connectivity, Jvm, SiteMap Full Site, Ssl Certificate, SpringBoot, FTP Server
- Mysql, PostgreSQL, MariaDB, Redis, ElasticSearch, SqlServer, Oracle, MongoDB, Damon, OpenGauss, ClickHouse, IoTDB, Redis Cluster
@@ -166,7 +166,7 @@ HertzBeat 提供云边协同能力,可以在多个隔离网络部署边缘采
- Huawei Switch, HPE Switch, TP-LINK Switch, Cisco Switch
- and more for your custom monitoring.
- Notifications support `Discord` `Slack` `Telegram` `Mail` `Pinning` `WeChat` `FlyBook` `SMS` `Webhook`.
- 和更多自定义监控模
- 和更多自定义监控模
- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook`。
---
@@ -77,7 +77,7 @@ HertzBeat 赫兹跳动是一个拥有强大自定义监控能力,高性能集
***监控+告警+通知** 为一体,支持对应用服务,数据库,操作系统,中间件,云原生,网络等监控阈值告警通知一步到位。
* 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
*`Http,Jmx,Ssh,Snmp,Jdbc` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
*`Http,Jmx,Ssh,Snmp,Jdbc` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
* 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
* 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
@@ -19,7 +19,7 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
- **采集器集群的UI界面管理** @Ceilzcx @tomsun28
- **功能页面帮助信息模块和阈值表达式增强** 开源之夏和GLCC课题 @YutingNie @mikezzb
- **新的控制台登陆界面和欢迎页面**
- **监控指标名称国际化** 用户可以看指标的中英文名称啦,欢迎一起完善监控模里面的i18n国际化资源
- **监控指标名称国际化** 用户可以看指标的中英文名称啦,欢迎一起完善监控模里面的i18n国际化资源
- **支持kubernetes helm charts一键部署** 见 <https://artifacthub.io/packages/search?repo=hertzbeat>
**更多的特性和BUG修复,稳定性提示** 感谢 @zqr10159 @Carpe-Wang @luxx-lq @l646505418 @LINGLUOJUN @luelueking @qyaaaa @novohit @gcdd1993
@@ -54,7 +54,7 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
-**监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` 等方式消息及时送达。
@@ -94,8 +94,8 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
## ⛄ 已支持
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
- Site Monitor, Port Availability, Http Api, Ping Connectivity, Jvm, SiteMap Full Site, Ssl Certificate, SpringBoot, FTP Server
- Mysql, PostgreSQL, MariaDB, Redis, ElasticSearch, SqlServer, Oracle, MongoDB, Damon, OpenGauss, ClickHouse, IoTDB, Redis Cluster
@@ -105,7 +105,7 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
- Huawei Switch, HPE Switch, TP-LINK Switch, Cisco Switch
- and more for your custom monitoring.
- Notifications support `Discord` `Slack` `Telegram` `Mail` `Pinning` `WeChat` `FlyBook` `SMS` `Webhook`.
- 和更多自定义监控模
- 和更多自定义监控模
- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱`。
---
@@ -1,5 +1,5 @@
---
title: HertzBeat v1.4.2 版本发布,自定义消息通知模
title: HertzBeat v1.4.2 版本发布,自定义消息通知模
author: tom
author_title: tom
author_url: https://github.com/tomsun28
@@ -14,8 +14,8 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
### 总结起来如下
- **消息通知模特性,开源之夏课题**
- **支持华为云OBS存储监控模文件**
- **消息通知模特性,开源之夏课题**
- **支持华为云OBS存储监控模文件**
- **支持MQTT消息服务器 emqx 监控**
- **支持对 udp 端口可用性监控**
- **更多的特性功能支持和BUG修复**
@@ -31,7 +31,7 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
-**监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
@@ -71,8 +71,8 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
## ⛄ 已支持
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
- Site Monitor, Port Availability, Http Api, Ping Connectivity, Jvm, SiteMap Full Site, Ssl Certificate, SpringBoot, FTP Server
- Mysql, PostgreSQL, MariaDB, Redis, ElasticSearch, SqlServer, Oracle, MongoDB, Damon, OpenGauss, ClickHouse, IoTDB, Redis Cluster
@@ -82,7 +82,7 @@ keywords: [open source monitoring system, alerting system, Linux monitoring]
- Huawei Switch, HPE Switch, TP-LINK Switch, Cisco Switch
- and more for your custom monitoring.
- Notifications support `Discord` `Slack` `Telegram` `Mail` `Pinning` `WeChat` `FlyBook` `SMS` `Webhook`.
- 和更多自定义监控模
- 和更多自定义监控模
- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱`。
---
@@ -16,7 +16,7 @@ keywords: [open source monitoring system, alerting system]
-**监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 兼容 `Prometheus` 的系统生态并且更多,只需页面操作就可以监控 `Prometheus` 所能监控的。
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
@@ -66,8 +66,8 @@ keywords: [open source monitoring system, alerting system]
## ⛄ 已支持
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
- Site Monitor, Port Availability, Http Api, Ping Connectivity, Jvm, SiteMap Full Site, Ssl Certificate, SpringBoot, FTP Server
- Mysql, PostgreSQL, MariaDB, Redis, ElasticSearch, SqlServer, Oracle, MongoDB, Damon, OpenGauss, ClickHouse, IoTDB, Redis Cluster
@@ -77,7 +77,7 @@ keywords: [open source monitoring system, alerting system]
- Huawei Switch, HPE Switch, TP-LINK Switch, Cisco Switch
- and more for your custom monitoring.
- Notifications support `Discord` `Slack` `Telegram` `Mail` `Pinning` `WeChat` `FlyBook` `SMS` `Webhook`.
- 和更多自定义监控模
- 和更多自定义监控模
- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱`。
---
@@ -122,7 +122,7 @@ keywords: [open source monitoring system, alerting system]
-**监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 兼容 `Prometheus` 的系统生态并且更多,只需页面操作就可以监控 `Prometheus` 所能监控的。
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
@@ -16,7 +16,7 @@ keywords: [open source monitoring system, alerting system]
-**监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 兼容 `Prometheus` 的系统生态并且更多,只需页面操作就可以监控 `Prometheus` 所能监控的。
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
@@ -67,8 +67,8 @@ keywords: [open source monitoring system, alerting system]
## ⛄ 已支持
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
> 我们将监控采集类型(mysql,jvm,k8s)都定义为yml监控模,用户可以导入这些模来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模
- Site Monitor, Port Availability, Http Api, Ping Connectivity, Jvm, SiteMap Full Site, Ssl Certificate, SpringBoot, FTP Server
- Mysql, PostgreSQL, MariaDB, Redis, ElasticSearch, SqlServer, Oracle, MongoDB, Damon, OpenGauss, ClickHouse, IoTDB, Redis Cluster
@@ -78,7 +78,7 @@ keywords: [open source monitoring system, alerting system]
- Huawei Switch, HPE Switch, TP-LINK Switch, Cisco Switch
- and more for your custom monitoring.
- Notifications support `Discord` `Slack` `Telegram` `Mail` `Pinning` `WeChat` `FlyBook` `SMS` `Webhook`.
- 和更多自定义监控模
- 和更多自定义监控模
- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱`。
---
@@ -137,7 +137,7 @@ keywords: [open source monitoring system, alerting system]
- Update app-zookeeper.yml by @hurenjie1 in <https://github.com/apache/hertzbeat/pull/1458>
- add hurenjie1 as a contributor for code by @allcontributors in <https://github.com/apache/hertzbeat/pull/1459>
- update dashboard ui, remove ssh custom SignatureFactories, update app name by @tomsun28 in <https://github.com/apache/hertzbeat/pull/1460>
- Task Monitoring Template Yml Metrics I18n | 监控模指标国际化任务认领 #1212 by @tslj1024 in <https://github.com/apache/hertzbeat/pull/1461>
- Task Monitoring Template Yml Metrics I18n | 监控模指标国际化任务认领 #1212 by @tslj1024 in <https://github.com/apache/hertzbeat/pull/1461>
- add tslj1024 as a contributor for code by @allcontributors in <https://github.com/apache/hertzbeat/pull/1462>
- Add alarm trigger time for alarm restore by @Calvin979 in <https://github.com/apache/hertzbeat/pull/1464>
- bugfix history range query not work when victoria-metrics store by @tomsun28 in <https://github.com/apache/hertzbeat/pull/1463>
@@ -28,7 +28,7 @@ HertzBeat 于 2022 年 1 月在 Dromara 开源社区正式开源,经过两年
-**监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 兼容 `Prometheus` 的系统生态并且更多,只需页面操作就可以监控 `Prometheus` 所能监控的。
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
@@ -8,7 +8,7 @@
-**监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 兼容 `Prometheus` 的系统生态并且更多,只需页面操作就可以监控 `Prometheus` 所能监控的。
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
@@ -39,7 +39,7 @@
## HertzBeat 课题
### 1、实现监控模市场商店
### 1、实现监控模市场商店
**项目难度:进阶/Advanced**
@@ -47,7 +47,7 @@
对我们想要监控的指标进行采集。一些不同用户对一些中间件的数据的指标需求可能不同,`HertzBeat` 官方自带
的 yml 配置可能并不能满足每一个用户,所以我们的目的就是去让用户贡献自己的 yml 模去让更多的人受惠。
的 yml 配置可能并不能满足每一个用户,所以我们的目的就是去让用户贡献自己的 yml 模去让更多的人受惠。
这样不仅能让 `HertzBeat` 的生态更加完善,也能让用户的体验变的更好!
@@ -55,7 +55,7 @@
1. 使用Java17, springboot3编写后端代码,Angular(建议)或Vue编写前端代码。
2. 实现yml模板文件的搜索、下载、分享功能(无需登录)。
3. 模板页面展示下载量、分类、模板描述信息、模历史版本(可选)。
3. 模板页面展示下载量、分类、模板描述信息、模历史版本(可选)。
4. 实现用户个人页面注册、登录(后期),上传模板。
**产出:**
@@ -29,7 +29,7 @@ keywords: [open source, monitoring, alerting]
- 集 **监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web 服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
- 将 `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 将 `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 兼容 `Prometheus` 的系统生态并且更多,只需页面操作就可以监控 `Prometheus` 所能监控的。
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
@@ -28,7 +28,7 @@ keywords: [open source monitoring system, alerting system]
## 开始贡献
我的第一个 PR 是修改了一个 PR 模里的错误路径,社区处理的非常快,所以第一次贡献就好感倍增。
我的第一个 PR 是修改了一个 PR 模里的错误路径,社区处理的非常快,所以第一次贡献就好感倍增。
于是我便尝试开始阅读 HertzBeat 的一些核心采集代码,发现当时许多逻辑都没有提供单测,所以我就开始补全这些测试。
@@ -18,7 +18,7 @@
3. 数据备份
> 1. 若使用了自定义监控模
> 1. 若使用了自定义监控模
>
> - 需要备份 `kubectl cp hertzbeat/hertzbeat-978477f84-fr894:/opt/hertzbeat/define ./define` 当前运行 pod里面的 `/opt/hertzbeat/define` 目录到当前主机下,如果做了持久化 请拷贝持久化目录
> - `kubectl cp hertzbeat/hertzbeat-978477f84-fr894:/opt/hertzbeat/define ./define`
@@ -84,7 +84,7 @@ sidebar_label: 系统默认解析方式
]
```
**对应的监控模YML可以配置为如下**
**对应的监控模YML可以配置为如下**
```yaml
category: custom
@@ -96,9 +96,9 @@ name:
en-US: EXAMPLE APP
# The description and help of this monitoring type
help:
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
en-US: "HertzBeat supports custom monitoring, and you only need to configure the monitoring template YML to adapt to a custom monitoring type. <br>Definition process as follow: HertzBeat Pages -> Main Menu -> Monitor Template -> edit and save -> apply this template."
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-point/
en-US: https://hertzbeat.apache.org/docs/advanced/extend-point/
@@ -57,12 +57,12 @@ sidebar_label: 教程一:适配一款HTTP协议监控
**我们这次获取其app下的 `category`,`app`,`status`,`size`,`availableSize`等指标数据。**
### 新增自定义监控模YML
### 新增自定义监控模YML
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
> 监控模YML用于定义 *监控类型的名称(国际化), 请求参数结构定义(前端页面根据配置自动渲染UI), 采集指标信息, 采集协议配置* 等。
> 即我们通过自定义这个监控模,配置定义什么监控类型,前端页面需要输入什么参数,采集哪些性能指标,通过什么协议去采集。
> 监控模YML用于定义 *监控类型的名称(国际化), 请求参数结构定义(前端页面根据配置自动渲染UI), 采集指标信息, 采集协议配置* 等。
> 即我们通过自定义这个监控模,配置定义什么监控类型,前端页面需要输入什么参数,采集哪些性能指标,通过什么协议去采集。
样例:自定义一个名称为`hertzbeat`的自定义监控类型,其使用HTTP协议采集指标数据。
@@ -38,7 +38,7 @@ sidebar_label: 教程二:获取TOKEN后续认证使用
### 新增自定义监控类型`hertzbeat_token`
1. 自定义监控类型需新增配置监控模YML,我们直接复用教程一的 `hertzbeat` 监控类型,在其基础上修改
1. 自定义监控类型需新增配置监控模YML,我们直接复用教程一的 `hertzbeat` 监控类型,在其基础上修改
监控配置定义文件是用来定义采集类型是啥,需要用哪种协议采集方式,采集的指标是啥,协议的配置参数等。
我们直接复用 app-hertzbeat.yml 里面的定义内容,修改为我们当前的监控类型`hertzbeat_auth`配置参数, 比如 `app, category等`
@@ -104,7 +104,7 @@ sidebar_label: JsonPath解析方式
此数据结构符合HertzBeat的数据格式规范,成功提取指标`type,num`值。
**对应的监控模YML可以配置为如下**
**对应的监控模YML可以配置为如下**
```yaml
category: custom
@@ -18,18 +18,18 @@ HTTP协议支持我们自定义HTTP请求路径,请求header,请求参数,
### 自定义步骤
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
![HertzBeat](/img/docs/advanced/extend-point-1.png)
-------
下面详细介绍下监控模YML的配置用法,请注意看使用注释。
下面详细介绍下监控模YML的配置用法,请注意看使用注释。
### 监控模YML
### 监控模YML
> 监控模YML用于定义 *监控类型的名称(国际化), 请求参数结构定义(前端页面根据配置自动渲染UI), 采集指标信息, 采集协议配置* 等。
> 即我们通过自定义这个监控模,配置定义什么监控类型,前端页面需要输入什么参数,采集哪些性能指标,通过什么协议去采集。
> 监控模YML用于定义 *监控类型的名称(国际化), 请求参数结构定义(前端页面根据配置自动渲染UI), 采集指标信息, 采集协议配置* 等。
> 即我们通过自定义这个监控模,配置定义什么监控类型,前端页面需要输入什么参数,采集哪些性能指标,通过什么协议去采集。
样例:自定义一个名称为example_http的自定义监控类型,其使用HTTP协议采集指标数据。
@@ -44,9 +44,9 @@ name:
en-US: EXAMPLE APP
# The description and help of this monitoring type
help:
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
en-US: "HertzBeat supports custom monitoring, and you only need to configure the monitoring template YML to adapt to a custom monitoring type. <br>Definition process as follow: HertzBeat Pages -> Main Menu -> Monitor Template -> edit and save -> apply this template."
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-point/
en-US: https://hertzbeat.apache.org/docs/advanced/extend-point/
@@ -55,7 +55,7 @@ SQL响应数据:
### 自定义步骤
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
![HertzBeat](/img/docs/advanced/extend-point-1.png)
@@ -63,7 +63,7 @@ SQL响应数据:
下面详细介绍下文件的配置用法,请注意看使用注释。
### 监控模YML
### 监控模YML
> 监控配置定义文件用于定义 *监控类型的名称(国际化), 请求参数结构定义(前端页面根据配置自动渲染UI), 采集指标信息, 采集协议配置* 等。
> 即我们通过自定义这个YML,配置定义什么监控类型,前端页面需要输入什么参数,采集哪些性能指标,通过什么协议去采集。
@@ -15,19 +15,19 @@ sidebar_label: JMX协议自定义监控
### 数据解析方式
通过配置监控模YML的指标`field`, `aliasFields`, `jmx` 协议的 `objectName` 来和对端系统暴露的 `Mbean`对象信息映射解析。
通过配置监控模YML的指标`field`, `aliasFields`, `jmx` 协议的 `objectName` 来和对端系统暴露的 `Mbean`对象信息映射解析。
### 自定义步骤
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
![HertzBeat](/img/docs/advanced/extend-point-1.png)
-------
下面详细介绍下监控模的配置用法,请注意看使用注释。
下面详细介绍下监控模的配置用法,请注意看使用注释。
### 监控模YML
### 监控模YML
> 监控配置定义文件用于定义 *监控类型的名称(国际化), 请求参数结构定义(前端页面根据配置自动渲染UI), 采集指标信息, 采集协议配置* 等。
> 即我们通过自定义这个YML,配置定义什么监控类型,前端页面需要输入什么参数,采集哪些性能指标,通过什么协议去采集。
@@ -69,7 +69,7 @@ NGQL查询回来的数据字段和我们需要的指标映射,就能获取对
### 自定义步骤
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
![HertzBeat](/img/docs/advanced/extend-point-1.png)
@@ -77,7 +77,7 @@ NGQL查询回来的数据字段和我们需要的指标映射,就能获取对
下面详细介绍下文件的配置用法,请注意看使用注释。
### 监控模YML
### 监控模YML
> 监控配置定义文件用于定义 *监控类型的名称(国际化), 请求参数结构定义(前端页面根据配置自动渲染UI), 采集指标信息, 采集协议配置* 等。
> 即我们通过自定义这个YML,配置定义什么监控类型,前端页面需要输入什么参数,采集哪些性能指标,通过什么协议去采集。
@@ -4,12 +4,12 @@ title: 自定义监控
sidebar_label: 自定义监控
---
> HertzBeat拥有自定义监控能力,您只需配置监控模YML就能适配一款自定义的监控类型。
> HertzBeat拥有自定义监控能力,您只需配置监控模YML就能适配一款自定义的监控类型。
> 目前自定义监控支持[HTTP协议](extend-http)[JDBC协议](extend-jdbc)[SSH协议](extend-ssh)[JMX协议](extend-jmx)[SNMP协议](extend-snmp),后续会支持更多通用协议。
### 自定义流程
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
![HertzBeat](/img/docs/advanced/extend-point-1.png)
@@ -19,17 +19,17 @@ sidebar_label: 自定义监控
-------
### 监控模YML
### 监控模YML
**HertzBeat的设计是一个监控模对应一个监控类型,所有监控类型都是由监控模来定义的**。
**HertzBeat的设计是一个监控模对应一个监控类型,所有监控类型都是由监控模来定义的**。
> 监控模YML定义了 *监控类型的名称(国际化), 配置参数映射, 采集指标信息, 采集协议配置* 等。
> 监控模YML定义了 *监控类型的名称(国际化), 配置参数映射, 采集指标信息, 采集协议配置* 等。
下面使用样例详细介绍下这监控模YML的配置用法。
下面使用样例详细介绍下这监控模YML的配置用法。
样例:自定义一个 `app` 名称为 `example2` 的自定义监控类型,其使用HTTP协议采集指标数据。
[监控模] -> [新增监控类型] -> [右边配置如下监控模YML] -> [保存并应用]
[监控模] -> [新增监控类型] -> [右边配置如下监控模YML] -> [保存并应用]
```yaml
# The monitoring type categoryservice-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
@@ -45,9 +45,9 @@ name:
en-US: EXAMPLE WEBSITE
# The description and help of this monitoring type
help:
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
zh-CN: HertzBeat 支持自定义监控,您只需配置监控模 YML 就能适配一款自定义的监控类型。<br>定义流程如下:HertzBeat 页面 -> 监控模菜单 -> 新增监控类型 -> 配置自定义监控模YML -> 点击保存应用 -> 使用新监控类型添加监控。
en-US: "HertzBeat supports custom monitoring, and you only need to configure the monitoring template YML to adapt to a custom monitoring type. <br>Definition process as follow: HertzBeat Pages -> Main Menu -> Monitor Template -> edit and save -> apply this template."
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
zh-TW: HertzBeat支持自定義監控,您只需配寘監控模YML就能適配一款自定義的監控類型。<br>定義流程如下:HertzBeat頁面->監控模選單->新增監控類型->配寘自定義監控模YML ->點擊保存應用->使用新監控類型添加監控。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-point/
en-US: https://hertzbeat.apache.org/docs/advanced/extend-point/
@@ -15,11 +15,11 @@ sidebar_label: SNMP协议自定义监控
### 数据解析方式
通过配置监控模YML的指标`field`, `aliasFields`, `snmp` 协议下的 `oids`来抓取对端指定的数据并解析映射。
通过配置监控模YML的指标`field`, `aliasFields`, `snmp` 协议下的 `oids`来抓取对端指定的数据并解析映射。
### 自定义步骤
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
![HertzBeat](/img/docs/advanced/extend-point-1.png)
@@ -27,7 +27,7 @@ sidebar_label: SNMP协议自定义监控
下面详细介绍下文件的配置用法,请注意看使用注释。
### 监控模YML
### 监控模YML
> 监控配置定义文件用于定义 *监控类型的名称(国际化), 请求参数结构定义(前端页面根据配置自动渲染UI), 采集指标信息, 采集协议配置* 等。
> 即我们通过自定义这个YML,配置定义什么监控类型,前端页面需要输入什么参数,采集哪些性能指标,通过什么协议去采集。
@@ -67,7 +67,7 @@ total used free buff_cache available
### 自定义步骤
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
![HertzBeat](/img/docs/advanced/extend-point-1.png)
@@ -75,7 +75,7 @@ total used free buff_cache available
下面详细介绍下文件的配置用法,请注意看使用注释。
### 监控模YML
### 监控模YML
> 监控配置定义文件用于定义 *监控类型的名称(国际化), 请求参数结构定义(前端页面根据配置自动渲染UI), 采集指标信息, 采集协议配置* 等。
> 即我们通过自定义这个YML,配置定义什么监控类型,前端页面需要输入什么参数,采集哪些性能指标,通过什么协议去采集。
@@ -15,11 +15,11 @@ sidebar_label: Telnet协议自定义监控
### 数据解析方式
通过配置监控模YML的指标field, aliasFields, telnet 协议下的获取数据映射。
通过配置监控模YML的指标field, aliasFields, telnet 协议下的获取数据映射。
### 自定义步骤
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML** -> **点击保存应用** -> **使用新监控类型添加监控**
![HertzBeat](/img/docs/advanced/extend-point-1.png)
@@ -27,7 +27,7 @@ sidebar_label: Telnet协议自定义监控
下面详细介绍下文件的配置用法,请注意看使用注释。
### 监控模YML
### 监控模YML
> 监控配置定义文件用于定义 *监控类型的名称(国际化), 请求参数结构定义(前端页面根据配置自动渲染UI), 采集指标信息, 采集协议配置* 等。
> 即我们通过自定义这个YML,配置定义什么监控类型,前端页面需要输入什么参数,采集哪些性能指标,通过什么协议去采集。
@@ -57,13 +57,13 @@ sidebar_label: 教程案例
**我们这次获取其app下的 `category`,`app`,`status`,`size`,`availableSize`等指标数据。**
### 新增配置监控模YML
### 新增配置监控模YML
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML**
**HertzBeat页面** -> **监控模菜单** -> **新增监控类型** -> **配置自定义监控模YML**
定义我们在页面上需要输入哪些参数,一般的HTTP协议参数主要有ip, port, headers, params, uri, 账户密码等,我们直接复用 `api`监控模 里面的参数定义内容,删除其中的我们不需要输入的uri参数和keyword关键字等参数即可。
定义我们在页面上需要输入哪些参数,一般的HTTP协议参数主要有ip, port, headers, params, uri, 账户密码等,我们直接复用 `api`监控模 里面的参数定义内容,删除其中的我们不需要输入的uri参数和keyword关键字等参数即可。
定义采集类型是啥,需要用哪种协议采集方式,采集的指标是啥,协议的配置参数等。我们直接复用 `api`监控模 里面的定义内容,修改为我们当前的监控类型`hertzbeat`配置参数即可,如下:注意⚠️我们这次获取接口响应数据中的`category`,`app`,`status`,`size`,`availableSize`等字段作为指标数据。
定义采集类型是啥,需要用哪种协议采集方式,采集的指标是啥,协议的配置参数等。我们直接复用 `api`监控模 里面的定义内容,修改为我们当前的监控类型`hertzbeat`配置参数即可,如下:注意⚠️我们这次获取接口响应数据中的`category`,`app`,`status`,`size`,`availableSize`等字段作为指标数据。
```yaml
# The monitoring type categoryservice-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
@@ -441,7 +441,6 @@ ChunJin Mu
发送孵化社区投票邮件需要至少三个`+1`,且无`-1`
> `Send to`: <general@incubator.apache.org> <br />
> `cc`: <dev@hertzbeat.apache.org>、<private@hertzbeat.apache.org> <br />
> `Title`: [VOTE] Release Apache HertzBeat (incubating) 1.6.0-rc1 <br />
> `Body`:
@@ -7,7 +7,7 @@ sidebar_label: 阈值规则
:::tip
告警阈值规则是 `HertzBeat` 的核心功能,用户可以通过阈值规则来配置告警的触发条件。
阈值规则支持实时阈值和计划阈值,实时阈值可以在监控数据采集时直接触发告警,计划阈值支持 PromQL 等表达式在指定时间段内计算触发告警。
支持可视化页面配置或更高灵活性的表达式规则配置,支持配置触发次数,告警级别,通知模,关联指定监控等。
支持可视化页面配置或更高灵活性的表达式规则配置,支持配置触发次数,告警级别,通知模,关联指定监控等。
:::
![threshold](/img/docs/help/alert-threshold-1.png)
@@ -20,7 +20,7 @@ sidebar_label: 阈值规则
> 系统页面 -> 告警 -> 告警阈值 -> 新增阈值 -> 新增实时阈值规则
配置阈值,例如: 选择SSL证书指标对象,配置告警表达式-当指标`expired``true`触发,即`equals(expired,"true")` , 设置告警级别通知模信息等。
配置阈值,例如: 选择SSL证书指标对象,配置告警表达式-当指标`expired``true`触发,即`equals(expired,"true")` , 设置告警级别通知模信息等。
![HertzBeat](/img/docs/start/ssl_5.png)
@@ -32,7 +32,7 @@ sidebar_label: 阈值规则
- **关联监控**:应用此阈值规则到指定的监控对象(支持直接绑定和标签关联),若未配置,则应用到所有符合此阈值类型规则的监控对象上。
- **告警级别**:触发阈值的告警级别,从低到高依次为:警告-warning,严重-critical,紧急-emergency
- **触发次数**:设置触发阈值多少次之后才会真正的触发告警
- **通知模**:告警触发后发送的通知信息模,模环境变量见页面提示,例如:`${__instancename__} ${__metric__} 指标的值为 ${responseTime},大于 50 触发告警`
- **通知模**:告警触发后发送的通知信息模,模环境变量见页面提示,例如:`${__instancename__} ${__metric__} 指标的值为 ${responseTime},大于 50 触发告警`
- **附加标签**:给此阈值规则附加标签,当产生告警时,此标签也会附加到告警上。
- **附加声明**:给此阈值规则附加声明信息(声明内容支持环境变量),当产生告警时,此声明信息会被渲染并附加到告警上。
- **启用告警**:此告警阈值配置开启生效或关闭
@@ -111,7 +111,7 @@ sidebar_label: 帮助入门
### 告警配置
> 指标阈值配置,提供表达式形式的指标阈值配置,可设置告警级别,触发次数,告警通知模和是否启用,关联监控等功能。
> 指标阈值配置,提供表达式形式的指标阈值配置,可设置告警级别,触发次数,告警通知模和是否启用,关联监控等功能。
详见&emsp;&#x1F449;&emsp;[阈值告警](alert_threshold) <br />
&emsp;&emsp;&emsp;&#x1F449;&emsp;[阈值表达式](alert_threshold_expr)
@@ -5,7 +5,7 @@ sidebar_label: 安全模型
---
:::tip
Apache HertzBeat 是一个高可扩展的系统,其提供用户大量的自定义能力,用户可以通过自定义监控模,自定义监控器,自定义插件等来对平台增强。在这种情况下,安全性是非常重要的。
Apache HertzBeat 是一个高可扩展的系统,其提供用户大量的自定义能力,用户可以通过自定义监控模,自定义监控器,自定义插件等来对平台增强。在这种情况下,安全性是非常重要的。
本文档将介绍 Apache HertzBeat 的安全模型。
这里的安全模型主要涉及用户在扩展过程中需要注意的安全边界,以及如何保证用户的自定义不会对系统造成安全隐患。
:::
@@ -16,9 +16,9 @@ Apache HertzBeat 使用 [Sureness](https://github.com/dromara/sureness) 来支
使用 Sureness 提供的 `sureness.yml` 来配置用户账户,角色,API资源等,强烈建议初始用户修改账户密码,具体参考 [账户权限管理](../start/account-modify)
## 监控模安全
## 监控模安全
Apache HertzBeat 提供了监控模功能,用户可以通过配置监控模里面的自定义脚本来定义监控规则。
Apache HertzBeat 提供了监控模功能,用户可以通过配置监控模里面的自定义脚本来定义监控规则。
脚本类型包含 `SQL` `SHELL` `JMX` `URL` `API` 等,当用户自定义脚本时需要自行保证自定义脚本的安全性,避免脚本中包含恶意代码等。
@@ -17,7 +17,7 @@ slug: /
- 集 **监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web服务器,云原生,网络,自定义等监控阈值告警通知一步到位。
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
- 将 `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 将 `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 兼容 `Prometheus` 的系统生态并且更多,只需页面操作就可以监控 `Prometheus` 所能监控的。
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
@@ -27,22 +27,22 @@ slug: /
---
### 强大的监控模
### 强大的监控模
> 开始我们就说 HertzBeat 的特点是自定义监控能力,无需 Agent。在讨论这两点之前,我们先介绍下 HertzBeat 的不一样的监控模。而正是因为这样的监控模设计,才会有了后面的高级特性。
> 开始我们就说 HertzBeat 的特点是自定义监控能力,无需 Agent。在讨论这两点之前,我们先介绍下 HertzBeat 的不一样的监控模。而正是因为这样的监控模设计,才会有了后面的高级特性。
HertzBeat 自身并没有去创造一种采集数据协议让监控对端来适配它。而是充分使用了现有的生态,`SNMP协议`采集网络交换机路由器信息,`JMX规范`采集JAVA应用信息,`JDBC规范`采集数据集信息,`SSH`直连执行脚本获取回显信息,`HTTP+(JsonPath | prometheus等)`解析API接口信息,`IPMI协议`采集服务器信息等等。
HertzBeat 使用这些已有的标准协议或规范,将他们抽象规范可配置化,最后使其都可以通过编写YML格式监控模的形式,来制定模使用这些协议来采集任何想要的指标数据。
HertzBeat 使用这些已有的标准协议或规范,将他们抽象规范可配置化,最后使其都可以通过编写YML格式监控模的形式,来制定模使用这些协议来采集任何想要的指标数据。
![HertzBeat](/img/blog/multi-protocol.png)
你相信用户只需在UI页面编写一个监控模,点击保存后,就能立刻适配一款`K8s``Docker`等新的监控类型吗?
你相信用户只需在UI页面编写一个监控模,点击保存后,就能立刻适配一款`K8s``Docker`等新的监控类型吗?
![HertzBeat](/img/home/9.png)
### 内置监控类型
**官方内置了大量的监控模类型,方便用户直接在页面添加使用,一款监控类型对应一个YML监控模**
**官方内置了大量的监控模类型,方便用户直接在页面添加使用,一款监控类型对应一个YML监控模**
- [Website](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-website.yml), [Port Telnet](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-port.yml),
[Http Api](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-api.yml), [Ping Connect](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ping.yml),
@@ -80,14 +80,14 @@ HertzBeat 使用这些已有的标准协议或规范,将他们抽象规范可
- [CiscoSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-cisco_switch.yml), [HpeSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-hpe_switch.yml),
[HuaweiSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-huawei_switch.yml), [TpLinkSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-tplink_switch.yml),
[H3cSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-h3c_switch.yml)
- 和更多自定义监控模
- 和更多自定义监控模
- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱`
### 自定义能力
> 由前面的**监控模**介绍,大概清楚了 `HertzBeat` 拥有的自定义功能。
> 我们将每个监控类型都视为一个监控模,不管是官方内置的还是后期用户自定义新增的。用户都可以方便的通过修改监控模来新增修改删除监控指标。
> 模里面包含各个协议的使用配置,环境变量,指标转换,指标计算,单位转换,指标采集等一系列功能,帮助用户能采集到自己想要的监控指标。
> 由前面的**监控模**介绍,大概清楚了 `HertzBeat` 拥有的自定义功能。
> 我们将每个监控类型都视为一个监控模,不管是官方内置的还是后期用户自定义新增的。用户都可以方便的通过修改监控模来新增修改删除监控指标。
> 模里面包含各个协议的使用配置,环境变量,指标转换,指标计算,单位转换,指标采集等一系列功能,帮助用户能采集到自己想要的监控指标。
![HertzBeat](/img/docs/custom-arch.png)
@@ -127,9 +127,9 @@ HertzBeat 使用这些已有的标准协议或规范,将他们抽象规范可
### 易用友好
- 集 **监控+告警+通知** All in one, 无需单独部署多个组件服务。
- 全UI界面操作,不管是新增监控,修改监控模,还是告警阈值通知,都可在WEB界面操作完成,无需要修改文件或脚本或重启。
- 全UI界面操作,不管是新增监控,修改监控模,还是告警阈值通知,都可在WEB界面操作完成,无需要修改文件或脚本或重启。
- 无需 Agent, 监控对端我们只需在WEB界面填写所需IP端口账户密码等参数即可。
- 自定义友好,只需一个监控模YML,自动生成对应监控类型的监控管理页面,数据图表页面,阈值配置等。
- 自定义友好,只需一个监控模YML,自动生成对应监控类型的监控管理页面,数据图表页面,阈值配置等。
- 阈值告警通知友好,基于表达式阈值配置,多种告警通知渠道,支持告警静默,时段标签告警级别过滤等。
### 完全开源
@@ -217,7 +217,7 @@ Docker 环境下运行一条命令即可:`docker run -d -p 1157:1157 -p 1158:1
### 新增监控
- 新增或修改指定监控类型的监控实例,配置对端监控的IP,端口等参数,设置采集周期,采集任务调度方式,支持提前探测可用性等。
- 页面上配置的监控参数由对应监控类型的监控模所定义,用户可以通过修改监控模来修改页面配置参数。
- 页面上配置的监控参数由对应监控类型的监控模所定义,用户可以通过修改监控模来修改页面配置参数。
- 支持关联标签,用标签来管理监控分组,告警匹配等。
![HertzBeat](/img/home/10.png)
@@ -244,7 +244,7 @@ Docker 环境下运行一条命令即可:`docker run -d -p 1157:1157 -p 1158:1
- 告警阈值规则是 `HertzBeat` 的核心功能,用户可以通过阈值规则来配置告警的触发条件。
- 阈值规则支持实时阈值和计划阈值,实时阈值可以在监控数据采集时直接触发告警,计划阈值支持 PromQL 等表达式在指定时间段内计算触发告警。
- 阈值规则支持可视化页面配置或更高灵活性的表达式规则配置,支持配置触发次数,告警级别,通知模,关联指定监控等。
- 阈值规则支持可视化页面配置或更高灵活性的表达式规则配置,支持配置触发次数,告警级别,通知模,关联指定监控等。
![HertzBeat](/img/home/6.png)
@@ -284,7 +284,7 @@ Docker 环境下运行一条命令即可:`docker run -d -p 1157:1157 -p 1158:1
- 功能包含接收人信息管理和通知策略管理,接收人管理维护接收人信息以其通知方式信息,通知策略管理维护把哪些告警信息通知给哪些接收人的策略规则。
- 通知方式支持 `邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` 等方式。
- 通知策略支持标签匹配和告警级别匹配,方便的使不同标签的告警和告警级别分派给不同的接收处理人。
- 支持通知模,用户可以自定义通过模内容格式来满足自己的个性化通知展示需求。
- 支持通知模,用户可以自定义通过模内容格式来满足自己的个性化通知展示需求。
![HertzBeat](/img/home/16.png)
@@ -294,10 +294,10 @@ Docker 环境下运行一条命令即可:`docker run -d -p 1157:1157 -p 1158:1
![HertzBeat](/img/home/14.png)
### 监控模
### 监控模
- HertzBeat 将 `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 同理我们内置的所有监控类型(mysql,website,jvm,k8s)也一一映射为对应的监控模,用户可以新增修改监控模来自定义监控功能。
- HertzBeat 将 `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 同理我们内置的所有监控类型(mysql,website,jvm,k8s)也一一映射为对应的监控模,用户可以新增修改监控模来自定义监控功能。
![HertzBeat](/img/home/9.png)

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