mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 18:19:02 +00:00
Compare commits
50
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99ccf6cd48 | ||
|
|
986e833798 | ||
|
|
13b87b6c51 | ||
|
|
292f03045b | ||
|
|
2746615f63 | ||
|
|
195e7e95fa | ||
|
|
d0b3c2dba2 | ||
|
|
886f0b74f6 | ||
|
|
32e1a43aa5 | ||
|
|
dcd806802e | ||
|
|
5746cbbbd7 | ||
|
|
e23903fd0c | ||
|
|
780710f226 | ||
|
|
4607ede541 | ||
|
|
67ad4b04ef | ||
|
|
6432d689dd | ||
|
|
2eb856fffb | ||
|
|
56312831ca | ||
|
|
fe54d42bc0 | ||
|
|
2ea24c1b3a | ||
|
|
e0040e2ede | ||
|
|
0ac0fd4a8d | ||
|
|
0ef87bcc08 | ||
|
|
660bda6e14 | ||
|
|
242cf40135 | ||
|
|
7319c55430 | ||
|
|
5ea29f610b | ||
|
|
b74aff0500 | ||
|
|
d2e8f2f4aa | ||
|
|
28681a1f9e | ||
|
|
6814c7c357 | ||
|
|
f475540508 | ||
|
|
44660a5042 | ||
|
|
339386fd2b | ||
|
|
faa7cb71db | ||
|
|
014a376c30 | ||
|
|
377172e44a | ||
|
|
5b9e19cc30 | ||
|
|
0457ec7d16 | ||
|
|
2947ee218e | ||
|
|
4e841a9fb1 | ||
|
|
b7ecb9b2ec | ||
|
|
7e1873bc10 | ||
|
|
8eb60210a3 | ||
|
|
d608f732f7 | ||
|
|
2d9a2955ef | ||
|
|
cae4423f30 | ||
|
|
f0e53a9fb3 | ||
|
|
79da1a198b | ||
|
|
64cb804147 |
@@ -16,7 +16,7 @@
|
||||
#
|
||||
|
||||
github:
|
||||
description: Apache HertzBeat(incubating) is a real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
|
||||
description: Real-time observability system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
|
||||
homepage: https://hertzbeat.apache.org/
|
||||
labels:
|
||||
- monitoring
|
||||
|
||||
@@ -67,6 +67,7 @@ header:
|
||||
- 'karma.conf.js'
|
||||
- 'proxy.conf.js'
|
||||
- '.helmignore'
|
||||
- 'script/helm/**'
|
||||
- 'web-app/src/app/core/**'
|
||||
- 'web-app/src/app/layout/**'
|
||||
- 'web-app/src/app/routes/exception/**'
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
Apache HertzBeat (incubating) is an effort undergoing incubation at the Apache
|
||||
Software Foundation (ASF), sponsored by the Apache Incubator PMC.
|
||||
|
||||
Incubation is required of all newly accepted projects until a further review
|
||||
indicates that the infrastructure, communications, and decision making process
|
||||
have stabilized in a manner consistent with other successful ASF projects.
|
||||
|
||||
While incubation status is not necessarily a reflection of the completeness
|
||||
or stability of the code, it does indicate that the project has yet to be
|
||||
fully endorsed by the ASF.
|
||||
@@ -1,4 +1,4 @@
|
||||
Apache HertzBeat (incubating)
|
||||
Apache HertzBeat™
|
||||
Copyright 2024-2025 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<b><a href="README.md">English</a></b> | <a href="README_CN.md">中文</a> | <a href="README_JP.md">日本語</a>
|
||||
</p>
|
||||
|
||||
> A real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
|
||||
> A real-time observability system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
|
||||
|
||||
[](https://discord.gg/Fb6M73htGr)
|
||||
[](https://www.reddit.com/r/hertzbeat/)
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
## 🎡 <font color="green">Introduction</font>
|
||||
|
||||
[Apache HertzBeat](https://github.com/apache/hertzbeat) (incubating) is an easy-to-use, open source, real-time monitoring system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
|
||||
[Apache HertzBeat™](https://github.com/apache/hertzbeat) is an easy-to-use, open source, real-time observability system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
|
||||
|
||||
### Features
|
||||
|
||||
@@ -572,8 +572,8 @@ HertzBeat is built on so many great open source projects, thanks to them!
|
||||
<p align="left">
|
||||
<img src="./home/static/img/home/cncf-landscape-left-logo.svg" width="300"> <img src="./home/static/img/home/cncf-right-logo.svg" width="345" />
|
||||
<br /><br />
|
||||
HertzBeat has been included in the <a href="https://landscape.cncf.io/guide?item=observability-and-analysis--monitoring--hertzbeat#observability-and-analysis--monitoring">
|
||||
CNCF Observability And Analysis - Monitoring Landscape.</a>
|
||||
HertzBeat has been included in the <a href="https://landscape.cncf.io/?item=observability-and-analysis--observability--hertzbeat">
|
||||
CNCF Observability And Analysis - Observability Landscape.</a>
|
||||
</p>
|
||||
|
||||
## 🛡️ License
|
||||
|
||||
+4
-4
@@ -9,7 +9,7 @@
|
||||
<a href="README.md">English</a> | <b><a href="README_CN.md">中文</a></b> | <a href="README_JP.md">日本語</a>
|
||||
</p>
|
||||
|
||||
> 实时监控系统,无需 Agent,性能集群,兼容 Prometheus,自定义监控和状态页构建能力。
|
||||
> 实时观测系统,无需 Agent,性能集群,兼容 Prometheus,自定义监控和状态页构建能力。
|
||||
|
||||
[](https://discord.gg/Fb6M73htGr)
|
||||
[](https://www.reddit.com/r/hertzbeat/)
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
## 🎡 <font color="green">介绍</font>
|
||||
|
||||
[Apache HertzBeat](https://github.com/apache/hertzbeat) (incubating)是一个易用友好的开源实时监控告警系统,无需 Agent,高性能集群,兼容 Prometheus,提供强大的自定义监控和状态页构建能力。
|
||||
[Apache HertzBeat™](https://github.com/apache/hertzbeat) 是一个易用友好的开源实时监控告警系统,无需 Agent,高性能集群,兼容 Prometheus,提供强大的自定义监控和状态页构建能力。
|
||||
|
||||
### 特点
|
||||
|
||||
@@ -572,8 +572,8 @@ HertzBeat is built on so many great open source projects, thanks to them!
|
||||
<p align="left">
|
||||
<img src="./home/static/img/home/cncf-landscape-left-logo.svg" width="300"> <img src="./home/static/img/home/cncf-right-logo.svg" width="345" />
|
||||
<br /><br />
|
||||
HertzBeat has been included in the <a href="https://landscape.cncf.io/guide?item=observability-and-analysis--monitoring--hertzbeat#observability-and-analysis--monitoring">
|
||||
CNCF Observability And Analysis - Monitoring Landscape.</a>
|
||||
HertzBeat has been included in the <a href="https://landscape.cncf.io/?item=observability-and-analysis--observability--hertzbeat">
|
||||
CNCF Observability And Analysis - Observability Landscape.</a>
|
||||
</p>
|
||||
|
||||
## 🛡️ License
|
||||
|
||||
+2
-2
@@ -576,8 +576,8 @@ HertzBeat is built on so many great open source projects, thanks to them!
|
||||
<p align="left">
|
||||
<img src="./home/static/img/home/cncf-landscape-left-logo.svg" width="300"> <img src="./home/static/img/home/cncf-right-logo.svg" width="345" />
|
||||
<br /><br />
|
||||
HertzBeat has been included in the <a href="https://landscape.cncf.io/guide?item=observability-and-analysis--monitoring--hertzbeat#observability-and-analysis--monitoring">
|
||||
CNCF Observability And Analysis - Monitoring Landscape.</a>
|
||||
HertzBeat has been included in the <a href="https://landscape.cncf.io/?item=observability-and-analysis--observability--hertzbeat">
|
||||
CNCF Observability And Analysis - Observability Landscape.</a>
|
||||
</p>
|
||||
|
||||
## 🛡️ License
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
# Security Policy
|
||||
|
||||
Apache HertzBeat follows the [ASF vulnerability handling process](https://apache.org/security/#vulnerability-handling)
|
||||
Apache HertzBeat™ follows the [ASF vulnerability handling process](https://apache.org/security/#vulnerability-handling)
|
||||
|
||||
## Supported Versions
|
||||
|
||||
@@ -17,6 +17,6 @@ To report a new vulnerability you have discovered please follow the [ASF vulnera
|
||||
|
||||
## Extra Information
|
||||
|
||||
- [Apache HertzBeat Security Model](https://hertzbeat.apache.org/docs/help/security_model)
|
||||
- [Apache HertzBeat™ Security Model](https://hertzbeat.apache.org/docs/help/security_model)
|
||||
- [ASF Security](https://www.apache.org/security/)
|
||||
- [Apache HertzBeat Document](https://hertzbeat.apache.org/docs/)
|
||||
- [Apache HertzBeat™ Document](https://hertzbeat.apache.org/docs/)
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public class ServerChanAlertNotifyHandlerImpl extends AbstractAlertNotifyHandler
|
||||
String webHookUrl = String.format(alerterProperties.getServerChanWebhookUrl(), sanitizedToken);
|
||||
|
||||
// Validate the constructed URL against a whitelist
|
||||
List<String> allowedBaseUrls = List.of("https://api.serverchan.com", "https://serverchan.example.com");
|
||||
List<String> allowedBaseUrls = List.of("https://api.serverchan.com", "https://serverchan.example.com", "https://sctapi.ftqq.com");
|
||||
boolean isValidUrl = allowedBaseUrls.stream().anyMatch(webHookUrl::startsWith);
|
||||
if (!isValidUrl) {
|
||||
throw new AlertNoticeException("Invalid webhook URL: " + webHookUrl);
|
||||
|
||||
+5
-3
@@ -640,11 +640,13 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
.collect(Collectors.toMap(MetricFamily.Label::getName, MetricFamily.Label::getValue));
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String aliasField : aliasFields) {
|
||||
if ("value".equals(aliasField)) {
|
||||
String columnValue = labelMap.get(aliasField);
|
||||
if (columnValue != null) {
|
||||
valueRowBuilder.addColumn(columnValue);
|
||||
} else if (CommonConstants.PROM_VALUE.equals(aliasField) || CommonConstants.PROM_METRIC_VALUE.equals(aliasField)) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getValue()));
|
||||
} else {
|
||||
String columnValue = labelMap.get(aliasField);
|
||||
valueRowBuilder.addColumn(columnValue == null ? CommonConstants.NULL_VALUE : columnValue);
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
|
||||
+1
-2
@@ -60,7 +60,7 @@ public class PrometheusMatrixParser extends AbstractPrometheusParse {
|
||||
boolean setValueFlag = false;
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String aliasField : aliasFields) {
|
||||
if (!CollectUtil.assertPromRequireField(aliasField)) {
|
||||
if (!CollectUtil.assertPromRequireField(aliasField) || CollectUtil.isValueAsLabel(aliasField, r.getMetric())) {
|
||||
JsonElement jsonElement = r.getMetric().get(aliasField);
|
||||
if (jsonElement != null) {
|
||||
valueRowBuilder.addColumn(jsonElement.getAsString());
|
||||
@@ -93,7 +93,6 @@ public class PrometheusMatrixParser extends AbstractPrometheusParse {
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class PrometheusVectorParser extends AbstractPrometheusParse {
|
||||
for (PromVectorOrMatrix.Result r : result) {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String aliasField : aliasFields) {
|
||||
if (!CollectUtil.assertPromRequireField(aliasField)) {
|
||||
if (!CollectUtil.assertPromRequireField(aliasField) || CollectUtil.isValueAsLabel(aliasField, r.getMetric())) {
|
||||
JsonElement jsonElement = r.getMetric().get(aliasField);
|
||||
if (jsonElement != null) {
|
||||
valueRowBuilder.addColumn(jsonElement.getAsString());
|
||||
|
||||
-308
@@ -1,308 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.prometheus;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.common.http.CommonHttpClient;
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.collector.util.CollectUtil;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.constants.NetworkConstants;
|
||||
import org.apache.hertzbeat.common.constants.SignConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.PrometheusProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.util.Base64Util;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.apache.hertzbeat.common.util.IpDomainUtil;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.methods.RequestBuilder;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.auth.DigestScheme;
|
||||
import org.apache.http.impl.client.BasicAuthCache;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.SignConstants.RIGHT_DASH;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class PrometheusProxyCollectImpl implements PrometheusCollect {
|
||||
|
||||
private final Set<Integer> defaultSuccessStatusCodes = Stream.of(HttpStatus.SC_OK, HttpStatus.SC_CREATED,
|
||||
HttpStatus.SC_ACCEPTED, HttpStatus.SC_MULTIPLE_CHOICES, HttpStatus.SC_MOVED_PERMANENTLY,
|
||||
HttpStatus.SC_MOVED_TEMPORARILY).collect(Collectors.toSet());
|
||||
|
||||
public static final String RAW_TEXT_CONTENT_FIELD_NAME = "raw_text_content";
|
||||
|
||||
@Override
|
||||
public List<CollectRep.MetricsData> collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
PrometheusProtocol prometheusProtocol = metrics.getPrometheus();
|
||||
HttpUriRequest request;
|
||||
try {
|
||||
validateParams(metrics);
|
||||
} catch (Exception e) {
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(e.getMessage());
|
||||
return Collections.singletonList(builder.build());
|
||||
}
|
||||
|
||||
HttpContext httpContext = createHttpContext(prometheusProtocol);
|
||||
request = createHttpRequest(prometheusProtocol);
|
||||
|
||||
try (CloseableHttpResponse response = CommonHttpClient.getHttpClient().execute(request, httpContext)) {
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
log.debug("Prometheus proxy collect, response status: {}", statusCode);
|
||||
|
||||
if (!defaultSuccessStatusCodes.contains(statusCode)) {
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(NetworkConstants.STATUS_CODE + SignConstants.BLANK + statusCode);
|
||||
return Collections.singletonList(builder.build());
|
||||
}
|
||||
|
||||
String rawTextContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
||||
|
||||
builder.clearFields();
|
||||
builder.clearValues();
|
||||
|
||||
CollectRep.Field rawDataField = CollectRep.Field.newBuilder()
|
||||
.setName(RAW_TEXT_CONTENT_FIELD_NAME)
|
||||
.setType(CommonConstants.TYPE_STRING)
|
||||
.build();
|
||||
builder.addField(rawDataField);
|
||||
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
valueRowBuilder.addColumn(rawTextContent);
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
|
||||
builder.setCode(CollectRep.Code.SUCCESS);
|
||||
} catch (ClientProtocolException e1) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e1);
|
||||
log.error("Prometheus proxy collect error: {}. Host: {}, Port: {}", errorMsg, prometheusProtocol.getHost(), prometheusProtocol.getPort(), e1);
|
||||
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
|
||||
builder.setMsg(errorMsg);
|
||||
} catch (UnknownHostException e2) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e2);
|
||||
log.info("Prometheus proxy collect unknown host: {}. Host: {}", errorMsg, prometheusProtocol.getHost(), e2);
|
||||
builder.setCode(CollectRep.Code.UN_REACHABLE);
|
||||
builder.setMsg("unknown host:" + errorMsg);
|
||||
} catch (InterruptedIOException | ConnectException | SSLException e3) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e3);
|
||||
log.info("Prometheus proxy collect connect error: {}. Host: {}, Port: {}", errorMsg, prometheusProtocol.getHost(), prometheusProtocol.getPort(), e3);
|
||||
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
|
||||
builder.setMsg(errorMsg);
|
||||
} catch (IOException e4) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e4);
|
||||
log.info("Prometheus proxy collect IO error: {}. Host: {}, Port: {}", errorMsg, prometheusProtocol.getHost(), prometheusProtocol.getPort(), e4);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(errorMsg);
|
||||
} catch (Exception e) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e);
|
||||
log.error("Prometheus proxy collect unknown error: {}. Host: {}, Port: {}", errorMsg, prometheusProtocol.getHost(), prometheusProtocol.getPort(), e);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(errorMsg);
|
||||
} finally {
|
||||
if (request != null) {
|
||||
request.abort();
|
||||
}
|
||||
}
|
||||
return Collections.singletonList(builder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportProtocol() {
|
||||
return DispatchConstants.PROTOCOL_PROMETHEUS;
|
||||
}
|
||||
|
||||
private void validateParams(Metrics metrics) throws Exception {
|
||||
if (metrics == null || metrics.getPrometheus() == null) {
|
||||
throw new Exception("Prometheus collect must has prometheus params");
|
||||
}
|
||||
PrometheusProtocol protocol = metrics.getPrometheus();
|
||||
if (!StringUtils.hasText(protocol.getHost())
|
||||
|| !StringUtils.hasText(protocol.getPort())) {
|
||||
throw new Exception("Prometheus collect must has host and port params");
|
||||
}
|
||||
if (protocol.getPath() == null
|
||||
|| !StringUtils.hasText(protocol.getPath())
|
||||
|| !protocol.getPath().startsWith(RIGHT_DASH)) {
|
||||
protocol.setPath(protocol.getPath() == null ? RIGHT_DASH : RIGHT_DASH + protocol.getPath().trim());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create httpContext
|
||||
* This method is adapted from PrometheusAutoCollectImpl
|
||||
* @param protocol prometheus protocol
|
||||
* @return context
|
||||
*/
|
||||
public HttpContext createHttpContext(PrometheusProtocol protocol) {
|
||||
PrometheusProtocol.Authorization auth = protocol.getAuthorization();
|
||||
if (auth != null && DispatchConstants.DIGEST_AUTH.equals(auth.getType())) {
|
||||
HttpClientContext clientContext = new HttpClientContext();
|
||||
if (StringUtils.hasText(auth.getDigestAuthUsername())
|
||||
&& StringUtils.hasText(auth.getDigestAuthPassword())) {
|
||||
CredentialsProvider provider = new BasicCredentialsProvider();
|
||||
UsernamePasswordCredentials credentials =
|
||||
new UsernamePasswordCredentials(auth.getDigestAuthUsername(), auth.getDigestAuthPassword());
|
||||
provider.setCredentials(AuthScope.ANY, credentials);
|
||||
AuthCache authCache = new BasicAuthCache();
|
||||
HttpHost targetHost = new HttpHost(protocol.getHost(), Integer.parseInt(protocol.getPort()));
|
||||
authCache.put(targetHost, new DigestScheme());
|
||||
clientContext.setCredentialsProvider(provider);
|
||||
clientContext.setAuthCache(authCache);
|
||||
return clientContext;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* create http request
|
||||
* This method is adapted from PrometheusAutoCollectImpl
|
||||
* @param protocol http params
|
||||
* @return http uri request
|
||||
*/
|
||||
public HttpUriRequest createHttpRequest(PrometheusProtocol protocol) {
|
||||
RequestBuilder requestBuilder = RequestBuilder.get();
|
||||
// params
|
||||
Map<String, String> params = protocol.getParams();
|
||||
if (params != null && !params.isEmpty()) {
|
||||
for (Map.Entry<String, String> param : params.entrySet()) {
|
||||
if (StringUtils.hasText(param.getValue())) {
|
||||
requestBuilder.addParameter(param.getKey(), param.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
requestBuilder.addHeader(HttpHeaders.CONNECTION, NetworkConstants.KEEP_ALIVE);
|
||||
requestBuilder.addHeader(HttpHeaders.USER_AGENT, NetworkConstants.USER_AGENT);
|
||||
// headers The custom request header is overwritten here
|
||||
Map<String, String> headers = protocol.getHeaders();
|
||||
if (headers != null && !headers.isEmpty()) {
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
if (StringUtils.hasText(header.getValue())) {
|
||||
requestBuilder.addHeader(CollectUtil.replaceUriSpecialChar(header.getKey()),
|
||||
CollectUtil.replaceUriSpecialChar(header.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (headers == null || headers.keySet().stream().noneMatch(HttpHeaders.ACCEPT::equalsIgnoreCase)) {
|
||||
requestBuilder.addHeader(HttpHeaders.ACCEPT, MediaType.TEXT_PLAIN_VALUE + ";version=0.0.4,*/*;q=0.1");
|
||||
}
|
||||
|
||||
if (protocol.getAuthorization() != null) {
|
||||
PrometheusProtocol.Authorization authorization = protocol.getAuthorization();
|
||||
if (DispatchConstants.BEARER_TOKEN.equalsIgnoreCase(authorization.getType())) {
|
||||
if (StringUtils.hasText(authorization.getBearerTokenToken())) {
|
||||
String value = DispatchConstants.BEARER + " " + authorization.getBearerTokenToken();
|
||||
requestBuilder.addHeader(HttpHeaders.AUTHORIZATION, value);
|
||||
}
|
||||
} else if (DispatchConstants.BASIC_AUTH.equals(authorization.getType())) {
|
||||
if (StringUtils.hasText(authorization.getBasicAuthUsername())
|
||||
&& StringUtils.hasText(authorization.getBasicAuthPassword())) {
|
||||
String authStr = authorization.getBasicAuthUsername() + ":" + authorization.getBasicAuthPassword();
|
||||
String encodedAuth = Base64Util.encode(authStr);
|
||||
requestBuilder.addHeader(HttpHeaders.AUTHORIZATION, DispatchConstants.BASIC + " " + encodedAuth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.hasLength(protocol.getPayload())) {
|
||||
requestBuilder.setEntity(new StringEntity(protocol.getPayload(), StandardCharsets.UTF_8));
|
||||
if (headers == null || headers.keySet().stream().noneMatch(HttpHeaders.CONTENT_TYPE::equalsIgnoreCase)) {
|
||||
requestBuilder.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
String uriPath = CollectUtil.replaceUriSpecialChar(protocol.getPath());
|
||||
if (IpDomainUtil.isHasSchema(protocol.getHost())) {
|
||||
requestBuilder.setUri(protocol.getHost() + SignConstants.DOUBLE_MARK + protocol.getPort() + uriPath);
|
||||
} else {
|
||||
String ipAddressType = IpDomainUtil.checkIpAddressType(protocol.getHost());
|
||||
String baseUri = NetworkConstants.IPV6.equals(ipAddressType)
|
||||
? String.format("[%s]:%s%s", protocol.getHost(), protocol.getPort(), uriPath)
|
||||
: String.format("%s:%s%s", protocol.getHost(), protocol.getPort(), uriPath);
|
||||
boolean ssl = Boolean.parseBoolean(protocol.getSsl());
|
||||
if (ssl) {
|
||||
requestBuilder.setUri(NetworkConstants.HTTPS_HEADER + baseUri);
|
||||
} else {
|
||||
requestBuilder.setUri(NetworkConstants.HTTP_HEADER + baseUri);
|
||||
}
|
||||
}
|
||||
|
||||
// custom timeout
|
||||
int timeout = CollectUtil.getTimeout(protocol.getTimeout());
|
||||
if (timeout > 0) {
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(timeout)
|
||||
.setSocketTimeout(timeout)
|
||||
.setConnectionRequestTimeout(timeout)
|
||||
.setRedirectsEnabled(true)
|
||||
.build();
|
||||
requestBuilder.setConfig(requestConfig);
|
||||
} else {
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setRedirectsEnabled(true)
|
||||
.build();
|
||||
requestBuilder.setConfig(requestConfig);
|
||||
}
|
||||
return requestBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* get collect instance
|
||||
* @return instance
|
||||
*/
|
||||
public static PrometheusProxyCollectImpl getInstance() {
|
||||
return PrometheusProxyCollectImpl.SingleInstance.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* static instance
|
||||
*/
|
||||
private static class SingleInstance {
|
||||
private static final PrometheusProxyCollectImpl INSTANCE = new PrometheusProxyCollectImpl();
|
||||
}
|
||||
}
|
||||
+8
@@ -185,6 +185,10 @@ public class OnlineParser {
|
||||
stringBuilder.append((char) i);
|
||||
i = getChar(inputStream);
|
||||
}
|
||||
// Skip \r character to handle Windows line endings
|
||||
if (i == '\r') {
|
||||
i = getChar(inputStream);
|
||||
}
|
||||
return new CharChecker(i);
|
||||
}
|
||||
|
||||
@@ -193,6 +197,10 @@ public class OnlineParser {
|
||||
while (i >= '0' && i <= '9') {
|
||||
i = getChar(inputStream);
|
||||
}
|
||||
// Skip \r character to handle Windows line endings
|
||||
if (i == '\r') {
|
||||
i = getChar(inputStream);
|
||||
}
|
||||
return new CharChecker(i);
|
||||
}
|
||||
|
||||
|
||||
+252
@@ -25,7 +25,10 @@ import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -289,4 +292,253 @@ class HttpCollectImplTest {
|
||||
firstRow = capturedRows.get(0);
|
||||
assertEquals("0.268751364291017", firstRow.getColumns(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParsePromQlLabelValue() throws Exception {
|
||||
// Create Prometheus format test data
|
||||
String prometheusData = """
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"resultType": "vector",
|
||||
"result": [
|
||||
{
|
||||
"metric": {
|
||||
"__name__": "taos_cluster_info_first_ep",
|
||||
"cluster_id": "590779086215866783",
|
||||
"instance": "host.docker.internal:6043",
|
||||
"job": "tdengine",
|
||||
"value": "localhost:6030"
|
||||
},
|
||||
"value": [
|
||||
1756233177.048,
|
||||
"1"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}""";
|
||||
List<CollectRep.ValueRow> capturedRows = new ArrayList<>();
|
||||
CollectRep.MetricsData.Builder builder = new CollectRep.MetricsData.Builder() {
|
||||
@Override
|
||||
public CollectRep.MetricsData.Builder addValueRow(CollectRep.ValueRow valueRow) {
|
||||
capturedRows.add(valueRow);
|
||||
return super.addValueRow(valueRow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetrics() {
|
||||
return "jvm_memory_used_bytes";
|
||||
}
|
||||
};
|
||||
Method parseMethod = HttpCollectImpl.class.getDeclaredMethod(
|
||||
"parseResponseByPromQl",
|
||||
String.class,
|
||||
List.class,
|
||||
HttpProtocol.class,
|
||||
CollectRep.MetricsData.Builder.class);
|
||||
parseMethod.setAccessible(true);
|
||||
|
||||
parseMethod.invoke(httpCollectImpl, prometheusData, Lists.newArrayList("cluster_id", "value"), new HttpProtocol(), builder);
|
||||
|
||||
// Verify the results
|
||||
assertEquals(1, capturedRows.size());
|
||||
CollectRep.ValueRow firstRow = capturedRows.get(0);
|
||||
assertEquals("590779086215866783", firstRow.getColumns(0));
|
||||
assertEquals("localhost:6030", firstRow.getColumns(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParsePromQlMetricValue() throws Exception {
|
||||
// Create Prometheus format test data
|
||||
String prometheusData = """
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"resultType": "vector",
|
||||
"result": [
|
||||
{
|
||||
"metric": {
|
||||
"__name__": "taos_cluster_info_first_ep",
|
||||
"cluster_id": "590779086215866783",
|
||||
"instance": "host.docker.internal:6043",
|
||||
"job": "tdengine",
|
||||
"value": "localhost:6030"
|
||||
},
|
||||
"value": [
|
||||
1756233177.048,
|
||||
"1"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}""";
|
||||
List<CollectRep.ValueRow> capturedRows = new ArrayList<>();
|
||||
CollectRep.MetricsData.Builder builder = new CollectRep.MetricsData.Builder() {
|
||||
@Override
|
||||
public CollectRep.MetricsData.Builder addValueRow(CollectRep.ValueRow valueRow) {
|
||||
capturedRows.add(valueRow);
|
||||
return super.addValueRow(valueRow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetrics() {
|
||||
return "jvm_memory_used_bytes";
|
||||
}
|
||||
};
|
||||
Method parseMethod = HttpCollectImpl.class.getDeclaredMethod(
|
||||
"parseResponseByPromQl",
|
||||
String.class,
|
||||
List.class,
|
||||
HttpProtocol.class,
|
||||
CollectRep.MetricsData.Builder.class);
|
||||
parseMethod.setAccessible(true);
|
||||
|
||||
parseMethod.invoke(httpCollectImpl, prometheusData, Lists.newArrayList("cluster_id", "value", "metric_value"), new HttpProtocol(), builder);
|
||||
|
||||
// Verify the results
|
||||
assertEquals(1, capturedRows.size());
|
||||
CollectRep.ValueRow firstRow = capturedRows.get(0);
|
||||
assertEquals("590779086215866783", firstRow.getColumns(0));
|
||||
assertEquals("localhost:6030", firstRow.getColumns(1));
|
||||
assertEquals("1", firstRow.getColumns(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParsePromQlValue() throws Exception {
|
||||
// Create Prometheus format test data
|
||||
String prometheusData = """
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"resultType": "vector",
|
||||
"result": [
|
||||
{
|
||||
"metric": {
|
||||
"__name__": "taos_cluster_info_first_ep",
|
||||
"cluster_id": "590779086215866783",
|
||||
"instance": "host.docker.internal:6043",
|
||||
"job": "tdengine"
|
||||
},
|
||||
"value": [
|
||||
1756233177.048,
|
||||
"1"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}""";
|
||||
List<CollectRep.ValueRow> capturedRows = new ArrayList<>();
|
||||
CollectRep.MetricsData.Builder builder = new CollectRep.MetricsData.Builder() {
|
||||
@Override
|
||||
public CollectRep.MetricsData.Builder addValueRow(CollectRep.ValueRow valueRow) {
|
||||
capturedRows.add(valueRow);
|
||||
return super.addValueRow(valueRow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetrics() {
|
||||
return "jvm_memory_used_bytes";
|
||||
}
|
||||
};
|
||||
Method parseMethod = HttpCollectImpl.class.getDeclaredMethod(
|
||||
"parseResponseByPromQl",
|
||||
String.class,
|
||||
List.class,
|
||||
HttpProtocol.class,
|
||||
CollectRep.MetricsData.Builder.class);
|
||||
parseMethod.setAccessible(true);
|
||||
|
||||
parseMethod.invoke(httpCollectImpl, prometheusData, Lists.newArrayList("cluster_id", "value"), new HttpProtocol(), builder);
|
||||
|
||||
// Verify the results
|
||||
assertEquals(1, capturedRows.size());
|
||||
CollectRep.ValueRow firstRow = capturedRows.get(0);
|
||||
assertEquals("590779086215866783", firstRow.getColumns(0));
|
||||
assertEquals("1", firstRow.getColumns(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParsePrometheusLabelValue() throws Exception {
|
||||
// Create Prometheus format test data
|
||||
String prometheusData = """
|
||||
# HELP jvm_memory_used_bytes The amount of used memory in bytes
|
||||
# TYPE jvm_memory_used_bytes gauge
|
||||
jvm_memory_used_bytes{area="heap",value="G1 Survivor Space"} 1048576
|
||||
""";
|
||||
InputStream inputStream = new ByteArrayInputStream(prometheusData.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
List<CollectRep.ValueRow> capturedRows = new ArrayList<>();
|
||||
CollectRep.MetricsData.Builder builder = new CollectRep.MetricsData.Builder() {
|
||||
@Override
|
||||
public CollectRep.MetricsData.Builder addValueRow(CollectRep.ValueRow valueRow) {
|
||||
capturedRows.add(valueRow);
|
||||
return super.addValueRow(valueRow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetrics() {
|
||||
return "jvm_memory_used_bytes";
|
||||
}
|
||||
};
|
||||
Method parseMethod = HttpCollectImpl.class.getDeclaredMethod(
|
||||
"parseResponseByPrometheusExporter",
|
||||
InputStream.class,
|
||||
List.class,
|
||||
CollectRep.MetricsData.Builder.class);
|
||||
parseMethod.setAccessible(true);
|
||||
|
||||
parseMethod.invoke(httpCollectImpl, inputStream, Lists.newArrayList("area", "value"), builder);
|
||||
|
||||
// Verify the results
|
||||
assertEquals(1, capturedRows.size());
|
||||
CollectRep.ValueRow firstRow = capturedRows.get(0);
|
||||
assertEquals("heap", firstRow.getColumns(0));
|
||||
assertEquals("G1 Survivor Space", firstRow.getColumns(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParsePrometheus() throws Exception {
|
||||
// Create Prometheus format test data
|
||||
String prometheusData = """
|
||||
# HELP jvm_memory_used_bytes The amount of used memory
|
||||
# TYPE jvm_memory_used_bytes gauge
|
||||
jvm_memory_used_bytes{area="heap",id="G1 Eden Space"} 1.63577856E8
|
||||
jvm_memory_used_bytes{area="heap",id="G1 Old Gen"} 2.7874304E7
|
||||
jvm_memory_used_bytes{area="heap",id="G1 Survivor Space"} 512032.0
|
||||
jvm_memory_used_bytes{area="nonheap",id="CodeCache"} 1.460288E7
|
||||
jvm_memory_used_bytes{area="nonheap",id="Compressed Class Space"} 5844504.0
|
||||
jvm_memory_used_bytes{area="nonheap",id="Metaspace"} 4.1576344E7
|
||||
""";
|
||||
InputStream inputStream = new ByteArrayInputStream(prometheusData.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
List<CollectRep.ValueRow> capturedRows = new ArrayList<>();
|
||||
CollectRep.MetricsData.Builder builder = new CollectRep.MetricsData.Builder() {
|
||||
@Override
|
||||
public CollectRep.MetricsData.Builder addValueRow(CollectRep.ValueRow valueRow) {
|
||||
capturedRows.add(valueRow);
|
||||
return super.addValueRow(valueRow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetrics() {
|
||||
return "jvm_memory_used_bytes";
|
||||
}
|
||||
};
|
||||
Method parseMethod = HttpCollectImpl.class.getDeclaredMethod(
|
||||
"parseResponseByPrometheusExporter",
|
||||
InputStream.class,
|
||||
List.class,
|
||||
CollectRep.MetricsData.Builder.class);
|
||||
parseMethod.setAccessible(true);
|
||||
|
||||
parseMethod.invoke(httpCollectImpl, inputStream, Lists.newArrayList("area", "id"), builder);
|
||||
|
||||
// Verify the results
|
||||
assertEquals(6, capturedRows.size());
|
||||
CollectRep.ValueRow firstRow = capturedRows.get(0);
|
||||
assertEquals("heap", firstRow.getColumns(0));
|
||||
assertEquals("G1 Eden Space", firstRow.getColumns(1));
|
||||
capturedRows.forEach(t -> assertEquals(2, t.getColumnsList().size()));
|
||||
}
|
||||
}
|
||||
|
||||
+182
@@ -105,4 +105,186 @@ class OnlineParserTest {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseMetricsWithCrLf() throws Exception {
|
||||
String str = "# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\r\n"
|
||||
+ "# TYPE go_gc_duration_seconds summary\r\n"
|
||||
+ "jvm_gc_pause_seconds_count{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 1.0\r\n"
|
||||
+ "jvm_gc_pause_seconds_sum{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 0.139\r\n";
|
||||
InputStream inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||
Map<String, MetricFamily> metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
assertNotNull(metricFamilyMap);
|
||||
assertEquals(2, metricFamilyMap.values().size());
|
||||
|
||||
MetricFamily metricFamily = metricFamilyMap.get("jvm_gc_pause_seconds_count");
|
||||
assertEquals("jvm_gc_pause_seconds_count", metricFamily.getName());
|
||||
assertEquals(1.0, metricFamily.getMetricList().get(0).getValue());
|
||||
|
||||
MetricFamily metricFamily1 = metricFamilyMap.get("jvm_gc_pause_seconds_sum");
|
||||
assertEquals("jvm_gc_pause_seconds_sum", metricFamily1.getName());
|
||||
assertEquals(0.139, metricFamily1.getMetricList().get(0).getValue());
|
||||
|
||||
str = "# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\r\n"
|
||||
+ "# TYPE go_gc_duration_seconds summary\r\n"
|
||||
+ "jvm_gc_pause_seconds_count{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 1.0 1234567890\r\n"
|
||||
+ "jvm_gc_pause_seconds_sum{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 0.139 1234567890\r\n";
|
||||
inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||
metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
assertNotNull(metricFamilyMap);
|
||||
assertEquals(2, metricFamilyMap.values().size());
|
||||
|
||||
metricFamily = metricFamilyMap.get("jvm_gc_pause_seconds_count");
|
||||
assertEquals("jvm_gc_pause_seconds_count", metricFamily.getName());
|
||||
assertEquals(1.0, metricFamily.getMetricList().get(0).getValue());
|
||||
|
||||
metricFamily1 = metricFamilyMap.get("jvm_gc_pause_seconds_sum");
|
||||
assertEquals("jvm_gc_pause_seconds_sum", metricFamily1.getName());
|
||||
assertEquals(0.139, metricFamily1.getMetricList().get(0).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseMetricsWithLf() throws Exception {
|
||||
String str = "# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\n"
|
||||
+ "# TYPE go_gc_duration_seconds summary\n"
|
||||
+ "jvm_gc_pause_seconds_count{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 1.0\n"
|
||||
+ "jvm_gc_pause_seconds_sum{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 0.139\n";
|
||||
InputStream inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||
Map<String, MetricFamily> metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
assertNotNull(metricFamilyMap);
|
||||
assertEquals(2, metricFamilyMap.values().size());
|
||||
|
||||
MetricFamily metricFamily = metricFamilyMap.get("jvm_gc_pause_seconds_count");
|
||||
assertEquals("jvm_gc_pause_seconds_count", metricFamily.getName());
|
||||
assertEquals(1.0, metricFamily.getMetricList().get(0).getValue());
|
||||
|
||||
MetricFamily metricFamily1 = metricFamilyMap.get("jvm_gc_pause_seconds_sum");
|
||||
assertEquals("jvm_gc_pause_seconds_sum", metricFamily1.getName());
|
||||
assertEquals(0.139, metricFamily1.getMetricList().get(0).getValue());
|
||||
|
||||
str = "# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\n"
|
||||
+ "# TYPE go_gc_duration_seconds summary\n"
|
||||
+ "jvm_gc_pause_seconds_count{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 1.0 1234567890\n"
|
||||
+ "jvm_gc_pause_seconds_sum{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 0.139 1234567890\n";
|
||||
inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||
metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
assertNotNull(metricFamilyMap);
|
||||
assertEquals(2, metricFamilyMap.values().size());
|
||||
|
||||
metricFamily = metricFamilyMap.get("jvm_gc_pause_seconds_count");
|
||||
assertEquals("jvm_gc_pause_seconds_count", metricFamily.getName());
|
||||
assertEquals(1.0, metricFamily.getMetricList().get(0).getValue());
|
||||
|
||||
metricFamily1 = metricFamilyMap.get("jvm_gc_pause_seconds_sum");
|
||||
assertEquals("jvm_gc_pause_seconds_sum", metricFamily1.getName());
|
||||
assertEquals(0.139, metricFamily1.getMetricList().get(0).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseMetricsWithoutFinalNewline() throws Exception {
|
||||
String str = "# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\r\n"
|
||||
+ "# TYPE go_gc_duration_seconds summary\r\n"
|
||||
+ "jvm_gc_pause_seconds_count{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 1.0\r\n"
|
||||
+ "jvm_gc_pause_seconds_sum{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 0.139";
|
||||
|
||||
InputStream inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||
Map<String, MetricFamily> metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
|
||||
assertNotNull(metricFamilyMap);
|
||||
assertEquals(2, metricFamilyMap.values().size());
|
||||
|
||||
MetricFamily metricFamily = metricFamilyMap.get("jvm_gc_pause_seconds_count");
|
||||
assertEquals("jvm_gc_pause_seconds_count", metricFamily.getName());
|
||||
assertEquals(1.0, metricFamily.getMetricList().get(0).getValue());
|
||||
|
||||
MetricFamily metricFamily1 = metricFamilyMap.get("jvm_gc_pause_seconds_sum");
|
||||
assertEquals("jvm_gc_pause_seconds_sum", metricFamily1.getName());
|
||||
assertEquals(0.139, metricFamily1.getMetricList().get(0).getValue());
|
||||
|
||||
str = "# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\n"
|
||||
+ "# TYPE go_gc_duration_seconds summary\n"
|
||||
+ "jvm_gc_pause_seconds_count{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 1.0\n"
|
||||
+ "jvm_gc_pause_seconds_sum{action=\"end of major GC\",cause=\"Metadata GC Threshold\",} 0.139";
|
||||
|
||||
inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||
metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
|
||||
assertNotNull(metricFamilyMap);
|
||||
assertEquals(2, metricFamilyMap.values().size());
|
||||
|
||||
metricFamily = metricFamilyMap.get("jvm_gc_pause_seconds_count");
|
||||
assertEquals("jvm_gc_pause_seconds_count", metricFamily.getName());
|
||||
assertEquals(1.0, metricFamily.getMetricList().get(0).getValue());
|
||||
|
||||
metricFamily1 = metricFamilyMap.get("jvm_gc_pause_seconds_sum");
|
||||
assertEquals("jvm_gc_pause_seconds_sum", metricFamily1.getName());
|
||||
assertEquals(0.139, metricFamily1.getMetricList().get(0).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseMetricsWithEmptyLabelsAndCrLf() throws Exception {
|
||||
String str = "# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\r\n"
|
||||
+ "# TYPE go_gc_duration_seconds summary\r\n"
|
||||
+ "jvm_gc_pause_seconds_count 1.0\r\n"
|
||||
+ "jvm_gc_pause_seconds_sum{} 0.139";
|
||||
|
||||
InputStream inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||
Map<String, MetricFamily> metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
|
||||
assertNotNull(metricFamilyMap);
|
||||
assertEquals(2, metricFamilyMap.values().size());
|
||||
|
||||
MetricFamily metricFamily = metricFamilyMap.get("jvm_gc_pause_seconds_count");
|
||||
assertEquals("jvm_gc_pause_seconds_count", metricFamily.getName());
|
||||
assertEquals(1.0, metricFamily.getMetricList().get(0).getValue());
|
||||
|
||||
MetricFamily metricFamily1 = metricFamilyMap.get("jvm_gc_pause_seconds_sum");
|
||||
assertEquals("jvm_gc_pause_seconds_sum", metricFamily1.getName());
|
||||
assertEquals(0.139, metricFamily1.getMetricList().get(0).getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseMetricsWithEmptyLabelsAndLf() throws Exception {
|
||||
String str = "# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\n"
|
||||
+ "# TYPE go_gc_duration_seconds summary\n"
|
||||
+ "jvm_gc_pause_seconds_count 1.0\n"
|
||||
+ "jvm_gc_pause_seconds_sum{} 0.139";
|
||||
|
||||
InputStream inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||
Map<String, MetricFamily> metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
|
||||
assertNotNull(metricFamilyMap);
|
||||
assertEquals(2, metricFamilyMap.values().size());
|
||||
|
||||
MetricFamily metricFamily = metricFamilyMap.get("jvm_gc_pause_seconds_count");
|
||||
assertEquals("jvm_gc_pause_seconds_count", metricFamily.getName());
|
||||
assertEquals(1.0, metricFamily.getMetricList().get(0).getValue());
|
||||
|
||||
MetricFamily metricFamily1 = metricFamilyMap.get("jvm_gc_pause_seconds_sum");
|
||||
assertEquals("jvm_gc_pause_seconds_sum", metricFamily1.getName());
|
||||
assertEquals(0.139, metricFamily1.getMetricList().get(0).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseMetricsWithMixedLineEndings() throws Exception {
|
||||
String str = "# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\r\n"
|
||||
+ "# TYPE go_gc_duration_seconds summary\n"
|
||||
+ "jvm_gc_pause_seconds_count 1.0\n"
|
||||
+ "jvm_gc_pause_seconds_sum{} 0.139\r\n";
|
||||
|
||||
InputStream inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||
Map<String, MetricFamily> metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
|
||||
assertNotNull(metricFamilyMap);
|
||||
assertEquals(2, metricFamilyMap.values().size());
|
||||
|
||||
MetricFamily metricFamily = metricFamilyMap.get("jvm_gc_pause_seconds_count");
|
||||
assertEquals("jvm_gc_pause_seconds_count", metricFamily.getName());
|
||||
assertEquals(1.0, metricFamily.getMetricList().get(0).getValue());
|
||||
|
||||
MetricFamily metricFamily1 = metricFamilyMap.get("jvm_gc_pause_seconds_sum");
|
||||
assertEquals("jvm_gc_pause_seconds_sum", metricFamily1.getName());
|
||||
assertEquals(0.139, metricFamily1.getMetricList().get(0).getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,4 +345,4 @@
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
</project>
|
||||
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.dispatch;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.metrics.HertzBeatMetricsCollector;
|
||||
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;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.timer.Timeout;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CollectTaskTimeoutMonitor {
|
||||
/**
|
||||
* Collection task timeout value
|
||||
*/
|
||||
private static final long DURATION_TIME = 240_000L;
|
||||
/**
|
||||
* Metrics task and start time mapping map
|
||||
*/
|
||||
private final Map<String, MetricsTime> metricsTimeoutMonitorMap = new ConcurrentHashMap<>(16);
|
||||
|
||||
@Autowired
|
||||
private HertzBeatMetricsCollector metricsCollector;
|
||||
private CommonDispatcher commonDispatcher;
|
||||
|
||||
public void start(CommonDispatcher commonDispatcher) {
|
||||
this.commonDispatcher = commonDispatcher;
|
||||
|
||||
// monitoring metrics collection task execution timeout
|
||||
ThreadFactory threadFactory = new ThreadFactoryBuilder()
|
||||
.setNameFormat("metrics-task-timeout-monitor-%d")
|
||||
.setDaemon(true)
|
||||
.build();
|
||||
ScheduledThreadPoolExecutor scheduledExecutor = new ScheduledThreadPoolExecutor(1, threadFactory);
|
||||
scheduledExecutor.scheduleWithFixedDelay(this::monitorCollectTaskTimeout, 2, 20, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public void putMetrics(String key, MetricsTime value) {
|
||||
this.metricsTimeoutMonitorMap.put(key, value);
|
||||
}
|
||||
|
||||
public MetricsTime removeMetrics(String key) {
|
||||
return this.metricsTimeoutMonitorMap.remove(key);
|
||||
}
|
||||
|
||||
private void monitorCollectTaskTimeout() {
|
||||
try {
|
||||
// Detect whether the collection unit of each metrics has timed out for 4 minutes,
|
||||
// and if it times out, it will be discarded and an exception will be returned.
|
||||
long deadline = System.currentTimeMillis() - DURATION_TIME;
|
||||
for (Map.Entry<String, MetricsTime> entry : metricsTimeoutMonitorMap.entrySet()) {
|
||||
MetricsTime metricsTime = entry.getValue();
|
||||
if (metricsTime.getStartTime() < deadline) {
|
||||
// Metrics collection timeout
|
||||
MetricsTime removedMetricsTime = metricsTimeoutMonitorMap.remove(entry.getKey());
|
||||
if (removedMetricsTime == null) {
|
||||
continue;
|
||||
}
|
||||
WheelTimerTask timerJob = (WheelTimerTask) metricsTime.getTimeout().task();
|
||||
Job job = timerJob.getJob();
|
||||
// timeout metrics
|
||||
if (metricsCollector != null) {
|
||||
long duration = System.currentTimeMillis() - removedMetricsTime.getStartTime();
|
||||
metricsCollector.recordCollectMetrics(job, duration, "timeout");
|
||||
}
|
||||
|
||||
CollectRep.MetricsData metricsData = CollectRep.MetricsData.newBuilder()
|
||||
.setId(job.getMonitorId())
|
||||
.setTenantId(job.getTenantId())
|
||||
.setApp(job.getApp())
|
||||
.setMetrics(metricsTime.getMetrics().getName())
|
||||
.setPriority(metricsTime.getMetrics().getPriority())
|
||||
.setTime(System.currentTimeMillis())
|
||||
.setCode(CollectRep.Code.TIMEOUT)
|
||||
.setMsg("collect timeout")
|
||||
.build();
|
||||
log.error("[Collect Timeout]: \n{}", metricsData);
|
||||
if (metricsData.getPriority() == CommonConstants.AVAILABLE_METRICS) {
|
||||
//todo 使用chain bootstrap
|
||||
// commonDispatcher.dispatchCollectData(metricsTime.timeout, metricsTime.getMetrics(), metricsData);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[Task Timeout Monitor]-{}.", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Metrics times.
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public static class MetricsTime {
|
||||
private long startTime;
|
||||
private Metrics metrics;
|
||||
private Timeout timeout;
|
||||
}
|
||||
}
|
||||
+138
-178
@@ -17,13 +17,23 @@
|
||||
|
||||
package org.apache.hertzbeat.collector.dispatch;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.google.gson.Gson;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.constants.ContextKey;
|
||||
import org.apache.hertzbeat.collector.context.impl.DefaultContext;
|
||||
import org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectJobService;
|
||||
import org.apache.hertzbeat.collector.handler.ChainBootstrap;
|
||||
import org.apache.hertzbeat.collector.handler.CollectMetricsDataDataStream;
|
||||
import org.apache.hertzbeat.collector.listener.CalculateFieldsListener;
|
||||
import org.apache.hertzbeat.collector.listener.MetricsDataDeliveryListener;
|
||||
import org.apache.hertzbeat.collector.listener.RemoveTimeoutMonitorListener;
|
||||
import org.apache.hertzbeat.collector.listener.RerunDataStream;
|
||||
import org.apache.hertzbeat.collector.listener.ResponseJobDataListener;
|
||||
import org.apache.hertzbeat.collector.listener.ValidateResponseListener;
|
||||
import org.apache.hertzbeat.collector.metrics.HertzBeatMetricsCollector;
|
||||
import org.apache.hertzbeat.collector.handler.impl.BatchExecuteTaskChain;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.collector.CollectorMetaData;
|
||||
import org.apache.hertzbeat.common.timer.Timeout;
|
||||
import org.apache.hertzbeat.collector.timer.TimerDispatch;
|
||||
import org.apache.hertzbeat.collector.timer.WheelTimerTask;
|
||||
@@ -37,17 +47,18 @@ import org.apache.hertzbeat.common.queue.CommonDataQueue;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Collection task and response data scheduler
|
||||
@@ -56,10 +67,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
@Slf4j
|
||||
public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatch {
|
||||
|
||||
/**
|
||||
* Collection task timeout value
|
||||
*/
|
||||
private static final long DURATION_TIME = 240_000L;
|
||||
/**
|
||||
* Trigger sub task max num
|
||||
*/
|
||||
@@ -81,16 +88,14 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
||||
* collection data exporter
|
||||
*/
|
||||
private final CommonDataQueue commonDataQueue;
|
||||
/**
|
||||
* Metrics task and start time mapping map
|
||||
*/
|
||||
private final Map<String, MetricsTime> metricsTimeoutMonitorMap;
|
||||
|
||||
private final List<UnitConvert> unitConvertList;
|
||||
|
||||
private final WorkerPool workerPool;
|
||||
|
||||
private final String collectorIdentity;
|
||||
private final CollectorMetaData metaData;
|
||||
|
||||
private final CollectTaskTimeoutMonitor collectTaskTimeoutMonitor;
|
||||
|
||||
@Autowired
|
||||
private HertzBeatMetricsCollector metricsCollector;
|
||||
@@ -100,17 +105,24 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
||||
CommonDataQueue commonDataQueue,
|
||||
WorkerPool workerPool,
|
||||
CollectJobService collectJobService,
|
||||
List<UnitConvert> unitConvertList) {
|
||||
List<UnitConvert> unitConvertList,
|
||||
CollectTaskTimeoutMonitor collectTaskTimeoutMonitor) {
|
||||
this.commonDataQueue = commonDataQueue;
|
||||
this.jobRequestQueue = jobRequestQueue;
|
||||
this.timerDispatch = timerDispatch;
|
||||
this.unitConvertList = unitConvertList;
|
||||
this.workerPool = workerPool;
|
||||
this.collectorIdentity = collectJobService.getCollectorIdentity();
|
||||
this.metricsTimeoutMonitorMap = new ConcurrentHashMap<>(16);
|
||||
this.start();
|
||||
this.metaData = CollectorMetaData.builder()
|
||||
.identity(collectJobService.getCollectorIdentity())
|
||||
.mode(collectJobService.getCollectorMode())
|
||||
.startTime(new Date())
|
||||
.build();
|
||||
this.collectTaskTimeoutMonitor = collectTaskTimeoutMonitor;
|
||||
// this.start();
|
||||
this.collectTaskTimeoutMonitor.start(this);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void start() {
|
||||
try {
|
||||
// Pull the collection task from the task queue and put it into the thread pool for execution
|
||||
@@ -138,91 +150,104 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
||||
}
|
||||
log.info("Thread Interrupted, Shutdown the [metrics-task-dispatcher]");
|
||||
});
|
||||
// monitoring metrics collection task execution timeout
|
||||
ThreadFactory threadFactory = new ThreadFactoryBuilder()
|
||||
.setNameFormat("metrics-task-timeout-monitor-%d")
|
||||
.setDaemon(true)
|
||||
.build();
|
||||
ScheduledThreadPoolExecutor scheduledExecutor = new ScheduledThreadPoolExecutor(1, threadFactory);
|
||||
scheduledExecutor.scheduleWithFixedDelay(this::monitorCollectTaskTimeout, 2, 20, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
log.error("Common Dispatcher error: {}.", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void monitorCollectTaskTimeout() {
|
||||
try {
|
||||
// Detect whether the collection unit of each metrics has timed out for 4 minutes,
|
||||
// and if it times out, it will be discarded and an exception will be returned.
|
||||
long deadline = System.currentTimeMillis() - DURATION_TIME;
|
||||
for (Map.Entry<String, MetricsTime> entry : metricsTimeoutMonitorMap.entrySet()) {
|
||||
MetricsTime metricsTime = entry.getValue();
|
||||
if (metricsTime.getStartTime() < deadline) {
|
||||
// Metrics collection timeout
|
||||
MetricsTime removedMetricsTime = metricsTimeoutMonitorMap.remove(entry.getKey());
|
||||
if (removedMetricsTime == null) {
|
||||
continue;
|
||||
}
|
||||
WheelTimerTask timerJob = (WheelTimerTask) metricsTime.getTimeout().task();
|
||||
Job job = timerJob.getJob();
|
||||
// timeout metrics
|
||||
if (metricsCollector != null) {
|
||||
long duration = System.currentTimeMillis() - removedMetricsTime.getStartTime();
|
||||
metricsCollector.recordCollectMetrics(job, duration, "timeout");
|
||||
}
|
||||
|
||||
CollectRep.MetricsData metricsData = CollectRep.MetricsData.newBuilder()
|
||||
.setId(job.getMonitorId())
|
||||
.setTenantId(job.getTenantId())
|
||||
.setApp(job.getApp())
|
||||
.setMetrics(metricsTime.getMetrics().getName())
|
||||
.setPriority(metricsTime.getMetrics().getPriority())
|
||||
.setTime(System.currentTimeMillis())
|
||||
.setCode(CollectRep.Code.TIMEOUT).setMsg("collect timeout").build();
|
||||
log.error("[Collect Timeout]: \n{}", metricsData);
|
||||
if (metricsData.getPriority() == 0) {
|
||||
dispatchCollectData(metricsTime.timeout, metricsTime.getMetrics(), metricsData);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[Task Timeout Monitor]-{}.", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchMetricsTask(Timeout timeout) {
|
||||
// Divide the collection task of a single application into corresponding collection tasks of the metrics under it.
|
||||
// Put each collect task into the thread pool for scheduling
|
||||
WheelTimerTask timerTask = (WheelTimerTask) timeout.task();
|
||||
Job job = timerTask.getJob();
|
||||
job.constructPriorMetrics();
|
||||
Set<Metrics> metricsSet = job.getNextCollectMetrics(null, true);
|
||||
metricsSet.forEach(metrics -> {
|
||||
MetricsCollect metricsCollect = new MetricsCollect(metrics, timeout, this,
|
||||
collectorIdentity, unitConvertList);
|
||||
jobRequestQueue.addJob(metricsCollect);
|
||||
if (metrics.getPrometheus() != null) {
|
||||
metricsTimeoutMonitorMap.put(String.valueOf(job.getId()),
|
||||
new MetricsTime(System.currentTimeMillis(), metrics, timeout));
|
||||
} else {
|
||||
metricsTimeoutMonitorMap.put(job.getId() + "-" + metrics.getName(),
|
||||
new MetricsTime(System.currentTimeMillis(), metrics, timeout));
|
||||
}
|
||||
});
|
||||
|
||||
ChainBootstrap bootstrap = constructMetricsCollectTaskChain(job);
|
||||
//todo context需要划分作用域
|
||||
bootstrap.addContext(ContextKey.META_DATA, metaData)
|
||||
.addContext(ContextKey.JOB, job)
|
||||
.addContext(ContextKey.TIMEOUT, timeout)
|
||||
.addListener(new CalculateFieldsListener(unitConvertList))
|
||||
.addListener(new ValidateResponseListener())
|
||||
.onEachDataStreamComplete(new RemoveTimeoutMonitorListener(collectTaskTimeoutMonitor));
|
||||
|
||||
if (job.isCyclic()) {
|
||||
bootstrap.withWorkerPool(workerPool)
|
||||
.addListener(new MetricsDataDeliveryListener(commonDataQueue))
|
||||
.onComplete(new RerunDataStream(timerDispatch));
|
||||
} else {
|
||||
bootstrap.addListener(new ResponseJobDataListener(timerDispatch));
|
||||
}
|
||||
|
||||
|
||||
bootstrap.start();
|
||||
}
|
||||
|
||||
private ChainBootstrap constructMetricsCollectTaskChain(Job job) {
|
||||
long now = System.currentTimeMillis();
|
||||
Map<Byte, List<Metrics>> currentCollectMetrics = job.getMetrics().stream()
|
||||
.filter(metrics -> (now >= metrics.getCollectTime() + metrics.getInterval() * 1000L))
|
||||
.peek(metric -> {
|
||||
metric.setCollectTime(now);
|
||||
// Determine whether to configure aliasFields If not, configure the default
|
||||
if ((metric.getAliasFields() == null || metric.getAliasFields().isEmpty()) && metric.getFields() != null) {
|
||||
metric.setAliasFields(metric.getFields().stream().map(Metrics.Field::getField).collect(Collectors.toList()));
|
||||
}
|
||||
// Set the default metrics execution priority, if not filled, the default last priority
|
||||
if (metric.getPriority() == null) {
|
||||
metric.setPriority(Byte.MAX_VALUE);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.groupingBy(Metrics::getPriority));
|
||||
|
||||
// the current collect metrics can not empty, if empty, add a default availability metrics
|
||||
// due the metric collect is trigger by the previous metric collect
|
||||
if (currentCollectMetrics.isEmpty()) {
|
||||
Optional<Metrics> defaultMetricOption = job.getMetrics().stream()
|
||||
.filter(metric -> metric.getPriority() == CommonConstants.AVAILABLE_METRICS).findFirst();
|
||||
if (defaultMetricOption.isPresent()) {
|
||||
Metrics defaultMetric = defaultMetricOption.get();
|
||||
defaultMetric.setCollectTime(now);
|
||||
currentCollectMetrics.put(CommonConstants.AVAILABLE_METRICS, Collections.singletonList(defaultMetric));
|
||||
} else {
|
||||
log.error("metrics must has one priority 0 metrics at least.");
|
||||
}
|
||||
}
|
||||
|
||||
ChainBootstrap chainBootstrap = ChainBootstrap.withContext(DefaultContext.newInstance())
|
||||
.withChain(new BatchExecuteTaskChain<Metrics>());
|
||||
// order by priority
|
||||
currentCollectMetrics.keySet().stream()
|
||||
.sorted()
|
||||
.forEach(priority -> {
|
||||
if (job.isCyclic() || isOneTimeJobAndIsAvailableMetrics(job, priority)) {
|
||||
List<Metrics> metricsList = currentCollectMetrics.get(priority);
|
||||
CollectMetricsDataDataStream collectHandler = CollectMetricsDataDataStream.builder()
|
||||
.collectTaskTimeoutMonitor(collectTaskTimeoutMonitor)
|
||||
.build();
|
||||
collectHandler.setSourceDataList(metricsList);
|
||||
|
||||
chainBootstrap.addDataStream(collectHandler);
|
||||
}
|
||||
});
|
||||
|
||||
return chainBootstrap;
|
||||
}
|
||||
|
||||
private boolean isOneTimeJobAndIsAvailableMetrics(Job job, byte priority) {
|
||||
return (!job.isCyclic()) && priority == CommonConstants.AVAILABLE_METRICS;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void dispatchCollectData(Timeout timeout, Metrics metrics, CollectRep.MetricsData metricsData) {
|
||||
WheelTimerTask timerJob = (WheelTimerTask) timeout.task();
|
||||
Job job = timerJob.getJob();
|
||||
String monitorKey;
|
||||
String monitorKey = job.getId() + "-" + metrics.getName();
|
||||
if (metrics.isHasSubTask()) {
|
||||
monitorKey = job.getId() + "-" + metrics.getName() + "-sub-" + metrics.getSubTaskId();
|
||||
} else {
|
||||
monitorKey = job.getId() + "-" + metrics.getName();
|
||||
monitorKey = monitorKey + "-sub-" + metrics.getSubTaskId();
|
||||
}
|
||||
MetricsTime metricsTime = metricsTimeoutMonitorMap.remove(monitorKey);
|
||||
CollectTaskTimeoutMonitor.MetricsTime metricsTime = this.collectTaskTimeoutMonitor.removeMetrics(monitorKey);
|
||||
|
||||
// job completed metrics
|
||||
if (metricsTime != null && metricsCollector != null) {
|
||||
@@ -238,31 +263,28 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Set<Metrics> metricsSet = job.getNextCollectMetrics(metrics, false);
|
||||
if (job.isCyclic()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Cyclic Job: {} - {} - {}", job.getMonitorId(), job.getApp(), metricsData.getMetrics());
|
||||
for (CollectRep.ValueRow valueRow : metricsData.getValues()) {
|
||||
for (CollectRep.Field field : metricsData.getFields()) {
|
||||
log.debug("Field-->{},Value-->{}", field.getName(), valueRow.getColumns(metricsData.getFields().indexOf(field)));
|
||||
}
|
||||
}
|
||||
}
|
||||
cyclicJobDebugLog(job, metricsData);
|
||||
|
||||
// If metricsSet is null, it means that the execution is completed or whether the priority of the collection metrics is 0, that is, the availability collection metrics.
|
||||
// If the availability collection fails, the next metrics scheduling will be cancelled and the next round of scheduling will be entered directly.
|
||||
boolean isAvailableCollectFailed = metricsSet != null && !metricsSet.isEmpty()
|
||||
&& metrics.getPriority() == (byte) 0 && metricsData.getCode() != CollectRep.Code.SUCCESS;
|
||||
&& metrics.getPriority() == CommonConstants.AVAILABLE_METRICS && metricsData.getCode() != CollectRep.Code.SUCCESS;
|
||||
if (metricsSet == null || isAvailableCollectFailed || job.isSd()) {
|
||||
// The collection and execution task of this job are completed.
|
||||
// The periodic task pushes the task to the time wheel again.
|
||||
// First, determine the execution time of the task and the task collection interval.
|
||||
if (!timeout.isCancelled()) {
|
||||
long spendTime = System.currentTimeMillis() - job.getDispatchTime();
|
||||
long interval = job.getInterval() - spendTime / 1000;
|
||||
long interval = job.getInterval() - spendTime / 1000L;
|
||||
interval = interval <= 0 ? 0 : interval;
|
||||
timerDispatch.cyclicJob(timerJob, interval, TimeUnit.SECONDS);
|
||||
}
|
||||
} else if (!metricsSet.isEmpty()) {
|
||||
}
|
||||
else if (!metricsSet.isEmpty()) {
|
||||
// The execution of the current level metrics is completed, and the execution of the next level metrics starts
|
||||
// use pre collect metrics data to replace next metrics config params
|
||||
List<Map<String, Configmap>> configmapList = CollectUtil.getConfigmapFromPreCollectData(metricsData);
|
||||
@@ -273,12 +295,15 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
||||
Set<String> cryPlaceholderFields = CollectUtil.matchCryPlaceholderField(GSON.toJsonTree(metricItem));
|
||||
if (cryPlaceholderFields.isEmpty()) {
|
||||
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this,
|
||||
collectorIdentity, unitConvertList);
|
||||
metaData.getIdentity(), unitConvertList);
|
||||
jobRequestQueue.addJob(metricsCollect);
|
||||
metricsTimeoutMonitorMap.put(job.getId() + "-" + metricItem.getName(),
|
||||
new MetricsTime(System.currentTimeMillis(), metricItem, timeout));
|
||||
|
||||
this.collectTaskTimeoutMonitor.putMetrics(job.getId() + "-" + metricItem.getName(),
|
||||
new CollectTaskTimeoutMonitor.MetricsTime(System.currentTimeMillis(), metricItem, timeout));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
boolean isSubTask = configmapList.stream().anyMatch(map -> map.keySet().stream().anyMatch(cryPlaceholderFields::contains));
|
||||
int subTaskNum = isSubTask ? Math.min(configmapList.size(), MAX_SUB_TASK_NUM) : 1;
|
||||
AtomicInteger subTaskNumAtomic = new AtomicInteger(subTaskNum);
|
||||
@@ -294,95 +319,30 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
||||
metric.setSubTaskId(index);
|
||||
metric.setSubTaskDataRef(metricsDataReference);
|
||||
MetricsCollect metricsCollect = new MetricsCollect(metric, timeout, this,
|
||||
collectorIdentity, unitConvertList);
|
||||
metaData.getIdentity(), unitConvertList);
|
||||
jobRequestQueue.addJob(metricsCollect);
|
||||
metricsTimeoutMonitorMap.put(job.getId() + "-" + metric.getName() + "-sub-" + index,
|
||||
new MetricsTime(System.currentTimeMillis(), metric, timeout));
|
||||
|
||||
this.collectTaskTimeoutMonitor.putMetrics(job.getId() + "-" + metric.getName() + "-sub-" + index,
|
||||
new CollectTaskTimeoutMonitor.MetricsTime(System.currentTimeMillis(), metric, timeout));
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
// The list of metrics at the current execution level has not been fully executed.
|
||||
// It needs to wait for the execution of other metrics task of the same level to complete the execution and enter the next level for execution.
|
||||
}
|
||||
// If it is an asynchronous periodic cyclic task, directly response the collected data
|
||||
if (job.isSd()) {
|
||||
CollectRep.MetricsData sdMetricsData = CollectRep.MetricsData.newBuilder(metricsData).build();
|
||||
commonDataQueue.sendServiceDiscoveryData(sdMetricsData);
|
||||
}
|
||||
commonDataQueue.sendMetricsData(metricsData);
|
||||
} else {
|
||||
// If it is a temporary one-time task, you need to wait for the collected data of all metrics task to be packaged and returned.
|
||||
// Insert the current metrics data into the job for unified assembly
|
||||
job.addCollectMetricsData(metricsData);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("One-time Job: {}", metricsData.getMetrics());
|
||||
for (CollectRep.ValueRow valueRow : metricsData.getValues()) {
|
||||
for (CollectRep.Field field : metricsData.getFields()) {
|
||||
log.debug("Field-->{},Value-->{}", field.getName(), valueRow.getColumns(metricsData.getFields().indexOf(field)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (job.isSd() || metricsSet == null) {
|
||||
// The collection and execution of all metrics of this job are completed
|
||||
// and the result listener is notified of the combination of all metrics data
|
||||
timerDispatch.responseSyncJobData(job.getId(), job.getResponseDataTemp());
|
||||
} else if (!metricsSet.isEmpty()) {
|
||||
// The execution of the current level metrics is completed, and the execution of the next level metrics starts
|
||||
metricsSet.forEach(metricItem -> {
|
||||
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this,
|
||||
collectorIdentity, unitConvertList);
|
||||
jobRequestQueue.addJob(metricsCollect);
|
||||
metricsTimeoutMonitorMap.put(job.getId() + "-" + metricItem.getName(),
|
||||
new MetricsTime(System.currentTimeMillis(), metricItem, timeout));
|
||||
});
|
||||
} else {
|
||||
// The list of metrics task at the current execution level has not been fully executed.
|
||||
// It needs to wait for the execution of other metrics task of the same level to complete the execution and enter the next level for execution.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCollectData(Timeout timeout, Metrics metrics, List<CollectRep.MetricsData> metricsDataList) {
|
||||
WheelTimerTask timerJob = (WheelTimerTask) timeout.task();
|
||||
Job job = timerJob.getJob();
|
||||
MetricsTime metricsTime = metricsTimeoutMonitorMap.remove(String.valueOf(job.getId()));
|
||||
if (metricsTime != null && metricsCollector != null) {
|
||||
long duration = System.currentTimeMillis() - metricsTime.getStartTime();
|
||||
// For a list, we consider it a success if at least one item is successful.
|
||||
boolean isSuccess = metricsDataList.stream().anyMatch(item -> item.getCode() == CollectRep.Code.SUCCESS);
|
||||
metricsCollector.recordCollectMetrics(job, duration, isSuccess ? "success" : "fail");
|
||||
}
|
||||
if (job.isCyclic()) {
|
||||
// The collection and execution of all task of this job are completed.
|
||||
// The periodic task pushes the task to the time wheel again.
|
||||
// First, determine the execution time of the task and the task collection interval.
|
||||
if (!timeout.isCancelled()) {
|
||||
long spendTime = System.currentTimeMillis() - job.getDispatchTime();
|
||||
long interval = job.getInterval() - spendTime / 1000;
|
||||
interval = interval <= 0 ? 0 : interval;
|
||||
timerDispatch.cyclicJob(timerJob, interval, TimeUnit.SECONDS);
|
||||
}
|
||||
// it is an asynchronous periodic cyclic task, directly response the collected data
|
||||
metricsDataList.forEach(commonDataQueue::sendMetricsData);
|
||||
} else {
|
||||
// The collection and execution of all metrics of this job are completed
|
||||
// and the result listener is notified of the combination of all metrics data
|
||||
timerDispatch.responseSyncJobData(job.getId(), metricsDataList);
|
||||
private void cyclicJobDebugLog(Job job, CollectRep.MetricsData metricsData) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Cyclic Job: {} - {} - {}", job.getMonitorId(), job.getApp(), metricsData.getMetrics());
|
||||
metricsDataDebugLog(metricsData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Metrics times.
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
protected static class MetricsTime {
|
||||
private long startTime;
|
||||
private Metrics metrics;
|
||||
private Timeout timeout;
|
||||
private void metricsDataDebugLog(CollectRep.MetricsData metricsData) {
|
||||
for (CollectRep.ValueRow valueRow : metricsData.getValues()) {
|
||||
for (CollectRep.Field field : metricsData.getFields()) {
|
||||
log.debug("Field-->{},Value-->{}", field.getName(), valueRow.getColumns(metricsData.getFields().indexOf(field)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-320
@@ -129,7 +129,6 @@ public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
|
||||
this.newTime = System.currentTimeMillis();
|
||||
this.timeout = timeout;
|
||||
this.metrics = metrics;
|
||||
this.collectorIdentity = collectorIdentity;
|
||||
WheelTimerTask timerJob = (WheelTimerTask) timeout.task();
|
||||
Job job = timerJob.getJob();
|
||||
this.id = job.getMonitorId();
|
||||
@@ -153,327 +152,9 @@ public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
this.startTime = System.currentTimeMillis();
|
||||
setNewThreadName(id, app, startTime, metrics);
|
||||
CollectRep.MetricsData.Builder response = CollectRep.MetricsData.newBuilder();
|
||||
response.setApp(app).setId(id).setTenantId(tenantId)
|
||||
.setLabels(labels).setAnnotations(annotations).addMetadataAll(metadata);
|
||||
// for prometheus auto or proxy mode
|
||||
if (DispatchConstants.PROTOCOL_PROMETHEUS.equalsIgnoreCase(metrics.getProtocol())) {
|
||||
List<CollectRep.MetricsData> metricsData;
|
||||
|
||||
// TODO: Refactor Prometheus metrics collection logic.
|
||||
// The current implementation for proxy mode and auto mode needs review and potential simplification.
|
||||
// Consider a more unified approach or clarify the conditions for each mode.
|
||||
/*
|
||||
// TODO USE PROXY MODE
|
||||
if (prometheusProxyMode) {
|
||||
List<CollectRep.MetricsData> proxyData = PrometheusProxyCollectImpl.getInstance().collect(response, metrics);
|
||||
List<CollectRep.MetricsData> autoData = PrometheusAutoCollectImpl.getInstance().collect(response, metrics);
|
||||
metricsData = new LinkedList<>();
|
||||
if (proxyData != null) {
|
||||
metricsData.addAll(proxyData);
|
||||
}
|
||||
if (autoData != null) {
|
||||
metricsData.addAll(autoData);
|
||||
}
|
||||
} else {
|
||||
metricsData = PrometheusAutoCollectImpl.getInstance().collect(response, metrics);
|
||||
}
|
||||
*/
|
||||
metricsData = PrometheusAutoCollectImpl.getInstance().collect(response, metrics);
|
||||
validateResponse(metricsData == null ? null : metricsData.stream().findFirst().orElse(null));
|
||||
collectDataDispatch.dispatchCollectData(timeout, metrics, metricsData);
|
||||
return;
|
||||
}
|
||||
response.setMetrics(metrics.getName());
|
||||
// According to the metrics collection protocol, application type, etc.,
|
||||
// dispatch to the real application metrics collection implementation class
|
||||
AbstractCollect abstractCollect = CollectStrategyFactory.invoke(metrics.getProtocol());
|
||||
if (abstractCollect == null) {
|
||||
log.error("[Dispatcher] - not support this: app: {}, metrics: {}, protocol: {}.",
|
||||
app, metrics.getName(), metrics.getProtocol());
|
||||
response.setCode(CollectRep.Code.FAIL);
|
||||
response.setMsg("not support " + app + ", "
|
||||
+ metrics.getName() + ", " + metrics.getProtocol());
|
||||
} else {
|
||||
try {
|
||||
abstractCollect.preCheck(metrics);
|
||||
abstractCollect.collect(response, metrics);
|
||||
} catch (Exception e) {
|
||||
String msg = e.getMessage();
|
||||
if (msg == null && e.getCause() != null) {
|
||||
msg = e.getCause().getMessage();
|
||||
}
|
||||
if (e instanceof IllegalArgumentException) {
|
||||
log.error("[Metrics PreCheck]: {}.", msg, e);
|
||||
} else {
|
||||
log.error("[Metrics Collect]: {}.", msg, e);
|
||||
}
|
||||
response.setCode(CollectRep.Code.FAIL);
|
||||
if (msg != null) {
|
||||
response.setMsg(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Alias attribute expression replacement calculation
|
||||
if (fastFailed()) {
|
||||
return;
|
||||
}
|
||||
calculateFields(metrics, response);
|
||||
CollectRep.MetricsData metricsData = validateResponse(response);
|
||||
collectDataDispatch.dispatchCollectData(timeout, metrics, metricsData);
|
||||
// collectDataDispatch.dispatchCollectData(timeout, metrics, metricsData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the real metrics value according to the calculates and aliasFields configuration
|
||||
*
|
||||
* @param metrics Metrics configuration
|
||||
* @param collectData Data collection
|
||||
*/
|
||||
public void calculateFields(Metrics metrics, CollectRep.MetricsData.Builder collectData) {
|
||||
collectData.setPriority(metrics.getPriority());
|
||||
List<CollectRep.Field> fieldList = new LinkedList<>();
|
||||
for (Metrics.Field field : metrics.getFields()) {
|
||||
CollectRep.Field.Builder fieldBuilder = CollectRep.Field.newBuilder();
|
||||
fieldBuilder.setName(field.getField()).setType(field.getType()).setLabel(field.isLabel());
|
||||
if (field.getUnit() != null) {
|
||||
fieldBuilder.setUnit(field.getUnit());
|
||||
}
|
||||
fieldList.add(fieldBuilder.build());
|
||||
}
|
||||
collectData.addAllFields(fieldList);
|
||||
List<CollectRep.ValueRow> aliasRowList = collectData.getValuesList();
|
||||
if (aliasRowList == null || aliasRowList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
collectData.clearValues();
|
||||
// Preprocess calculates first
|
||||
if (metrics.getCalculates() == null) {
|
||||
metrics.setCalculates(Collections.emptyList());
|
||||
}
|
||||
// eg: database_pages=Database pages unconventional mapping
|
||||
Map<String, String> fieldAliasMap = new HashMap<>(8);
|
||||
Map<String, JexlExpression> fieldExpressionMap = metrics.getCalculates()
|
||||
.stream()
|
||||
.map(cal -> transformCal(cal, fieldAliasMap))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(arr -> (String) arr[0], arr -> (JexlExpression) arr[1], (oldValue, newValue) -> newValue));
|
||||
|
||||
if (metrics.getUnits() == null) {
|
||||
metrics.setUnits(Collections.emptyList());
|
||||
}
|
||||
Map<String, Pair<String, String>> fieldUnitMap = metrics.getUnits()
|
||||
.stream()
|
||||
.map(this::transformUnit)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(arr -> (String) arr[0], arr -> (Pair<String, String>) arr[1], (oldValue, newValue) -> newValue));
|
||||
|
||||
List<Metrics.Field> fields = metrics.getFields();
|
||||
List<String> aliasFields = Optional.ofNullable(metrics.getAliasFields()).orElseGet(Collections::emptyList);
|
||||
Map<String, String> aliasFieldValueMap = new HashMap<>(8);
|
||||
Map<String, Object> fieldValueMap = new HashMap<>(8);
|
||||
Map<String, Object> stringTypefieldValueMap = new HashMap<>(8);
|
||||
Map<String, String> aliasFieldUnitMap = new HashMap<>(8);
|
||||
CollectRep.ValueRow.Builder realValueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (CollectRep.ValueRow aliasRow : aliasRowList) {
|
||||
for (int aliasIndex = 0; aliasIndex < aliasFields.size(); aliasIndex++) {
|
||||
String aliasFieldValue = aliasRow.getColumns(aliasIndex);
|
||||
String aliasField = aliasFields.get(aliasIndex);
|
||||
if (!CommonConstants.NULL_VALUE.equals(aliasFieldValue)) {
|
||||
aliasFieldValueMap.put(aliasField, aliasFieldValue);
|
||||
// whether the alias field is a number
|
||||
CollectUtil.DoubleAndUnit doubleAndUnit = CollectUtil
|
||||
.extractDoubleAndUnitFromStr(aliasFieldValue);
|
||||
if (doubleAndUnit != null && doubleAndUnit.getValue() != null) {
|
||||
fieldValueMap.put(aliasField, doubleAndUnit.getValue());
|
||||
if (doubleAndUnit.getUnit() != null) {
|
||||
aliasFieldUnitMap.put(aliasField, doubleAndUnit.getUnit());
|
||||
}
|
||||
} else {
|
||||
fieldValueMap.put(aliasField, aliasFieldValue);
|
||||
}
|
||||
stringTypefieldValueMap.put(aliasField, aliasFieldValue);
|
||||
} else {
|
||||
fieldValueMap.put(aliasField, null);
|
||||
stringTypefieldValueMap.put(aliasField, null);
|
||||
}
|
||||
}
|
||||
|
||||
for (Metrics.Field field : fields) {
|
||||
String realField = field.getField();
|
||||
JexlExpression expression = fieldExpressionMap.get(realField);
|
||||
String value = null;
|
||||
String aliasFieldUnit = null;
|
||||
if (expression != null) {
|
||||
try {
|
||||
Map<String, Object> context;
|
||||
if (CommonConstants.TYPE_STRING == field.getType()) {
|
||||
context = stringTypefieldValueMap;
|
||||
} else {
|
||||
for (Map.Entry<String, String> unitEntry : aliasFieldUnitMap.entrySet()) {
|
||||
if (expression.getSourceText().contains(unitEntry.getKey())) {
|
||||
aliasFieldUnit = unitEntry.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
context = fieldValueMap;
|
||||
}
|
||||
|
||||
// Also executed when valueList is empty, covering pure string assignment expressions
|
||||
Object objValue = JexlExpressionRunner.evaluate(expression, context);
|
||||
|
||||
if (objValue != null) {
|
||||
value = String.valueOf(objValue);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("[calculates execute warning, use original value.] {}", e.getMessage());
|
||||
value = Optional.ofNullable(fieldValueMap.get(expression.getSourceText()))
|
||||
.map(String::valueOf)
|
||||
.orElse(null);
|
||||
}
|
||||
} else {
|
||||
// does not exist then map the alias value
|
||||
String aliasField = fieldAliasMap.get(realField);
|
||||
if (aliasField != null) {
|
||||
value = aliasFieldValueMap.get(aliasField);
|
||||
} else {
|
||||
value = aliasFieldValueMap.get(realField);
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
final byte fieldType = field.getType();
|
||||
if (fieldType == CommonConstants.TYPE_NUMBER) {
|
||||
CollectUtil.DoubleAndUnit doubleAndUnit = CollectUtil
|
||||
.extractDoubleAndUnitFromStr(value);
|
||||
final Double tempValue = doubleAndUnit == null ? null : doubleAndUnit.getValue();
|
||||
value = tempValue == null ? null : String.valueOf(tempValue);
|
||||
aliasFieldUnit = doubleAndUnit == null ? null : doubleAndUnit.getUnit();
|
||||
} else if (fieldType == CommonConstants.TYPE_TIME) {
|
||||
final int tempValue;
|
||||
value = (tempValue = CommonUtil.parseTimeStrToSecond(value)) == -1 ? null : String.valueOf(tempValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Pair<String, String> unitPair = fieldUnitMap.get(realField);
|
||||
if (aliasFieldUnit != null) {
|
||||
if (unitPair != null) {
|
||||
unitPair.setLeft(aliasFieldUnit);
|
||||
} else if (field.getUnit() != null && !aliasFieldUnit.equalsIgnoreCase(field.getUnit())) {
|
||||
unitPair = Pair.of(aliasFieldUnit, field.getUnit());
|
||||
}
|
||||
}
|
||||
if (value != null && unitPair != null) {
|
||||
for (UnitConvert unitConvert : unitConvertList) {
|
||||
if (unitConvert.checkUnit(unitPair.getLeft()) && unitConvert.checkUnit(unitPair.getRight())) {
|
||||
value = unitConvert.convert(value, unitPair.getLeft(), unitPair.getRight());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handle metrics values that may have units such as 34%, 34Mb, and limit values to 4 decimal places
|
||||
if (CommonConstants.TYPE_NUMBER == field.getType()) {
|
||||
value = CommonUtil.parseDoubleStr(value, field.getUnit());
|
||||
}
|
||||
if (value == null) {
|
||||
value = CommonConstants.NULL_VALUE;
|
||||
}
|
||||
realValueRowBuilder.addColumn(value);
|
||||
}
|
||||
aliasFieldValueMap.clear();
|
||||
fieldValueMap.clear();
|
||||
aliasFieldUnitMap.clear();
|
||||
stringTypefieldValueMap.clear();
|
||||
CollectRep.ValueRow realValueRow = realValueRowBuilder.build();
|
||||
realValueRowBuilder.clear();
|
||||
// apply filter calculation to the real value row
|
||||
if (!CollectionUtils.isEmpty(metrics.getFilters())) {
|
||||
Map<String, Object> contextMap = new HashMap<>(8);
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
Metrics.Field field = fields.get(i);
|
||||
String value = realValueRow.getColumns(i);
|
||||
contextMap.put(field.getField(), value);
|
||||
}
|
||||
boolean isMatch = false;
|
||||
for (String filterExpr : metrics.getFilters()) {
|
||||
try {
|
||||
JexlExpression expression = JexlExpressionRunner.compile(filterExpr);
|
||||
if ((Boolean) JexlExpressionRunner.evaluate(expression, contextMap)) {
|
||||
isMatch = true;
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("[metrics data row filters execute warning] {}.", e.getMessage());
|
||||
}
|
||||
}
|
||||
if (!isMatch) {
|
||||
// ignore this data row
|
||||
continue;
|
||||
}
|
||||
}
|
||||
collectData.addValueRow(realValueRow);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cal cal
|
||||
* @param fieldAliasMap field alias map
|
||||
* @return expr
|
||||
*/
|
||||
private Object[] transformCal(String cal, Map<String, String> fieldAliasMap) {
|
||||
int splitIndex = cal.indexOf("=");
|
||||
if (splitIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
String field = cal.substring(0, splitIndex).trim();
|
||||
String expressionStr = cal.substring(splitIndex + 1).trim().replace("\\#", "#");
|
||||
JexlExpression expression;
|
||||
try {
|
||||
expression = JexlExpressionRunner.compile(expressionStr);
|
||||
} catch (Exception e) {
|
||||
fieldAliasMap.put(field, expressionStr);
|
||||
return null;
|
||||
}
|
||||
return new Object[]{field, expression};
|
||||
}
|
||||
|
||||
/**
|
||||
* transform unit
|
||||
*
|
||||
* @param unit unit
|
||||
* @return units
|
||||
*/
|
||||
private Object[] transformUnit(String unit) {
|
||||
int equalIndex = unit.indexOf("=");
|
||||
int arrowIndex = unit.indexOf("->");
|
||||
if (equalIndex < 0 || arrowIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
String field = unit.substring(0, equalIndex).trim();
|
||||
String originUnit = unit.substring(equalIndex + 1, arrowIndex).trim();
|
||||
String newUnit = unit.substring(arrowIndex + 2).trim();
|
||||
return new Object[]{field, Pair.of(originUnit, newUnit)};
|
||||
}
|
||||
|
||||
private boolean fastFailed() {
|
||||
return this.timeout == null || this.timeout.isCancelled();
|
||||
}
|
||||
|
||||
private CollectRep.MetricsData validateResponse(CollectRep.MetricsData.Builder builder) {
|
||||
long endTime = System.currentTimeMillis();
|
||||
builder.setTime(endTime);
|
||||
long runningTime = endTime - startTime;
|
||||
long allTime = endTime - newTime;
|
||||
if (startTime - newTime >= WARN_DISPATCH_TIME) {
|
||||
log.warn("[Collector Dispatch Warn, Dispatch Use {}ms.", startTime - newTime);
|
||||
}
|
||||
if (builder.getCode() != CollectRep.Code.SUCCESS) {
|
||||
log.info("[Collect Failed, Run {}ms, All {}ms] Reason: {}", runningTime, allTime, builder.getMsg());
|
||||
} else {
|
||||
log.info("[Collect Success, Run {}ms, All {}ms].", runningTime, allTime);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private void validateResponse(CollectRep.MetricsData metricsData) {
|
||||
if (metricsData == null) {
|
||||
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.handler;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
import org.apache.hertzbeat.collector.collect.strategy.CollectStrategyFactory;
|
||||
import org.apache.hertzbeat.collector.constants.ContextKey;
|
||||
import org.apache.hertzbeat.collector.constants.ContextStatus;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.dispatch.CollectTaskTimeoutMonitor;
|
||||
import org.apache.hertzbeat.collector.handler.impl.AbstractBatchDataStream;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
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.Timeout;
|
||||
|
||||
|
||||
@Data
|
||||
@Slf4j
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class CollectMetricsDataDataStream extends AbstractBatchDataStream<Metrics, CollectRep.MetricsData.Builder> {
|
||||
private CollectTaskTimeoutMonitor collectTaskTimeoutMonitor;
|
||||
|
||||
@Override
|
||||
public CollectRep.MetricsData.Builder executeWithResponse(Context context, Metrics data) {
|
||||
// preset start info
|
||||
context.put(ContextKey.METRICS, data);
|
||||
Job job = context.get(ContextKey.JOB);
|
||||
long startTime = context.get(ContextKey.METRICS_COLLECT_START_TIME);
|
||||
setNewThreadName(job.getMonitorId(), job.getApp(), startTime, data);
|
||||
|
||||
|
||||
Timeout timeout = context.get(ContextKey.TIMEOUT);
|
||||
String key = data.getPrometheus() != null ? String.valueOf(job.getId()) : job.getId() + "-" + data.getName();
|
||||
context.put(ContextKey.METRICS_KEY, key);
|
||||
this.collectTaskTimeoutMonitor.putMetrics(key, new CollectTaskTimeoutMonitor.MetricsTime(startTime, data, timeout));
|
||||
|
||||
|
||||
CollectRep.MetricsData.Builder fetchedData = this.fetchData(job, data);
|
||||
if (fetchedData.getCode() != CollectRep.Code.SUCCESS && CommonConstants.AVAILABLE_METRICS == data.getPriority()) {
|
||||
context.setStatus(ContextStatus.TRUNCATE_HANDLER);
|
||||
}
|
||||
return fetchedData;
|
||||
}
|
||||
|
||||
private void setNewThreadName(long monitorId, String app, long startTime, Metrics metrics) {
|
||||
String builder = monitorId + "-" + app + "-" + metrics.getName() + "-" + String.valueOf(startTime).substring(9);
|
||||
Thread.currentThread().setName(builder);
|
||||
}
|
||||
|
||||
private CollectRep.MetricsData.Builder fetchData(Job job, Metrics metrics) {
|
||||
CollectRep.MetricsData.Builder response = CollectRep.MetricsData.newBuilder();
|
||||
response.setApp(job.getApp())
|
||||
.setId(job.getMonitorId())
|
||||
.setTenantId(job.getTenantId())
|
||||
.setLabels(job.getLabels())
|
||||
.setAnnotations(job.getAnnotations())
|
||||
.addMetadataAll(job.getMetadata());
|
||||
|
||||
//todo transcribe Prometheus to different chain
|
||||
// for prometheus auto or proxy mode
|
||||
// if (DispatchConstants.PROTOCOL_PROMETHEUS.equalsIgnoreCase(metrics.getProtocol())) {
|
||||
// List<CollectRep.MetricsData> metricsData = PrometheusAutoCollectImpl.getInstance().collect(response, metrics);
|
||||
// validateResponse(metricsData == null ? null : metricsData.stream().findFirst().orElse(null));
|
||||
// collectDataDispatch.dispatchCollectData(timeout, metrics, metricsData);
|
||||
// return null;
|
||||
// }
|
||||
|
||||
response.setMetrics(metrics.getName());
|
||||
// According to the metrics collection protocol, application type, etc.,
|
||||
// dispatch to the real application metrics collection implementation class
|
||||
AbstractCollect abstractCollect = CollectStrategyFactory.invoke(metrics.getProtocol());
|
||||
if (abstractCollect == null) {
|
||||
log.error("[Dispatcher] - not support this: app: {}, metrics: {}, protocol: {}.", job.getApp(), metrics.getName(), metrics.getProtocol());
|
||||
response.setCode(CollectRep.Code.FAIL);
|
||||
response.setMsg("not support " + job.getApp() + ", " + metrics.getName() + ", " + metrics.getProtocol());
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
try {
|
||||
abstractCollect.preCheck(metrics);
|
||||
abstractCollect.collect(response, metrics);
|
||||
} catch (Exception e) {
|
||||
String msg = e.getMessage();
|
||||
if (msg == null && e.getCause() != null) {
|
||||
msg = e.getCause().getMessage();
|
||||
}
|
||||
if (e instanceof IllegalArgumentException) {
|
||||
log.error("[Metrics PreCheck]: {}.", msg, e);
|
||||
} else {
|
||||
log.error("[Metrics Collect]: {}.", msg, e);
|
||||
}
|
||||
response.setCode(CollectRep.Code.FAIL);
|
||||
if (msg != null) {
|
||||
response.setMsg(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.handler;
|
||||
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.handler.impl.AbstractBatchDataStream;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DynamicSubTaskCollectMetricsDataDataStream extends AbstractBatchDataStream<Metrics, CollectRep.MetricsData.Builder> {
|
||||
@Override
|
||||
public CollectRep.MetricsData.Builder executeWithResponse(Context context, Metrics data) {
|
||||
//todo 动态拆分
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+289
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* 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.listener;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.jexl3.JexlExpression;
|
||||
import org.apache.hertzbeat.collector.constants.ContextKey;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.dispatch.unit.UnitConvert;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundListener;
|
||||
import org.apache.hertzbeat.collector.util.CollectUtil;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.apache.hertzbeat.common.util.JexlExpressionRunner;
|
||||
import org.apache.hertzbeat.common.util.Pair;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class CalculateFieldsListener implements ContextBoundListener<CollectRep.MetricsData.Builder> {
|
||||
private List<UnitConvert> unitConvertList;
|
||||
|
||||
@Override
|
||||
public void execute(Context context, CollectRep.MetricsData.Builder data) {
|
||||
Metrics metrics = context.get(ContextKey.METRICS);
|
||||
|
||||
this.calculateFields(metrics, unitConvertList, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the real metrics value according to the calculates and aliasFields configuration
|
||||
*
|
||||
* @param metrics Metrics configuration
|
||||
* @param collectData Data collection
|
||||
*/
|
||||
private void calculateFields(Metrics metrics, List<UnitConvert> unitConvertList, CollectRep.MetricsData.Builder collectData) {
|
||||
collectData.setPriority(metrics.getPriority());
|
||||
List<CollectRep.Field> fieldList = new LinkedList<>();
|
||||
for (Metrics.Field field : metrics.getFields()) {
|
||||
CollectRep.Field.Builder fieldBuilder = CollectRep.Field.newBuilder();
|
||||
fieldBuilder.setName(field.getField()).setType(field.getType()).setLabel(field.isLabel());
|
||||
if (field.getUnit() != null) {
|
||||
fieldBuilder.setUnit(field.getUnit());
|
||||
}
|
||||
fieldList.add(fieldBuilder.build());
|
||||
}
|
||||
collectData.addAllFields(fieldList);
|
||||
List<CollectRep.ValueRow> aliasRowList = collectData.getValuesList();
|
||||
if (aliasRowList == null || aliasRowList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
collectData.clearValues();
|
||||
// Preprocess calculates first
|
||||
if (metrics.getCalculates() == null) {
|
||||
metrics.setCalculates(Collections.emptyList());
|
||||
}
|
||||
// eg: database_pages=Database pages unconventional mapping
|
||||
Map<String, String> fieldAliasMap = new HashMap<>(8);
|
||||
Map<String, JexlExpression> fieldExpressionMap = metrics.getCalculates()
|
||||
.stream()
|
||||
.map(cal -> transformCal(cal, fieldAliasMap))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(arr -> (String) arr[0], arr -> (JexlExpression) arr[1], (oldValue, newValue) -> newValue));
|
||||
|
||||
if (metrics.getUnits() == null) {
|
||||
metrics.setUnits(Collections.emptyList());
|
||||
}
|
||||
Map<String, Pair<String, String>> fieldUnitMap = metrics.getUnits()
|
||||
.stream()
|
||||
.map(this::transformUnit)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(arr -> (String) arr[0], arr -> (Pair<String, String>) arr[1], (oldValue, newValue) -> newValue));
|
||||
|
||||
List<Metrics.Field> fields = metrics.getFields();
|
||||
List<String> aliasFields = Optional.ofNullable(metrics.getAliasFields()).orElseGet(Collections::emptyList);
|
||||
Map<String, String> aliasFieldValueMap = new HashMap<>(8);
|
||||
Map<String, Object> fieldValueMap = new HashMap<>(8);
|
||||
Map<String, Object> stringTypefieldValueMap = new HashMap<>(8);
|
||||
Map<String, String> aliasFieldUnitMap = new HashMap<>(8);
|
||||
CollectRep.ValueRow.Builder realValueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (CollectRep.ValueRow aliasRow : aliasRowList) {
|
||||
for (int aliasIndex = 0; aliasIndex < aliasFields.size(); aliasIndex++) {
|
||||
String aliasFieldValue = aliasRow.getColumns(aliasIndex);
|
||||
String aliasField = aliasFields.get(aliasIndex);
|
||||
if (!CommonConstants.NULL_VALUE.equals(aliasFieldValue)) {
|
||||
aliasFieldValueMap.put(aliasField, aliasFieldValue);
|
||||
// whether the alias field is a number
|
||||
CollectUtil.DoubleAndUnit doubleAndUnit = CollectUtil
|
||||
.extractDoubleAndUnitFromStr(aliasFieldValue);
|
||||
if (doubleAndUnit != null && doubleAndUnit.getValue() != null) {
|
||||
fieldValueMap.put(aliasField, doubleAndUnit.getValue());
|
||||
if (doubleAndUnit.getUnit() != null) {
|
||||
aliasFieldUnitMap.put(aliasField, doubleAndUnit.getUnit());
|
||||
}
|
||||
} else {
|
||||
fieldValueMap.put(aliasField, aliasFieldValue);
|
||||
}
|
||||
stringTypefieldValueMap.put(aliasField, aliasFieldValue);
|
||||
} else {
|
||||
fieldValueMap.put(aliasField, null);
|
||||
stringTypefieldValueMap.put(aliasField, null);
|
||||
}
|
||||
}
|
||||
|
||||
for (Metrics.Field field : fields) {
|
||||
String realField = field.getField();
|
||||
JexlExpression expression = fieldExpressionMap.get(realField);
|
||||
String value = null;
|
||||
String aliasFieldUnit = null;
|
||||
if (expression != null) {
|
||||
try {
|
||||
Map<String, Object> context;
|
||||
if (CommonConstants.TYPE_STRING == field.getType()) {
|
||||
context = stringTypefieldValueMap;
|
||||
} else {
|
||||
for (Map.Entry<String, String> unitEntry : aliasFieldUnitMap.entrySet()) {
|
||||
if (expression.getSourceText().contains(unitEntry.getKey())) {
|
||||
aliasFieldUnit = unitEntry.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
context = fieldValueMap;
|
||||
}
|
||||
|
||||
// Also executed when valueList is empty, covering pure string assignment expressions
|
||||
Object objValue = JexlExpressionRunner.evaluate(expression, context);
|
||||
|
||||
if (objValue != null) {
|
||||
value = String.valueOf(objValue);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("[calculates execute warning, use original value.] {}", e.getMessage());
|
||||
value = Optional.ofNullable(fieldValueMap.get(expression.getSourceText()))
|
||||
.map(String::valueOf)
|
||||
.orElse(null);
|
||||
}
|
||||
} else {
|
||||
// does not exist then map the alias value
|
||||
String aliasField = fieldAliasMap.get(realField);
|
||||
if (aliasField != null) {
|
||||
value = aliasFieldValueMap.get(aliasField);
|
||||
} else {
|
||||
value = aliasFieldValueMap.get(realField);
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
final byte fieldType = field.getType();
|
||||
if (fieldType == CommonConstants.TYPE_NUMBER) {
|
||||
CollectUtil.DoubleAndUnit doubleAndUnit = CollectUtil
|
||||
.extractDoubleAndUnitFromStr(value);
|
||||
final Double tempValue = doubleAndUnit == null ? null : doubleAndUnit.getValue();
|
||||
value = tempValue == null ? null : String.valueOf(tempValue);
|
||||
aliasFieldUnit = doubleAndUnit == null ? null : doubleAndUnit.getUnit();
|
||||
} else if (fieldType == CommonConstants.TYPE_TIME) {
|
||||
final int tempValue;
|
||||
value = (tempValue = CommonUtil.parseTimeStrToSecond(value)) == -1 ? null : String.valueOf(tempValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Pair<String, String> unitPair = fieldUnitMap.get(realField);
|
||||
if (aliasFieldUnit != null) {
|
||||
if (unitPair != null) {
|
||||
unitPair.setLeft(aliasFieldUnit);
|
||||
} else if (field.getUnit() != null && !aliasFieldUnit.equalsIgnoreCase(field.getUnit())) {
|
||||
unitPair = Pair.of(aliasFieldUnit, field.getUnit());
|
||||
}
|
||||
}
|
||||
if (value != null && unitPair != null) {
|
||||
for (UnitConvert unitConvert : unitConvertList) {
|
||||
if (unitConvert.checkUnit(unitPair.getLeft()) && unitConvert.checkUnit(unitPair.getRight())) {
|
||||
value = unitConvert.convert(value, unitPair.getLeft(), unitPair.getRight());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handle metrics values that may have units such as 34%, 34Mb, and limit values to 4 decimal places
|
||||
if (CommonConstants.TYPE_NUMBER == field.getType()) {
|
||||
value = CommonUtil.parseDoubleStr(value, field.getUnit());
|
||||
}
|
||||
if (value == null) {
|
||||
value = CommonConstants.NULL_VALUE;
|
||||
}
|
||||
realValueRowBuilder.addColumn(value);
|
||||
}
|
||||
aliasFieldValueMap.clear();
|
||||
fieldValueMap.clear();
|
||||
aliasFieldUnitMap.clear();
|
||||
stringTypefieldValueMap.clear();
|
||||
CollectRep.ValueRow realValueRow = realValueRowBuilder.build();
|
||||
realValueRowBuilder.clear();
|
||||
// apply filter calculation to the real value row
|
||||
if (!CollectionUtils.isEmpty(metrics.getFilters())) {
|
||||
Map<String, Object> contextMap = new HashMap<>(8);
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
Metrics.Field field = fields.get(i);
|
||||
String value = realValueRow.getColumns(i);
|
||||
contextMap.put(field.getField(), value);
|
||||
}
|
||||
boolean isMatch = false;
|
||||
for (String filterExpr : metrics.getFilters()) {
|
||||
try {
|
||||
JexlExpression expression = JexlExpressionRunner.compile(filterExpr);
|
||||
if ((Boolean) JexlExpressionRunner.evaluate(expression, contextMap)) {
|
||||
isMatch = true;
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("[metrics data row filters execute warning] {}.", e.getMessage());
|
||||
}
|
||||
}
|
||||
if (!isMatch) {
|
||||
// ignore this data row
|
||||
continue;
|
||||
}
|
||||
}
|
||||
collectData.addValueRow(realValueRow);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cal cal
|
||||
* @param fieldAliasMap field alias map
|
||||
* @return expr
|
||||
*/
|
||||
private Object[] transformCal(String cal, Map<String, String> fieldAliasMap) {
|
||||
int splitIndex = cal.indexOf("=");
|
||||
if (splitIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
String field = cal.substring(0, splitIndex).trim();
|
||||
String expressionStr = cal.substring(splitIndex + 1).trim().replace("\\#", "#");
|
||||
JexlExpression expression;
|
||||
try {
|
||||
expression = JexlExpressionRunner.compile(expressionStr);
|
||||
} catch (Exception e) {
|
||||
fieldAliasMap.put(field, expressionStr);
|
||||
return null;
|
||||
}
|
||||
return new Object[]{field, expression};
|
||||
}
|
||||
|
||||
/**
|
||||
* transform unit
|
||||
*
|
||||
* @param unit unit
|
||||
* @return units
|
||||
*/
|
||||
private Object[] transformUnit(String unit) {
|
||||
int equalIndex = unit.indexOf("=");
|
||||
int arrowIndex = unit.indexOf("->");
|
||||
if (equalIndex < 0 || arrowIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
String field = unit.substring(0, equalIndex).trim();
|
||||
String originUnit = unit.substring(equalIndex + 1, arrowIndex).trim();
|
||||
String newUnit = unit.substring(arrowIndex + 2).trim();
|
||||
return new Object[]{field, Pair.of(originUnit, newUnit)};
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.listener;
|
||||
|
||||
import org.apache.hertzbeat.collector.constants.ContextKey;
|
||||
import org.apache.hertzbeat.collector.constants.ContextStatus;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundListener;
|
||||
import org.apache.hertzbeat.common.timer.Timeout;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class CommonMetricsDataListener<T> implements ContextBoundListener<T> {
|
||||
@Override
|
||||
public void execute(Context context, T data) {
|
||||
Timeout timeout = context.get(ContextKey.TIMEOUT);
|
||||
|
||||
if (timeout == null || timeout.isCancelled()) {
|
||||
context.setStatus(ContextStatus.STOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.listener;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.constants.ContextKey;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundListener;
|
||||
import org.apache.hertzbeat.common.entity.job.Job;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.queue.CommonDataQueue;
|
||||
|
||||
/**
|
||||
* 周期任务专用
|
||||
*/
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class MetricsDataDeliveryListener implements ContextBoundListener<CollectRep.MetricsData.Builder> {
|
||||
private CommonDataQueue commonDataQueue;
|
||||
|
||||
@Override
|
||||
public void execute(Context context, CollectRep.MetricsData.Builder data) {
|
||||
Job job = context.get(ContextKey.JOB);
|
||||
CollectRep.MetricsData metricsData = data.build();
|
||||
|
||||
cyclicJobDebugLog(job, metricsData);
|
||||
|
||||
sendToQueue(job, metricsData);
|
||||
}
|
||||
|
||||
private void sendToQueue(Job job, CollectRep.MetricsData metricsData) {
|
||||
if (job.isSd()) {
|
||||
CollectRep.MetricsData sdMetricsData = CollectRep.MetricsData.newBuilder(metricsData).build();
|
||||
commonDataQueue.sendServiceDiscoveryData(sdMetricsData);
|
||||
}
|
||||
commonDataQueue.sendMetricsData(metricsData);
|
||||
}
|
||||
|
||||
private void cyclicJobDebugLog(Job job, CollectRep.MetricsData metricsData) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Cyclic Job: {} - {} - {}", job.getMonitorId(), job.getApp(), metricsData.getMetrics());
|
||||
metricsDataDebugLog(metricsData);
|
||||
}
|
||||
}
|
||||
|
||||
private void metricsDataDebugLog(CollectRep.MetricsData metricsData) {
|
||||
for (CollectRep.ValueRow valueRow : metricsData.getValues()) {
|
||||
for (CollectRep.Field field : metricsData.getFields()) {
|
||||
log.debug("Field-->{},Value-->{}", field.getName(), valueRow.getColumns(metricsData.getFields().indexOf(field)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.listener;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.collector.constants.ContextKey;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.dispatch.CollectTaskTimeoutMonitor;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundListener;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class RemoveTimeoutMonitorListener implements ContextBoundListener<Object> {
|
||||
private CollectTaskTimeoutMonitor collectTaskTimeoutMonitor;
|
||||
|
||||
@Override
|
||||
public void execute(Context context, Object data) {
|
||||
String metricsKey = context.get(ContextKey.METRICS_KEY);
|
||||
if (StringUtils.isBlank(metricsKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
collectTaskTimeoutMonitor.removeMetrics(metricsKey);
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.listener;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.hertzbeat.collector.constants.ContextKey;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundDataStream;
|
||||
import org.apache.hertzbeat.collector.timer.TimerDispatch;
|
||||
import org.apache.hertzbeat.collector.timer.WheelTimerTask;
|
||||
import org.apache.hertzbeat.common.entity.job.Job;
|
||||
import org.apache.hertzbeat.common.timer.Timeout;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 周期任务专用
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class RerunDataStream implements ContextBoundDataStream<Object> {
|
||||
private TimerDispatch timerDispatch;
|
||||
|
||||
@Override
|
||||
public void execute(Context context, Object data) {
|
||||
Job job = context.get(ContextKey.JOB);
|
||||
Timeout timeout = context.get(ContextKey.TIMEOUT);
|
||||
|
||||
if (!timeout.isCancelled()) {
|
||||
long spendTime = System.currentTimeMillis() - job.getDispatchTime();
|
||||
long interval = job.getInterval() - spendTime / 1000L;
|
||||
interval = interval <= 0 ? 0 : interval;
|
||||
timerDispatch.cyclicJob((WheelTimerTask) timeout.task(), interval, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenException(Context context, Object data, Throwable throwable) {
|
||||
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.listener;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.constants.ContextKey;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundListener;
|
||||
import org.apache.hertzbeat.collector.timer.TimerDispatch;
|
||||
import org.apache.hertzbeat.common.entity.job.Job;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
|
||||
/**
|
||||
* 一次性任务专用
|
||||
*/
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class ResponseJobDataListener implements ContextBoundListener<CollectRep.MetricsData.Builder> {
|
||||
private TimerDispatch timerDispatch;
|
||||
|
||||
@Override
|
||||
public void execute(Context context, CollectRep.MetricsData.Builder data) {
|
||||
Job job = context.get(ContextKey.JOB);
|
||||
CollectRep.MetricsData metricsData = data.build();
|
||||
|
||||
oneTimeJobDebugLog(metricsData);
|
||||
timerDispatch.responseSyncJobData(job.getId(), Lists.newArrayList(metricsData));
|
||||
}
|
||||
|
||||
private void oneTimeJobDebugLog(CollectRep.MetricsData metricsData) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("One-time Job: {}", metricsData.getMetrics());
|
||||
metricsDataDebugLog(metricsData);
|
||||
}
|
||||
}
|
||||
|
||||
private void metricsDataDebugLog(CollectRep.MetricsData metricsData) {
|
||||
for (CollectRep.ValueRow valueRow : metricsData.getValues()) {
|
||||
for (CollectRep.Field field : metricsData.getFields()) {
|
||||
log.debug("Field-->{},Value-->{}", field.getName(), valueRow.getColumns(metricsData.getFields().indexOf(field)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.listener;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.constants.ContextKey;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundListener;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Calvin
|
||||
* @date 9/1/2025
|
||||
*/
|
||||
@Slf4j
|
||||
public class ValidateResponseListener implements ContextBoundListener<CollectRep.MetricsData.Builder> {
|
||||
|
||||
@Override
|
||||
public void execute(Context context, CollectRep.MetricsData.Builder data) {
|
||||
long startTime = context.get(ContextKey.METRICS_COLLECT_START_TIME);
|
||||
Metrics metrics = context.get(ContextKey.METRICS);
|
||||
|
||||
this.validateResponse(startTime, metrics, data);
|
||||
}
|
||||
|
||||
private void validateResponse(long startTime, Metrics metrics, CollectRep.MetricsData.Builder builder) {
|
||||
long endTime = System.currentTimeMillis();
|
||||
builder.setTime(endTime);
|
||||
long allTime = endTime - startTime;
|
||||
if (builder.getCode() != CollectRep.Code.SUCCESS) {
|
||||
log.info("[Metrics: {}][Collect Failed, Run {}ms] Reason: {}", metrics.getName(), allTime, builder.getMsg());
|
||||
} else {
|
||||
log.info("[Metrics: {}][Collect Success, Run {}ms].", metrics.getName(), allTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -55,7 +55,7 @@ spring:
|
||||
|
||||
collector:
|
||||
info:
|
||||
version: ${COLLECTOR_VERSION:1.7.2}
|
||||
version: ${COLLECTOR_VERSION:1.7.3}
|
||||
ip: ${COLLECTOR_IP:}
|
||||
dispatch:
|
||||
entrance:
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.constants;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.apache.hertzbeat.common.entity.collector.CollectorMetaData;
|
||||
import org.apache.hertzbeat.common.entity.job.Job;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.timer.Timeout;
|
||||
|
||||
public enum ContextKey {
|
||||
META_DATA(CollectorMetaData.class),
|
||||
JOB(Job.class),
|
||||
TIMEOUT(Timeout.class),
|
||||
METRICS_COLLECT_START_TIME(Long.class),
|
||||
METRICS(Metrics.class),
|
||||
METRICS_KEY(String.class),
|
||||
;
|
||||
|
||||
@Getter
|
||||
private final Class<?> clazz;
|
||||
|
||||
ContextKey(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -15,11 +15,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.constants;
|
||||
package org.apache.hertzbeat.collector.constants;
|
||||
|
||||
/**
|
||||
* Enum representing the possible statuses of a collector.
|
||||
*
|
||||
*/
|
||||
public enum CollectorStatus {
|
||||
ONLINE, OFFLINE;
|
||||
public enum ContextStatus {
|
||||
WAITING, RUNNING, STOP, TRUNCATE_HANDLER
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.constants;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public enum HandlerType {
|
||||
NORMAL, ON_COMPLETE
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.context;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.hertzbeat.collector.constants.ContextStatus;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractInmemoryContext implements Context {
|
||||
protected final AtomicReference<ContextStatus> contextStatus = new AtomicReference<>(ContextStatus.WAITING);
|
||||
protected final Map<Object, Object> map = new ConcurrentHashMap<>();
|
||||
@Getter
|
||||
@Setter
|
||||
private Throwable error;
|
||||
|
||||
|
||||
@Override
|
||||
public <T> void put(Object key, T value) {
|
||||
this.map.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T remove(Object key) {
|
||||
return (T) this.map.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T get(Object key) {
|
||||
return (T) this.map.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getOrDefault(Object key, T defaultValue) {
|
||||
return (T) this.map.getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasKey(Object key) {
|
||||
return this.map.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextStatus getStatus() {
|
||||
return contextStatus.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(ContextStatus status) {
|
||||
contextStatus.set(status);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.context;
|
||||
|
||||
import org.apache.hertzbeat.collector.constants.ContextStatus;
|
||||
|
||||
/**
|
||||
* 只维护与上下文的元数据
|
||||
*/
|
||||
public interface Context extends ContextView, ContextOperation {
|
||||
ContextStatus getStatus();
|
||||
|
||||
void setStatus(ContextStatus status);
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.context;
|
||||
|
||||
import io.micrometer.common.lang.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface ContextOperation {
|
||||
<T> void put(Object key, T value);
|
||||
|
||||
<T> T remove(Object key);
|
||||
|
||||
@Nullable
|
||||
Throwable getError();
|
||||
|
||||
void setError(Throwable error);
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.context;
|
||||
|
||||
/**
|
||||
* 对上下文内容的查询操作
|
||||
*/
|
||||
public interface ContextView {
|
||||
<T> T get(Object key);
|
||||
|
||||
<T> T getOrDefault(Object key, T defaultValue);
|
||||
|
||||
boolean hasKey(Object key);
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.context.impl;
|
||||
|
||||
import org.apache.hertzbeat.collector.context.AbstractInmemoryContext;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DefaultContext extends AbstractInmemoryContext {
|
||||
private DefaultContext() {
|
||||
}
|
||||
|
||||
public static DefaultContext newInstance() {
|
||||
return new DefaultContext();
|
||||
}
|
||||
}
|
||||
-9
@@ -36,13 +36,4 @@ public interface CollectDataDispatch {
|
||||
*/
|
||||
void dispatchCollectData(Timeout timeout, Metrics metrics, CollectRep.MetricsData metricsData);
|
||||
|
||||
/**
|
||||
* Processing and distributing collection result data
|
||||
*
|
||||
* @param timeout time wheel timeout
|
||||
* @param metrics The following metrics collection tasks
|
||||
* @param metricsDataList Collect result data
|
||||
*/
|
||||
void dispatchCollectData(Timeout timeout, Metrics metrics, List<CollectRep.MetricsData> metricsDataList);
|
||||
|
||||
}
|
||||
|
||||
+113
@@ -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.handler;
|
||||
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.hertzbeat.collector.constants.HandlerType;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.dispatch.WorkerPool;
|
||||
import org.apache.hertzbeat.collector.handler.impl.AbstractListenerBoundDataStream;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
public class ChainBootstrap {
|
||||
@Setter
|
||||
private Context context;
|
||||
private TaskChain<?> taskChain;
|
||||
private WorkerPool workerPool;
|
||||
private final List<ContextBoundDataStream> contextBoundDataStreamList = new ArrayList<>();
|
||||
private final List<ContextBoundDataStream> onCompleteContextBoundDataStreamList = new ArrayList<>();
|
||||
private final List<ContextBoundListener> dataListenerList = new ArrayList<>();
|
||||
private final List<ContextBoundListener> onCompleteListenerList = new ArrayList<>();
|
||||
|
||||
public static ChainBootstrap withContext(Context context) {
|
||||
ChainBootstrap bootstrap = new ChainBootstrap();
|
||||
bootstrap.setContext(context);
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
public ChainBootstrap withChain(TaskChain<?> taskChain) {
|
||||
this.taskChain = taskChain;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChainBootstrap withWorkerPool(WorkerPool workerPool) {
|
||||
this.workerPool = workerPool;
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T> ChainBootstrap addContext(Object key, T value) {
|
||||
context.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChainBootstrap addDataStream(ContextBoundDataStream contextBoundDataStream) {
|
||||
contextBoundDataStreamList.add(contextBoundDataStream);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChainBootstrap onComplete(ContextBoundDataStream contextBoundDataStream) {
|
||||
onCompleteContextBoundDataStreamList.add(contextBoundDataStream);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChainBootstrap addListener(ContextBoundListener dataListener) {
|
||||
dataListenerList.add(dataListener);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChainBootstrap onEachDataStreamComplete(ContextBoundListener dataListener) {
|
||||
onCompleteListenerList.add(dataListener);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (taskChain == null || context == null) {
|
||||
log.error("Failed to start chain boostrap due to null value of Context or TaskChain");
|
||||
return;
|
||||
}
|
||||
|
||||
for (ContextBoundDataStream contextBoundDataStream : contextBoundDataStreamList) {
|
||||
if (contextBoundDataStream instanceof AbstractListenerBoundDataStream listenerBoundHandler) {
|
||||
if (CollectionUtils.isNotEmpty(dataListenerList)) {
|
||||
listenerBoundHandler.getDataListenerList().addAll(dataListenerList);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(onCompleteListenerList)) {
|
||||
listenerBoundHandler.getOnCompleteListenerList().addAll(onCompleteListenerList);
|
||||
}
|
||||
}
|
||||
|
||||
taskChain.addLast(HandlerType.NORMAL, contextBoundDataStream);
|
||||
}
|
||||
|
||||
onCompleteContextBoundDataStreamList.forEach(handler -> taskChain.addLast(HandlerType.ON_COMPLETE, handler));
|
||||
|
||||
if (workerPool != null) {
|
||||
workerPool.executeJob(() -> taskChain.execute(context));
|
||||
} else {
|
||||
taskChain.execute(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.handler;
|
||||
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface ContextBoundDataStream<T> {
|
||||
void execute(Context context, T data);
|
||||
|
||||
void whenException(Context context, T data, Throwable throwable);
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.handler;
|
||||
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
|
||||
/**
|
||||
*/
|
||||
public interface ContextBoundListener<T> {
|
||||
void execute(Context context, T data);
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.handler;
|
||||
|
||||
import org.apache.hertzbeat.collector.constants.HandlerType;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface TaskChain<T> {
|
||||
void execute(Context context);
|
||||
|
||||
void execute(Context context, T data);
|
||||
|
||||
void addLast(HandlerType handlerType, ContextBoundDataStream<T> handler);
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.handler.impl;
|
||||
|
||||
import lombok.Setter;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractBatchDataStream<T, R> extends AbstractListenerBoundDataStream<T, R> {
|
||||
@Setter
|
||||
protected List<T> sourceDataList;
|
||||
|
||||
@Override
|
||||
public void execute(Context context, T data) {
|
||||
for (T t : sourceDataList) {
|
||||
super.execute(context, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.handler.impl;
|
||||
|
||||
import org.apache.hertzbeat.collector.constants.HandlerType;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundDataStream;
|
||||
import org.apache.hertzbeat.collector.handler.TaskChain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractContextBoundTaskChain<T> implements TaskChain<T> {
|
||||
protected final Map<HandlerType, List<ContextBoundDataStream<T>>> contextBoundHandlerMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void addLast(HandlerType handlerType, ContextBoundDataStream<T> handler) {
|
||||
if (!contextBoundHandlerMap.containsKey(handlerType)) {
|
||||
contextBoundHandlerMap.put(handlerType, new ArrayList<>());
|
||||
}
|
||||
|
||||
contextBoundHandlerMap.get(handlerType).add(handler);
|
||||
}
|
||||
}
|
||||
+90
@@ -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.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.handler.impl;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.hertzbeat.collector.constants.ContextKey;
|
||||
import org.apache.hertzbeat.collector.constants.ContextStatus;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundDataStream;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractListenerBoundDataStream<T, R> implements ContextBoundDataStream<T> {
|
||||
@Getter
|
||||
private final List<? extends ContextBoundListener<R>> dataListenerList = new ArrayList<>();
|
||||
@Getter
|
||||
private final List<? extends ContextBoundListener<R>> onCompleteListenerList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void execute(Context context, T data) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
context.put(ContextKey.METRICS_COLLECT_START_TIME, startTime);
|
||||
|
||||
R executeResult = executeWithResponse(context, data);
|
||||
|
||||
runListener(context, executeResult);
|
||||
|
||||
runOnCompleteListener(context, executeResult);
|
||||
}
|
||||
|
||||
public R executeWithResponse(Context context, T data) {
|
||||
// no-op
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenException(Context context, T data, Throwable throwable) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
private void runListener(Context context, R executeResult) {
|
||||
if (CollectionUtils.isEmpty(dataListenerList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ContextStatus.STOP.equals(context.getStatus())) {
|
||||
return;
|
||||
}
|
||||
|
||||
//todo 异常处理
|
||||
for (ContextBoundListener<R> listener : dataListenerList) {
|
||||
listener.execute(context, executeResult);
|
||||
|
||||
if (ContextStatus.STOP.equals(context.getStatus())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void runOnCompleteListener(Context context, R executeResult) {
|
||||
if (CollectionUtils.isEmpty(onCompleteListenerList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ContextBoundListener<R> listener : onCompleteListenerList) {
|
||||
listener.execute(context, executeResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -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.collector.handler.impl;
|
||||
|
||||
import org.apache.hertzbeat.collector.constants.ContextStatus;
|
||||
import org.apache.hertzbeat.collector.constants.HandlerType;
|
||||
import org.apache.hertzbeat.collector.context.Context;
|
||||
import org.apache.hertzbeat.collector.handler.ContextBoundDataStream;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class BatchExecuteTaskChain<T> extends AbstractContextBoundTaskChain<T> {
|
||||
@Override
|
||||
public void execute(Context context) {
|
||||
this.execute(context, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Context context, T data) {
|
||||
context.setStatus(ContextStatus.RUNNING);
|
||||
|
||||
for (ContextBoundDataStream<T> contextBoundDataStream : contextBoundHandlerMap.getOrDefault(HandlerType.NORMAL, new ArrayList<>())) {
|
||||
runHandler(context, data, contextBoundDataStream);
|
||||
|
||||
if (ContextStatus.TRUNCATE_HANDLER.equals(context.getStatus()) || ContextStatus.STOP.equals(context.getStatus())) {
|
||||
break;
|
||||
}
|
||||
|
||||
// in order to init error info for the next loop
|
||||
context.setError(null);
|
||||
}
|
||||
|
||||
contextBoundHandlerMap.getOrDefault(HandlerType.ON_COMPLETE, new ArrayList<>()).forEach(handler -> runHandler(context, data, handler));
|
||||
}
|
||||
|
||||
private static <T> void runHandler(Context context, T data, ContextBoundDataStream<T> contextBoundDataStream) {
|
||||
try {
|
||||
contextBoundDataStream.execute(context, data);
|
||||
} catch (Exception exception) {
|
||||
context.setError(exception);
|
||||
contextBoundDataStream.whenException(context, data, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -171,7 +171,16 @@ public final class CollectUtil {
|
||||
* assert prom field
|
||||
*/
|
||||
public static Boolean assertPromRequireField(String aliasField) {
|
||||
return CommonConstants.PROM_TIME.equals(aliasField) || CommonConstants.PROM_VALUE.equals(aliasField);
|
||||
return CommonConstants.PROM_TIME.equals(aliasField)
|
||||
|| CommonConstants.PROM_VALUE.equals(aliasField)
|
||||
|| CommonConstants.PROM_METRIC_VALUE.equals(aliasField);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if "value" field should be treated as a label instead of special field
|
||||
*/
|
||||
public static Boolean isValueAsLabel(String aliasField, JsonObject metric) {
|
||||
return CommonConstants.PROM_VALUE.equals(aliasField) && null != metric && metric.has(aliasField);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,13 +83,10 @@
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>apache-${project.artifactId}-${hzb.version}</finalName>
|
||||
</build>
|
||||
|
||||
|
||||
|
||||
</project>
|
||||
|
||||
+7
@@ -197,6 +197,11 @@ public interface CommonConstants {
|
||||
*/
|
||||
String PROM_VALUE = "value";
|
||||
|
||||
/**
|
||||
* prometheus metric value alias
|
||||
*/
|
||||
String PROM_METRIC_VALUE = "metric_value";
|
||||
|
||||
/**
|
||||
* Parameter Type Number
|
||||
*/
|
||||
@@ -377,4 +382,6 @@ public interface CommonConstants {
|
||||
* JEXL custom function `json`
|
||||
*/
|
||||
String JEXL_CUSTOM_JSON_FUNCTION = "json";
|
||||
|
||||
byte AVAILABLE_METRICS = 0;
|
||||
}
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.collector;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CollectorMetaData {
|
||||
private String identity;
|
||||
private String mode;
|
||||
private Date startTime;
|
||||
}
|
||||
@@ -293,6 +293,21 @@
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>make-docker-zip</id>
|
||||
<!--Bound maven operation-->
|
||||
<phase>package</phase>
|
||||
<!--Run once-->
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>../dist</outputDirectory>
|
||||
<descriptors>
|
||||
<descriptor>../script/assembly/server/assembly-docker.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>make-docker-compose-script</id>
|
||||
<!--Bound maven operation-->
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
package org.apache.hertzbeat.manager;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.apache.hertzbeat.common.constants.ConfigConstants;
|
||||
import org.apache.hertzbeat.manager.nativex.HertzbeatRuntimeHintsRegistrar;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@@ -38,10 +36,10 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableJpaAuditing
|
||||
@EnableJpaRepositories(basePackages = {ConfigConstants.PkgConstant.PKG})
|
||||
@EntityScan(basePackages = {ConfigConstants.PkgConstant.PKG})
|
||||
@ComponentScan(basePackages = {ConfigConstants.PkgConstant.PKG})
|
||||
@ConfigurationPropertiesScan(basePackages = {ConfigConstants.PkgConstant.PKG})
|
||||
@EnableJpaRepositories(basePackages = {"org.apache.hertzbeat"})
|
||||
@EntityScan(basePackages = {"org.apache.hertzbeat"})
|
||||
@ComponentScan(basePackages = {"org.apache.hertzbeat"})
|
||||
@ConfigurationPropertiesScan(basePackages = {"org.apache.hertzbeat"})
|
||||
@ImportRuntimeHints(HertzbeatRuntimeHintsRegistrar.class)
|
||||
@EnableAsync
|
||||
@EnableScheduling
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.entity.manager.StatusPageComponent;
|
||||
import org.apache.hertzbeat.common.entity.manager.StatusPageHistory;
|
||||
import org.apache.hertzbeat.common.entity.manager.StatusPageOrg;
|
||||
import org.apache.hertzbeat.manager.properties.StatusProperties;
|
||||
import org.apache.hertzbeat.manager.config.StatusProperties;
|
||||
import org.apache.hertzbeat.manager.dao.MonitorDao;
|
||||
import org.apache.hertzbeat.manager.dao.StatusPageComponentDao;
|
||||
import org.apache.hertzbeat.manager.dao.StatusPageHistoryDao;
|
||||
|
||||
+4
-4
@@ -18,8 +18,8 @@
|
||||
package org.apache.hertzbeat.manager.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.manager.scheduler.ConsistentHashCollectorKeeper;
|
||||
import org.apache.hertzbeat.manager.properties.SchedulerProperties;
|
||||
import org.apache.hertzbeat.manager.scheduler.ConsistentHash;
|
||||
import org.apache.hertzbeat.manager.scheduler.SchedulerProperties;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -33,8 +33,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
public class SchedulerConfig {
|
||||
|
||||
@Bean
|
||||
public ConsistentHashCollectorKeeper consistentHasInstance() {
|
||||
return new ConsistentHashCollectorKeeper();
|
||||
public ConsistentHash consistentHasInstance() {
|
||||
return new ConsistentHash();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.manager.properties;
|
||||
package org.apache.hertzbeat.manager.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
+18
-8
@@ -17,10 +17,14 @@
|
||||
|
||||
package org.apache.hertzbeat.manager.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import org.springframework.data.domain.Page;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
@@ -37,6 +41,7 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
@@ -49,7 +54,7 @@ public class StatusPageController {
|
||||
|
||||
@Autowired
|
||||
private StatusPageService statusPageService;
|
||||
|
||||
|
||||
@GetMapping("/org")
|
||||
@Operation(summary = "Query Status Page Organization")
|
||||
public ResponseEntity<Message<StatusPageOrg>> queryStatusPageOrg() {
|
||||
@@ -66,35 +71,35 @@ public class StatusPageController {
|
||||
StatusPageOrg org = statusPageService.saveStatusPageOrg(statusPageOrg);
|
||||
return ResponseEntity.ok(Message.success(org));
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/component")
|
||||
@Operation(summary = "Query Status Page Components")
|
||||
public ResponseEntity<Message<List<StatusPageComponent>>> queryStatusPageComponent() {
|
||||
List<StatusPageComponent> statusPageComponents = statusPageService.queryStatusPageComponents();
|
||||
return ResponseEntity.ok(Message.success(statusPageComponents));
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/component")
|
||||
@Operation(summary = "Save Status Page Component")
|
||||
public ResponseEntity<Message<Void>> newStatusPageComponent(@Valid @RequestBody StatusPageComponent statusPageComponent) {
|
||||
statusPageService.newStatusPageComponent(statusPageComponent);
|
||||
return ResponseEntity.ok(Message.success("Add success"));
|
||||
}
|
||||
|
||||
|
||||
@PutMapping("/component")
|
||||
@Operation(summary = "Update Status Page Component")
|
||||
public ResponseEntity<Message<Void>> updateStatusPageComponent(@Valid @RequestBody StatusPageComponent statusPageComponent) {
|
||||
statusPageService.updateStatusPageComponent(statusPageComponent);
|
||||
return ResponseEntity.ok(Message.success("Update success"));
|
||||
}
|
||||
|
||||
|
||||
@DeleteMapping("/component/{id}")
|
||||
@Operation(summary = "Delete Status Page Component")
|
||||
public ResponseEntity<Message<Void>> deleteStatusPageComponent(@PathVariable("id") final long id) {
|
||||
statusPageService.deleteStatusPageComponent(id);
|
||||
return ResponseEntity.ok(Message.success("Delete success"));
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/component/{id}")
|
||||
@Operation(summary = "Query Status Page Component")
|
||||
public ResponseEntity<Message<StatusPageComponent>> queryStatusPageComponent(@PathVariable("id") final long id) {
|
||||
@@ -132,8 +137,13 @@ public class StatusPageController {
|
||||
|
||||
@GetMapping("/incident")
|
||||
@Operation(summary = "Query Status Page Incidents")
|
||||
public ResponseEntity<Message<List<StatusPageIncident>>> queryStatusPageIncident() {
|
||||
List<StatusPageIncident> incidents = statusPageService.queryStatusPageIncidents();
|
||||
public ResponseEntity<Message<Page<StatusPageIncident>>> queryStatusPageIncident(
|
||||
@Parameter(description = "Search-Target", example = "x") @RequestParam(required = false) String search,
|
||||
@Parameter(description = "Start Time", example = "1756384301907") @RequestParam(required = false) Long startTime,
|
||||
@Parameter(description = "End Time", example = "1756384301907") @RequestParam(required = false) Long endTime,
|
||||
@Parameter(description = "List current page", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
|
||||
@Parameter(description = "Number of list pages", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
|
||||
Page<StatusPageIncident> incidents = statusPageService.queryStatusPageIncidents(search, startTime, endTime, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(incidents));
|
||||
}
|
||||
}
|
||||
|
||||
+15
-5
@@ -17,10 +17,14 @@
|
||||
|
||||
package org.apache.hertzbeat.manager.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import org.springframework.data.domain.Page;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
import org.apache.hertzbeat.common.entity.manager.StatusPageIncident;
|
||||
@@ -32,6 +36,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
@@ -44,7 +49,7 @@ public class StatusPagePublicController {
|
||||
|
||||
@Autowired
|
||||
private StatusPageService statusPageService;
|
||||
|
||||
|
||||
@GetMapping("/org")
|
||||
@Operation(summary = "Query Status Page Organization")
|
||||
public ResponseEntity<Message<StatusPageOrg>> queryStatusPageOrg() {
|
||||
@@ -54,14 +59,14 @@ public class StatusPagePublicController {
|
||||
}
|
||||
return ResponseEntity.ok(Message.success(statusPageOrg));
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/component")
|
||||
@Operation(summary = "Query Status Page Components")
|
||||
public ResponseEntity<Message<List<ComponentStatus>>> queryStatusPageComponent() {
|
||||
List<ComponentStatus> componentStatusList = statusPageService.queryComponentsStatus();
|
||||
return ResponseEntity.ok(Message.success(componentStatusList));
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/component/{id}")
|
||||
@Operation(summary = "Query Status Page Component")
|
||||
public ResponseEntity<Message<ComponentStatus>> queryStatusPageComponent(@PathVariable("id") final long id) {
|
||||
@@ -71,8 +76,13 @@ public class StatusPagePublicController {
|
||||
|
||||
@GetMapping("/incident")
|
||||
@Operation(summary = "Query Status Page Incidents")
|
||||
public ResponseEntity<Message<List<StatusPageIncident>>> queryStatusPageIncident() {
|
||||
List<StatusPageIncident> incidents = statusPageService.queryStatusPageIncidents();
|
||||
public ResponseEntity<Message<Page<StatusPageIncident>>> queryStatusPageIncident(
|
||||
@Parameter(description = "Search-Target", example = "x") @RequestParam(required = false) String search,
|
||||
@Parameter(description = "Start Time", example = "1756384301907") @RequestParam(required = false) Long startTime,
|
||||
@Parameter(description = "End Time", example = "1756384301907") @RequestParam(required = false) Long endTime,
|
||||
@Parameter(description = "List current page", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
|
||||
@Parameter(description = "Number of list pages", example = "10") @RequestParam(defaultValue = "10") int pageSize) {
|
||||
Page<StatusPageIncident> incidents = statusPageService.queryStatusPageIncidents(search, startTime, endTime, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(incidents));
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -19,6 +19,7 @@
|
||||
|
||||
package org.apache.hertzbeat.manager.nativex;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Set;
|
||||
import org.apache.sshd.common.channel.ChannelListener;
|
||||
import org.apache.sshd.common.forward.PortForwardingEventListener;
|
||||
@@ -27,6 +28,7 @@ import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory;
|
||||
import org.apache.sshd.common.session.SessionListener;
|
||||
import org.apache.sshd.common.util.security.bouncycastle.BouncyCastleSecurityProviderRegistrar;
|
||||
import org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderRegistrar;
|
||||
import org.springframework.aot.hint.ExecutableMode;
|
||||
import org.springframework.aot.hint.MemberCategory;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
@@ -58,4 +60,11 @@ public class HertzbeatRuntimeHintsRegistrar implements RuntimeHintsRegistrar {
|
||||
TypeReference.of(PortForwardingEventListener.class), TypeReference.of(SessionListener.class));
|
||||
}
|
||||
}
|
||||
|
||||
private void registerConstructor(RuntimeHints hints, Class<?> clazz) {
|
||||
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
|
||||
for (Constructor<?> declaredConstructor : declaredConstructors) {
|
||||
hints.reflection().registerConstructor(declaredConstructor, ExecutableMode.INVOKE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.manager.pojo;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.hertzbeat.common.constants.CollectorStatus;
|
||||
import org.apache.hertzbeat.manager.scheduler.AssignJobs;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Collector Node
|
||||
*/
|
||||
@Data
|
||||
public class CollectorNode {
|
||||
/**
|
||||
* Default number of VM nodes
|
||||
*/
|
||||
private static final byte VIRTUAL_NODE_DEFAULT_SIZE = 10;
|
||||
|
||||
/**
|
||||
* collector identity
|
||||
*/
|
||||
private final String identity;
|
||||
|
||||
/**
|
||||
* collector mode: public or private
|
||||
*/
|
||||
private String mode;
|
||||
|
||||
/**
|
||||
* ip
|
||||
*/
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* collector On-line time stamp
|
||||
*/
|
||||
private long uptime;
|
||||
|
||||
/**
|
||||
* collector's own performance service quality score 0 - 127
|
||||
* The number of virtual nodes will be calculated based on this service quality score
|
||||
*
|
||||
*/
|
||||
private Byte quality;
|
||||
|
||||
private CollectorStatus collectorStatus;
|
||||
|
||||
/**
|
||||
* use this collector's collect job ID list
|
||||
* jobId,jobVersion
|
||||
*/
|
||||
private AssignJobs assignJobs;
|
||||
|
||||
/**
|
||||
* the collection task ID list mapped by each virtual node corresponding to this node
|
||||
* Long[] [0]-jobId, [1]-dispatchHash
|
||||
*/
|
||||
private Map<Integer, Set<Long[]>> virtualNodeMap;
|
||||
|
||||
public CollectorNode(String identity, String mode, String ip, long uptime, Byte quality) {
|
||||
this.identity = identity;
|
||||
this.mode = mode;
|
||||
this.ip = ip;
|
||||
this.uptime = uptime;
|
||||
this.quality = quality;
|
||||
assignJobs = new AssignJobs();
|
||||
virtualNodeMap = new ConcurrentHashMap<>(VIRTUAL_NODE_DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
public synchronized void addJob(Integer virtualNodeKey, Integer dispatchHash, Long jobId, boolean isFlushed) {
|
||||
if (virtualNodeMap == null) {
|
||||
virtualNodeMap = new ConcurrentHashMap<>(VIRTUAL_NODE_DEFAULT_SIZE);
|
||||
}
|
||||
if (assignJobs == null) {
|
||||
assignJobs = new AssignJobs();
|
||||
}
|
||||
Set<Long[]> virtualNodeJob = virtualNodeMap.computeIfAbsent(virtualNodeKey, k -> ConcurrentHashMap.newKeySet(16));
|
||||
virtualNodeJob.add(new Long[]{jobId, dispatchHash.longValue()});
|
||||
if (isFlushed) {
|
||||
assignJobs.addAssignJob(jobId);
|
||||
} else {
|
||||
assignJobs.addAddingJob(jobId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the collection task routed by the specified virtual node according to virtualNodeKey
|
||||
* @param virtualNodeKey virtualNodeKey
|
||||
* @return collection task
|
||||
*/
|
||||
public Set<Long[]> clearVirtualNodeJobs(Integer virtualNodeKey) {
|
||||
if (virtualNodeMap == null || virtualNodeMap.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Set<Long[]> virtualNodeJobs = virtualNodeMap.remove(virtualNodeKey);
|
||||
virtualNodeMap.put(virtualNodeKey, ConcurrentHashMap.newKeySet(16));
|
||||
return virtualNodeJobs;
|
||||
}
|
||||
|
||||
public void addVirtualNodeJobs(Integer virtualHashKey, Set<Long[]> reDispatchJobs) {
|
||||
if (reDispatchJobs == null) {
|
||||
return;
|
||||
}
|
||||
if (virtualNodeMap == null) {
|
||||
virtualNodeMap = new ConcurrentHashMap<>(16);
|
||||
}
|
||||
virtualNodeMap.computeIfPresent(virtualHashKey, (k, v) -> {
|
||||
reDispatchJobs.addAll(v);
|
||||
return v;
|
||||
});
|
||||
virtualNodeMap.put(virtualHashKey, reDispatchJobs);
|
||||
}
|
||||
|
||||
public void removeVirtualNodeJob(Long jobId) {
|
||||
if (jobId == null || virtualNodeMap == null) {
|
||||
return;
|
||||
}
|
||||
for (Set<Long[]> jobSet : virtualNodeMap.values()) {
|
||||
Optional<Long[]> optional = jobSet.stream().filter(item -> Objects.equals(item[0], jobId)).findFirst();
|
||||
if (optional.isPresent()) {
|
||||
jobSet.remove(optional.get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (assignJobs != null) {
|
||||
assignJobs.clear();
|
||||
}
|
||||
if (virtualNodeMap != null) {
|
||||
virtualNodeMap.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.manager.pojo;
|
||||
|
||||
import org.apache.hertzbeat.common.entity.job.Job;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Utility class for caching {@link Job} objects in memory.
|
||||
* <p>
|
||||
* This class provides static methods to store, retrieve, and remove {@code Job} instances
|
||||
* using a thread-safe {@link ConcurrentHashMap}. It is intended to be used as a simple
|
||||
* in-memory cache for job data within the manager component.
|
||||
* <p>
|
||||
* Usage:
|
||||
* <pre>
|
||||
* JobCache.put(job);
|
||||
* Job job = JobCache.get(jobId);
|
||||
* JobCache.remove(jobId);
|
||||
* </pre>
|
||||
*/
|
||||
public class JobCache {
|
||||
private static final Map<Long, Job> jobContentCache = new ConcurrentHashMap<>(16);
|
||||
|
||||
public static Job get(Long jobId) {
|
||||
return jobContentCache.get(jobId);
|
||||
}
|
||||
|
||||
public static void put(Job job) {
|
||||
jobContentCache.put(job.getId(), job);
|
||||
}
|
||||
|
||||
public static void remove(Long jobId) {
|
||||
jobContentCache.remove(jobId);
|
||||
}
|
||||
}
|
||||
+4
-5
@@ -29,7 +29,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
@Slf4j
|
||||
@Data
|
||||
public class AssignJobs {
|
||||
private static final Integer DEFAULT_CAPACITY = 16;
|
||||
|
||||
/**
|
||||
* current assign jobIds
|
||||
@@ -52,10 +51,10 @@ public class AssignJobs {
|
||||
private Set<Long> pinnedJobs;
|
||||
|
||||
public AssignJobs() {
|
||||
jobs = ConcurrentHashMap.newKeySet(DEFAULT_CAPACITY);
|
||||
addingJobs = ConcurrentHashMap.newKeySet(DEFAULT_CAPACITY);
|
||||
removingJobs = ConcurrentHashMap.newKeySet(DEFAULT_CAPACITY);
|
||||
pinnedJobs = ConcurrentHashMap.newKeySet(DEFAULT_CAPACITY);
|
||||
jobs = ConcurrentHashMap.newKeySet(16);
|
||||
addingJobs = ConcurrentHashMap.newKeySet(16);
|
||||
removingJobs = ConcurrentHashMap.newKeySet(16);
|
||||
pinnedJobs = ConcurrentHashMap.newKeySet(16);
|
||||
}
|
||||
|
||||
public void addAssignJob(Long jobId) {
|
||||
|
||||
+15
-1
@@ -24,8 +24,15 @@ import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
/**
|
||||
* Collection job management provides api interface
|
||||
*/
|
||||
public interface JobOperation {
|
||||
public interface CollectJobScheduling {
|
||||
|
||||
/**
|
||||
* Execute a one-time collection task and get the collected data response
|
||||
* @param job Collect task details
|
||||
* @return Collection results
|
||||
*/
|
||||
List<CollectRep.MetricsData> collectSyncJobData(Job job);
|
||||
|
||||
/**
|
||||
* Execute a one-time collection task and get the collected data response
|
||||
* @param job Collect task details
|
||||
@@ -42,6 +49,13 @@ public interface JobOperation {
|
||||
*/
|
||||
long addAsyncCollectJob(Job job, String collector);
|
||||
|
||||
/**
|
||||
* Update the periodic asynchronous collection tasks that have been delivered
|
||||
* @param modifyJob Collect task details
|
||||
* @return long Job ID
|
||||
*/
|
||||
long updateAsyncCollectJob(Job modifyJob);
|
||||
|
||||
/**
|
||||
* Update the periodic asynchronous collection tasks that have been delivered
|
||||
* @param modifyJob Collect task details
|
||||
+158
-97
@@ -29,14 +29,11 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectJobService;
|
||||
import org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectResponseEventListener;
|
||||
import org.apache.hertzbeat.common.constants.CollectorStatus;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.dto.CollectorInfo;
|
||||
import org.apache.hertzbeat.common.entity.dto.ServerInfo;
|
||||
@@ -56,10 +53,6 @@ import org.apache.hertzbeat.manager.dao.CollectorDao;
|
||||
import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
|
||||
import org.apache.hertzbeat.manager.dao.MonitorDao;
|
||||
import org.apache.hertzbeat.manager.dao.ParamDao;
|
||||
import org.apache.hertzbeat.manager.pojo.CollectorNode;
|
||||
import org.apache.hertzbeat.manager.pojo.JobCache;
|
||||
import org.apache.hertzbeat.manager.properties.SchedulerProperties;
|
||||
import org.apache.hertzbeat.manager.scheduler.collector.CollectorKeeper;
|
||||
import org.apache.hertzbeat.manager.scheduler.netty.ManageServer;
|
||||
import org.apache.hertzbeat.manager.service.AppService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -72,7 +65,9 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
@AutoConfigureAfter(value = {SchedulerProperties.class})
|
||||
@Slf4j
|
||||
public class CollectorJobScheduler implements CollectorOperation, CollectorOperationReceiver, JobOperation {
|
||||
public class CollectorJobScheduler implements CollectorScheduling, CollectJobScheduling {
|
||||
|
||||
private final Map<Long, Job> jobContentCache = new ConcurrentHashMap<>(16);
|
||||
|
||||
private final Map<Long, CollectResponseEventListener> eventListeners = new ConcurrentHashMap<>(16);
|
||||
|
||||
@@ -82,6 +77,9 @@ public class CollectorJobScheduler implements CollectorOperation, CollectorOpera
|
||||
@Autowired
|
||||
private CollectorMonitorBindDao collectorMonitorBindDao;
|
||||
|
||||
@Autowired
|
||||
private ConsistentHash consistentHash;
|
||||
|
||||
@Autowired
|
||||
private CollectJobService collectJobService;
|
||||
|
||||
@@ -94,10 +92,6 @@ public class CollectorJobScheduler implements CollectorOperation, CollectorOpera
|
||||
@Autowired
|
||||
private ParamDao paramDao;
|
||||
|
||||
@Autowired
|
||||
private CollectorKeeper collectorKeeper;
|
||||
|
||||
@Setter
|
||||
private ManageServer manageServer;
|
||||
|
||||
@Override
|
||||
@@ -131,18 +125,15 @@ public class CollectorJobScheduler implements CollectorOperation, CollectorOpera
|
||||
.build();
|
||||
}
|
||||
collectorDao.save(collector);
|
||||
|
||||
CollectorNode node = new CollectorNode(identity, collector.getMode(), collector.getIp(), System.currentTimeMillis(), null);
|
||||
collectorKeeper.addNode(node);
|
||||
collectorKeeper.changeStatus(identity, CollectorStatus.ONLINE);
|
||||
collectorKeeper.rebalanceJobs(this::doRebalanceJobs);
|
||||
|
||||
ConsistentHash.Node node = new ConsistentHash.Node(identity, collector.getMode(),
|
||||
collector.getIp(), System.currentTimeMillis(), null);
|
||||
consistentHash.addNode(node);
|
||||
reBalanceCollectorAssignJobs();
|
||||
// Read database The fixed collection tasks at this collector are delivered
|
||||
List<CollectorMonitorBind> binds = collectorMonitorBindDao.findCollectorMonitorBindsByCollector(identity);
|
||||
if (CollectionUtils.isEmpty(binds)){
|
||||
return;
|
||||
}
|
||||
|
||||
List<Monitor> monitors = monitorDao.findMonitorsByIdIn(binds.stream().map(CollectorMonitorBind::getMonitorId).collect(Collectors.toSet()));
|
||||
for (Monitor monitor : monitors) {
|
||||
if (Objects.isNull(monitor) || monitor.getStatus() == CommonConstants.MONITOR_PAUSED_CODE) {
|
||||
@@ -198,12 +189,58 @@ public class CollectorJobScheduler implements CollectorOperation, CollectorOpera
|
||||
}
|
||||
collector.setStatus(CommonConstants.COLLECTOR_STATUS_OFFLINE);
|
||||
collectorDao.save(collector);
|
||||
|
||||
collectorKeeper.changeStatus(identity, CollectorStatus.OFFLINE);
|
||||
collectorKeeper.rebalanceJobs(this::doRebalanceJobs);
|
||||
consistentHash.removeNode(identity);
|
||||
reBalanceCollectorAssignJobs();
|
||||
log.info("the collector: {} go offline success.", identity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reBalanceCollectorAssignJobs() {
|
||||
consistentHash.getAllNodes().entrySet().parallelStream().forEach(entry -> {
|
||||
String collectorName = entry.getKey();
|
||||
AssignJobs assignJobs = entry.getValue().getAssignJobs();
|
||||
if (StringUtils.isBlank(collectorName) || Objects.isNull(assignJobs)) {
|
||||
return;
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(assignJobs.getAddingJobs())) {
|
||||
Set<Long> addedJobIds = new HashSet<>(8);
|
||||
for (Long addingJobId : assignJobs.getAddingJobs()) {
|
||||
Job job = jobContentCache.get(addingJobId);
|
||||
if (Objects.isNull(job)) {
|
||||
log.error("assigning job {} content is null.", addingJobId);
|
||||
continue;
|
||||
}
|
||||
addedJobIds.add(addingJobId);
|
||||
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorName)) {
|
||||
collectJobService.addAsyncCollectJob(job);
|
||||
} else {
|
||||
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
|
||||
.setDirection(ClusterMsg.Direction.REQUEST)
|
||||
.setType(ClusterMsg.MessageType.ISSUE_CYCLIC_TASK)
|
||||
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(job)))
|
||||
.build();
|
||||
this.manageServer.sendMsg(collectorName, message);
|
||||
}
|
||||
}
|
||||
assignJobs.addAssignJobs(addedJobIds);
|
||||
assignJobs.removeAddingJobs(addedJobIds);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(assignJobs.getRemovingJobs())) {
|
||||
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorName)) {
|
||||
assignJobs.getRemovingJobs().forEach(jobId -> collectJobService.cancelAsyncCollectJob(jobId));
|
||||
} else {
|
||||
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
|
||||
.setDirection(ClusterMsg.Direction.REQUEST)
|
||||
.setType(ClusterMsg.MessageType.DELETE_CYCLIC_TASK)
|
||||
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(assignJobs.getRemovingJobs())))
|
||||
.build();
|
||||
this.manageServer.sendMsg(collectorName, message);
|
||||
}
|
||||
assignJobs.clearRemovingJobs();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offlineCollector(String identity) {
|
||||
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
|
||||
@@ -248,11 +285,56 @@ public class CollectorJobScheduler implements CollectorOperation, CollectorOpera
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CollectRep.MetricsData> collectSyncJobData(Job job) {
|
||||
// todo dispatchKey ip+port or id
|
||||
String dispatchKey = String.valueOf(job.getMonitorId());
|
||||
ConsistentHash.Node node = consistentHash.preDispatchJob(dispatchKey);
|
||||
if (Objects.isNull(node)) {
|
||||
log.error("there is no collector online to assign job.");
|
||||
CollectRep.MetricsData metricsData = CollectRep.MetricsData.newBuilder()
|
||||
.setCode(CollectRep.Code.FAIL)
|
||||
.setMsg("no collector online to assign job")
|
||||
.build();
|
||||
return Collections.singletonList(metricsData);
|
||||
}
|
||||
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(node.getIdentity())) {
|
||||
return collectJobService.collectSyncJobData(job);
|
||||
} else {
|
||||
List<CollectRep.MetricsData> metricsData = new LinkedList<>();
|
||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
|
||||
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
|
||||
.setType(ClusterMsg.MessageType.ISSUE_ONE_TIME_TASK)
|
||||
.setDirection(ClusterMsg.Direction.REQUEST)
|
||||
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(job)))
|
||||
.build();
|
||||
boolean result = this.manageServer.sendMsg(node.getIdentity(), message);
|
||||
|
||||
if (result) {
|
||||
CollectResponseEventListener listener = new CollectResponseEventListener() {
|
||||
@Override
|
||||
public void response(List<CollectRep.MetricsData> responseMetrics) {
|
||||
if (responseMetrics != null) {
|
||||
metricsData.addAll(responseMetrics);
|
||||
}
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
};
|
||||
eventListeners.put(job.getMonitorId(), listener);
|
||||
}
|
||||
try {
|
||||
countDownLatch.await(120, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
log.info("The sync task runs for 120 seconds with no response and returns");
|
||||
}
|
||||
return metricsData;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CollectRep.MetricsData> collectSyncJobData(Job job, String collector) {
|
||||
CollectorNode node = StringUtils.isBlank(collector)
|
||||
? collectorKeeper.determineNode(job.getMonitorId())
|
||||
: collectorKeeper.getNode(collector);
|
||||
ConsistentHash.Node node = consistentHash.getNode(collector);
|
||||
if (Objects.isNull(node)) {
|
||||
log.error("there is no collector online to assign job.");
|
||||
CollectRep.MetricsData metricsData = CollectRep.MetricsData.newBuilder()
|
||||
@@ -261,11 +343,9 @@ public class CollectorJobScheduler implements CollectorOperation, CollectorOpera
|
||||
.build();
|
||||
return Collections.singletonList(metricsData);
|
||||
}
|
||||
|
||||
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(node.getIdentity())) {
|
||||
return collectJobService.collectSyncJobData(job);
|
||||
}
|
||||
|
||||
List<CollectRep.MetricsData> metricsData = new LinkedList<>();
|
||||
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
|
||||
.setType(ClusterMsg.MessageType.ISSUE_ONE_TIME_TASK)
|
||||
@@ -298,10 +378,25 @@ public class CollectorJobScheduler implements CollectorOperation, CollectorOpera
|
||||
public long addAsyncCollectJob(Job job, String collector) {
|
||||
long jobId = SnowFlakeIdGenerator.generateId();
|
||||
job.setId(jobId);
|
||||
|
||||
CollectorNode collectorNode = collectorKeeper.addJob(job, collector);
|
||||
|
||||
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorNode.getIdentity())) {
|
||||
jobContentCache.put(jobId, job);
|
||||
ConsistentHash.Node node;
|
||||
if (StringUtils.isBlank(collector)) {
|
||||
// todo dispatchKey ip+port or id
|
||||
String dispatchKey = String.valueOf(job.getMonitorId());
|
||||
node = consistentHash.dispatchJob(dispatchKey, jobId);
|
||||
if (node == null) {
|
||||
log.error("there is no collector online to assign job.");
|
||||
return jobId;
|
||||
}
|
||||
} else {
|
||||
node = consistentHash.getNode(collector);
|
||||
if (node == null) {
|
||||
log.error("there is no collector name: {} online to assign job.", collector);
|
||||
return jobId;
|
||||
}
|
||||
node.getAssignJobs().addPinnedJob(jobId);
|
||||
}
|
||||
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(node.getIdentity())) {
|
||||
collectJobService.addAsyncCollectJob(job);
|
||||
} else {
|
||||
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
|
||||
@@ -309,16 +404,27 @@ public class CollectorJobScheduler implements CollectorOperation, CollectorOpera
|
||||
.setDirection(ClusterMsg.Direction.REQUEST)
|
||||
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(job)))
|
||||
.build();
|
||||
this.manageServer.sendMsg(collectorNode.getIdentity(), message);
|
||||
this.manageServer.sendMsg(node.getIdentity(), message);
|
||||
}
|
||||
return jobId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long updateAsyncCollectJob(Job modifyJob) {
|
||||
// delete and add
|
||||
long preJobId = modifyJob.getId();
|
||||
long newJobId = addAsyncCollectJob(modifyJob, null);
|
||||
jobContentCache.remove(preJobId);
|
||||
cancelAsyncCollectJob(preJobId);
|
||||
return newJobId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long updateAsyncCollectJob(Job modifyJob, String collector) {
|
||||
// delete and add
|
||||
long preJobId = modifyJob.getId();
|
||||
long newJobId = addAsyncCollectJob(modifyJob, collector);
|
||||
jobContentCache.remove(preJobId);
|
||||
cancelAsyncCollectJob(preJobId);
|
||||
return newJobId;
|
||||
}
|
||||
@@ -328,21 +434,24 @@ public class CollectorJobScheduler implements CollectorOperation, CollectorOpera
|
||||
if (jobId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CollectorNode collectorNode = collectorKeeper.removeJob(jobId);
|
||||
if (collectorNode == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorNode.getIdentity())) {
|
||||
collectJobService.cancelAsyncCollectJob(jobId);
|
||||
} else {
|
||||
ClusterMsg.Message deleteMessage = ClusterMsg.Message.newBuilder()
|
||||
.setType(ClusterMsg.MessageType.DELETE_CYCLIC_TASK)
|
||||
.setDirection(ClusterMsg.Direction.REQUEST)
|
||||
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(List.of(jobId))))
|
||||
.build();
|
||||
this.manageServer.sendMsg(collectorNode.getIdentity(), deleteMessage);
|
||||
jobContentCache.remove(jobId);
|
||||
for (ConsistentHash.Node node : consistentHash.getAllNodes().values()) {
|
||||
AssignJobs assignJobs = node.getAssignJobs();
|
||||
if (assignJobs.getPinnedJobs().remove(jobId)
|
||||
|| assignJobs.getJobs().remove(jobId) || assignJobs.getAddingJobs().remove(jobId)) {
|
||||
node.removeVirtualNodeJob(jobId);
|
||||
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(node.getIdentity())) {
|
||||
collectJobService.cancelAsyncCollectJob(jobId);
|
||||
} else {
|
||||
ClusterMsg.Message deleteMessage = ClusterMsg.Message.newBuilder()
|
||||
.setType(ClusterMsg.MessageType.DELETE_CYCLIC_TASK)
|
||||
.setDirection(ClusterMsg.Direction.REQUEST)
|
||||
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(List.of(jobId))))
|
||||
.build();
|
||||
this.manageServer.sendMsg(node.getIdentity(), deleteMessage);
|
||||
}
|
||||
// break; if is there jod exist in multi collector?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,55 +468,7 @@ public class CollectorJobScheduler implements CollectorOperation, CollectorOpera
|
||||
}
|
||||
}
|
||||
|
||||
private void doRebalanceJobs(AssignJobs assignJobs, String collectorName) {
|
||||
handleAddingJobs(assignJobs, collectorName);
|
||||
|
||||
handleRemovingJobs(assignJobs, collectorName);
|
||||
}
|
||||
|
||||
private void handleAddingJobs(AssignJobs assignJobs, String collectorName) {
|
||||
if (CollectionUtils.isEmpty(assignJobs.getAddingJobs())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Long> addedJobIds = new HashSet<>(8);
|
||||
for (Long addingJobId : assignJobs.getAddingJobs()) {
|
||||
Job job = JobCache.get(addingJobId);
|
||||
if (Objects.isNull(job)) {
|
||||
log.error("assigning job {} content is null.", addingJobId);
|
||||
continue;
|
||||
}
|
||||
addedJobIds.add(addingJobId);
|
||||
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorName)) {
|
||||
collectJobService.addAsyncCollectJob(job);
|
||||
} else {
|
||||
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
|
||||
.setDirection(ClusterMsg.Direction.REQUEST)
|
||||
.setType(ClusterMsg.MessageType.ISSUE_CYCLIC_TASK)
|
||||
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(job)))
|
||||
.build();
|
||||
this.manageServer.sendMsg(collectorName, message);
|
||||
}
|
||||
}
|
||||
assignJobs.addAssignJobs(addedJobIds);
|
||||
assignJobs.removeAddingJobs(addedJobIds);
|
||||
}
|
||||
|
||||
private void handleRemovingJobs(AssignJobs assignJobs, String collectorName) {
|
||||
if (CollectionUtils.isEmpty(assignJobs.getRemovingJobs())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CommonConstants.MAIN_COLLECTOR_NODE.equals(collectorName)) {
|
||||
assignJobs.getRemovingJobs().forEach(jobId -> collectJobService.cancelAsyncCollectJob(jobId));
|
||||
} else {
|
||||
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
|
||||
.setDirection(ClusterMsg.Direction.REQUEST)
|
||||
.setType(ClusterMsg.MessageType.DELETE_CYCLIC_TASK)
|
||||
.setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(assignJobs.getRemovingJobs())))
|
||||
.build();
|
||||
this.manageServer.sendMsg(collectorName, message);
|
||||
}
|
||||
assignJobs.clearRemovingJobs();
|
||||
public void setManageServer(ManageServer manageServer) {
|
||||
this.manageServer = manageServer;
|
||||
}
|
||||
}
|
||||
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.manager.scheduler;
|
||||
|
||||
/**
|
||||
* Interface defining operations for managing collector.
|
||||
* Implementations of this interface provide functionality to control the operation state
|
||||
* of collectors in the system.
|
||||
*/
|
||||
public interface CollectorOperation {
|
||||
|
||||
/**
|
||||
* Takes a collector offline by stopping its collection operations.
|
||||
* This is typically used for maintenance, updates, or when the collector is no longer needed.
|
||||
*
|
||||
* @param identity The unique identifier of the collector to be taken offline
|
||||
* @return true if the collector was successfully taken offline,
|
||||
* false if the operation failed or the collector wasn't found
|
||||
*/
|
||||
boolean offlineCollector(String identity);
|
||||
|
||||
/**
|
||||
* Brings a collector online by starting its collection operations.
|
||||
* This is used to activate a collector that was previously offline.
|
||||
*
|
||||
* @param identity The unique identifier of the collector to be brought online
|
||||
* @return true if the collector was successfully brought online,
|
||||
* false if the operation failed or the collector wasn't found
|
||||
*/
|
||||
boolean onlineCollector(String identity);
|
||||
}
|
||||
+28
-14
@@ -20,25 +20,39 @@ package org.apache.hertzbeat.manager.scheduler;
|
||||
import org.apache.hertzbeat.common.entity.dto.CollectorInfo;
|
||||
|
||||
/**
|
||||
* Interface defining operations for receiving collector status updates from remote collectors.
|
||||
* This interface serves as a callback mechanism for handling collector online/offline events.
|
||||
* slave collector service
|
||||
*/
|
||||
public interface CollectorOperationReceiver {
|
||||
public interface CollectorScheduling {
|
||||
|
||||
/**
|
||||
* Notifies the system when a collector comes online.
|
||||
* This method should be called when a collector establishes connection and becomes available.
|
||||
*
|
||||
* @param identity The unique identifier of the collector (e.g., hostname, IP, or custom ID)
|
||||
* @param collectorInfo Detailed information about the collector including capabilities,
|
||||
* configuration, and status metadata
|
||||
* register collector go online
|
||||
* @param identity collector identity name
|
||||
* @param collectorInfo collector information
|
||||
*/
|
||||
void collectorGoOnline(String identity, CollectorInfo collectorInfo);
|
||||
|
||||
|
||||
/**
|
||||
* Notifies the system when a collector goes offline.
|
||||
* This method should be called when a collector disconnects or becomes unavailable.
|
||||
*
|
||||
* @param identity The unique identifier of the collector to be marked as offline
|
||||
* register collector go offline
|
||||
* @param identity collector identity name
|
||||
*/
|
||||
void collectorGoOffline(String identity);
|
||||
|
||||
/**
|
||||
* reBalance dispatch monitoring jobs when collector go online or offline or timeout
|
||||
*/
|
||||
void reBalanceCollectorAssignJobs();
|
||||
|
||||
/**
|
||||
* offline collector(stop collector collect operation)
|
||||
* @param identity collector identity name
|
||||
* @return true/false
|
||||
*/
|
||||
boolean offlineCollector(String identity);
|
||||
|
||||
/**
|
||||
* online collector(start collector collect operation)
|
||||
* @param identity collector identity name
|
||||
* @return true/false
|
||||
*/
|
||||
boolean onlineCollector(String identity);
|
||||
}
|
||||
+232
-142
@@ -23,149 +23,46 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.common.constants.CollectorStatus;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Job;
|
||||
import org.apache.hertzbeat.manager.pojo.CollectorNode;
|
||||
import org.apache.hertzbeat.manager.pojo.JobCache;
|
||||
import org.apache.hertzbeat.manager.scheduler.collector.CollectorKeeper;
|
||||
|
||||
/**
|
||||
* Collector and task mapping scheduling implemented by consistent hashing
|
||||
*/
|
||||
@Slf4j
|
||||
public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
public class ConsistentHash {
|
||||
|
||||
/**
|
||||
* consistent hash circle
|
||||
*/
|
||||
private final ConcurrentTreeMap<Integer, CollectorNode> hashCircle = new ConcurrentTreeMap<>();
|
||||
private final ConcurrentTreeMap<Integer, Node> hashCircle;
|
||||
|
||||
/**
|
||||
* collector node
|
||||
*/
|
||||
private final Map<String, CollectorNode> existNodeMap = new ConcurrentHashMap<>(16);
|
||||
private final Map<String, Node> existNodeMap;
|
||||
|
||||
/**
|
||||
* not dispatched job cache, in order to obtain the cached collection scheduling task
|
||||
* not dispatched job cache
|
||||
*/
|
||||
@Getter
|
||||
private final List<DispatchJob> dispatchJobCache = Collections.synchronizedList(new LinkedList<>());
|
||||
private final List<DispatchJob> dispatchJobCache;
|
||||
|
||||
/**
|
||||
* Default number of VM nodes
|
||||
*/
|
||||
private static final byte VIRTUAL_NODE_DEFAULT_SIZE = 10;
|
||||
|
||||
/**
|
||||
* add collector node
|
||||
* @param newNode node
|
||||
*/
|
||||
@Override
|
||||
public void addNode(CollectorNode newNode) {
|
||||
// when mode is cluster public, need reBalance dispatch jobs. else not when is cloud-edge private
|
||||
if (!CommonConstants.MODE_PRIVATE.equals(newNode.getMode())) {
|
||||
byte virtualNodeNum = newNode.getQuality() == null ? VIRTUAL_NODE_DEFAULT_SIZE : newNode.getQuality();
|
||||
for (byte i = 0; i < virtualNodeNum; i++) {
|
||||
addVirtualNode(newNode, newNode.getIdentity() + i);
|
||||
}
|
||||
}
|
||||
existNodeMap.put(newNode.getIdentity(), newNode);
|
||||
dispatchJobInCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectorNode addJob(Job job, String collectorId) {
|
||||
JobCache.put(job);
|
||||
CollectorNode collectorNode;
|
||||
|
||||
if (StringUtils.isBlank(collectorId)) {
|
||||
// todo dispatchKey ip+port or id
|
||||
String dispatchKey = String.valueOf(job.getMonitorId());
|
||||
collectorNode = this.dispatchJob(dispatchKey, job.getId());
|
||||
if (collectorNode == null) {
|
||||
log.error("there is no collector online to assign job.");
|
||||
}
|
||||
} else {
|
||||
collectorNode = getNode(collectorId);
|
||||
if (collectorNode == null) {
|
||||
log.error("there is no collector name: {} online to assign job.", collectorId);
|
||||
return null;
|
||||
}
|
||||
collectorNode.getAssignJobs().addPinnedJob(job.getId());
|
||||
}
|
||||
|
||||
return collectorNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* get node
|
||||
* @param collectorName collector name
|
||||
* @return node
|
||||
*/
|
||||
@Override
|
||||
public CollectorNode getNode(String collectorName) {
|
||||
return existNodeMap.get(collectorName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectorNode determineNode(Long jobId) {
|
||||
String dispatchKey = String.valueOf(jobId);
|
||||
if (dispatchKey == null || StringUtils.isBlank(dispatchKey)) {
|
||||
log.error("The dispatch key can not null.");
|
||||
return null;
|
||||
}
|
||||
int dispatchHash = hash(dispatchKey);
|
||||
return preDispatchJob(dispatchHash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeStatus(String collectorId, CollectorStatus collectorStatus) {
|
||||
switch (collectorStatus) {
|
||||
case ONLINE -> this.getNode(collectorId).setCollectorStatus(collectorStatus);
|
||||
case OFFLINE -> this.removeNode(collectorId);
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rebalanceJobs(BiConsumer<AssignJobs, String> assignJobCollectorConsumer) {
|
||||
existNodeMap.entrySet().parallelStream().forEach(entry -> {
|
||||
String collectorName = entry.getKey();
|
||||
AssignJobs assignJobs = entry.getValue().getAssignJobs();
|
||||
if (StringUtils.isBlank(collectorName) || Objects.isNull(assignJobs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
assignJobCollectorConsumer.accept(assignJobs, collectorName);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectorNode removeJob(Long jobId) {
|
||||
JobCache.remove(jobId);
|
||||
|
||||
for (CollectorNode node : existNodeMap.values()) {
|
||||
AssignJobs assignJobs = node.getAssignJobs();
|
||||
if (assignJobs.getPinnedJobs().remove(jobId)
|
||||
|| assignJobs.getJobs().remove(jobId) || assignJobs.getAddingJobs().remove(jobId)) {
|
||||
node.removeVirtualNodeJob(jobId);
|
||||
|
||||
return node;
|
||||
// break; if is there jod exist in multi collector?
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
public ConsistentHash() {
|
||||
hashCircle = new ConcurrentTreeMap<>();
|
||||
existNodeMap = new ConcurrentHashMap<>(16);
|
||||
dispatchJobCache = Collections.synchronizedList(new LinkedList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,15 +70,15 @@ public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
* @param newNode node
|
||||
* @param identity virtual node identity
|
||||
*/
|
||||
private synchronized void addVirtualNode(CollectorNode newNode, String identity){
|
||||
public synchronized void addVirtualNode(Node newNode, String identity){
|
||||
int virtualHashKey = hash(identity);
|
||||
hashCircle.put(virtualHashKey, newNode);
|
||||
newNode.addVirtualNodeJobs(virtualHashKey, ConcurrentHashMap.newKeySet(16));
|
||||
Map.Entry<Integer, CollectorNode> higherVirtualNode = hashCircle.higherOrFirstEntry(virtualHashKey);
|
||||
Map.Entry<Integer, Node> higherVirtualNode = hashCircle.higherOrFirstEntry(virtualHashKey);
|
||||
// Reassign tasks that are routed to the higherVirtualNode virtual node
|
||||
// Tasks are either on the original virtual node or on the new virtual node
|
||||
Integer higherVirtualNodeKey = higherVirtualNode.getKey();
|
||||
CollectorNode higherNode = higherVirtualNode.getValue();
|
||||
Node higherNode = higherVirtualNode.getValue();
|
||||
Set<Long[]> dispatchJobs = higherNode.clearVirtualNodeJobs(higherVirtualNodeKey);
|
||||
if (dispatchJobs != null && !dispatchJobs.isEmpty()) {
|
||||
Set<Long[]> reDispatchJobs = ConcurrentHashMap.newKeySet(dispatchJobs.size());
|
||||
@@ -194,37 +91,53 @@ public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
higherNode.getVirtualNodeMap().put(higherVirtualNodeKey, dispatchJobs);
|
||||
higherNode.virtualNodeMap.put(higherVirtualNodeKey, dispatchJobs);
|
||||
Set<Long> jobIds = reDispatchJobs.stream().map(item -> item[0]).collect(Collectors.toSet());
|
||||
newNode.addVirtualNodeJobs(virtualHashKey, reDispatchJobs);
|
||||
if (higherNode != newNode) {
|
||||
higherNode.getAssignJobs().removeAssignJobs(jobIds);
|
||||
higherNode.getAssignJobs().addRemovingJobs(jobIds);
|
||||
newNode.getAssignJobs().addAddingJobs(jobIds);
|
||||
higherNode.assignJobs.removeAssignJobs(jobIds);
|
||||
higherNode.assignJobs.addRemovingJobs(jobIds);
|
||||
newNode.assignJobs.addAddingJobs(jobIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add collector node
|
||||
* @param newNode node
|
||||
*/
|
||||
public void addNode(Node newNode) {
|
||||
// when mode is cluster public, need reBalance dispatch jobs. else not when is cloud-edge private
|
||||
if (!CommonConstants.MODE_PRIVATE.equals(newNode.mode)) {
|
||||
byte virtualNodeNum = newNode.quality == null ? VIRTUAL_NODE_DEFAULT_SIZE : newNode.quality;
|
||||
for (byte i = 0; i < virtualNodeNum; i++) {
|
||||
addVirtualNode(newNode, newNode.identity + i);
|
||||
}
|
||||
}
|
||||
existNodeMap.put(newNode.identity, newNode);
|
||||
dispatchJobInCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* remove virtual node
|
||||
* @param deletedNode node
|
||||
* @param virtualNodeHash virtual node hash key
|
||||
*/
|
||||
private synchronized void removeVirtualNode(CollectorNode deletedNode, Integer virtualNodeHash) {
|
||||
Set<Long[]> removeJobHashSet = deletedNode.getVirtualNodeMap().get(virtualNodeHash);
|
||||
public synchronized void removeVirtualNode(Node deletedNode, Integer virtualNodeHash) {
|
||||
Set<Long[]> removeJobHashSet = deletedNode.virtualNodeMap.get(virtualNodeHash);
|
||||
// Migrate the virtualNodeEntry collection task to the nearest virtual node that is larger than it
|
||||
hashCircle.remove(virtualNodeHash);
|
||||
if (removeJobHashSet == null || removeJobHashSet.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Map.Entry<Integer, CollectorNode> higherVirtualEntry = hashCircle.higherOrFirstEntry(virtualNodeHash);
|
||||
Map.Entry<Integer, Node> higherVirtualEntry = hashCircle.higherOrFirstEntry(virtualNodeHash);
|
||||
if (higherVirtualEntry == null || higherVirtualEntry.getValue() == deletedNode) {
|
||||
higherVirtualEntry = null;
|
||||
}
|
||||
// jobId
|
||||
Set<Long> removeJobIds = removeJobHashSet.stream().map(item -> item[0]).collect(Collectors.toSet());
|
||||
deletedNode.getAssignJobs().removeAssignJobs(removeJobIds);
|
||||
deletedNode.getAssignJobs().addRemovingJobs(removeJobIds);
|
||||
deletedNode.assignJobs.removeAssignJobs(removeJobIds);
|
||||
deletedNode.assignJobs.addRemovingJobs(removeJobIds);
|
||||
if (higherVirtualEntry == null) {
|
||||
// jobId-dispatchHash
|
||||
removeJobHashSet.forEach(value -> {
|
||||
@@ -237,9 +150,9 @@ public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
CollectorNode higherVirtualNode = higherVirtualEntry.getValue();
|
||||
Node higherVirtualNode = higherVirtualEntry.getValue();
|
||||
higherVirtualNode.addVirtualNodeJobs(higherVirtualEntry.getKey(), removeJobHashSet);
|
||||
higherVirtualNode.getAssignJobs().addAddingJobs(removeJobIds);
|
||||
higherVirtualNode.assignJobs.addAddingJobs(removeJobIds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,19 +160,20 @@ public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
* deleted collector node
|
||||
* @param name collector name
|
||||
*/
|
||||
private void removeNode(String name) {
|
||||
CollectorNode deletedNode = existNodeMap.remove(name);
|
||||
public Node removeNode(String name) {
|
||||
Node deletedNode = existNodeMap.remove(name);
|
||||
if (deletedNode == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
for (Integer virtualNodeHash : deletedNode.virtualNodeMap.keySet()) {
|
||||
removeVirtualNode(deletedNode, virtualNodeHash);
|
||||
}
|
||||
|
||||
deletedNode.getVirtualNodeMap().keySet()
|
||||
.forEach(virtualNodeHash -> removeVirtualNode(deletedNode, virtualNodeHash));
|
||||
deletedNode.destroy();
|
||||
dispatchJobInCache();
|
||||
return deletedNode;
|
||||
}
|
||||
|
||||
private synchronized void dispatchJobInCache() {
|
||||
public synchronized void dispatchJobInCache() {
|
||||
if (!dispatchJobCache.isEmpty()) {
|
||||
int size = dispatchJobCache.size();
|
||||
for (int index = 0; index < size; index++) {
|
||||
@@ -269,6 +183,31 @@ public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get all collector nodes
|
||||
* @return nodes
|
||||
*/
|
||||
public Map<String, Node> getAllNodes() {
|
||||
return existNodeMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* get node
|
||||
* @param collectorName collector name
|
||||
* @return node
|
||||
*/
|
||||
public Node getNode(String collectorName) {
|
||||
return existNodeMap.get(collectorName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the cached collection scheduling task
|
||||
* @return cache task
|
||||
*/
|
||||
public List<DispatchJob> getDispatchJobCache() {
|
||||
return dispatchJobCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the collector node according to the collection task information
|
||||
*
|
||||
@@ -276,7 +215,7 @@ public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
* @param jobId jobId
|
||||
* @return collector node
|
||||
*/
|
||||
private CollectorNode dispatchJob(String dispatchKey, Long jobId) {
|
||||
public Node dispatchJob(String dispatchKey, Long jobId) {
|
||||
if (dispatchKey == null || StringUtils.isBlank(dispatchKey)) {
|
||||
log.error("The dispatch key can not null.");
|
||||
return null;
|
||||
@@ -285,23 +224,38 @@ public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
return dispatchJob(dispatchHash, jobId, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* The collector node to which the collector is assigned is obtained in advance based on the collection task information
|
||||
*
|
||||
* @param dispatchKey collector task route key: ip+appId
|
||||
* @return collector node
|
||||
*/
|
||||
public Node preDispatchJob(String dispatchKey) {
|
||||
if (dispatchKey == null || StringUtils.isBlank(dispatchKey)) {
|
||||
log.error("The dispatch key can not null.");
|
||||
return null;
|
||||
}
|
||||
int dispatchHash = hash(dispatchKey);
|
||||
return preDispatchJob(dispatchHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the collector node to which the collector is assigned based on the collection task information
|
||||
*
|
||||
* @param dispatchHash The task route hash is collected
|
||||
* @param jobId jobId
|
||||
* @param isFlushed if it has flushed this job or wait to dispatch
|
||||
* @param isFlushed is has flush this job or wait to dispatch
|
||||
* @return collector node
|
||||
*/
|
||||
private CollectorNode dispatchJob(Integer dispatchHash, Long jobId, boolean isFlushed) {
|
||||
public Node dispatchJob(Integer dispatchHash, Long jobId, boolean isFlushed) {
|
||||
if (dispatchHash == null || hashCircle == null || hashCircle.isEmpty()) {
|
||||
log.warn("There is no available collector registered. Cache the job {}.", jobId);
|
||||
dispatchJobCache.add(new DispatchJob(dispatchHash, jobId));
|
||||
return null;
|
||||
}
|
||||
Map.Entry<Integer, CollectorNode> ceilEntry = hashCircle.ceilingOrFirstEntry(dispatchHash);
|
||||
Map.Entry<Integer, Node> ceilEntry = hashCircle.ceilingOrFirstEntry(dispatchHash);
|
||||
int virtualKey = ceilEntry.getKey();
|
||||
CollectorNode curNode = ceilEntry.getValue();
|
||||
Node curNode = ceilEntry.getValue();
|
||||
|
||||
curNode.addJob(virtualKey, dispatchHash, jobId, isFlushed);
|
||||
return curNode;
|
||||
@@ -313,15 +267,25 @@ public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
* @param dispatchHash The task route hash is collected
|
||||
* @return collector node
|
||||
*/
|
||||
private CollectorNode preDispatchJob(Integer dispatchHash) {
|
||||
public Node preDispatchJob(Integer dispatchHash) {
|
||||
if (dispatchHash == null || hashCircle == null || hashCircle.isEmpty()) {
|
||||
log.warn("There is no available collector registered.");
|
||||
return null;
|
||||
}
|
||||
Map.Entry<Integer, CollectorNode> ceilEntry = hashCircle.ceilingOrFirstEntry(dispatchHash);
|
||||
Map.Entry<Integer, Node> ceilEntry = hashCircle.ceilingOrFirstEntry(dispatchHash);
|
||||
return ceilEntry.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* hash long
|
||||
* @param key long value
|
||||
* @return hash value
|
||||
*/
|
||||
private int hash(long key) {
|
||||
String keyStr = String.valueOf(key);
|
||||
return hash(keyStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* FNV1_32_HASH algorithm
|
||||
* @param key the key
|
||||
@@ -350,7 +314,7 @@ public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
* dispatch job summary
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
private static class DispatchJob {
|
||||
public static class DispatchJob {
|
||||
|
||||
/**
|
||||
* dispatch task route key
|
||||
@@ -363,4 +327,130 @@ public class ConsistentHashCollectorKeeper implements CollectorKeeper {
|
||||
@Getter
|
||||
private Long jobId;
|
||||
}
|
||||
|
||||
/**
|
||||
* collector node machine address
|
||||
*/
|
||||
public static class Node {
|
||||
|
||||
/**
|
||||
* collector identity
|
||||
*/
|
||||
@Getter
|
||||
private final String identity;
|
||||
|
||||
/**
|
||||
* collector mode: public or private
|
||||
*/
|
||||
private final String mode;
|
||||
|
||||
/**
|
||||
* ip
|
||||
*/
|
||||
private final String ip;
|
||||
|
||||
/**
|
||||
* collector On-line time stamp
|
||||
*/
|
||||
private final long uptime;
|
||||
|
||||
/**
|
||||
* collector's own performance service quality score 0 - 127
|
||||
* The number of virtual nodes will be calculated based on this service quality score
|
||||
*
|
||||
*/
|
||||
private final Byte quality;
|
||||
|
||||
/**
|
||||
* use this collector's collect job ID list
|
||||
* jobId,jobVersion
|
||||
*/
|
||||
private AssignJobs assignJobs;
|
||||
|
||||
/**
|
||||
* the collection task ID list mapped by each virtual node corresponding to this node
|
||||
* Long[] [0]-jobId, [1]-dispatchHash
|
||||
*/
|
||||
private Map<Integer, Set<Long[]>> virtualNodeMap;
|
||||
|
||||
public Node(String identity, String mode, String ip, long uptime, Byte quality) {
|
||||
this.identity = identity;
|
||||
this.mode = mode;
|
||||
this.ip = ip;
|
||||
this.uptime = uptime;
|
||||
this.quality = quality;
|
||||
assignJobs = new AssignJobs();
|
||||
virtualNodeMap = new ConcurrentHashMap<>(VIRTUAL_NODE_DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
private synchronized void addJob(Integer virtualNodeKey, Integer dispatchHash, Long jobId, boolean isFlushed) {
|
||||
if (virtualNodeMap == null) {
|
||||
virtualNodeMap = new ConcurrentHashMap<>(VIRTUAL_NODE_DEFAULT_SIZE);
|
||||
}
|
||||
if (assignJobs == null) {
|
||||
assignJobs = new AssignJobs();
|
||||
}
|
||||
Set<Long[]> virtualNodeJob = virtualNodeMap.computeIfAbsent(virtualNodeKey, k -> ConcurrentHashMap.newKeySet(16));
|
||||
virtualNodeJob.add(new Long[]{jobId, dispatchHash.longValue()});
|
||||
if (isFlushed) {
|
||||
assignJobs.addAssignJob(jobId);
|
||||
} else {
|
||||
assignJobs.addAddingJob(jobId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the collection task routed by the specified virtual node according to virtualNodeKey
|
||||
* @param virtualNodeKey virtualNodeKey
|
||||
* @return collection task
|
||||
*/
|
||||
private Set<Long[]> clearVirtualNodeJobs(Integer virtualNodeKey) {
|
||||
if (virtualNodeMap == null || virtualNodeMap.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Set<Long[]> virtualNodeJobs = virtualNodeMap.remove(virtualNodeKey);
|
||||
virtualNodeMap.put(virtualNodeKey, ConcurrentHashMap.newKeySet(16));
|
||||
return virtualNodeJobs;
|
||||
}
|
||||
|
||||
private void addVirtualNodeJobs(Integer virtualHashKey, Set<Long[]> reDispatchJobs) {
|
||||
if (reDispatchJobs == null) {
|
||||
return;
|
||||
}
|
||||
if (virtualNodeMap == null) {
|
||||
virtualNodeMap = new ConcurrentHashMap<>(16);
|
||||
}
|
||||
virtualNodeMap.computeIfPresent(virtualHashKey, (k, v) -> {
|
||||
reDispatchJobs.addAll(v);
|
||||
return v;
|
||||
});
|
||||
virtualNodeMap.put(virtualHashKey, reDispatchJobs);
|
||||
}
|
||||
|
||||
public void removeVirtualNodeJob(Long jobId) {
|
||||
if (jobId == null || virtualNodeMap == null) {
|
||||
return;
|
||||
}
|
||||
for (Set<Long[]> jobSet : virtualNodeMap.values()) {
|
||||
Optional<Long[]> optional = jobSet.stream().filter(item -> Objects.equals(item[0], jobId)).findFirst();
|
||||
if (optional.isPresent()) {
|
||||
jobSet.remove(optional.get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AssignJobs getAssignJobs() {
|
||||
return assignJobs;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (assignJobs != null) {
|
||||
assignJobs.clear();
|
||||
}
|
||||
if (virtualNodeMap != null) {
|
||||
virtualNodeMap.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -52,10 +52,10 @@ import org.springframework.util.StringUtils;
|
||||
public class SchedulerInit implements CommandLineRunner {
|
||||
|
||||
@Autowired
|
||||
private CollectorOperationReceiver collectorOperationReceiver;
|
||||
private CollectorScheduling collectorScheduling;
|
||||
|
||||
@Autowired
|
||||
private JobOperation jobOperation;
|
||||
private CollectJobScheduling collectJobScheduling;
|
||||
|
||||
private static final String MAIN_COLLECTOR_NODE_IP = "127.0.0.1";
|
||||
private static final String DEFAULT_COLLECTOR_VERSION = "DEBUG";
|
||||
@@ -91,7 +91,7 @@ public class SchedulerInit implements CommandLineRunner {
|
||||
.ip(MAIN_COLLECTOR_NODE_IP)
|
||||
.version(DEFAULT_COLLECTOR_VERSION)
|
||||
.build();
|
||||
collectorOperationReceiver.collectorGoOnline(CommonConstants.MAIN_COLLECTOR_NODE, collectorInfo);
|
||||
collectorScheduling.collectorGoOnline(CommonConstants.MAIN_COLLECTOR_NODE, collectorInfo);
|
||||
// init jobs
|
||||
List<Monitor> monitors = monitorDao.findMonitorsByStatusNotInAndJobIdNotNull(List.of(CommonConstants.MONITOR_PAUSED_CODE));
|
||||
List<CollectorMonitorBind> monitorBinds = collectorMonitorBindDao.findAll();
|
||||
@@ -136,7 +136,7 @@ public class SchedulerInit implements CommandLineRunner {
|
||||
});
|
||||
appDefine.setConfigmap(configmaps);
|
||||
String collector = monitorIdCollectorMap.get(monitor.getId());
|
||||
long jobId = jobOperation.addAsyncCollectJob(appDefine, collector);
|
||||
long jobId = collectJobScheduling.addAsyncCollectJob(appDefine, collector);
|
||||
monitor.setJobId(jobId);
|
||||
monitorDao.save(monitor);
|
||||
} catch (Exception e) {
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.manager.properties;
|
||||
package org.apache.hertzbeat.manager.scheduler;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.manager.scheduler.collector;
|
||||
|
||||
import org.apache.hertzbeat.common.constants.CollectorStatus;
|
||||
import org.apache.hertzbeat.common.entity.job.Job;
|
||||
import org.apache.hertzbeat.manager.pojo.CollectorNode;
|
||||
import org.apache.hertzbeat.manager.scheduler.AssignJobs;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* Interface for managing collector nodes and their associated jobs.
|
||||
* Maintains all collector information and provides operations for managing collectors and job assignments.
|
||||
*/
|
||||
public interface CollectorKeeper {
|
||||
|
||||
/**
|
||||
* Adds a new collector node to the keeper's management pool.
|
||||
* @param newNode The collector node to be added to the management system
|
||||
*/
|
||||
void addNode(CollectorNode newNode);
|
||||
|
||||
/**
|
||||
* Assigns a monitoring job to a specific collector node.
|
||||
* @param job The monitoring job to be assigned
|
||||
* @param collectorId The unique identifier of the target collector node
|
||||
* @return The collector node that received the job assignment
|
||||
*/
|
||||
CollectorNode addJob(Job job, String collectorId);
|
||||
|
||||
/**
|
||||
* Retrieves a collector node by its unique identifier.
|
||||
* @param collectorId The unique identifier of the collector node
|
||||
* @return The collector node matching the given ID, or null if not found
|
||||
*/
|
||||
CollectorNode getNode(String collectorId);
|
||||
|
||||
/**
|
||||
* Determines the most appropriate collector node for a given job based on scheduling logic.
|
||||
* @param jobId The unique identifier of the job to be assigned
|
||||
* @return The collector node selected to handle this job
|
||||
*/
|
||||
CollectorNode determineNode(Long jobId);
|
||||
|
||||
/**
|
||||
* Updates the operational status of a collector node.
|
||||
* @param collectorId The unique identifier of the collector node
|
||||
* @param collectorStatus The new status to assign to the collector
|
||||
*/
|
||||
void changeStatus(String collectorId, CollectorStatus collectorStatus);
|
||||
|
||||
/**
|
||||
* Rebalances job assignments across collector nodes, typically triggered by status changes.
|
||||
* Uses a callback mechanism to handle job reassignments.
|
||||
* @param assignJobCollectorConsumer A biconsumer that handles the job reassignment process,
|
||||
* taking the job assignment logic and collector ID as parameters
|
||||
*/
|
||||
void rebalanceJobs(BiConsumer<AssignJobs, String> assignJobCollectorConsumer);
|
||||
|
||||
/**
|
||||
* Removes a job from whichever collector node it is currently assigned to.
|
||||
* @param jobId The unique identifier of the job to be removed
|
||||
* @return The collector node from which the job was removed, or null if job wasn't found
|
||||
*/
|
||||
CollectorNode removeJob(Long jobId);
|
||||
}
|
||||
+1
-4
@@ -28,7 +28,7 @@ import org.apache.hertzbeat.alert.calculate.CollectorAlertHandler;
|
||||
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
|
||||
import org.apache.hertzbeat.common.support.CommonThreadPool;
|
||||
import org.apache.hertzbeat.manager.scheduler.CollectorJobScheduler;
|
||||
import org.apache.hertzbeat.manager.properties.SchedulerProperties;
|
||||
import org.apache.hertzbeat.manager.scheduler.SchedulerProperties;
|
||||
import org.apache.hertzbeat.manager.scheduler.netty.process.CollectCyclicDataResponseProcessor;
|
||||
import org.apache.hertzbeat.manager.scheduler.netty.process.CollectCyclicServiceDiscoveryDataResponseProcessor;
|
||||
import org.apache.hertzbeat.manager.scheduler.netty.process.CollectOneTimeDataResponseProcessor;
|
||||
@@ -45,8 +45,6 @@ import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
/**
|
||||
* manage server
|
||||
*/
|
||||
@@ -114,7 +112,6 @@ public class ManageServer implements CommandLineRunner {
|
||||
}, 10, 3, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void shutdown() {
|
||||
this.remotingServer.shutdown();
|
||||
|
||||
|
||||
+31
-10
@@ -18,10 +18,12 @@
|
||||
package org.apache.hertzbeat.manager.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.hertzbeat.common.entity.manager.StatusPageComponent;
|
||||
import org.apache.hertzbeat.common.entity.manager.StatusPageIncident;
|
||||
import org.apache.hertzbeat.common.entity.manager.StatusPageOrg;
|
||||
import org.apache.hertzbeat.manager.pojo.dto.ComponentStatus;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
/**
|
||||
* status page service interface.
|
||||
@@ -30,42 +32,49 @@ public interface StatusPageService {
|
||||
|
||||
/**
|
||||
* query status page organization.
|
||||
*
|
||||
* @return status page organization
|
||||
*/
|
||||
StatusPageOrg queryStatusPageOrg();
|
||||
|
||||
/**
|
||||
* save status page organization.
|
||||
*
|
||||
* @return status page organization
|
||||
*/
|
||||
StatusPageOrg saveStatusPageOrg(StatusPageOrg statusPageOrg);
|
||||
|
||||
|
||||
/**
|
||||
* query status page components.
|
||||
*
|
||||
* @return status page components
|
||||
*/
|
||||
List<StatusPageComponent> queryStatusPageComponents();
|
||||
|
||||
|
||||
/**
|
||||
* save status page component.
|
||||
*
|
||||
* @param statusPageComponent status page component
|
||||
*/
|
||||
void newStatusPageComponent(StatusPageComponent statusPageComponent);
|
||||
|
||||
|
||||
/**
|
||||
* update status page component.
|
||||
*
|
||||
* @param statusPageComponent status page component
|
||||
*/
|
||||
void updateStatusPageComponent(StatusPageComponent statusPageComponent);
|
||||
|
||||
/**
|
||||
* delete status page component.
|
||||
*
|
||||
* @param id status page component id
|
||||
*/
|
||||
void deleteStatusPageComponent(long id);
|
||||
|
||||
/**
|
||||
* query status page component.
|
||||
*
|
||||
* @param id status page component id
|
||||
* @return status page component
|
||||
*/
|
||||
@@ -73,44 +82,56 @@ public interface StatusPageService {
|
||||
|
||||
/**
|
||||
* query status page components status.
|
||||
*
|
||||
* @return status page components status
|
||||
*/
|
||||
List<ComponentStatus> queryComponentsStatus();
|
||||
|
||||
/**
|
||||
* query status page component status.
|
||||
*
|
||||
* @param id status page component id
|
||||
* @return status page component status
|
||||
*/
|
||||
ComponentStatus queryComponentStatus(long id);
|
||||
|
||||
|
||||
/**
|
||||
* query status page incidents.
|
||||
* @return status page incidents
|
||||
*
|
||||
* @param search Search Target
|
||||
* @param startTime Start Time
|
||||
* @param endTime End Time
|
||||
* @param pageIndex List current page
|
||||
* @param pageSize Number of list pages
|
||||
* @return The query results
|
||||
*/
|
||||
List<StatusPageIncident> queryStatusPageIncidents();
|
||||
|
||||
Page<StatusPageIncident> queryStatusPageIncidents(String search, Long startTime, Long endTime, int pageIndex, int pageSize);
|
||||
|
||||
/**
|
||||
* query status page incident.
|
||||
*
|
||||
* @param id status page incident id
|
||||
* @return status page incident
|
||||
*/
|
||||
StatusPageIncident queryStatusPageIncident(long id);
|
||||
|
||||
|
||||
/**
|
||||
* save status page incident.
|
||||
*
|
||||
* @param statusPageIncident status page incident
|
||||
*/
|
||||
void newStatusPageIncident(StatusPageIncident statusPageIncident);
|
||||
|
||||
|
||||
/**
|
||||
* update status page incident.
|
||||
*
|
||||
* @param statusPageIncident status page incident
|
||||
*/
|
||||
void updateStatusPageIncident(StatusPageIncident statusPageIncident);
|
||||
|
||||
|
||||
/**
|
||||
* delete status page incident.
|
||||
*
|
||||
* @param id status page incident id
|
||||
*/
|
||||
void deleteStatusPageIncident(long id);
|
||||
|
||||
+1
-1
@@ -212,7 +212,7 @@ public class AppServiceImpl implements AppService, InitializingBean {
|
||||
var name = job.getName();
|
||||
var i18nName = CommonUtil.getLangMappingValueFromI18nMap(lang, name);
|
||||
if (i18nName != null) {
|
||||
i18nMap.put("monitor.app." + job.getApp().toLowerCase(), i18nName);
|
||||
i18nMap.put("monitor.app." + job.getApp(), i18nName);
|
||||
}
|
||||
var help = job.getHelp();
|
||||
var i18nHelp = CommonUtil.getLangMappingValueFromI18nMap(lang, help);
|
||||
|
||||
+3
-4
@@ -31,9 +31,8 @@ import org.apache.hertzbeat.common.support.exception.CommonException;
|
||||
import org.apache.hertzbeat.common.util.IpDomainUtil;
|
||||
import org.apache.hertzbeat.manager.dao.CollectorDao;
|
||||
import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
|
||||
import org.apache.hertzbeat.manager.pojo.CollectorNode;
|
||||
import org.apache.hertzbeat.manager.scheduler.AssignJobs;
|
||||
import org.apache.hertzbeat.manager.scheduler.ConsistentHashCollectorKeeper;
|
||||
import org.apache.hertzbeat.manager.scheduler.ConsistentHash;
|
||||
import org.apache.hertzbeat.manager.scheduler.netty.ManageServer;
|
||||
import org.apache.hertzbeat.manager.service.CollectorService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -58,7 +57,7 @@ public class CollectorServiceImpl implements CollectorService {
|
||||
private CollectorMonitorBindDao collectorMonitorBindDao;
|
||||
|
||||
@Autowired
|
||||
private ConsistentHashCollectorKeeper consistentHashCollectorKeeper;
|
||||
private ConsistentHash consistentHash;
|
||||
|
||||
@Autowired(required = false)
|
||||
private ManageServer manageServer;
|
||||
@@ -82,7 +81,7 @@ public class CollectorServiceImpl implements CollectorService {
|
||||
List<CollectorSummary> collectorSummaryList = new LinkedList<>();
|
||||
for (Collector collector : collectors.getContent()) {
|
||||
CollectorSummary.CollectorSummaryBuilder summaryBuilder = CollectorSummary.builder().collector(collector);
|
||||
CollectorNode node = consistentHashCollectorKeeper.getNode(collector.getName());
|
||||
ConsistentHash.Node node = consistentHash.getNode(collector.getName());
|
||||
if (node != null && node.getAssignJobs() != null) {
|
||||
AssignJobs assignJobs = node.getAssignJobs();
|
||||
summaryBuilder.pinMonitorNum(assignJobs.getPinnedJobs().size());
|
||||
|
||||
+48
-34
@@ -60,7 +60,7 @@ import org.apache.hertzbeat.manager.dao.MonitorDao;
|
||||
import org.apache.hertzbeat.manager.dao.ParamDao;
|
||||
import org.apache.hertzbeat.manager.pojo.dto.AppCount;
|
||||
import org.apache.hertzbeat.manager.pojo.dto.MonitorDto;
|
||||
import org.apache.hertzbeat.manager.scheduler.JobOperation;
|
||||
import org.apache.hertzbeat.manager.scheduler.CollectJobScheduling;
|
||||
import org.apache.hertzbeat.manager.service.AppService;
|
||||
import org.apache.hertzbeat.manager.service.ImExportService;
|
||||
import org.apache.hertzbeat.manager.service.LabelService;
|
||||
@@ -113,7 +113,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
@Autowired
|
||||
private AppService appService;
|
||||
@Autowired
|
||||
private JobOperation jobOperation;
|
||||
private CollectJobScheduling collectJobScheduling;
|
||||
@Autowired
|
||||
private MonitorDao monitorDao;
|
||||
@Autowired
|
||||
@@ -193,10 +193,11 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
return new Configmap(param.getField(), param.getParamValue(), param.getType());
|
||||
}).collect(Collectors.toList());
|
||||
appDefine.setConfigmap(configmaps);
|
||||
long jobId = jobOperation.addAsyncCollectJob(appDefine, collector);
|
||||
|
||||
|
||||
detectMonitorSafely(monitor, params, collector);
|
||||
long jobId = collector == null ? collectJobScheduling.addAsyncCollectJob(appDefine, null) :
|
||||
collectJobScheduling.addAsyncCollectJob(appDefine, collector);
|
||||
try {
|
||||
detectMonitor(monitor, params, collector);
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
try {
|
||||
if (collector != null) {
|
||||
@@ -216,7 +217,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
paramDao.saveAll(params);
|
||||
} catch (Exception e) {
|
||||
log.error("Error while adding monitor: {}", e.getMessage(), e);
|
||||
jobOperation.cancelAsyncCollectJob(jobId);
|
||||
collectJobScheduling.cancelAsyncCollectJob(jobId);
|
||||
throw new MonitorDatabaseException(e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -509,11 +510,18 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
List<Configmap> configmaps = params.stream().map(param ->
|
||||
new Configmap(param.getField(), param.getParamValue(), param.getType())).collect(Collectors.toList());
|
||||
appDefine.setConfigmap(configmaps);
|
||||
long newJobId = jobOperation.updateAsyncCollectJob(appDefine, collector);
|
||||
long newJobId;
|
||||
if (collector == null) {
|
||||
newJobId = collectJobScheduling.updateAsyncCollectJob(appDefine);
|
||||
} else {
|
||||
newJobId = collectJobScheduling.updateAsyncCollectJob(appDefine, collector);
|
||||
}
|
||||
monitor.setJobId(newJobId);
|
||||
|
||||
// execute only in non paused status
|
||||
detectMonitorSafely(monitor, params, collector);
|
||||
try {
|
||||
detectMonitor(monitor, params, collector);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
// After the update is successfully released, refresh the database
|
||||
@@ -540,7 +548,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
// Repository brushing abnormally cancels the previously delivered task
|
||||
jobOperation.cancelAsyncCollectJob(monitor.getJobId());
|
||||
collectJobScheduling.cancelAsyncCollectJob(monitor.getJobId());
|
||||
throw new MonitorDatabaseException(e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -570,7 +578,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
for (Monitor monitor : monitors) {
|
||||
monitorBindDao.deleteByMonitorId(monitor.getId());
|
||||
collectorMonitorBindDao.deleteCollectorMonitorBindsByMonitorId(monitor.getId());
|
||||
jobOperation.cancelAsyncCollectJob(monitor.getJobId());
|
||||
collectJobScheduling.cancelAsyncCollectJob(monitor.getJobId());
|
||||
applicationContext.publishEvent(new MonitorDeletedEvent(applicationContext, monitor.getId()));
|
||||
}
|
||||
}
|
||||
@@ -684,17 +692,17 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
// The jobId is not deleted, and the jobId is reused again after the management is started.
|
||||
Set<Long> subMonitorIds = monitorBindDao.findMonitorBindsByBizIdIn(ids).stream().map(MonitorBind::getMonitorId).collect(Collectors.toSet());
|
||||
ids.addAll(subMonitorIds);
|
||||
List<Monitor> managedMonitors = monitorDao.findMonitorsByIdIn(ids).stream()
|
||||
.filter(monitor -> monitor.getStatus() != CommonConstants.MONITOR_PAUSED_CODE)
|
||||
List<Monitor> managedMonitors = monitorDao.findMonitorsByIdIn(ids)
|
||||
.stream().filter(monitor ->
|
||||
monitor.getStatus() != CommonConstants.MONITOR_PAUSED_CODE)
|
||||
.peek(monitor -> monitor.setStatus(CommonConstants.MONITOR_PAUSED_CODE))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtils.isEmpty(managedMonitors)) {
|
||||
return;
|
||||
if (!CollectionUtils.isEmpty(managedMonitors)) {
|
||||
for (Monitor monitor : managedMonitors) {
|
||||
collectJobScheduling.cancelAsyncCollectJob(monitor.getJobId());
|
||||
}
|
||||
monitorDao.saveAll(managedMonitors);
|
||||
}
|
||||
|
||||
managedMonitors.forEach(monitor -> jobOperation.cancelAsyncCollectJob(monitor.getJobId()));
|
||||
monitorDao.saveAll(managedMonitors);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -702,8 +710,9 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
// Update monitoring status Add corresponding monitoring periodic task
|
||||
Set<Long> subMonitorIds = monitorBindDao.findMonitorBindsByBizIdIn(ids).stream().map(MonitorBind::getMonitorId).collect(Collectors.toSet());
|
||||
ids.addAll(subMonitorIds);
|
||||
List<Monitor> unManagedMonitors = monitorDao.findMonitorsByIdIn(ids).stream()
|
||||
.filter(monitor -> monitor.getStatus() == CommonConstants.MONITOR_PAUSED_CODE)
|
||||
List<Monitor> unManagedMonitors = monitorDao.findMonitorsByIdIn(ids)
|
||||
.stream().filter(monitor ->
|
||||
monitor.getStatus() == CommonConstants.MONITOR_PAUSED_CODE)
|
||||
.peek(monitor -> monitor.setStatus(CommonConstants.MONITOR_UP_CODE))
|
||||
.collect(Collectors.toList());
|
||||
if (unManagedMonitors.isEmpty()) {
|
||||
@@ -748,11 +757,13 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
Optional<CollectorMonitorBind> bindOptional =
|
||||
collectorMonitorBindDao.findCollectorMonitorBindByMonitorId(monitor.getId());
|
||||
String collector = bindOptional.map(CollectorMonitorBind::getCollector).orElse(null);
|
||||
long newJobId = jobOperation.addAsyncCollectJob(appDefine, collector);
|
||||
long newJobId = collectJobScheduling.addAsyncCollectJob(appDefine, collector);
|
||||
monitor.setJobId(newJobId);
|
||||
applicationContext.publishEvent(new MonitorDeletedEvent(applicationContext, monitor.getId()));
|
||||
|
||||
detectMonitorSafely(monitor, params, collector);
|
||||
try {
|
||||
detectMonitor(monitor, params, collector);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
monitorDao.saveAll(unManagedMonitors);
|
||||
}
|
||||
@@ -841,7 +852,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
// if is pinned collector
|
||||
String collector = monitorIdCollectorMap.get(monitor.getId());
|
||||
// Delivering a collection task
|
||||
long newJobId = jobOperation.updateAsyncCollectJob(appDefine, collector);
|
||||
long newJobId = collectJobScheduling.updateAsyncCollectJob(appDefine, collector);
|
||||
monitor.setJobId(newJobId);
|
||||
monitorDao.save(monitor);
|
||||
} catch (Exception e) {
|
||||
@@ -921,8 +932,12 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
new Configmap(param.getField(), param.getParamValue(), param.getType())).collect(Collectors.toList());
|
||||
appDefine.setConfigmap(configmaps);
|
||||
appDefine.setSd(true);
|
||||
List<CollectRep.MetricsData> collectRep = jobOperation.collectSyncJobData(appDefine, collector);
|
||||
|
||||
List<CollectRep.MetricsData> collectRep;
|
||||
if (collector != null) {
|
||||
collectRep = collectJobScheduling.collectSyncJobData(appDefine, collector);
|
||||
} else {
|
||||
collectRep = collectJobScheduling.collectSyncJobData(appDefine);
|
||||
}
|
||||
monitor.setStatus(CommonConstants.MONITOR_UP_CODE);
|
||||
// If the detection result fails, a detection exception is thrown
|
||||
if (collectRep == null || collectRep.isEmpty()) {
|
||||
@@ -960,7 +975,12 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
List<Metrics> availableMetrics = appDefine.getMetrics().stream()
|
||||
.filter(item -> item.getPriority() == 0).collect(Collectors.toList());
|
||||
appDefine.setMetrics(availableMetrics);
|
||||
List<CollectRep.MetricsData> collectRep = jobOperation.collectSyncJobData(appDefine, collector);
|
||||
List<CollectRep.MetricsData> collectRep;
|
||||
if (collector != null) {
|
||||
collectRep = collectJobScheduling.collectSyncJobData(appDefine, collector);
|
||||
} else {
|
||||
collectRep = collectJobScheduling.collectSyncJobData(appDefine);
|
||||
}
|
||||
monitor.setStatus(CommonConstants.MONITOR_UP_CODE);
|
||||
|
||||
// If the detection result fails, a detection exception is thrown
|
||||
@@ -974,10 +994,4 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
}
|
||||
collectRep.forEach(CollectRep.MetricsData::close);
|
||||
}
|
||||
|
||||
private void detectMonitorSafely(Monitor monitor, List<Param> params, String collector) {
|
||||
try {
|
||||
detectMonitor(monitor, params, collector);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
+28
-2
@@ -21,9 +21,12 @@ import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.manager.StatusPageComponent;
|
||||
@@ -40,8 +43,12 @@ import org.apache.hertzbeat.manager.dao.StatusPageOrgDao;
|
||||
import org.apache.hertzbeat.manager.pojo.dto.ComponentStatus;
|
||||
import org.apache.hertzbeat.manager.service.StatusPageService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* status page service implement.
|
||||
@@ -257,9 +264,28 @@ public class StatusPageServiceImpl implements StatusPageService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StatusPageIncident> queryStatusPageIncidents() {
|
||||
public Page<StatusPageIncident> queryStatusPageIncidents(String search, Long startTime, Long endTime, int pageIndex, int pageSize) {
|
||||
// build search condition
|
||||
Specification<StatusPageIncident> specification = (root, query, criteriaBuilder) -> {
|
||||
List<Predicate> andList = new ArrayList<>();
|
||||
if (StringUtils.hasText(search)) {
|
||||
Predicate predicateName = criteriaBuilder.like(criteriaBuilder.lower(root.get("name")), "%" + search.toLowerCase() + "%");
|
||||
andList.add(predicateName);
|
||||
}
|
||||
if (startTime != null) {
|
||||
andList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("startTime"), startTime));
|
||||
}
|
||||
if (endTime != null) {
|
||||
andList.add(criteriaBuilder.lessThanOrEqualTo(root.get("endTime"), endTime));
|
||||
}
|
||||
|
||||
Predicate[] predicates = new Predicate[andList.size()];
|
||||
return criteriaBuilder.and(andList.toArray(predicates));
|
||||
};
|
||||
|
||||
Sort sort = Sort.by(Sort.Direction.DESC, "startTime");
|
||||
return statusPageIncidentDao.findAll(sort);
|
||||
PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sort);
|
||||
return statusPageIncidentDao.findAll(specification, pageRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -208,6 +208,11 @@ warehouse:
|
||||
database: public
|
||||
username: greptime
|
||||
password: greptime
|
||||
questdb:
|
||||
enabled: false
|
||||
url: localhost:9000
|
||||
username: admin
|
||||
password: quest
|
||||
iot-db:
|
||||
enabled: false
|
||||
host: 127.0.0.1
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
|
||||
-- ensure every sql can rerun without error
|
||||
|
||||
-- Modify message column to TEXT (H2 TEXT is equivalent to CLOB)
|
||||
ALTER TABLE HZB_STATUS_PAGE_INCIDENT_CONTENT ALTER COLUMN message CLOB;
|
||||
@@ -0,0 +1,52 @@
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
|
||||
-- ensure every sql can rerun without error
|
||||
|
||||
-- Modify hzb_status_page_incident_content table columns to TEXT type to resolve MySQL row size limit issue
|
||||
|
||||
DELIMITER //
|
||||
CREATE PROCEDURE ModifyStatusIncidentContentColumns()
|
||||
BEGIN
|
||||
DECLARE table_exists INT;
|
||||
DECLARE col_exists INT;
|
||||
|
||||
-- Check if the table exists
|
||||
SELECT COUNT(*) INTO table_exists
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'HZB_STATUS_PAGE_INCIDENT_CONTENT';
|
||||
|
||||
IF table_exists = 1 THEN
|
||||
-- Check and modify message column to TEXT
|
||||
SELECT COUNT(*) INTO col_exists
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'HZB_STATUS_PAGE_INCIDENT_CONTENT'
|
||||
AND COLUMN_NAME = 'message'
|
||||
AND DATA_TYPE != 'text';
|
||||
|
||||
IF col_exists = 1 THEN
|
||||
ALTER TABLE HZB_STATUS_PAGE_INCIDENT_CONTENT MODIFY COLUMN message TEXT;
|
||||
END IF;
|
||||
END IF;
|
||||
END //
|
||||
|
||||
DELIMITER ;
|
||||
|
||||
CALL ModifyStatusIncidentContentColumns();
|
||||
DROP PROCEDURE IF EXISTS ModifyStatusIncidentContentColumns;
|
||||
COMMIT;
|
||||
@@ -0,0 +1,23 @@
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
|
||||
-- ensure every sql can rerun without error
|
||||
|
||||
-- Modify message column to TEXT
|
||||
ALTER TABLE HZB_STATUS_PAGE_INCIDENT_CONTENT ALTER COLUMN message TYPE TEXT;
|
||||
|
||||
commit;
|
||||
@@ -21,10 +21,12 @@ app: dolphinscheduler
|
||||
name:
|
||||
zh-CN: Apache DolphinScheduler
|
||||
en-US: Apache DolphinScheduler
|
||||
ja-JP: Apache DolphinScheduler
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 对 Apache DolphinScheduler (支持v3.3.0或更高版本)通用指标进行测量监控。<br>您可以点击 “<i>新建 Apache DolphinScheduler</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat measures and monitors the general metrics of Apache DolphinScheduler (support v3.3.0 or later).<br>You can click on “<i>Create New Apache DolphinScheduler</i>” to configure it, or select “<i>More Actions</i>” to import an existing configuration.
|
||||
ja-JP: Hertzbeat は Apache DolphinScheduler(v3.3.0+)の一般的なメトリクスを監視します。<br>「<i>新規 Apache DolphinScheduler</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/dolphinscheduler
|
||||
en-US: https://hertzbeat.apache.org/docs/help/dolphinscheduler
|
||||
@@ -36,6 +38,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
|
||||
@@ -46,6 +49,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
|
||||
@@ -60,6 +64,7 @@ params:
|
||||
name:
|
||||
zh-CN: 查询超时时间
|
||||
en-US: Query Timeout
|
||||
ja-JP: クエリタイムアウト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# required-true or false
|
||||
@@ -74,6 +79,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: SSL
|
||||
ja-JP: SSL
|
||||
# type-param field type(boolean mapping the html h tag)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -83,6 +89,7 @@ params:
|
||||
name:
|
||||
zh-CN: 令牌
|
||||
en-US: Token
|
||||
ja-JP: トークン
|
||||
type: text
|
||||
limit: 100
|
||||
required: true
|
||||
@@ -93,6 +100,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Master
|
||||
en-US: Master
|
||||
ja-JP: マスター情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -104,76 +112,90 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 主机地址
|
||||
en-US: Host
|
||||
ja-JP: ホスト
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
- field: serverStatus
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: Server Status
|
||||
ja-JP: サーバーステータス
|
||||
- field: processId
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 进程 ID
|
||||
en-US: Process Id
|
||||
ja-JP: プロセスID
|
||||
- field: runningTime
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 运行时间
|
||||
en-US: Running Time
|
||||
en-US: Up Time
|
||||
ja-JP: アップタイム
|
||||
- field: cpuUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 处理器使用量
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: memoryUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存使用量
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: diskUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 磁盘使用量
|
||||
en-US: Disk Usage
|
||||
ja-JP: ディスク使用率
|
||||
- field: jvmCpuUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: JVM CPU 使用量
|
||||
en-US: JVM CPU Usage
|
||||
ja-JP: Java仮想マシンのCPU使用率
|
||||
- field: jvmMemoryUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: JVM 内存 使用量
|
||||
en-US: JVM Memory Usage
|
||||
ja-JP: Java仮想マシンのメモリ使用率
|
||||
- field: jvmHeapUsed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 已使用的堆内存大小
|
||||
en-US: JVM Heap Used
|
||||
ja-JP: Java仮想マシンが使用したヒープメモリのサイズ
|
||||
- field: jvmNonHeapUsed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 已使用的非堆内存大小
|
||||
en-US: JVM NonHeap Used
|
||||
ja-JP: Java仮想マシンが使用したノンヒープメモリのサイズ
|
||||
- field: jvmHeapMax
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 配置的最大堆内存大小
|
||||
en-US: JVM Heap Max
|
||||
ja-JP: Java仮想マシンのヒープメモリの最大値
|
||||
- field: jvmNonHeapMax
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 配置的最大非堆内存大小
|
||||
en-US: JVM NonHeap Max
|
||||
ja-JP: Java仮想マシンのノンヒープメモリの最大値
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.heartBeatInfo
|
||||
@@ -219,6 +241,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Worker
|
||||
en-US: Worker
|
||||
ja-JP: ワーカー情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 1
|
||||
@@ -230,92 +253,109 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 主机地址
|
||||
en-US: Host
|
||||
ja-JP: ホスト
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
- field: serverStatus
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: Server Status
|
||||
ja-JP: サーバーステータス
|
||||
- field: processId
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 进程 ID
|
||||
en-US: Process Id
|
||||
ja-JP: プロセスID
|
||||
- field: runningTime
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 运行时间
|
||||
en-US: Running Time
|
||||
en-US: Up Time
|
||||
ja-JP: アップタイム
|
||||
- field: cpuUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 处理器使用量
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: memoryUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存使用量
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: diskUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 磁盘使用量
|
||||
en-US: Disk Usage
|
||||
ja-JP: ディスク使用率
|
||||
- field: jvmCpuUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: JVM CPU 使用量
|
||||
en-US: JVM CPU Usage
|
||||
ja-JP: Java仮想マシンのCPU使用率
|
||||
- field: jvmMemoryUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: JVM 内存 使用量
|
||||
en-US: JVM Memory Usage
|
||||
ja-JP: Java仮想マシンのメモリ使用率
|
||||
- field: jvmHeapUsed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 已使用的堆内存大小
|
||||
en-US: JVM Heap Used
|
||||
ja-JP: Java仮想マシンが使用したヒープメモリのサイズ
|
||||
- field: jvmNonHeapUsed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 已使用的非堆内存大小
|
||||
en-US: JVM NonHeap Used
|
||||
ja-JP: Java仮想マシンが使用したノンヒープメモリのサイズ
|
||||
- field: jvmHeapMax
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 配置的最大堆内存大小
|
||||
en-US: JVM Heap Max
|
||||
ja-JP: Java仮想マシンのヒープメモリの最大値
|
||||
- field: jvmNonHeapMax
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 配置的最大非堆内存大小
|
||||
en-US: JVM NonHeap Max
|
||||
ja-JP: Java仮想マシンのノンヒープメモリの最大値
|
||||
- field: workerHostWeight
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 权重
|
||||
en-US: Weight
|
||||
ja-JP: ウェイト
|
||||
- field: threadPoolUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 线程池使用量
|
||||
en-US: Thread Pool Usage
|
||||
en-US: Thread Pool Usage
|
||||
ja-JP: スレッドプールの使用率
|
||||
- field: workerGroup
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Worker 组
|
||||
en-US: Worker Group
|
||||
ja-JP: ワーカーグループ
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.heartBeatInfo
|
||||
@@ -364,6 +404,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Alert Server
|
||||
en-US: Alert Server
|
||||
ja-JP: アラートサーバーの情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -375,76 +416,90 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 主机地址
|
||||
en-US: Host
|
||||
ja-JP: ホスト
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
- field: serverStatus
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: Server Status
|
||||
ja-JP: サーバーステータス
|
||||
- field: processId
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 进程 ID
|
||||
en-US: Process Id
|
||||
ja-JP: プロセスID
|
||||
- field: runningTime
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 运行时间
|
||||
en-US: Running Time
|
||||
en-US: Up Time
|
||||
ja-JP: アップタイム
|
||||
- field: cpuUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 处理器使用量
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: memoryUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存使用量
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: diskUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 磁盘使用量
|
||||
en-US: Disk Usage
|
||||
ja-JP: ディスク使用率
|
||||
- field: jvmCpuUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: JVM CPU 使用量
|
||||
en-US: JVM CPU Usage
|
||||
ja-JP: Java仮想マシンのCPU使用率
|
||||
- field: jvmMemoryUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: JVM 内存 使用量
|
||||
en-US: JVM Memory Usage
|
||||
ja-JP: Java仮想マシンのメモリ使用率
|
||||
- field: jvmHeapUsed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 已使用的堆内存大小
|
||||
en-US: JVM Heap Used
|
||||
ja-JP: Java仮想マシンが使用したヒープメモリのサイズ
|
||||
- field: jvmNonHeapUsed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 已使用的非堆内存大小
|
||||
en-US: JVM NonHeap Used
|
||||
ja-JP: Java仮想マシンが使用したノンヒープメモリのサイズ
|
||||
- field: jvmHeapMax
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 配置的最大堆内存大小
|
||||
en-US: JVM Heap Max
|
||||
ja-JP: Java仮想マシンのヒープメモリの最大値
|
||||
- field: jvmNonHeapMax
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: JVM 配置的最大非堆内存大小
|
||||
en-US: JVM NonHeap Max
|
||||
ja-JP: Java仮想マシンのノンヒープメモリの最大値
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- $.heartBeatInfo
|
||||
@@ -490,6 +545,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库
|
||||
en-US: Database
|
||||
ja-JP: データベース情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 2
|
||||
@@ -501,26 +557,31 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库类型
|
||||
en-US: Database Type
|
||||
ja-JP: データベースのタイプ
|
||||
- field: state
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: State
|
||||
ja-JP: 状態
|
||||
- field: maxConnections
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大连接数
|
||||
en-US: Max Connections
|
||||
ja-JP: 最大接続数
|
||||
- field: threadsConnections
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 当前连接数
|
||||
en-US: Threads Connections
|
||||
ja-JP: 現在接続数
|
||||
- field: threadsRunningConnections
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 当前活跃连接数
|
||||
en-US: Threads Running Connections
|
||||
ja-JP: 現在のアクティブな接続数
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- dbType
|
||||
|
||||
@@ -490,7 +490,7 @@ metrics:
|
||||
zh-CN: 次数
|
||||
en-US: Num
|
||||
ja-JP: 数量
|
||||
- field: size
|
||||
- field: Size
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
|
||||
@@ -62,6 +62,7 @@ params:
|
||||
type: number
|
||||
required: false
|
||||
hide: true
|
||||
defaultValue: 6000
|
||||
- field: authType
|
||||
name:
|
||||
zh-CN: 认证方式
|
||||
@@ -125,7 +126,7 @@ metrics:
|
||||
zh-CN: 状态
|
||||
en-US: Status
|
||||
ja-JP: ステータス
|
||||
- field: size
|
||||
- field: Size
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
@@ -137,6 +138,18 @@ metrics:
|
||||
zh-CN: 可用数量
|
||||
en-US: Available Size
|
||||
ja-JP: 利用可能なサイズ
|
||||
aliasFields:
|
||||
- $.app
|
||||
- $.category
|
||||
- $.status
|
||||
- $.size
|
||||
- $.availableSize
|
||||
calculates:
|
||||
- app=$.app
|
||||
- category=$.category
|
||||
- status=$.status
|
||||
- Size=$.size
|
||||
- availableSize=$.availableSize
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk, we use HTTP protocol here
|
||||
protocol: http
|
||||
# the config content when protocol is http
|
||||
@@ -228,7 +241,7 @@ metrics:
|
||||
priority: 1
|
||||
fields:
|
||||
- field: state
|
||||
type: 2
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: State
|
||||
|
||||
@@ -160,7 +160,7 @@ metrics:
|
||||
zh-CN: 状态
|
||||
en-US: Status
|
||||
ja-JP: ステータス
|
||||
- field: size
|
||||
- field: Size
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
@@ -172,6 +172,18 @@ metrics:
|
||||
zh-CN: 可用数量
|
||||
en-US: Available Size
|
||||
ja-JP: 利用可能なサイズ
|
||||
aliasFields:
|
||||
- $.app
|
||||
- $.category
|
||||
- $.status
|
||||
- $.size
|
||||
- $.availableSize
|
||||
calculates:
|
||||
- app=$.app
|
||||
- category=$.category
|
||||
- status=$.status
|
||||
- Size=$.size
|
||||
- availableSize=$.availableSize
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -26,7 +26,7 @@ help:
|
||||
zh-CN: Hertzbeat 使用 Prometheus PromQL 从 Prometheus 服务器中查询到 InfluxDB 的通用指标数据来进行监控。此方案适用于 Prometheus 已监控 InfluxDB,需要从 Prometheus 服务器抓取 InfluxDB 的监控数据。<br>您可以点击 “<i>新建 InfluxDB-PromQL</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses Prometheus PromQL query metrics data from Prometheus Server to monitoring InfluxDB. This solution is suitable for Prometheus to monitor InfluxDB, and it need to capture InfluxDB monitoring data from the Prometheus server. <br>You could click the "<i>New InfluxDB-PromQL</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 Prometheus PromQL 從 Prometheus 服務器中查詢到 InfluxDB 的通用指標數據來進行監控。此方案適用于 Prometheus 已監控 InfluxDB,需要從 Prometheus 服務器抓取 InfluxDB 的監控數據。<br>您可以點擊 “<i>新建 InfluxDB-PromQL</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は Prometheus PromQL を介して Prometheus サーバーに InfluxDB の一般的なパフォーマンスのメトリクスをクエリして監視します。このシナリオは、PrometheusがすでにInfluxDBを監視しており、PrometheusサーバーからInfluxDBの監視データを取得する必要がある場合に適用されます。。<br>「<i>新規 InfluxDB-PromQL</i>」をクリックして設定しましょう。
|
||||
ja-JP: Hertzbeat は Prometheus PromQL を介して Prometheus サーバーに InfluxDB の一般的なパフォーマンスのメトリクスをクエリして監視します。このシナリオは、PrometheusがすでにInfluxDBを監視しており、PrometheusサーバーからInfluxDBの監視データを取得する必要がある場合に適用されます。<br>「<i>新規 InfluxDB-PromQL</i>」をクリックして設定しましょう。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/influxdb_promql
|
||||
en-US: https://hertzbeat.apache.org/docs/help/influxdb_promql
|
||||
|
||||
@@ -26,7 +26,7 @@ help:
|
||||
zh-CN: Hertzbeat 使用 Prometheus PromQL 从 Prometheus 服务器中查询到 Kafka 的通用指标数据来进行监控。此方案适用于 Prometheus 已监控 Kafka,需要从 Prometheus 服务器抓取 Kafka 的监控数据。<br>您可以点击 “<i>新建 Kafka-PromQL</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses Prometheus PromQL query metrics data from Prometheus Server to monitoring Kafka. This solution is suitable for Prometheus to monitor Kafka, and it need to capture Kafka monitoring data from the Prometheus server. <br>You could click the "<i>New Kafka-PromQL</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 Prometheus PromQL 從 Prometheus 服務器中查詢到 Kafka 的通用指標數據來進行監控。此方案適用于 Prometheus 已監控 Kafka,需要從 Prometheus 服務器抓取 Kafka 的監控數據。<br>您可以點擊 “<i>新建 Kafka-PromQL</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は Prometheus PromQL を介して Prometheus サーバーに Kafka の一般的なパフォーマンスのメトリクスをクエリして監視します。このシナリオは、PrometheusがすでにKafkaを監視しており、PrometheusサーバーからKafkaの監視データを取得する必要がある場合に適用されます。。<br>「<i>新規 Kafka-PromQL</i>」をクリックして設定しましょう。
|
||||
ja-JP: Hertzbeat は Prometheus PromQL を介して Prometheus サーバーに Kafka の一般的なパフォーマンスのメトリクスをクエリして監視します。このシナリオは、PrometheusがすでにKafkaを監視しており、PrometheusサーバーからKafkaの監視データを取得する必要がある場合に適用されます。<br>「<i>新規 Kafka-PromQL</i>」をクリックして設定しましょう。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/kafka_promql
|
||||
en-US: https://hertzbeat.apache.org/docs/help/kafka_promql
|
||||
|
||||
@@ -490,7 +490,7 @@ metrics:
|
||||
zh-CN: 次数
|
||||
en-US: Num
|
||||
ja-JP: 数量
|
||||
- field: size
|
||||
- field: Size
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
|
||||
@@ -0,0 +1,750 @@
|
||||
# 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: os
|
||||
# The monitoring type eg: linux windows tomcat mysql aws...
|
||||
app: macos
|
||||
# The monitoring i18n name
|
||||
name:
|
||||
zh-CN: macOS
|
||||
en-US: macOS
|
||||
ja-JP: macOS
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 macOS 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 macOS</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 macOS 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 macOS</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> 對 macOS 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 macOS</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> macOS システムの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 macOS</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/macos/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/macos/
|
||||
# Input params define for monitoring(render web ui by the definition)
|
||||
params:
|
||||
# field-param field key
|
||||
- field: host
|
||||
# name-param field display i18n name
|
||||
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
|
||||
required: true
|
||||
# field-param field key
|
||||
- field: port
|
||||
# name-param field display i18n name
|
||||
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
|
||||
range: '[0,65535]'
|
||||
# required-true or false
|
||||
required: true
|
||||
# default value
|
||||
defaultValue: 22
|
||||
# field-param field key
|
||||
- field: timeout
|
||||
# name-param field display i18n name
|
||||
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
|
||||
range: '[400,200000]'
|
||||
# required-true or false
|
||||
required: false
|
||||
# default value
|
||||
defaultValue: 6000
|
||||
# field-param field key
|
||||
- field: reuseConnection
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: 接続再利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
required: true
|
||||
defaultValue: true
|
||||
# field-param field key
|
||||
- field: useProxy
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシ接続利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
required: true
|
||||
defaultValue: false
|
||||
# field-param field key
|
||||
- field: username
|
||||
# name-param field display i18n name
|
||||
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
|
||||
limit: 50
|
||||
# required-true or false
|
||||
required: true
|
||||
# field-param field key
|
||||
- field: password
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
required: false
|
||||
# field-param field key
|
||||
- field: privateKey
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 私钥
|
||||
en-US: PrivateKey
|
||||
ja-JP: 秘密鍵
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
# required-true or false
|
||||
required: false
|
||||
# hide param-true or false
|
||||
hide: true
|
||||
# field-param field key
|
||||
- field: privateKeyPassphrase
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 密钥短语
|
||||
en-US: PrivateKey PassPhrase
|
||||
ja-JP: 秘密鍵フレーズ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: password
|
||||
# required-true or false
|
||||
required: false
|
||||
# hide param-true or false
|
||||
hide: true
|
||||
# field-param field key
|
||||
- field: proxyHost
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 代理主机
|
||||
en-US: Proxy Host
|
||||
ja-JP: プロキシホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
required: false
|
||||
# hide param-true or false
|
||||
hide: true
|
||||
- field: proxyPort
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 代理端口
|
||||
en-US: Proxy Port
|
||||
ja-JP: プロキシポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
range: '[0,65535]'
|
||||
# required-true or false
|
||||
required: false
|
||||
# hide param-true or false
|
||||
hide: true
|
||||
# default value
|
||||
defaultValue: 22
|
||||
# field-param field key
|
||||
- field: proxyUsername
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 代理用户名
|
||||
en-US: Proxy Username
|
||||
ja-JP: プロキシユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
limit: 50
|
||||
# required-true or false
|
||||
required: false
|
||||
# hide param-true or false
|
||||
hide: true
|
||||
# field-param field key
|
||||
- field: proxyPassword
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 代理密码
|
||||
en-US: Proxy Password
|
||||
ja-JP: プロキシパスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
required: false
|
||||
# hide param-true or false
|
||||
hide: true
|
||||
# field-param field key
|
||||
- field: proxyPrivateKey
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 代理主机私钥
|
||||
en-US: proxyPrivateKey
|
||||
ja-JP: プロキシ秘密鍵
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
# required-true or false
|
||||
required: false
|
||||
# hide param-true or false
|
||||
hide: true
|
||||
# collect metrics config list
|
||||
metrics:
|
||||
# metrics - basic, inner monitoring metrics (responseTime - response time)
|
||||
- name: basic
|
||||
i18n:
|
||||
zh-CN: 系统基本信息
|
||||
en-US: Basic Info
|
||||
ja-JP: システム基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
# 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: hostname
|
||||
type: 1
|
||||
label: true
|
||||
i18n:
|
||||
zh-CN: 主机名称
|
||||
en-US: Host Name
|
||||
ja-JP: ホスト名
|
||||
- field: version
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: オーエスバージョン
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 启动时间
|
||||
en-US: Uptime
|
||||
ja-JP: アップタイム
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: ssh
|
||||
# the config content when protocol is ssh
|
||||
ssh:
|
||||
# ssh host: ipv4 ipv6 domain
|
||||
host: ^_^host^_^
|
||||
# ssh port
|
||||
port: ^_^port^_^
|
||||
# ssh username
|
||||
username: ^_^username^_^
|
||||
# ssh password
|
||||
password: ^_^password^_^
|
||||
# ssh private key
|
||||
privateKey: ^_^privateKey^_^
|
||||
# ssh private key passphrase
|
||||
privateKeyPassphrase: ^_^privateKeyPassphrase^_^
|
||||
timeout: ^_^timeout^_^
|
||||
reuseConnection: ^_^reuseConnection^_^
|
||||
# whether to use proxy server for ssh connection
|
||||
useProxy: ^_^useProxy^_^
|
||||
# ssh proxy host: ipv4 domain
|
||||
proxyHost: ^_^proxyHost^_^
|
||||
# ssh proxy port
|
||||
proxyPort: ^_^proxyPort^_^
|
||||
# ssh proxy username
|
||||
proxyUsername: ^_^proxyUsername^_^
|
||||
# ssh proxy password
|
||||
proxyPassword: ^_^proxyPassword^_^
|
||||
# ssh proxy private key
|
||||
proxyPrivateKey: ^_^proxyPrivateKey^_^
|
||||
# ssh run collect script
|
||||
script: scutil --get ComputerName; echo "$(sw_vers -productName) $(sw_vers -productVersion) ($(sw_vers -buildVersion))"; uptime| awk '{print $1,$2,$3,$4}' | sed 's/,//'
|
||||
# ssh response data parse type: oneRow, multiRow
|
||||
parseType: oneRow
|
||||
|
||||
- name: cpu
|
||||
i18n:
|
||||
zh-CN: CPU 信息
|
||||
en-US: CPU Info
|
||||
ja-JP: CPU情報
|
||||
priority: 1
|
||||
fields:
|
||||
- field: info
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 型号
|
||||
en-US: Info
|
||||
ja-JP: バージョン
|
||||
- field: cores
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 核数
|
||||
en-US: Cores
|
||||
ja-JP: コア数
|
||||
- field: load
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 负载
|
||||
en-US: Load
|
||||
ja-JP: ロード
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 使用率
|
||||
en-US: Usage
|
||||
ja-JP: 使用率
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- info
|
||||
- cores
|
||||
- load
|
||||
- idle
|
||||
# mapping and conversion expressions, use these and aliasField above to calculate metrics value
|
||||
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
|
||||
calculates:
|
||||
- info=info
|
||||
- cores=cores
|
||||
- load=load
|
||||
- usage=idle
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
username: ^_^username^_^
|
||||
password: ^_^password^_^
|
||||
privateKey: ^_^privateKey^_^
|
||||
privateKeyPassphrase: ^_^privateKeyPassphrase^_^
|
||||
timeout: ^_^timeout^_^
|
||||
reuseConnection: ^_^reuseConnection^_^
|
||||
# whether to use proxy server for ssh connection
|
||||
useProxy: ^_^useProxy^_^
|
||||
# ssh proxy host: ipv4 domain
|
||||
proxyHost: ^_^proxyHost^_^
|
||||
# ssh proxy port
|
||||
proxyPort: ^_^proxyPort^_^
|
||||
# ssh proxy username
|
||||
proxyUsername: ^_^proxyUsername^_^
|
||||
# ssh proxy password
|
||||
proxyPassword: ^_^proxyPassword^_^
|
||||
# ssh proxy private key
|
||||
proxyPrivateKey: ^_^proxyPrivateKey^_^
|
||||
script: sysctl -n machdep.cpu.brand_string; sysctl -n hw.ncpu; sysctl -n vm.loadavg | awk '{print $2,$3,$4}'; top -l 1 | grep 'CPU usage' | awk '{print $3}' | sed 's/%//'
|
||||
parseType: oneRow
|
||||
|
||||
- name: memory
|
||||
i18n:
|
||||
zh-CN: 内存信息
|
||||
en-US: Memory Info
|
||||
ja-JP: メモリ情報
|
||||
priority: 2
|
||||
fields:
|
||||
- field: total
|
||||
type: 1
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 总内存容量
|
||||
en-US: Total Memory
|
||||
ja-JP: メモリ容量
|
||||
- field: used
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 用户程序内存量
|
||||
en-US: User Program Memory
|
||||
ja-JP: ユーザープログラムメモリ
|
||||
- field: free
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 空闲内存容量
|
||||
en-US: Free Memory
|
||||
ja-JP: 空きメモリ
|
||||
- field: buff_cache
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 缓存占用内存
|
||||
en-US: Buff Cache Memory
|
||||
ja-JP: バッファメモリ
|
||||
- field: available
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 剩余可用内存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能のメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存使用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
aliasFields:
|
||||
- total
|
||||
- used
|
||||
- free
|
||||
- buff_cache
|
||||
- available
|
||||
calculates:
|
||||
- total=total
|
||||
- used=used
|
||||
- free=free
|
||||
- buff_cache=buff_cache
|
||||
- available=available
|
||||
- usage=(used / total) * 100
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
username: ^_^username^_^
|
||||
password: ^_^password^_^
|
||||
privateKey: ^_^privateKey^_^
|
||||
privateKeyPassphrase: ^_^privateKeyPassphrase^_^
|
||||
timeout: ^_^timeout^_^
|
||||
reuseConnection: ^_^reuseConnection^_^
|
||||
# whether to use proxy server for ssh connection
|
||||
useProxy: ^_^useProxy^_^
|
||||
# ssh proxy host: ipv4 domain
|
||||
proxyHost: ^_^proxyHost^_^
|
||||
# ssh proxy port
|
||||
proxyPort: ^_^proxyPort^_^
|
||||
# ssh proxy username
|
||||
proxyUsername: ^_^proxyUsername^_^
|
||||
# ssh proxy password
|
||||
proxyPassword: ^_^proxyPassword^_^
|
||||
# ssh proxy private key
|
||||
proxyPrivateKey: ^_^proxyPrivateKey^_^
|
||||
script: echo "total used free buff_cache available"; vm_stat | awk 'BEGIN{cmd="sysctl -n hw.memsize";cmd|getline total;close(cmd);cmd="sysctl -n hw.pagesize";cmd|getline ps;close(cmd);total=total/1024/1024} /Pages free/{free=$3} /Pages active/{active=$3} /Pages inactive/{inactive=$3} /Pages wired/{wired=$4} /Pages occupied by compressor/{comp=$5} END{free_mb=free*ps/1024/1024;used_mb=(active+inactive+wired+comp)*ps/1024/1024;inactive_mb=inactive*ps/1024/1024;avail_mb=(free+inactive)*ps/1024/1024;printf "%.0f %.0f %.0f %.0f %.0f\n",total,used_mb,free_mb,inactive_mb,avail_mb}'
|
||||
parseType: multiRow
|
||||
|
||||
- name: disk
|
||||
i18n:
|
||||
zh-CN: 磁盘信息
|
||||
en-US: Disk Info
|
||||
ja-JP: ディスク情報
|
||||
priority: 3
|
||||
fields:
|
||||
- field: disk_num
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 磁盘总数
|
||||
en-US: Disk Num
|
||||
ja-JP: ディスク番号
|
||||
- field: partition_num
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 分区总数
|
||||
en-US: Partition Num
|
||||
ja-JP: パーティション
|
||||
- field: block_write
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 写磁盘块数
|
||||
en-US: Block Write
|
||||
ja-JP: 書き込みディスクブロック数
|
||||
- field: block_read
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 读磁盘块数
|
||||
en-US: Block Read
|
||||
ja-JP: 読み取りブロック数
|
||||
- field: write_rate
|
||||
type: 0
|
||||
unit: iops
|
||||
i18n:
|
||||
zh-CN: 磁盘写速率
|
||||
en-US: Write Rate
|
||||
ja-JP: ディスク書き込み速度
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
username: ^_^username^_^
|
||||
password: ^_^password^_^
|
||||
privateKey: ^_^privateKey^_^
|
||||
privateKeyPassphrase: ^_^privateKeyPassphrase^_^
|
||||
timeout: ^_^timeout^_^
|
||||
reuseConnection: ^_^reuseConnection^_^
|
||||
# whether to use proxy server for ssh connection
|
||||
useProxy: ^_^useProxy^_^
|
||||
# ssh proxy host: ipv4 domain
|
||||
proxyHost: ^_^proxyHost^_^
|
||||
# ssh proxy port
|
||||
proxyPort: ^_^proxyPort^_^
|
||||
# ssh proxy username
|
||||
proxyUsername: ^_^proxyUsername^_^
|
||||
# ssh proxy password
|
||||
proxyPassword: ^_^proxyPassword^_^
|
||||
# ssh proxy private key
|
||||
proxyPrivateKey: ^_^proxyPrivateKey^_^
|
||||
script: iostat -d | awk 'NR==3{print $1}'; iostat -d | awk 'NR==3{print $2}'; vm_stat | awk '/Pages free/{print $3}' | tr -d ':'; vm_stat | awk '/Pages active/{print $3}' | tr -d ':'; sysctl -n hw.memsize | awk '{print int($1/1024/1024)}'
|
||||
parseType: oneRow
|
||||
|
||||
- name: interface
|
||||
i18n:
|
||||
zh-CN: 网卡信息
|
||||
en-US: Interface Info
|
||||
ja-JP: ネットワークカード情報
|
||||
priority: 4
|
||||
fields:
|
||||
- field: interface_name
|
||||
type: 1
|
||||
label: true
|
||||
i18n:
|
||||
zh-CN: 网卡名称
|
||||
en-US: Interface Name
|
||||
ja-JP: ネットワークカード名
|
||||
- field: receive_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 入站数据流量
|
||||
en-US: Receive Bytes
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: transmit_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 出站数据流量
|
||||
en-US: Transmit Bytes
|
||||
ja-JP: 転送されたバイト数
|
||||
units:
|
||||
- receive_bytes=B->MB
|
||||
- transmit_bytes=B->MB
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
username: ^_^username^_^
|
||||
password: ^_^password^_^
|
||||
privateKey: ^_^privateKey^_^
|
||||
privateKeyPassphrase: ^_^privateKeyPassphrase^_^
|
||||
timeout: ^_^timeout^_^
|
||||
reuseConnection: ^_^reuseConnection^_^
|
||||
# whether to use proxy server for ssh connection
|
||||
useProxy: ^_^useProxy^_^
|
||||
# ssh proxy host: ipv4 domain
|
||||
proxyHost: ^_^proxyHost^_^
|
||||
# ssh proxy port
|
||||
proxyPort: ^_^proxyPort^_^
|
||||
# ssh proxy username
|
||||
proxyUsername: ^_^proxyUsername^_^
|
||||
# ssh proxy password
|
||||
proxyPassword: ^_^proxyPassword^_^
|
||||
# ssh proxy private key
|
||||
proxyPrivateKey: ^_^proxyPrivateKey^_^
|
||||
script: netstat -ibn | awk 'NR==1{print "interface_name receive_bytes transmit_bytes"} NR>1 && $1!~/Name/ && $7~/^[0-9]+$/{print $1,$7,$10}'
|
||||
parseType: multiRow
|
||||
|
||||
- name: disk_free
|
||||
i18n:
|
||||
zh-CN: 文件系统
|
||||
en-US: Disk Free
|
||||
ja-JP: ファイルシステム
|
||||
priority: 5
|
||||
fields:
|
||||
- field: filesystem
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 文件系统
|
||||
en-US: Filesystem
|
||||
ja-JP: ファイルシステム
|
||||
- field: used
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 已使用量
|
||||
en-US: Used
|
||||
ja-JP: 使用済み
|
||||
- field: available
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 可用量
|
||||
en-US: Available
|
||||
ja-JP: 使用可能
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 使用率
|
||||
en-US: Usage
|
||||
ja-JP: 使用率
|
||||
- field: mounted
|
||||
type: 1
|
||||
label: true
|
||||
i18n:
|
||||
zh-CN: 挂载点
|
||||
en-US: Mounted
|
||||
ja-JP: マウント
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
username: ^_^username^_^
|
||||
password: ^_^password^_^
|
||||
privateKey: ^_^privateKey^_^
|
||||
privateKeyPassphrase: ^_^privateKeyPassphrase^_^
|
||||
timeout: ^_^timeout^_^
|
||||
reuseConnection: ^_^reuseConnection^_^
|
||||
# whether to use proxy server for ssh connection
|
||||
useProxy: ^_^useProxy^_^
|
||||
# ssh proxy host: ipv4 domain
|
||||
proxyHost: ^_^proxyHost^_^
|
||||
# ssh proxy port
|
||||
proxyPort: ^_^proxyPort^_^
|
||||
# ssh proxy username
|
||||
proxyUsername: ^_^proxyUsername^_^
|
||||
# ssh proxy password
|
||||
proxyPassword: ^_^proxyPassword^_^
|
||||
# ssh proxy private key
|
||||
proxyPrivateKey: ^_^proxyPrivateKey^_^
|
||||
script: df -m | tail -n +2 | awk 'BEGIN{ print "filesystem used available usage mounted"} {print $1,$3,$4,$5,$9}'
|
||||
parseType: multiRow
|
||||
|
||||
- name: top_cpu_process
|
||||
i18n:
|
||||
zh-CN: Top10 CPU 进程
|
||||
en-US: Top10 CPU Process
|
||||
ja-JP: トップ10 CPUプロセス
|
||||
priority: 6
|
||||
fields:
|
||||
- field: pid
|
||||
type: 1
|
||||
label: true
|
||||
i18n:
|
||||
zh-CN: 进程ID
|
||||
en-US: PID
|
||||
ja-JP: プロセスID
|
||||
- field: cpu_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: CPU占用率
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: mem_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存占用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: command
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
username: ^_^username^_^
|
||||
password: ^_^password^_^
|
||||
privateKey: ^_^privateKey^_^
|
||||
privateKeyPassphrase: ^_^privateKeyPassphrase^_^
|
||||
timeout: ^_^timeout^_^
|
||||
reuseConnection: ^_^reuseConnection^_^
|
||||
# whether to use proxy server for ssh connection
|
||||
useProxy: ^_^useProxy^_^
|
||||
# ssh proxy host: ipv4 domain
|
||||
proxyHost: ^_^proxyHost^_^
|
||||
# ssh proxy port
|
||||
proxyPort: ^_^proxyPort^_^
|
||||
# ssh proxy username
|
||||
proxyUsername: ^_^proxyUsername^_^
|
||||
# ssh proxy password
|
||||
proxyPassword: ^_^proxyPassword^_^
|
||||
# ssh proxy private key
|
||||
proxyPrivateKey: ^_^proxyPrivateKey^_^
|
||||
script: ps aux | sort -k3nr | awk 'BEGIN{ print "pid cpu_usage mem_usage command" } {printf "%s %s %s ", $2, $3, $4; for (i=11; i<=NF; i++) { printf "%s", $i; if (i < NF) printf " "; } print ""}' | head -n 11
|
||||
parseType: multiRow
|
||||
|
||||
- name: top_mem_process
|
||||
i18n:
|
||||
zh-CN: Top10 内存进程
|
||||
en-US: Top10 Memory Process
|
||||
ja-JP: トップ10 メモリプロセス
|
||||
priority: 7
|
||||
fields:
|
||||
- field: pid
|
||||
type: 1
|
||||
label: true
|
||||
i18n:
|
||||
zh-CN: 进程ID
|
||||
en-US: PID
|
||||
ja-JP: プロセスID
|
||||
- field: mem_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存占用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: cpu_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: CPU占用率
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: command
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
username: ^_^username^_^
|
||||
password: ^_^password^_^
|
||||
privateKey: ^_^privateKey^_^
|
||||
privateKeyPassphrase: ^_^privateKeyPassphrase^_^
|
||||
timeout: ^_^timeout^_^
|
||||
reuseConnection: ^_^reuseConnection^_^
|
||||
# whether to use proxy server for ssh connection
|
||||
useProxy: ^_^useProxy^_^
|
||||
# ssh proxy host: ipv4 domain
|
||||
proxyHost: ^_^proxyHost^_^
|
||||
# ssh proxy port
|
||||
proxyPort: ^_^proxyPort^_^
|
||||
# ssh proxy username
|
||||
proxyUsername: ^_^proxyUsername^_^
|
||||
# ssh proxy password
|
||||
proxyPassword: ^_^proxyPassword^_^
|
||||
# ssh proxy private key
|
||||
|
||||
proxyPrivateKey: ^_^proxyPrivateKey^_^
|
||||
script: ps aux | sort -k4nr | awk 'BEGIN{ print "pid cpu_usage mem_usage command" } NR>1{cmd=""; for(i=11;i<=NF;i++) cmd=cmd $i (i==NF?"":" "); printf "%s %s %s %s\n", $2, $3, $4, cmd}' | head -n 11
|
||||
parseType: multiRow
|
||||
@@ -651,7 +651,7 @@ metrics:
|
||||
zh-CN: 次数
|
||||
en-US: Num
|
||||
ja-JP: 数量
|
||||
- field: size
|
||||
- field: Size
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
|
||||
@@ -21,11 +21,13 @@ app: redis_sentinel
|
||||
name:
|
||||
zh-CN: Redis Sentinel
|
||||
en-US: Redis Sentinel
|
||||
ja-JP: Redis Sentinel
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 对 Redis Sentinel 的通用指标进行采集监控。<br>您可以点击 “<i>新建 Redis Cluster</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitors Redis Database Sentinel's general performance metrics. You could click the "<i>New Redis Cluster</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 對 Redis Sentinel 的通用指標進行采集監控。<br>您可以點擊 “<i>新建 Redis Cluster</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
zh-CN: Hertzbeat 对 Redis Sentinel 的通用指标进行采集监控。<br>您可以点击 “<i>新建 Redis Sentinel</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat monitors Redis Database Sentinel's general performance metrics. You could click the "<i>New Redis Sentinel</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 對 Redis Sentinel 的通用指標進行采集監控。<br>您可以點擊 “<i>新建 Redis Sentinel</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は Redis Sentinel の一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Redis Sentinel</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/influxdb_promql
|
||||
en-US: https://hertzbeat.apache.org/docs/help/influxdb_promql
|
||||
@@ -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
|
||||
@@ -46,6 +49,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
|
||||
@@ -60,6 +64,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
|
||||
# when type is number, range is required
|
||||
@@ -74,6 +79,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
|
||||
@@ -86,6 +92,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -96,6 +103,7 @@ params:
|
||||
name:
|
||||
zh-CN: 模式
|
||||
en-US: Pattern
|
||||
ja-JP: パターン
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# required-true or false
|
||||
@@ -108,6 +116,7 @@ params:
|
||||
name:
|
||||
zh-CN: 是否启用SSH隧道
|
||||
en-US: Enable SSH Tunnel
|
||||
ja-JP: SSHトンネルの有効化
|
||||
type: boolean
|
||||
required: true
|
||||
hide: true
|
||||
@@ -115,6 +124,7 @@ params:
|
||||
name:
|
||||
zh-CN: SSH Host
|
||||
en-US: SSH Host
|
||||
ja-JP: SSHホスト
|
||||
type: text
|
||||
required: false
|
||||
placeholder: 'When Enable SSH Tunnel'
|
||||
@@ -123,6 +133,7 @@ params:
|
||||
name:
|
||||
zh-CN: SSH端口
|
||||
en-US: SSH Port
|
||||
ja-JP: SSHポート
|
||||
type: number
|
||||
range: '[0,65535]'
|
||||
required: false
|
||||
@@ -133,6 +144,7 @@ params:
|
||||
name:
|
||||
zh-CN: SSH超时时间(ms)
|
||||
en-US: SSH Timeout(ms)
|
||||
ja-JP: SSHタイムアウト(ms)
|
||||
type: number
|
||||
required: false
|
||||
range: '[400,200000]'
|
||||
@@ -142,6 +154,7 @@ params:
|
||||
name:
|
||||
zh-CN: SSH用户名
|
||||
en-US: SSH Username
|
||||
ja-JP: SSHユーザー名
|
||||
type: text
|
||||
required: false
|
||||
placeholder: 'When Enable SSH tunnel'
|
||||
@@ -150,6 +163,7 @@ params:
|
||||
name:
|
||||
zh-CN: SSH密码
|
||||
en-US: SSH Password
|
||||
ja-JP: SSHパスワード
|
||||
type: password
|
||||
required: false
|
||||
hide: true
|
||||
@@ -157,6 +171,7 @@ params:
|
||||
name:
|
||||
zh-CN: 是否共享SSH连接
|
||||
en-US: Share SSH Connection
|
||||
ja-JP: SSH接続共有
|
||||
type: boolean
|
||||
required: true
|
||||
defaultValue: true
|
||||
@@ -165,6 +180,7 @@ params:
|
||||
name:
|
||||
zh-CN: SSH私钥
|
||||
en-US: SSH PrivateKey
|
||||
ja-JP: SSH秘密鍵
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
required: false
|
||||
@@ -173,6 +189,7 @@ params:
|
||||
name:
|
||||
zh-CN: SSH密钥短语
|
||||
en-US: SSH PrivateKey PassPhrase
|
||||
ja-JP: SSH秘密鍵フレーズ
|
||||
type: password
|
||||
required: false
|
||||
hide: true
|
||||
@@ -181,6 +198,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 服务器
|
||||
en-US: Server
|
||||
ja-JP: サーバー情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -191,121 +209,145 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 标识
|
||||
en-US: Identity
|
||||
ja-JP: ID
|
||||
- field: redis_version
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Redis 版本
|
||||
en-US: Redis Version
|
||||
ja-JP: Redisバージョン
|
||||
- field: redis_git_sha1
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Redis Git SHA1
|
||||
en-US: Redis Git SHA1
|
||||
ja-JP: Redis Git SHA1
|
||||
- field: redis_git_dirty
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Redis Git Dirty
|
||||
en-US: Redis Git Dirty
|
||||
ja-JP: RedisサーバーのGitリポジトリ状態
|
||||
- field: redis_build_id
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Redis Build ID
|
||||
en-US: Redis Build ID
|
||||
ja-JP: Redis ビルド Id
|
||||
- field: redis_mode
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Redis 模式
|
||||
en-US: Redis Mode
|
||||
ja-JP: Redis モード
|
||||
- field: os
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 操作系统
|
||||
en-US: Operating System
|
||||
ja-JP: オーエス
|
||||
- field: arch_bits
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 架构位数
|
||||
en-US: Architecture Bits
|
||||
ja-JP: アーキテクチャ
|
||||
- field: multiplexing_api
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 多路复用 API
|
||||
en-US: Multiplexing API
|
||||
ja-JP: IO多重化API
|
||||
- field: atomicvar_api
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 原子变量 API
|
||||
en-US: Atomicvar API
|
||||
ja-JP: 原子操作API
|
||||
- field: gcc_version
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: GCC 版本
|
||||
en-US: GCC Version
|
||||
ja-JP: GCC バージョン
|
||||
- field: process_id
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 进程 ID
|
||||
en-US: Process ID
|
||||
ja-JP: プロセスID
|
||||
- field: process_supervised
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 进程监控
|
||||
en-US: Process Supervised
|
||||
ja-JP: プロセスの監視方法
|
||||
- field: run_id
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 运行 ID
|
||||
en-US: Run ID
|
||||
ja-JP: Run ID
|
||||
- field: tcp_port
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: TCP 端口
|
||||
en-US: TCP Port
|
||||
ja-JP: TCP ポート
|
||||
- field: server_time_usec
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 基于纪元的系统时间
|
||||
en-US: Server Time Usec
|
||||
ja-JP: サーバーのタイムスタンプ
|
||||
- field: uptime_in_seconds
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 运行时间(秒)
|
||||
en-US: Uptime In Seconds
|
||||
ja-JP: アップタイム(秒)
|
||||
- field: uptime_in_days
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 运行时间(天)
|
||||
en-US: Uptime In Days
|
||||
ja-JP: アップタイム(日)
|
||||
- field: hz
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 定时器频率
|
||||
en-US: Hz
|
||||
ja-JP: イベントの実行頻度
|
||||
- field: configured_hz
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 配置定时器频率
|
||||
en-US: Configured Hz
|
||||
ja-JP: 設定されたイベントの実行頻度
|
||||
- field: lru_clock
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: LRU 时钟
|
||||
en-US: LRU Clock
|
||||
ja-JP: LRU クロック
|
||||
- field: executable
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 可执行文件
|
||||
en-US: Executable
|
||||
ja-JP: サーバーの実行パス
|
||||
- field: config_file
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 配置文件
|
||||
en-US: Config File
|
||||
ja-JP: 設定されたサーバーの実行ファイル
|
||||
- field: io_threads_active
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活动 IO 线程
|
||||
en-US: IO Threads Active
|
||||
ja-JP: 活動中のスレッド数
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: redis
|
||||
# the config content when protocol is redis
|
||||
@@ -336,6 +378,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 客户端
|
||||
en-US: Clients
|
||||
ja-JP: クライアント情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 1
|
||||
@@ -346,41 +389,49 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 已连接客户端
|
||||
en-US: Connected Clients
|
||||
ja-JP: 現在接続されているクライアントの数
|
||||
- field: cluster_connections
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 集群连接
|
||||
en-US: Cluster Connections
|
||||
ja-JP: クラスター内の接続数
|
||||
- field: maxclients
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大客户端数
|
||||
en-US: Maxclients
|
||||
ja-JP: 最大クライアント数
|
||||
- field: client_recent_max_input_buffer
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 客户端最近最大输入缓冲区
|
||||
en-US: Client Recent Max Input Buffer
|
||||
ja-JP: クライアントの最近の最大入力バッファサイズ
|
||||
- field: client_recent_max_output_buffer
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 客户端最近最大输出缓冲区
|
||||
en-US: Client Recent Max Output Buffer
|
||||
ja-JP: クライアントの最近の最大出力バッファサイズ
|
||||
- field: blocked_clients
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 阻塞客户端
|
||||
en-US: Blocked Clients
|
||||
ja-JP: ブロックされたクライアント数
|
||||
- field: tracking_clients
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 跟踪客户端
|
||||
en-US: Tracking Clients
|
||||
ja-JP: トラッキングを使用するクライアントの数
|
||||
- field: clients_in_timeout_table
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 超时表中的客户端
|
||||
en-US: Clients In Timeout Table
|
||||
ja-JP: タイムアウトテーブル内のクライアント数
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: redis
|
||||
# the config content when protocol is redis
|
||||
@@ -411,6 +462,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 统计
|
||||
en-US: Stats
|
||||
ja-JP: 統計情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 2
|
||||
@@ -421,191 +473,229 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 收到总连接数
|
||||
en-US: Total Connections Received
|
||||
ja-JP: サーバーの起動後に受信された合計接続数
|
||||
- field: total_commands_processed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 处理总命令数
|
||||
en-US: Total Commands Processed
|
||||
ja-JP: サーバーの起動後に処理した総コマンド数
|
||||
- field: instantaneous_ops_per_sec
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 瞬时每秒操作数
|
||||
en-US: Instantaneous Ops Per Sec
|
||||
ja-JP: 1秒当たりに処理されたコマンドの数
|
||||
- field: total_net_input_bytes
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 总网络输入字节
|
||||
en-US: Total Net Input Bytes
|
||||
ja-JP: 受信されたネットワークバイトの合計数
|
||||
- field: total_net_output_bytes
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 总网络输出字节
|
||||
en-US: Total Net Output Bytes
|
||||
ja-JP: 転送されたネットワークバイトの合計数
|
||||
- field: instantaneous_input_kbps
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 瞬时的输入 kbps
|
||||
en-US: Instantaneous Input Kbps
|
||||
ja-JP: 瞬間入力速度(kbps)
|
||||
- field: instantaneous_output_kbps
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 瞬时输出 kbps
|
||||
en-US: Instantaneous Output Kbps
|
||||
ja-JP: 瞬間出力速度(kbps)
|
||||
- field: rejected_connections
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 拒绝连接数
|
||||
en-US: Rejected Connections
|
||||
ja-JP: maxclients制限で拒否された接続数
|
||||
- field: sync_full
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 全量同步
|
||||
en-US: Sync Full
|
||||
ja-JP: 完全同期の回数
|
||||
- field: sync_partial_ok
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 部分同步成功
|
||||
en-US: Sync Partial Ok
|
||||
ja-JP: 部分同期の回数
|
||||
- field: sync_partial_err
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 部分同步失败
|
||||
en-US: Sync Partial Err
|
||||
ja-JP: 部分同期のエラー回数
|
||||
- field: expired_keys
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 过期键
|
||||
en-US: Expired Keys
|
||||
ja-JP: expireコマンドで削除されたキーの数
|
||||
- field: expired_stale_perc
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 过期key占比
|
||||
en-US: Expired Stale Perc
|
||||
ja-JP: 期限切れのステイルキーの比率
|
||||
- field: expired_time_cap_reached_count
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 达到过期时间上限计数
|
||||
en-US: Expired Time Cap Reached Count
|
||||
ja-JP: 満了時間の制限に達した回数
|
||||
- field: expire_cycle_cpu_milliseconds
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 过期周期 CPU 毫秒
|
||||
en-US: Expire Cycle CPU Milliseconds
|
||||
ja-JP: 満了サイクルでかかったCPU時間(ms)
|
||||
- field: evicted_keys
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 逐出键
|
||||
en-US: Evicted Keys
|
||||
ja-JP: メモリ不足で追放されたキーの数
|
||||
- field: keyspace_hits
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 命中键
|
||||
en-US: Keyspace Hits
|
||||
ja-JP: キースペースのヒット数
|
||||
- field: keyspace_misses
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 未命中键
|
||||
en-US: Keyspace Misses
|
||||
ja-JP: キースペースのミス数
|
||||
- field: pubsub_channels
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 发布订阅频道
|
||||
en-US: Pubsub Channels
|
||||
ja-JP: 有効になっているPub/Subチャネルに接続されているチャネルの数
|
||||
- field: pubsub_patterns
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 发布订阅模式
|
||||
en-US: Pubsub Patterns
|
||||
ja-JP: 有効になっているPub/Subパターンで接続されたパターンチャネルの数
|
||||
- field: latest_fork_usec
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最新 fork 毫秒
|
||||
en-US: Latest Fork Usec
|
||||
ja-JP: 最後のフォーク作業にかかった時間
|
||||
- field: total_forks
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 总 fork 数
|
||||
en-US: Total Forks
|
||||
ja-JP: 実行されたフォーク作業の合計数
|
||||
- field: migrate_cached_sockets
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 迁移缓存套接字
|
||||
en-US: Migrate Cached Sockets
|
||||
ja-JP: マイグレーションされたソケット数
|
||||
- field: slave_expires_tracked_keys
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 从节点过期跟踪键
|
||||
en-US: Slave Expires Tracked Keys
|
||||
ja-JP: スレーブで満了した、トラッキングされたキーの数
|
||||
- field: active_defrag_hits
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活跃碎片整理命中
|
||||
en-US: Active Defrag Hits
|
||||
ja-JP: アクティブなデフラグ操作中に発生したヒットの数
|
||||
- field: active_defrag_misses
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活跃碎片整理未命中
|
||||
en-US: Active Defrag Misses
|
||||
ja-JP: アクティブなデフラグ操作中に見逃したヒットの数
|
||||
- field: active_defrag_key_hits
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活跃碎片整理键命中
|
||||
en-US: Active Defrag Key Hits
|
||||
ja-JP: デフラグ操作でヒットしたキーの数
|
||||
- field: active_defrag_key_misses
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活跃碎片整理键未命中
|
||||
en-US: Active Defrag Key Misses
|
||||
ja-JP: デフラグ操作で見逃したキーの数
|
||||
- field: tracking_total_keys
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 跟踪键总数
|
||||
en-US: Tracking Total Keys
|
||||
ja-JP: トラッキングされたキーの合計数
|
||||
- field: tracking_total_items
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 跟踪项总数
|
||||
en-US: Tracking Total Items
|
||||
ja-JP: トラッキングされたアイテムの合計数
|
||||
- field: tracking_total_prefixes
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 跟踪前缀总数
|
||||
en-US: Tracking Total Prefixes
|
||||
ja-JP: トラッキングされたプレフィックスの合計数
|
||||
- field: unexpected_error_replies
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 意外错误回复
|
||||
en-US: Unexpected Error Replies
|
||||
ja-JP: 予期しないエラー応答の数
|
||||
- field: total_error_replies
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 总错误回复
|
||||
en-US: Total Error Replies
|
||||
ja-JP: 発生したエラーの合計応答の数
|
||||
- field: dump_payload_sanitizations
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 转储有效负载深度完整性验证的总数
|
||||
en-US: Dump Payload Sanitizations
|
||||
ja-JP: ダンプペイロードで実行された整理作業の数
|
||||
- field: total_reads_processed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 总读取处理
|
||||
en-US: Total Reads Processed
|
||||
ja-JP: 処理された読み取り作業の合計数
|
||||
- field: total_writes_processed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 总写入处理
|
||||
en-US: Total Writes Processed
|
||||
ja-JP: 処理された書き込み作業の合計数
|
||||
- field: io_threaded_reads_processed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: IO 线程读取处理
|
||||
en-US: Io Threaded Reads Processed
|
||||
ja-JP: I/Oスレッドで処理された読み取り作業の数
|
||||
- field: io_threaded_writes_processed
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: IO 线程写入处理
|
||||
en-US: Io Threaded Writes Processed
|
||||
ja-JP: I/Oスレッドで処理された書き込み作業の数
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: redis
|
||||
# the config content when protocol is redis
|
||||
@@ -636,6 +726,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: CPU
|
||||
en-US: CPU
|
||||
ja-JP: CPU情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 3
|
||||
@@ -646,31 +737,37 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 系统已使用 CPU
|
||||
en-US: Sys CPU Used
|
||||
ja-JP: システムモードで使用されたCPUの合計時間
|
||||
- field: used_cpu_user
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 用户已使用 CPU
|
||||
en-US: User CPU Used
|
||||
ja-JP: ユーザーモードで使用されたCPUの合計時間
|
||||
- field: used_cpu_sys_children
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Sys 子进程已使用 CPU
|
||||
en-US: Sys Children CPU Used
|
||||
ja-JP: 子プロセスがシステムモードで使用したCPU時間
|
||||
- field: used_cpu_user_children
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 用户子进程已使用 CPU
|
||||
en-US: User Children CPU Used
|
||||
ja-JP: 子プロセスがユーザーモードで使用したCPU時間
|
||||
- field: used_cpu_sys_main_thread
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 系统主线程已使用 CPU
|
||||
en-US: Sys Main Thread CPU Used
|
||||
ja-JP: プロセスがシステムモードで使用したCPU時間
|
||||
- field: used_cpu_user_main_thread
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 用户主线程已使用 CPU
|
||||
en-US: User Main Thread CPU Used
|
||||
ja-JP: プロセスがユーザーモードで使用したCPU時間
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: redis
|
||||
# the config content when protocol is redis
|
||||
@@ -701,6 +798,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 哨兵
|
||||
en-US: Sentinel
|
||||
ja-JP: Sentinel
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 4
|
||||
@@ -711,26 +809,31 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 主节点
|
||||
en-US: Masters
|
||||
ja-JP: マスターノード
|
||||
- field: sentinel_tilt
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 倾斜
|
||||
en-US: Tilt
|
||||
ja-JP: マスターをダウン状態としてマークする前の待機時間
|
||||
- field: sentinel_running_scripts
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 运行脚本
|
||||
en-US: Running Scripts
|
||||
ja-JP: 実行するスクリプト
|
||||
- field: sentinel_scripts_queue_length
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 脚本队列长度
|
||||
en-US: Scripts Queue Length
|
||||
ja-JP: 実行するスクリプトのキューの長さ
|
||||
- field: sentinel_simulate_failure_flags
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 模拟失败标志
|
||||
en-US: Simulate Failure Flags
|
||||
ja-JP: フェイルオーバー機能をテスト用のフラグ
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: redis
|
||||
# the config content when protocol is redis
|
||||
|
||||
@@ -21,11 +21,13 @@ app: rockylinux
|
||||
name:
|
||||
zh-CN: Rocky Linux
|
||||
en-US: Rocky Linux
|
||||
ja-JP: Rocky Linux
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 Rocky 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 Rocky</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 Rocky 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 Rocky</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> 對 Rocky 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 Rocky</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Rockyオーエスの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Rocky</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/rockylinux
|
||||
en-US: https://hertzbeat.apache.org/docs/help/rockylinux
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: 超时时间(ms)
|
||||
en-US: Timeout(ms)
|
||||
ja-JP: タイムアウト(ms)
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -75,6 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: 接続再利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -86,6 +92,7 @@ params:
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシ接続利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -97,6 +104,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -109,6 +117,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -119,6 +128,7 @@ params:
|
||||
name:
|
||||
zh-CN: 私钥
|
||||
en-US: PrivateKey
|
||||
ja-JP: 秘密鍵
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
@@ -132,6 +142,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密钥短语
|
||||
en-US: PrivateKey PassPhrase
|
||||
ja-JP: 秘密鍵フレーズ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -144,6 +155,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理主机
|
||||
en-US: Proxy Host
|
||||
ja-JP: プロキシホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
@@ -155,6 +167,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理端口
|
||||
en-US: Proxy Port
|
||||
ja-JP: プロキシポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -171,6 +184,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理用户名
|
||||
en-US: Proxy Username
|
||||
ja-JP: プロキシユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -185,6 +199,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理密码
|
||||
en-US: Proxy Password
|
||||
ja-JP: プロキシパスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -197,6 +212,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理主机私钥
|
||||
en-US: proxyPrivateKey
|
||||
ja-JP: プロキシ秘密鍵
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
@@ -211,6 +227,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 系统基本信息
|
||||
en-US: Basic Info
|
||||
ja-JP: システム基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -223,16 +240,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 主机名称
|
||||
en-US: Host Name
|
||||
ja-JP: ホスト名
|
||||
- field: version
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: システムバージョン
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 启动时间
|
||||
en-US: Uptime
|
||||
ja-JP: アップタイム
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: ssh
|
||||
# the config content when protocol is ssh
|
||||
@@ -272,6 +292,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: CPU 信息
|
||||
en-US: CPU Info
|
||||
ja-JP: CPU情報
|
||||
priority: 1
|
||||
fields:
|
||||
- field: info
|
||||
@@ -279,32 +300,38 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 型号
|
||||
en-US: Info
|
||||
ja-JP: バージョン
|
||||
- field: cores
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 核数
|
||||
en-US: Cores
|
||||
ja-JP: コア数
|
||||
- field: interrupt
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 中断数
|
||||
en-US: Interrupt
|
||||
ja-JP: 割り込み数
|
||||
- field: load
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 负载
|
||||
en-US: Load
|
||||
ja-JP: ロード
|
||||
- field: context_switch
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 上下文切换
|
||||
en-US: Context Switch
|
||||
ja-JP: コンテキストスイッチ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 使用率
|
||||
en-US: Usage
|
||||
ja-JP: 使用率
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- info
|
||||
@@ -351,6 +378,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 内存信息
|
||||
en-US: Memory Info
|
||||
ja-JP: メモリ情報
|
||||
priority: 2
|
||||
fields:
|
||||
- field: total
|
||||
@@ -359,36 +387,42 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 总内存容量
|
||||
en-US: Total Memory
|
||||
ja-JP: メモリ容量
|
||||
- field: used
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 用户程序内存量
|
||||
en-US: User Program Memory
|
||||
ja-JP: ユーザープログラムメモリ
|
||||
- field: free
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 空闲内存容量
|
||||
en-US: Free Memory
|
||||
ja-JP: 空きメモリ
|
||||
- field: buff_cache
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 缓存占用内存
|
||||
en-US: Buff Cache Memory
|
||||
ja-JP: バッファメモリ
|
||||
- field: available
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 剩余可用内存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能のメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存使用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
aliasFields:
|
||||
- total
|
||||
- used
|
||||
@@ -431,6 +465,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 磁盘信息
|
||||
en-US: Disk Info
|
||||
ja-JP: ディスク情報
|
||||
priority: 3
|
||||
fields:
|
||||
- field: disk_num
|
||||
@@ -438,27 +473,32 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 磁盘总数
|
||||
en-US: Disk Num
|
||||
ja-JP: ディスク番号
|
||||
- field: partition_num
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 分区总数
|
||||
en-US: Partition Num
|
||||
ja-JP: パーティション
|
||||
- field: block_write
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 写磁盘块数
|
||||
en-US: Block Write
|
||||
ja-JP: 書き込みディスクブロック数
|
||||
- field: block_read
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 读磁盘块数
|
||||
en-US: Block Read
|
||||
ja-JP: 読み取りブロック数
|
||||
- field: write_rate
|
||||
type: 0
|
||||
unit: iops
|
||||
i18n:
|
||||
zh-CN: 磁盘写速率
|
||||
en-US: Write Rate
|
||||
ja-JP: ディスク書き込み速度
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -488,6 +528,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 网卡信息
|
||||
en-US: Interface Info
|
||||
ja-JP: ネットワークカード情報
|
||||
priority: 4
|
||||
fields:
|
||||
- field: interface_name
|
||||
@@ -496,18 +537,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 网卡名称
|
||||
en-US: Interface Name
|
||||
ja-JP: ネットワークカード名
|
||||
- field: receive_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 入站数据流量
|
||||
en-US: Receive Bytes
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: transmit_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 出站数据流量
|
||||
en-US: Transmit Bytes
|
||||
ja-JP: 転送されたバイト数
|
||||
units:
|
||||
- receive_bytes=B->MB
|
||||
- transmit_bytes=B->MB
|
||||
@@ -540,6 +584,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 文件系统
|
||||
en-US: Disk Free
|
||||
ja-JP: ファイルシステム
|
||||
priority: 5
|
||||
fields:
|
||||
- field: filesystem
|
||||
@@ -547,30 +592,35 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 文件系统
|
||||
en-US: Filesystem
|
||||
ja-JP: ファイルシステム
|
||||
- field: used
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 已使用量
|
||||
en-US: Used
|
||||
ja-JP: 使用済み
|
||||
- field: available
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 可用量
|
||||
en-US: Available
|
||||
ja-JP: 使用可能
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 使用率
|
||||
en-US: Usage
|
||||
ja-JP: 使用率
|
||||
- field: mounted
|
||||
type: 1
|
||||
label: true
|
||||
i18n:
|
||||
zh-CN: 挂载点
|
||||
en-US: Mounted
|
||||
ja-JP: マウント
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -600,6 +650,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Top10 CPU 进程
|
||||
en-US: Top10 CPU Process
|
||||
ja-JP: トップ10 CPUプロセス
|
||||
priority: 6
|
||||
fields:
|
||||
- field: pid
|
||||
@@ -608,23 +659,27 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程ID
|
||||
en-US: PID
|
||||
ja-JP: プロセスID
|
||||
- field: cpu_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: CPU占用率
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: mem_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存占用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: command
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -654,6 +709,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Top10 内存进程
|
||||
en-US: Top10 Memory Process
|
||||
ja-JP: トップ10 メモリプロセス
|
||||
priority: 7
|
||||
fields:
|
||||
- field: pid
|
||||
@@ -662,23 +718,27 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程ID
|
||||
en-US: PID
|
||||
ja-JP: プロセスID
|
||||
- field: mem_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存占用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: cpu_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: CPU占用率
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: command
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -21,11 +21,13 @@ app: seatunnel
|
||||
name:
|
||||
zh-CN: Seatunnel
|
||||
en-US: Seatunnel
|
||||
ja-JP: Seatunnel
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 对 Seatunnel 通用指标进行测量监控。<br>您可以点击 “<i>新建 Seatunnel</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Hertzbeat measures and monitors the general metrics of Seatunnel.<br>You can click on “<i>Create New Seatunnel</i>” to configure it, or select “<i>More Actions</i>” to import an existing configuration.
|
||||
zh-TW: Hertzbeat 對 Seatunnel 通用指標進行測量監控。<br>您可以點擊 “<i>新建 Seatunnel</i>” 並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は Seatunnelの一般的なメトリクスを監視します。<br>「<i>新規 Seatunnel</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/seatunnel
|
||||
en-US: https://hertzbeat.apache.org/docs/help/seatunnel
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: 查询超时时间
|
||||
en-US: Query Timeout
|
||||
ja-JP: クエリタイムアウト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# required-true or false
|
||||
@@ -75,6 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: SSL
|
||||
ja-JP: SSL
|
||||
# type-param field type(boolean mapping the html h tag)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -86,6 +92,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 集群概览
|
||||
en-US: Cluster Overview
|
||||
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
|
||||
@@ -97,48 +104,56 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 项目版本
|
||||
en-US: Project Version
|
||||
ja-JP: プロジェクトバージョン
|
||||
- field: gitCommitAbbrev
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Git提交编号
|
||||
en-US: Git Commit Abbrev
|
||||
ja-JP: GitコミットID
|
||||
- field: totalSlot
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 总槽位数
|
||||
en-US: Total Slot
|
||||
ja-JP: スロット数
|
||||
- field: unassignedSlot
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 未分配槽位数
|
||||
en-US: Unassigned Slot
|
||||
ja-JP: 未割り当てのスロット数
|
||||
- field: runningJobs
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 运行中任务数
|
||||
en-US: Running Jobs
|
||||
ja-JP: 実行中のタスク数
|
||||
- field: finishedJobs
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 已完成任务数
|
||||
en-US: Finished Jobs
|
||||
ja-JP: 完了したタスク数
|
||||
- field: failedJobs
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 失败任务数
|
||||
en-US: Failed Jobs
|
||||
ja-JP: 失敗したタスク数
|
||||
- field: cancelledJobs
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 取消任务数
|
||||
en-US: Cancelled Jobs
|
||||
ja-JP: キャンセルされたタスク数
|
||||
- field: workers
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: Worker数
|
||||
en-US: Workers
|
||||
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:
|
||||
- projectVersion
|
||||
- gitCommitAbbrev
|
||||
@@ -182,6 +197,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 线程信息
|
||||
en-US: Thread Info
|
||||
ja-JP: スレッド情報
|
||||
priority: 1
|
||||
fields:
|
||||
- field: threadName
|
||||
@@ -190,21 +206,25 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 线程名称
|
||||
en-US: Thread Name
|
||||
ja-JP: スレッド名
|
||||
- field: threadId
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 线程ID
|
||||
en-US: Thread ID
|
||||
ja-JP: スレッドID
|
||||
- field: threadState
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 线程状态
|
||||
en-US: Thread State
|
||||
ja-JP: スレッド状態
|
||||
- field: stackTrace
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 堆栈信息
|
||||
en-US: Stack Trace
|
||||
ja-JP: スタックトレース
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
@@ -227,6 +247,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 节点监控
|
||||
en-US: Node Monitor
|
||||
ja-JP: ノード情報
|
||||
priority: 1
|
||||
fields:
|
||||
- field: isMaster
|
||||
@@ -235,241 +256,289 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 是否主节点
|
||||
en-US: Is Master
|
||||
ja-JP: マスターノード
|
||||
- field: host
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: IP地址
|
||||
en-US: IP Address
|
||||
ja-JP: IPアドレス
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
- field: processors
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 处理器数
|
||||
en-US: Processors
|
||||
ja-JP: プロセッサ数
|
||||
- field: physical.memory.total
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 物理内存总量
|
||||
en-US: Physical Memory Total
|
||||
ja-JP: 物理メモリ容量
|
||||
- field: physical.memory.free
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 物理内存可用
|
||||
en-US: Physical Memory Free
|
||||
ja-JP: 利用可能な物理メモリ
|
||||
- field: swap.space.total
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 交换空间总量
|
||||
en-US: Swap Space Total
|
||||
ja-JP: スワップ領域容量
|
||||
- field: swap.space.free
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 交换空间可用
|
||||
en-US: Swap Space Free
|
||||
ja-JP: 利用可能なスワップ領域
|
||||
- field: heap.memory.used
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 堆内存已用
|
||||
en-US: Heap Memory Used
|
||||
ja-JP: 使用したヒープメモリ
|
||||
- field: heap.memory.free
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 堆内存可用
|
||||
en-US: Heap Memory Free
|
||||
ja-JP: 利用可能なヒープメモリ
|
||||
- field: heap.memory.total
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 堆内存总量
|
||||
en-US: Heap Memory Total
|
||||
ja-JP: ヒープメモリ容量
|
||||
- field: heap.memory.max
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 堆内存最大
|
||||
en-US: Heap Memory Max
|
||||
ja-JP: ヒープメモリの最大値
|
||||
- field: heap.memory.used/total
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 堆内存使用率
|
||||
en-US: Heap Memory Used/Total
|
||||
ja-JP: ヒープメモリの使用率
|
||||
- field: heap.memory.used/max
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 堆内存使用率最大
|
||||
en-US: Heap Memory Used/Max
|
||||
ja-JP: ヒープメモリの使用率の最大値
|
||||
- field: minor.gc.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 小垃圾回收次数
|
||||
en-US: Minor GC Count
|
||||
ja-JP: 若い領域GC回数
|
||||
- field: minor.gc.time
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 小垃圾回收时间
|
||||
en-US: Minor GC Time
|
||||
ja-JP: 若い領域GC時間
|
||||
- field: major.gc.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 大垃圾回收次数
|
||||
en-US: Major GC Count
|
||||
ja-JP: 古い領域GC回数
|
||||
- field: major.gc.time
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 大垃圾回收时间
|
||||
en-US: Major GC Time
|
||||
ja-JP: 古い領域GC時間
|
||||
- field: load.process
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 进程负载
|
||||
en-US: Load Process
|
||||
ja-JP: プロセスロード
|
||||
- field: load.system
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 系统负载
|
||||
en-US: Load System
|
||||
ja-JP: システムロード
|
||||
- field: load.systemAverage
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 系统平均负载
|
||||
en-US: Load System Average
|
||||
ja-JP: システムの平均ロード
|
||||
- field: thread.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 线程数
|
||||
en-US: Thread Count
|
||||
ja-JP: スレッド数
|
||||
- field: thread.peakCount
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 线程峰值
|
||||
en-US: Thread Peak Count
|
||||
ja-JP: 最大スレッド数
|
||||
- field: cluster.timeDiff
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 集群时间差
|
||||
en-US: Cluster Time Diff
|
||||
ja-JP: クラスター間の時差
|
||||
- field: event.q.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 事件队列大小
|
||||
en-US: Event Queue Size
|
||||
ja-JP: イベントキューのサイズ
|
||||
- field: executor.q.async.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 异步执行队列大小
|
||||
en-US: Executor Queue Async Size
|
||||
ja-JP: 非同期実行キューのサイズ
|
||||
- field: executor.q.client.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 客户端执行队列大小
|
||||
en-US: Executor Queue Client Size
|
||||
ja-JP: クライアントが実行するキューのサイズ
|
||||
- field: executor.q.client.query.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 客户端查询队列大小
|
||||
en-US: Executor Queue Client Query Size
|
||||
ja-JP: クライアントが実行するクエリキューのサイズ
|
||||
- field: executor.q.client.blocking.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 客户端阻塞队列大小
|
||||
en-US: Executor Queue Client Blocking Size
|
||||
ja-JP: クライアントが実行するブロッキングキューのサイズ
|
||||
- field: executor.q.query.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 查询队列大小
|
||||
en-US: Executor Queue Query Size
|
||||
ja-JP: クエリキューのサイズ
|
||||
- field: executor.q.scheduled.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 定时执行队列大小
|
||||
en-US: Executor Queue Scheduled Size
|
||||
ja-JP: スケジュールされたキューのサイズ
|
||||
- field: executor.q.io.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: IO队列大小
|
||||
en-US: Executor Queue IO Size
|
||||
ja-JP: IOキューのサイズ
|
||||
- field: executor.q.system.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 系统执行队列大小
|
||||
en-US: Executor Queue System Size
|
||||
ja-JP: システムキューのサイズ
|
||||
- field: executor.q.operations.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 操作队列大小
|
||||
en-US: Executor Queue Operations Size
|
||||
ja-JP: 操作キューのサイズ
|
||||
- field: executor.q.priorityOperation.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 优先操作队列大小
|
||||
en-US: Executor Queue Priority Operation Size
|
||||
ja-JP: 優先操作キューのサイズ
|
||||
- field: operations.completed.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 完成操作次数
|
||||
en-US: Operations Completed Count
|
||||
ja-JP: 操作完了の回数
|
||||
- field: executor.q.mapLoad.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 映射加载队列大小
|
||||
en-US: Executor Queue Map Load Size
|
||||
ja-JP: Mapからロードするキューのサイズ
|
||||
- field: executor.q.mapLoadAllKeys.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 映射加载所有键大小
|
||||
en-US: Executor Queue Map Load All Keys Size
|
||||
ja-JP: Mapから全てのキーをロードするキューのサイズ
|
||||
- field: executor.q.cluster.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 集群执行队列大小
|
||||
en-US: Executor Queue Cluster Size
|
||||
ja-JP: クラスターキューのサイズ
|
||||
- field: executor.q.response.size
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 响应队列大小
|
||||
en-US: Executor Queue Response Size
|
||||
ja-JP: 応答キューのサイズ
|
||||
- field: operations.running.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 正在运行的操作数量
|
||||
en-US: Operations Running Count
|
||||
ja-JP: 実行中のキューのサイズ
|
||||
- field: operations.pending.invocations.percentage
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 待处理调用百分比
|
||||
en-US: Operations Pending Invocations Percentage
|
||||
ja-JP: 待機中の操作の比率
|
||||
- field: operations.pending.invocations.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 待处理调用数量
|
||||
en-US: Operations Pending Invocations Count
|
||||
ja-JP: 待機中の操作数
|
||||
- field: proxy.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 代理数量
|
||||
en-US: Proxy Count
|
||||
ja-JP: プロキシ数
|
||||
- field: clientEndpoint.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 客户端端点数量
|
||||
en-US: Client Endpoint Count
|
||||
ja-JP: クライアントエンドポイントの数
|
||||
- field: connection.active.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 活动连接数
|
||||
en-US: Connection Active Count
|
||||
ja-JP: アクティブな接続数
|
||||
- field: client.connection.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 客户端连接数
|
||||
en-US: Client Connection Count
|
||||
ja-JP: クライアント接続数
|
||||
- field: connection.count
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 总连接数
|
||||
en-US: Connection Count
|
||||
ja-JP: 接続総数
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -19,15 +19,15 @@ category: mid
|
||||
app: spring_gateway
|
||||
# The monitoring i18n name
|
||||
name:
|
||||
zh-CN: SpringGateway
|
||||
en-US: SpringGateway
|
||||
ja-JP: SpringGateway
|
||||
zh-CN: Spring Cloud Gateway
|
||||
en-US: Spring Cloud Gateway
|
||||
ja-JP: Spring Cloud Gateway
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: HertzBeat 对 <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a> 暴露的通用性能指标(globalfilters、routefilters、refresh、routes)进行采集监控。<span class='help_module_span'>注意⚠️:如果要监控 SpringGateway 中的信息,需要您的 SpringGateway 应用集成并开启 SpringBoot Actuator, <a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>点击查看具体步骤</a>。</span>
|
||||
en-US: HertzBeat collect and monitors SpringGateway through general performance metric that exposed by the SpringBoot Actuator. <br><span class='help_module_span'><br>Note⚠️:You should make sure that your SpringGateway application have already integrated and enabled the SpringBoot Actuator, <a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>click here to see the specific steps.</a></span>
|
||||
zh-TW: HertzBeat 對 <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a>暴露的通用性能指標(globalfilters、routefilters、refresh、routes)進行採集監控。<span class='help_module_span'>注意⚠️:如果要監控SpringGateway中的指標,需要您的SpringGateway應用集成並開啟SpringBoot Actuator,<a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>點擊查看具體步驟</a>。</span>
|
||||
ja-JP: HertzBeat は <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a> の一般的なパフォーマンスのメトリクスを監視します。<span class='help_module_span'>⚠️注意:SpringGateway で SpringBoot Actuatorを有効にする必要があります。<a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>クリックしてガイドを見ます</a>。</span>
|
||||
zh-CN: HertzBeat 对 <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a> 暴露的通用性能指标(globalfilters、routefilters、refresh、routes)进行采集监控。<span class='help_module_span'>注意⚠️:如果要监控 Spring Cloud Gateway 中的信息,需要您的 Spring Cloud Gateway 应用集成并开启 SpringBoot Actuator, <a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>点击查看具体步骤</a>。</span>
|
||||
en-US: HertzBeat collect and monitors SpringGateway through general performance metric that exposed by the SpringBoot Actuator. <br><span class='help_module_span'><br>Note⚠️:You should make sure that your Spring Cloud Gateway application have already integrated and enabled the SpringBoot Actuator, <a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>click here to see the specific steps.</a></span>
|
||||
zh-TW: HertzBeat 對 <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a>暴露的通用性能指標(globalfilters、routefilters、refresh、routes)進行採集監控。<span class='help_module_span'>注意⚠️:如果要監控 Spring Cloud Gateway 中的指標,需要您的 Spring Cloud Gateway 應用集成並開啟SpringBoot Actuator,<a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>點擊查看具體步驟</a>。</span>
|
||||
ja-JP: HertzBeat は <a class='help_module_content' href='https://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot Actuator </a> の一般的なパフォーマンスのメトリクスを監視します。<span class='help_module_span'>⚠️注意:Spring Cloud Gateway で SpringBoot Actuatorを有効にする必要があります。<a class='help_module_content' href='https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html'>クリックしてガイドを見ます</a>。</span>
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/spring_gateway
|
||||
en-US: https://hertzbeat.apache.org/docs/help/spring_gateway
|
||||
@@ -284,7 +284,7 @@ metrics:
|
||||
en-US: State
|
||||
ja-JP: 状態
|
||||
label: true
|
||||
- field: size
|
||||
- field: Size
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
@@ -294,7 +294,7 @@ metrics:
|
||||
- $.measurements[?(@.statistic == "VALUE")].value
|
||||
calculates:
|
||||
- state='^o^state^o^'
|
||||
- size=$.measurements[?(@.statistic == "VALUE")].value
|
||||
- Size=$.measurements[?(@.statistic == "VALUE")].value
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -0,0 +1,863 @@
|
||||
# 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 mid-middleware custom-custom monitoring os-operating system monitoring
|
||||
category: server
|
||||
# The monitoring type eg: linux windows tomcat mysql aws...
|
||||
app: synology
|
||||
# The monitoring i18n name
|
||||
name:
|
||||
zh-CN: Synology NAS
|
||||
en-US: Synology NAS
|
||||
ja-JP: Synology NAS
|
||||
# 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> 对 Synology NAS 的通用指标进行采集监控。<br><span class='help_module_span'>注意⚠️:Synology NAS 要开启 SNMP 服务,<a class='help_module_content' href='https://kb.synology.cn/zh-cn/DSM/help/DSM/AdminCenter/system_snmp'>点击查看开启步骤</a>。</span>您可以点击 “<i>新建 Synology NAS</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 Synology NAS general performance metrics. <br><span class='help_module_span'>Note⚠️:Synology NAS need enable the SNMP services <a class='help_module_content' href='https://kb.synology.com/en-global/DSM/help/DSM/AdminCenter/system_snmp'>Click here to view the specific steps.</a></span> You can click the "<i>Synology NAS</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> 对 Synology NAS 的通用指标进行采集监控。<br><span class='help_module_span'>注意⚠️:Synology NAS 需要开启 SNMP 服务,<a class='help_module_content' href='https://kb.synology.com/zh-tw/DSM/help/DSM/AdminCenter/system_snmp'>点击查看开启步骤</a>。</span>您可以点击 “<i>新建 Synology NAS</i>” 并进行配置SNMP相关参数添加,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP プロトコルを介して</a> Synology NAS 一般的なメトリクスを監視します。<br><span class='help_module_span'>注意⚠️:Synology NAS で SNMP サービスを有効にする必要があります,<a class='help_module_content' href='https://kb.synology.com/ja-jp/DSM/help/DSM/AdminCenter/system_snmp'>クリックしてガイドを見ます</a>。<br>「<i>新規 Synology NAS</i>」をクリックしてSNMPなどのパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/synology_nas
|
||||
en-US: https://hertzbeat.apache.org/docs/help/synology_nas
|
||||
# Input params define for monitoring(render web ui by the definition)
|
||||
params:
|
||||
# field-param field key
|
||||
- field: host
|
||||
# name-param field display i18n name
|
||||
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
|
||||
required: true
|
||||
# field-param field key
|
||||
- field: port
|
||||
# name-param field display i18n name
|
||||
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
|
||||
range: '[0,65535]'
|
||||
# required-true or false
|
||||
required: true
|
||||
# default value
|
||||
defaultValue: 161
|
||||
# field-param field key
|
||||
- field: snmpVersion
|
||||
# name-param field display i18n name
|
||||
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
|
||||
required: true
|
||||
# when type is radio checkbox, use option to show optional values {name1:value1,name2:value2}
|
||||
options:
|
||||
- label: SNMPv1
|
||||
value: 0
|
||||
- label: SNMPv2c
|
||||
value: 1
|
||||
- label: SNMPv3
|
||||
value: 3
|
||||
# field-param field key
|
||||
- field: community
|
||||
# name-param field display i18n name
|
||||
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
|
||||
limit: 100
|
||||
# required-true or false
|
||||
required: false
|
||||
# param field input placeholder
|
||||
placeholder: 'Snmp community for v1 v2c'
|
||||
# dependent parameter values list
|
||||
depend:
|
||||
snmpVersion:
|
||||
- 0
|
||||
- 1
|
||||
# field-param field key
|
||||
- field: username
|
||||
# name-param field display i18n name
|
||||
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
|
||||
limit: 50
|
||||
# required-true or false
|
||||
required: false
|
||||
# param field input placeholder
|
||||
placeholder: 'Snmp username for v3'
|
||||
# dependent parameter values list
|
||||
depend:
|
||||
snmpVersion:
|
||||
- 3
|
||||
# field-param field key
|
||||
- field: contextName
|
||||
# name-param field display i18n name
|
||||
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
|
||||
limit: 100
|
||||
# required-true or false
|
||||
required: false
|
||||
# param field input placeholder
|
||||
placeholder: 'Snmp contextName for v3'
|
||||
# dependent parameter values list
|
||||
depend:
|
||||
snmpVersion:
|
||||
- 3
|
||||
# field-param field key
|
||||
- field: authPassphrase
|
||||
# name-param field display i18n name
|
||||
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
|
||||
limit: 100
|
||||
# required-true or false
|
||||
required: false
|
||||
# param field input placeholder
|
||||
placeholder: 'Snmp authPassword for v3'
|
||||
# dependent parameter values list
|
||||
depend:
|
||||
snmpVersion:
|
||||
- 3
|
||||
# field-param field key
|
||||
- field: authPasswordEncryption
|
||||
# name-param field display i18n name
|
||||
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
|
||||
required: false
|
||||
# when type is radio checkbox, use option to show optional values {name1:value1,name2:value2}
|
||||
options:
|
||||
- label: MD5
|
||||
value: 0
|
||||
- label: SHA1
|
||||
value: 1
|
||||
# dependent parameter values list
|
||||
depend:
|
||||
snmpVersion:
|
||||
- 3
|
||||
# field-param field key
|
||||
- field: privPassphrase
|
||||
# name-param field display i18n name
|
||||
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
|
||||
limit: 100
|
||||
# required-true or false
|
||||
required: false
|
||||
# param field input placeholder
|
||||
placeholder: 'Snmp authPassword for v3'
|
||||
# dependent parameter values list
|
||||
depend:
|
||||
snmpVersion:
|
||||
- 3
|
||||
# field-param field key
|
||||
- field: privPasswordEncryption
|
||||
# name-param field display i18n name
|
||||
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
|
||||
required: false
|
||||
# when type is radio checkbox, use option to show optional values {name1:value1,name2:value2}
|
||||
options:
|
||||
- label: DES
|
||||
value: 0
|
||||
- label: AES128
|
||||
value: 1
|
||||
# dependent parameter values list
|
||||
depend:
|
||||
snmpVersion:
|
||||
- 3
|
||||
# field-param field key
|
||||
- field: timeout
|
||||
# name-param field display i18n name
|
||||
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
|
||||
range: '[0,100000]'
|
||||
# required-true or false
|
||||
required: false
|
||||
# hide-is hide this field and put it in advanced layout
|
||||
hide: true
|
||||
# default value
|
||||
defaultValue: 6000
|
||||
# collect metrics config list
|
||||
metrics:
|
||||
# metrics - system
|
||||
- name: system
|
||||
i18n:
|
||||
zh-CN: 系统
|
||||
en-US: System
|
||||
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
|
||||
fields:
|
||||
- field: modelName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 型号
|
||||
en-US: Name
|
||||
ja-JP: モデル
|
||||
- field: serialNumber
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 序列号
|
||||
en-US: Serial Number
|
||||
ja-JP: シリアル番号
|
||||
- field: version
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: DSM 版本
|
||||
en-US: Version
|
||||
ja-JP: DSM バージョン
|
||||
- field: controllerNumber
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 控制器编号
|
||||
en-US: Number of Users
|
||||
ja-JP: コントローラー番号
|
||||
protocol: snmp
|
||||
snmp:
|
||||
# server host: ipv4 ipv6 domain
|
||||
host: ^_^host^_^
|
||||
# server port
|
||||
port: ^_^port^_^
|
||||
# snmp username
|
||||
username: ^_^username^_^
|
||||
# snmp authPassphrase
|
||||
authPassphrase: ^_^authPassphrase^_^
|
||||
# snmp privPassphrase
|
||||
privPassphrase: ^_^privPassphrase^_^
|
||||
# snmp privPasswordEncryption
|
||||
privPasswordEncryption: ^_^privPasswordEncryption^_^
|
||||
# snmp authPasswordEncryption
|
||||
authPasswordEncryption: ^_^authPasswordEncryption^_^
|
||||
# contextName
|
||||
contextName: ^_^contextName^_^
|
||||
# snmp connect timeout
|
||||
timeout: ^_^timeout^_^
|
||||
# snmp community
|
||||
community: ^_^community^_^
|
||||
# snmp version
|
||||
version: ^_^snmpVersion^_^
|
||||
# snmp operation: get, walk
|
||||
operation: walk
|
||||
oids:
|
||||
modelName: 1.3.6.1.4.1.6574.1.5.1
|
||||
serialNumber: 1.3.6.1.4.1.6574.1.5.2
|
||||
version: 1.3.6.1.4.1.6574.1.5.3
|
||||
controllerNumber: 1.3.6.1.4.1.6574.1.6
|
||||
|
||||
- name: status
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: Status
|
||||
ja-JP: ステータス
|
||||
priority: 1
|
||||
fields:
|
||||
- field: powerStatus
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 电源
|
||||
en-US: Power
|
||||
ja-JP: 電源
|
||||
- field: systemFanStatus
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 系统风扇
|
||||
en-US: System Fan
|
||||
ja-JP: システムファン
|
||||
- field: cpuFanStatus
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: CPU 风扇
|
||||
en-US: CPU Fan
|
||||
ja-JP: CPUファン
|
||||
- field: systemStatus
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 系统分区
|
||||
en-US: System Partition
|
||||
ja-JP: システムパーティション
|
||||
- field: thermalStatus
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 散热状态
|
||||
en-US: Thermal Partition
|
||||
ja-JP: 熱源
|
||||
- field: temperature
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 温度
|
||||
en-US: Temperature
|
||||
ja-JP: 温度
|
||||
- field: cpuUtilization
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: CPU 利用率
|
||||
en-US: CPU Utilization
|
||||
ja-JP: CPU 使用率
|
||||
- field: memUtilization
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 内存利用率
|
||||
en-US: Memory Utilization
|
||||
ja-JP: メモリ使用率
|
||||
protocol: snmp
|
||||
snmp:
|
||||
# server host: ipv4 ipv6 domain
|
||||
host: ^_^host^_^
|
||||
# server port
|
||||
port: ^_^port^_^
|
||||
# snmp username
|
||||
username: ^_^username^_^
|
||||
# snmp authPassphrase
|
||||
authPassphrase: ^_^authPassphrase^_^
|
||||
# snmp privPassphrase
|
||||
privPassphrase: ^_^privPassphrase^_^
|
||||
# snmp privPasswordEncryption
|
||||
privPasswordEncryption: ^_^privPasswordEncryption^_^
|
||||
# snmp authPasswordEncryption
|
||||
authPasswordEncryption: ^_^authPasswordEncryption^_^
|
||||
# contextName
|
||||
contextName: ^_^contextName^_^
|
||||
# snmp connect timeout
|
||||
timeout: ^_^timeout^_^
|
||||
# snmp community
|
||||
community: ^_^community^_^
|
||||
# snmp version
|
||||
version: ^_^snmpVersion^_^
|
||||
# snmp operation: get, walk
|
||||
operation: walk
|
||||
oids:
|
||||
systemStatus: 1.3.6.1.4.1.6574.1.1
|
||||
temperature: 1.3.6.1.4.1.6574.1.2
|
||||
powerStatus: 1.3.6.1.4.1.6574.1.3
|
||||
systemFanStatus: 1.3.6.1.4.1.6574.1.4.1
|
||||
cpuFanStatus: 1.3.6.1.4.1.6574.1.4.2
|
||||
cpuUtilization: 1.3.6.1.4.1.6574.1.7.1
|
||||
memUtilization: 1.3.6.1.4.1.6574.1.7.2
|
||||
thermalStatus: 1.3.6.1.4.1.6574.1.78
|
||||
|
||||
- name: disk
|
||||
i18n:
|
||||
zh-CN: 硬盘
|
||||
en-US: Disk
|
||||
ja-JP: ディスク
|
||||
priority: 2
|
||||
fields:
|
||||
- field: diskID
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: ID
|
||||
en-US: ID
|
||||
ja-JP: ディスクID
|
||||
- field: diskModel
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 型号
|
||||
en-US: Model
|
||||
ja-JP: ディスクモデル
|
||||
- field: diskType
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 类型
|
||||
en-US: Type
|
||||
ja-JP: ディスクタイプ
|
||||
- field: diskStatus
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: Status
|
||||
ja-JP: ディスクステータス
|
||||
- field: diskTemperature
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 温度
|
||||
en-US: Temperature
|
||||
ja-JP: ディスク温度
|
||||
- field: diskRole
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 作用
|
||||
en-US: Role
|
||||
ja-JP: ディスク作用
|
||||
- field: diskRetry
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 连接重试次数
|
||||
en-US: Retry count
|
||||
ja-JP: ディスクリミネーション
|
||||
- field: diskBadSector
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 坏扇区数
|
||||
en-US: Bad Sector
|
||||
ja-JP: ディスクバッドセクタ
|
||||
- field: diskIdentifyFail
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 计数失败
|
||||
en-US: Identify Fail
|
||||
ja-JP: ディスク識別失敗
|
||||
- field: diskRemainLife
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 预计剩余寿命
|
||||
en-US: Remain Life
|
||||
ja-JP: ディスク残り寿命
|
||||
- field: diskName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 保留名称
|
||||
en-US: Disk Name
|
||||
ja-JP: ディスク名
|
||||
- field: diskHealthStatus
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 健康状况
|
||||
en-US: Health Status
|
||||
ja-JP: ディスクヘルスステータス
|
||||
protocol: snmp
|
||||
snmp:
|
||||
# server host: ipv4 ipv6 domain
|
||||
host: ^_^host^_^
|
||||
# server port
|
||||
port: ^_^port^_^
|
||||
# snmp username
|
||||
username: ^_^username^_^
|
||||
# snmp authPassphrase
|
||||
authPassphrase: ^_^authPassphrase^_^
|
||||
# snmp privPassphrase
|
||||
privPassphrase: ^_^privPassphrase^_^
|
||||
# snmp privPasswordEncryption
|
||||
privPasswordEncryption: ^_^privPasswordEncryption^_^
|
||||
# snmp authPasswordEncryption
|
||||
authPasswordEncryption: ^_^authPasswordEncryption^_^
|
||||
# contextName
|
||||
contextName: ^_^contextName^_^
|
||||
# snmp connect timeout
|
||||
timeout: ^_^timeout^_^
|
||||
# snmp community
|
||||
community: ^_^community^_^
|
||||
# snmp version
|
||||
version: ^_^snmpVersion^_^
|
||||
# snmp operation: get, walk
|
||||
operation: walk
|
||||
oids:
|
||||
diskID: 1.3.6.1.4.1.6574.2.1.1.2
|
||||
diskModel: 1.3.6.1.4.1.6574.2.1.1.3
|
||||
diskType: 1.3.6.1.4.1.6574.2.1.1.4
|
||||
diskStatus: 1.3.6.1.4.1.6574.2.1.1.5
|
||||
diskTemperature: 1.3.6.1.4.1.6574.2.1.1.6
|
||||
diskRole: 1.3.6.1.4.1.6574.2.1.1.7
|
||||
diskRetry: 1.3.6.1.4.1.6574.2.1.1.8
|
||||
diskBadSector: 1.3.6.1.4.1.6574.2.1.1.9
|
||||
diskIdentifyFail: 1.3.6.1.4.1.6574.2.1.1.10
|
||||
diskRemainLife: 1.3.6.1.4.1.6574.2.1.1.11
|
||||
diskName: 1.3.6.1.4.1.6574.2.1.1.12
|
||||
diskHealthStatus: 1.3.6.1.4.1.6574.2.1.1.13
|
||||
|
||||
- name: raid
|
||||
i18n:
|
||||
zh-CN: RAID
|
||||
en-US: RAID
|
||||
ja-JP: RAID
|
||||
priority: 3
|
||||
fields:
|
||||
- field: raidName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 名称
|
||||
en-US: Name
|
||||
ja-JP: 名
|
||||
- field: raidStatus
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: Status
|
||||
ja-JP: ディスクモデル
|
||||
- field: raidFreeSize
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 可用容量
|
||||
en-US: Free Size
|
||||
ja-JP: ディスク残りサイズ
|
||||
- field: raidTotalSize
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 总大小
|
||||
en-US: Total Size
|
||||
ja-JP: ディスクサイズ
|
||||
- field: raidHotspareCnt
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 热备数
|
||||
en-US: Hot Spare Count
|
||||
ja-JP: ディスクホットスパア数
|
||||
protocol: snmp
|
||||
snmp:
|
||||
# server host: ipv4 ipv6 domain
|
||||
host: ^_^host^_^
|
||||
# server port
|
||||
port: ^_^port^_^
|
||||
# snmp username
|
||||
username: ^_^username^_^
|
||||
# snmp authPassphrase
|
||||
authPassphrase: ^_^authPassphrase^_^
|
||||
# snmp privPassphrase
|
||||
privPassphrase: ^_^privPassphrase^_^
|
||||
# snmp privPasswordEncryption
|
||||
privPasswordEncryption: ^_^privPasswordEncryption^_^
|
||||
# snmp authPasswordEncryption
|
||||
authPasswordEncryption: ^_^authPasswordEncryption^_^
|
||||
# contextName
|
||||
contextName: ^_^contextName^_^
|
||||
# snmp connect timeout
|
||||
timeout: ^_^timeout^_^
|
||||
# snmp community
|
||||
community: ^_^community^_^
|
||||
# snmp version
|
||||
version: ^_^snmpVersion^_^
|
||||
# snmp operation: get, walk
|
||||
operation: walk
|
||||
oids:
|
||||
raidName: 1.3.6.1.4.1.6574.3.1.1.2
|
||||
raidStatus: 1.3.6.1.4.1.6574.3.1.1.3
|
||||
raidFreeSize: 1.3.6.1.4.1.6574.3.1.1.4
|
||||
raidTotalSize: 1.3.6.1.4.1.6574.3.1.1.5
|
||||
raidHotspareCnt: 1.3.6.1.4.1.6574.3.1.1.6
|
||||
|
||||
- name: smart
|
||||
i18n:
|
||||
zh-CN: S.M.A.R.T
|
||||
en-US: S.M.A.R.T
|
||||
ja-JP: S.M.A.R.T
|
||||
priority: 4
|
||||
fields:
|
||||
- field: diskSMARTInfoDevName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备名称
|
||||
en-US: Device Name
|
||||
ja-JP: ディスク名
|
||||
- field: diskSMARTAttrName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 属性名
|
||||
en-US: Attribute Name
|
||||
ja-JP: ディスク属性名
|
||||
- field: diskSMARTAttrId
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 属性 ID
|
||||
en-US: Attribute ID
|
||||
ja-JP: ディスク属性ID
|
||||
- field: diskSMARTAttrCurrent
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 当前值
|
||||
en-US: Attribute Current
|
||||
ja-JP: ディスク属性現在値
|
||||
- field: diskSMARTAttrWorst
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最差值
|
||||
en-US: Attribute Worst
|
||||
ja-JP: ディスク属性最差値
|
||||
- field: diskSMARTAttrThreshold
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 阈值
|
||||
en-US: Attribute Threshold
|
||||
ja-JP: ディスク属性しきい値
|
||||
- field: diskSMARTAttrRaw
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 原始值
|
||||
en-US: Raw
|
||||
ja-JP: ディスク属性原始値
|
||||
- field: diskSMARTAttrStatus
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 信息状态
|
||||
en-US: Attribute Status
|
||||
ja-JP: ディスク属性情報ステータス
|
||||
protocol: snmp
|
||||
snmp:
|
||||
# server host: ipv4 ipv6 domain
|
||||
host: ^_^host^_^
|
||||
# server port
|
||||
port: ^_^port^_^
|
||||
# snmp username
|
||||
username: ^_^username^_^
|
||||
# snmp authPassphrase
|
||||
authPassphrase: ^_^authPassphrase^_^
|
||||
# snmp privPassphrase
|
||||
privPassphrase: ^_^privPassphrase^_^
|
||||
# snmp privPasswordEncryption
|
||||
privPasswordEncryption: ^_^privPasswordEncryption^_^
|
||||
# snmp authPasswordEncryption
|
||||
authPasswordEncryption: ^_^authPasswordEncryption^_^
|
||||
# contextName
|
||||
contextName: ^_^contextName^_^
|
||||
# snmp connect timeout
|
||||
timeout: ^_^timeout^_^
|
||||
# snmp community
|
||||
community: ^_^community^_^
|
||||
# snmp version
|
||||
version: ^_^snmpVersion^_^
|
||||
# snmp operation: get, walk
|
||||
operation: walk
|
||||
oids:
|
||||
diskSMARTInfoDevName: 1.3.6.1.4.1.6574.5.1.1.2
|
||||
diskSMARTAttrName: 1.3.6.1.4.1.6574.5.1.1.3
|
||||
diskSMARTAttrId: 1.3.6.1.4.1.6574.5.1.1.4
|
||||
diskSMARTAttrCurrent: 1.3.6.1.4.1.6574.5.1.1.5
|
||||
diskSMARTAttrWorst: 1.3.6.1.4.1.6574.5.1.1.6
|
||||
diskSMARTAttrThreshold: 1.3.6.1.4.1.6574.5.1.1.7
|
||||
diskSMARTAttrRaw: 1.3.6.1.4.1.6574.5.1.1.8
|
||||
diskSMARTAttrStatus: 1.3.6.1.4.1.6574.5.1.1.9
|
||||
|
||||
- name: spaceio
|
||||
i18n:
|
||||
zh-CN: 存储空间 I/O
|
||||
en-US: Space I/O
|
||||
ja-JP: スペースI/O
|
||||
priority: 5
|
||||
fields:
|
||||
- field: spaceIODevice
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备名称
|
||||
en-US: Device Name
|
||||
ja-JP: ディスク名
|
||||
- field: spaceIOReads
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 读取访问次数
|
||||
en-US: Read Accesses Count
|
||||
ja-JP: ディスク属性読み込みアクセス回数
|
||||
- field: spaceIOWrites
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 写入访问次数
|
||||
en-US: Write Accesses Count
|
||||
ja-JP: ディスク属性書き込みアクセス回数
|
||||
- field: spaceIOLA
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 硬盘负载
|
||||
en-US: The load of disk
|
||||
ja-JP: ディスク属性ディスクロード
|
||||
- field: spaceIOLA1
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 1 分钟平均负载
|
||||
en-US: The 1-minute average load of disk
|
||||
ja-JP: 1分平均負荷
|
||||
- field: spaceIOLA5
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 5分钟平均负载
|
||||
en-US: The 5-minute average load of disk
|
||||
ja-JP: 5分平均負荷
|
||||
- field: spaceIOLA15
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 15 分钟平均负载
|
||||
en-US: The-15 minute average load of disk
|
||||
ja-JP: 15分平均負荷
|
||||
- field: spaceUUID
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 卷UUID
|
||||
en-US: UUID
|
||||
ja-JP: UUID
|
||||
protocol: snmp
|
||||
snmp:
|
||||
# server host: ipv4 ipv6 domain
|
||||
host: ^_^host^_^
|
||||
# server port
|
||||
port: ^_^port^_^
|
||||
# snmp username
|
||||
username: ^_^username^_^
|
||||
# snmp authPassphrase
|
||||
authPassphrase: ^_^authPassphrase^_^
|
||||
# snmp privPassphrase
|
||||
privPassphrase: ^_^privPassphrase^_^
|
||||
# snmp privPasswordEncryption
|
||||
privPasswordEncryption: ^_^privPasswordEncryption^_^
|
||||
# snmp authPasswordEncryption
|
||||
authPasswordEncryption: ^_^authPasswordEncryption^_^
|
||||
# contextName
|
||||
contextName: ^_^contextName^_^
|
||||
# snmp connect timeout
|
||||
timeout: ^_^timeout^_^
|
||||
# snmp community
|
||||
community: ^_^community^_^
|
||||
# snmp version
|
||||
version: ^_^snmpVersion^_^
|
||||
# snmp operation: get, walk
|
||||
operation: walk
|
||||
oids:
|
||||
spaceIODevice: 1.3.6.1.4.1.6574.102.1.1.2
|
||||
spaceIOReads: 1.3.6.1.4.1.6574.102.1.1.5
|
||||
spaceIOWrites: 1.3.6.1.4.1.6574.102.1.1.6
|
||||
spaceIOLA: 1.3.6.1.4.1.6574.102.1.1.7
|
||||
spaceIOLA1: 1.3.6.1.4.1.6574.102.1.1.8
|
||||
spaceIOLA5: 1.3.6.1.4.1.6574.102.1.1.9
|
||||
spaceIOLA15: 1.3.6.1.4.1.6574.102.1.1.10
|
||||
spaceUUID: 1.3.6.1.4.1.6574.102.1.1.13
|
||||
|
||||
- name: storageio
|
||||
i18n:
|
||||
zh-CN: 硬盘 I/O
|
||||
en-US: Storage I/O
|
||||
ja-JP: ハードディスクI/O
|
||||
priority: 6
|
||||
fields:
|
||||
- field: storageIODevice
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备名称
|
||||
en-US: Device Name
|
||||
ja-JP: ディスク名
|
||||
- field: storageIOReads
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 读取访问次数
|
||||
en-US: Read Accesses Count
|
||||
ja-JP: ディスク属性読み込みアクセス回数
|
||||
- field: storageIOWrites
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 写入访问次数
|
||||
en-US: Write Accesses Count
|
||||
ja-JP: ディスク属性書き込みアクセス回数
|
||||
- field: storageIOLA
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 硬盘负载
|
||||
en-US: The load of disk
|
||||
ja-JP: ディスク属性ディスクロード
|
||||
- field: storageIOLA1
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 1 分钟平均负载
|
||||
en-US: The 1-minute average load of disk
|
||||
ja-JP: 1分平均負荷
|
||||
- field: storageIOLA5
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 5分钟平均负载
|
||||
en-US: The 5-minute average load of disk
|
||||
ja-JP: 5分平均負荷
|
||||
- field: storageIOLA15
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 15 分钟平均负载
|
||||
en-US: The-15 minute average load of disk
|
||||
ja-JP: 15分平均負荷
|
||||
- field: storageIODeviceSerial
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 序列号
|
||||
en-US: Serial Number
|
||||
ja-JP: シリアルナンバー
|
||||
protocol: snmp
|
||||
snmp:
|
||||
# server host: ipv4 ipv6 domain
|
||||
host: ^_^host^_^
|
||||
# server port
|
||||
port: ^_^port^_^
|
||||
# snmp username
|
||||
username: ^_^username^_^
|
||||
# snmp authPassphrase
|
||||
authPassphrase: ^_^authPassphrase^_^
|
||||
# snmp privPassphrase
|
||||
privPassphrase: ^_^privPassphrase^_^
|
||||
# snmp privPasswordEncryption
|
||||
privPasswordEncryption: ^_^privPasswordEncryption^_^
|
||||
# snmp authPasswordEncryption
|
||||
authPasswordEncryption: ^_^authPasswordEncryption^_^
|
||||
# contextName
|
||||
contextName: ^_^contextName^_^
|
||||
# snmp connect timeout
|
||||
timeout: ^_^timeout^_^
|
||||
# snmp community
|
||||
community: ^_^community^_^
|
||||
# snmp version
|
||||
version: ^_^snmpVersion^_^
|
||||
# snmp operation: get, walk
|
||||
operation: walk
|
||||
oids:
|
||||
storageIODevice: 1.3.6.1.4.1.6574.101.1.1.2
|
||||
storageIOReads: 1.3.6.1.4.1.6574.101.1.1.5
|
||||
storageIOWrites: 1.3.6.1.4.1.6574.101.1.1.6
|
||||
storageIOLA: 1.3.6.1.4.1.6574.101.1.1.7
|
||||
storageIOLA1: 1.3.6.1.4.1.6574.101.1.1.8
|
||||
storageIOLA5: 1.3.6.1.4.1.6574.101.1.1.9
|
||||
storageIOLA15: 1.3.6.1.4.1.6574.101.1.1.10
|
||||
storageIODeviceSerial: 1.3.6.1.4.1.6574.101.1.1.13
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,11 +21,13 @@ app: tomcat
|
||||
name:
|
||||
zh-CN: Tomcat应用服务器
|
||||
en-US: Tomcat WebServer
|
||||
ja-JP: Tomcat WebServer
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: HertzBeat 使用 <a href="https://hertzbeat.apache.org/docs/advanced/extend-jmx">JMX 协议</a> 对 Tomcat 的通用性能指标(基础信息,内存池,类加载,线程信息等)进行采集监控。<br>⚠️注意:您需要在 Tomcat 应用中开启 JMX 服务,应用启动时添加 JMX 参数, 可自定义暴露端口,对外IP。<a href="https://hertzbeat.apache.org/zh-cn/docs/help/tomcat">点击查看开启步骤</a>。
|
||||
en-US: HertzBeat uses <a href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'>JMX Protocol</a> to monitoring and collect general performance metric of Tomcat. <br>⚠️Note:You need to enable JMX services in Tomcat application, and add the JXM parameters when the application start. You can also customize external IP address and exposed port.<a href='https://hertzbeat.apache.org/docs/help/tomcat'>Click here to view the activation steps.</a>"
|
||||
zh-TW: HertzBeat 使用 <a href="https://hertzbeat.apache.org/docs/advanced/extend-jmx">JMX 協議</a> 對 Tomcat 的通用性能指標(基礎信息,內存池,類加載,線程信息等)進行采集監控。<br>⚠️注意:您需要在 Tomcat 應用中開啓 JMX 服務,應用啓動時添加 JMX 參數, 可自定義暴露端口,對外IP。<a href="https://hertzbeat.apache.org/zh-cn/docs/help/tomcat">點擊查看開啓步驟</a>。
|
||||
ja-JP: HertzBeat は <a href="https://hertzbeat.apache.org/docs/advanced/extend-jmx"> JMXプロトコルを介して</a> Tomcat の一般的なパフォーマンスのメトリクスを監視します。⚠️注意:Tomcat応用 で JMXサービス を有効にする必要があります。<a href="https://hertzbeat.apache.org/docs/help/tomcat">クリックしてガイドを見ます</a>。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/tomcat
|
||||
en-US: https://hertzbeat.apache.org/docs/help/tomcat
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: JMX URL
|
||||
en-US: JMX URL
|
||||
ja-JP: JMX URL
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
@@ -75,6 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -89,6 +95,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -102,6 +109,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Tomcat 信息
|
||||
en-US: Tomcat Server
|
||||
ja-JP: Tomcatサーバー
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -113,26 +121,31 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 服务信息
|
||||
en-US: Server Info
|
||||
ja-JP: サーバー情報
|
||||
- field: serverNumber
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 服务版本
|
||||
en-US: Server Number
|
||||
ja-JP: サーバーバージョン
|
||||
- field: serverBuilt
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Server Built
|
||||
en-US: Server Built
|
||||
ja-JP: サーバービルド
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
- field: address
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 地址
|
||||
en-US: Address
|
||||
ja-JP: アドレス
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: jmx
|
||||
# the config content when protocol is http
|
||||
@@ -155,6 +168,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 内存池
|
||||
en-US: Memory Pool
|
||||
ja-JP: メモリプール
|
||||
fields:
|
||||
- field: name
|
||||
type: 1
|
||||
@@ -162,30 +176,35 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 指标名称
|
||||
en-US: Name
|
||||
ja-JP: 名前
|
||||
- field: committed
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 已分配内存
|
||||
en-US: Committed
|
||||
ja-JP: コミットされたメモリ
|
||||
- field: init
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 初始化内存
|
||||
en-US: Init
|
||||
ja-JP: イニシャルメモリ
|
||||
- field: max
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 最大内存
|
||||
en-US: Max
|
||||
ja-JP: 最大メモリ
|
||||
- field: used
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 已使用内存
|
||||
en-US: Used
|
||||
ja-JP: 使用したメモリ
|
||||
units:
|
||||
- committed=B->MB
|
||||
- init=B->MB
|
||||
@@ -222,6 +241,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 类加载信息
|
||||
en-US: Class Loading
|
||||
ja-JP: クラスローディング情報
|
||||
# collect metrics content
|
||||
fields:
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
@@ -230,16 +250,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 当前已加载类数量
|
||||
en-US: Loaded Class Count
|
||||
ja-JP: ロードされたクラス数
|
||||
- field: TotalLoadedClassCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 已加载类总数量
|
||||
en-US: Total Loaded Class Count
|
||||
ja-JP: ロードされたクラス総数
|
||||
- field: UnloadedClassCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 未加载类总数量
|
||||
en-US: Unloaded Class Count
|
||||
ja-JP: アンロードされたクラス総数
|
||||
protocol: jmx
|
||||
jmx:
|
||||
host: ^_^host^_^
|
||||
@@ -254,6 +277,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 线程信息
|
||||
en-US: Thread
|
||||
ja-JP: スレッド情報
|
||||
# collect metrics content
|
||||
fields:
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
@@ -262,33 +286,39 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 已启动线程总数
|
||||
en-US: Total Started Thread Count
|
||||
ja-JP: スレッド総数
|
||||
- field: ThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活跃线程数
|
||||
en-US: Thread Count
|
||||
ja-JP: 活躍スレッド数
|
||||
- field: PeakThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大峰值线程数
|
||||
en-US: Peak Thread Count
|
||||
ja-JP: 最大スレッド数
|
||||
- field: DaemonThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活跃守护线程数
|
||||
en-US: Daemon Thread Count
|
||||
ja-JP: デーモンスレッド数
|
||||
- field: CurrentThreadUserTime
|
||||
type: 0
|
||||
unit: s
|
||||
i18n:
|
||||
zh-CN: 线程占用的CPU时间(用户态)
|
||||
en-US: Current Thread User Time
|
||||
ja-JP: 現在のスレッドユーザー時間
|
||||
- field: CurrentThreadCpuTime
|
||||
type: 0
|
||||
unit: s
|
||||
i18n:
|
||||
zh-CN: 线程占用的CPU时间
|
||||
en-US: Current Thread CPU Time
|
||||
ja-JP: 現在のスレッドシステム時間
|
||||
units:
|
||||
- CurrentThreadUserTime=NS->S
|
||||
- CurrentThreadCpuTime=NS->S
|
||||
@@ -305,6 +335,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 应用信息
|
||||
en-US: Application
|
||||
ja-JP: 応用情報
|
||||
priority: 4
|
||||
fields:
|
||||
- field: name
|
||||
@@ -313,83 +344,99 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 名称
|
||||
en-US: Name
|
||||
ja-JP: 名前
|
||||
- field: acceptCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 接收请求数
|
||||
en-US: Accept Count
|
||||
ja-JP: 受け入れたリクエスト数
|
||||
- field: acceptorThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 接收处理线程数
|
||||
en-US: Acceptor Thread Count
|
||||
ja-JP: アクセプタスレッド数
|
||||
- field: acceptorThreadPriority
|
||||
type : 0
|
||||
i18n:
|
||||
zh-CN: 接收线程级别
|
||||
en-US: Acceptor Thread Priority
|
||||
ja-JP: アクセプタスレッド優先度
|
||||
- field: connectionTimeout
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 链接超时时间
|
||||
en-US: Connection Timeout
|
||||
ja-JP: 接続のタイムアウト
|
||||
- field: currentThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 当前线程数
|
||||
en-US: Current Thread Count
|
||||
ja-JP: 現在のスレッド数
|
||||
- field: currentThreadsBusy
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 繁忙线程数
|
||||
en-US: Current Threads Busy
|
||||
ja-JP: 現在の忙しいスレッド数
|
||||
- field: keepAliveCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 心跳保持链接数量
|
||||
en-US: Keep Alive Count
|
||||
ja-JP: ハートビート数量
|
||||
- field: keepAliveTimeout
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 心跳超时时间
|
||||
en-US: Keep Alive Timeout
|
||||
ja-JP: ハートビートのタイムアウト
|
||||
- field: maxConnections
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大链接数
|
||||
en-US: Max Connections
|
||||
ja-JP: 最大接続数
|
||||
- field: maxKeepAliveRequests
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大链接保持请求
|
||||
en-US: Max KeepAlive Requests
|
||||
ja-JP: 最大KeepAliveリクエスト数
|
||||
- field: maxThreads
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大线程数
|
||||
en-US: Max Threads
|
||||
ja-JP: 最大スレッド数
|
||||
- field: minSpareThreads
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最小备用线程数
|
||||
en-US: Min Spare Threads
|
||||
ja-JP: 最小予備スレッド数
|
||||
- field: pollerThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 轮询线程数
|
||||
en-US: Poller Thread Count
|
||||
ja-JP: ポーラースレッド数
|
||||
- field: pollerThreadPriority
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 轮询线程级别
|
||||
en-US: Poller Thread Priority
|
||||
ja-JP: ポーラースレッド優先度
|
||||
- field: running
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 运行中
|
||||
en-US: Running
|
||||
ja-JP: 実行中
|
||||
protocol: jmx
|
||||
jmx:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -21,11 +21,13 @@ app: ubuntu
|
||||
name:
|
||||
zh-CN: Ubuntu Linux
|
||||
en-US: Ubuntu Linux
|
||||
ja-JP: Ubuntu Linux
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 Ubuntu 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 Ubuntu</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 Ubuntu 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 Ubuntu</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> 對 Ubuntu 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建 Ubuntu</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> Ubuntuシステムの一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Ubuntu</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/ubuntu
|
||||
en-US: https://hertzbeat.apache.org/docs/help/ubuntu
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: 超时时间(ms)
|
||||
en-US: Timeout(ms)
|
||||
ja-JP: タイムアウト(ms)
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -75,6 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: 接続再利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -86,6 +92,7 @@ params:
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシ接続利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -97,6 +104,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -109,6 +117,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -119,6 +128,7 @@ params:
|
||||
name:
|
||||
zh-CN: 私钥
|
||||
en-US: PrivateKey
|
||||
ja-JP: 秘密鍵
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
@@ -132,6 +142,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密钥短语
|
||||
en-US: PrivateKey PassPhrase
|
||||
ja-JP: 秘密鍵フレーズ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -144,6 +155,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理主机
|
||||
en-US: Proxy Host
|
||||
ja-JP: プロキシホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
@@ -155,6 +167,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理端口
|
||||
en-US: Proxy Port
|
||||
ja-JP: プロキシポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -171,6 +184,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理用户名
|
||||
en-US: Proxy Username
|
||||
ja-JP: プロキシユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -185,6 +199,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理密码
|
||||
en-US: Proxy Password
|
||||
ja-JP: プロキシパスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -197,6 +212,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理主机私钥
|
||||
en-US: proxyPrivateKey
|
||||
ja-JP: プロキシ秘密鍵
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
@@ -211,6 +227,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 系统基本信息
|
||||
en-US: Basic Info
|
||||
ja-JP: システム基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -223,16 +240,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 主机名称
|
||||
en-US: Host Name
|
||||
ja-JP: ホスト名
|
||||
- field: version
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: オーエスバージョン
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 启动时间
|
||||
en-US: Uptime
|
||||
ja-JP: アップタイム
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: ssh
|
||||
# the config content when protocol is ssh
|
||||
@@ -272,6 +292,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: CPU 信息
|
||||
en-US: CPU Info
|
||||
ja-JP: CPU情報
|
||||
priority: 1
|
||||
fields:
|
||||
- field: info
|
||||
@@ -279,32 +300,38 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 型号
|
||||
en-US: Info
|
||||
ja-JP: バージョン
|
||||
- field: cores
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 核数
|
||||
en-US: Cores
|
||||
ja-JP: コア数
|
||||
- field: interrupt
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 中断数
|
||||
en-US: Interrupt
|
||||
ja-JP: 割り込み数
|
||||
- field: load
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 负载
|
||||
en-US: Load
|
||||
ja-JP: ロード
|
||||
- field: context_switch
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 上下文切换
|
||||
en-US: Context Switch
|
||||
ja-JP: コンテキストスイッチ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 使用率
|
||||
en-US: Usage
|
||||
ja-JP: 使用率
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- info
|
||||
@@ -351,6 +378,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 内存信息
|
||||
en-US: Memory Info
|
||||
ja-JP: メモリ情報
|
||||
priority: 2
|
||||
fields:
|
||||
- field: total
|
||||
@@ -359,36 +387,42 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 总内存容量
|
||||
en-US: Total Memory
|
||||
ja-JP: メモリ容量
|
||||
- field: used
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 用户程序内存量
|
||||
en-US: User Program Memory
|
||||
ja-JP: ユーザープログラムメモリ
|
||||
- field: free
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 空闲内存容量
|
||||
en-US: Free Memory
|
||||
ja-JP: 空きメモリ
|
||||
- field: buff_cache
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 缓存占用内存
|
||||
en-US: Buff Cache Memory
|
||||
ja-JP: バッファメモリ
|
||||
- field: available
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 剩余可用内存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能のメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存使用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
aliasFields:
|
||||
- total
|
||||
- used
|
||||
@@ -431,6 +465,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 磁盘信息
|
||||
en-US: Disk Info
|
||||
ja-JP: ディスク情報
|
||||
priority: 3
|
||||
fields:
|
||||
- field: disk_num
|
||||
@@ -438,27 +473,32 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 磁盘总数
|
||||
en-US: Disk Num
|
||||
ja-JP: ディスク番号
|
||||
- field: partition_num
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 分区总数
|
||||
en-US: Partition Num
|
||||
ja-JP: パーティション
|
||||
- field: block_write
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 写磁盘块数
|
||||
en-US: Block Write
|
||||
ja-JP: 書き込みディスクブロック数
|
||||
- field: block_read
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 读磁盘块数
|
||||
en-US: Block Read
|
||||
ja-JP: 読み取りブロック数
|
||||
- field: write_rate
|
||||
type: 0
|
||||
unit: iops
|
||||
i18n:
|
||||
zh-CN: 磁盘写速率
|
||||
en-US: Write Rate
|
||||
ja-JP: ディスク書き込み速度
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -488,6 +528,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 网卡信息
|
||||
en-US: Interface Info
|
||||
ja-JP: ネットワークカード情報
|
||||
priority: 4
|
||||
fields:
|
||||
- field: interface_name
|
||||
@@ -496,18 +537,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 网卡名称
|
||||
en-US: Interface Name
|
||||
ja-JP: ネットワークカード名
|
||||
- field: receive_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 入站数据流量
|
||||
en-US: Receive Bytes
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: transmit_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 出站数据流量
|
||||
en-US: Transmit Bytes
|
||||
ja-JP: 転送されたバイト数
|
||||
units:
|
||||
- receive_bytes=B->MB
|
||||
- transmit_bytes=B->MB
|
||||
@@ -540,6 +584,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 文件系统
|
||||
en-US: Disk Free
|
||||
ja-JP: ファイルシステム
|
||||
priority: 5
|
||||
fields:
|
||||
- field: filesystem
|
||||
@@ -547,30 +592,35 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 文件系统
|
||||
en-US: Filesystem
|
||||
ja-JP: ファイルシステム
|
||||
- field: used
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 已使用量
|
||||
en-US: Used
|
||||
ja-JP: 使用済み
|
||||
- field: available
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 可用量
|
||||
en-US: Available
|
||||
ja-JP: 使用可能
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 使用率
|
||||
en-US: Usage
|
||||
ja-JP: 使用率
|
||||
- field: mounted
|
||||
type: 1
|
||||
label: true
|
||||
i18n:
|
||||
zh-CN: 挂载点
|
||||
en-US: Mounted
|
||||
ja-JP: マウント
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -600,6 +650,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Top10 CPU 进程
|
||||
en-US: Top10 CPU Process
|
||||
ja-JP: トップ10 CPUプロセス
|
||||
priority: 6
|
||||
fields:
|
||||
- field: pid
|
||||
@@ -608,23 +659,27 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程ID
|
||||
en-US: PID
|
||||
ja-JP: プロセスID
|
||||
- field: cpu_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: CPU占用率
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: mem_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存占用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: command
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -654,6 +709,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Top10 内存进程
|
||||
en-US: Top10 Memory Process
|
||||
ja-JP: トップ10 メモリプロセス
|
||||
priority: 7
|
||||
fields:
|
||||
- field: pid
|
||||
@@ -662,23 +718,27 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程ID
|
||||
en-US: PID
|
||||
ja-JP: プロセスID
|
||||
- field: mem_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存占用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: cpu_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: CPU占用率
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: command
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: コマンド
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,11 +21,13 @@ app: vastbase
|
||||
name:
|
||||
zh-CN: Vastbase数据库
|
||||
en-US: Vastbase DB
|
||||
ja-JP: Vastbase データベース
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: HertzBeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jdbc'> JDBC 协议</a> 通过配置 SQL 对 Vastbase 数据库的通用性能指标 (basic、state、activity etc) 进行采集监控,支持版本为 Vastbase 9.2.4+。<br>您可以点击“<i>新建 Vastbase 数据库</i>”并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jdbc'> JDBC Protocol</a> to configure SQL for collecting general metrics of Vastbase database (basic、state、activity etc). Supported version is Vastbase 9.2.4+. <br>You can click "<i>New Vastbase Database</i>" and configure it, or select "<i>More Action</i>" to import the existing configuration.
|
||||
zh-TW: HertzBeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jdbc'> JDBC 協議</a> 通過配置 SQL 對 Vastbase 數據庫的通用性能指標 (basic、state、activity etc)進行采集監控,支持版本爲 Vastbase 9.2.4+。<br>您可以點擊“<i>新建 Vastbase 數據庫</i>”並進行配置,或者選擇“<i>更多操作</i>”,導入已有配置。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jdbc'> JDBCプロトコルを介して</a> Vastbase データベース(Vastbase 9.2.4+)の一般的なパフォーマンスのメトリクスを監視します。<br>「<i>新規 Vastbase データベース</i>」をクリックしてパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/vastbase
|
||||
en-US: https://hertzbeat.apache.org/docs/help/vastbase
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -59,6 +63,7 @@ params:
|
||||
name:
|
||||
zh-CN: 查询超时时间(ms)
|
||||
en-US: Query Timeout(ms)
|
||||
ja-JP: クエリタイムアウト(ms)
|
||||
type: number
|
||||
range: '[400,200000]'
|
||||
required: false
|
||||
@@ -68,6 +73,7 @@ params:
|
||||
name:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
type: text
|
||||
defaultValue: postgres
|
||||
required: false
|
||||
@@ -75,6 +81,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
type: text
|
||||
limit: 50
|
||||
required: false
|
||||
@@ -82,12 +89,14 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
type: password
|
||||
required: false
|
||||
- field: url
|
||||
name:
|
||||
zh-CN: URL
|
||||
en-US: URL
|
||||
ja-JP: URL
|
||||
type: text
|
||||
required: false
|
||||
hide: true
|
||||
@@ -99,6 +108,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 基本信息
|
||||
en-US: Basic Info
|
||||
ja-JP: 基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -111,26 +121,31 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 服务器版本
|
||||
en-US: Server Version
|
||||
ja-JP: バージョン
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
- field: server_encoding
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 服务器编码
|
||||
en-US: Server Encoding
|
||||
ja-JP: サーバーのエンコード
|
||||
- field: data_directory
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 数据目录
|
||||
en-US: Data Directory
|
||||
ja-JP: データディレクトリ
|
||||
- field: max_connections
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大连接数
|
||||
en-US: Max Connections
|
||||
ja-JP: 最大接続数
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: jdbc
|
||||
# the config content when protocol is jdbc
|
||||
@@ -155,6 +170,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 状态信息
|
||||
en-US: State Info
|
||||
ja-JP: 状態情報
|
||||
priority: 1
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -163,47 +179,55 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: conflicts
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 冲突次数
|
||||
en-US: Conflicts
|
||||
ja-JP: コンフリクト回数
|
||||
- field: deadlocks
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 死锁次数
|
||||
en-US: Deadlocks
|
||||
ja-JP: デッドロック回数
|
||||
- field: blks_read
|
||||
type: 0
|
||||
unit: blocks per second
|
||||
i18n:
|
||||
zh-CN: 读取块
|
||||
en-US: Blocks Read
|
||||
ja-JP: 読み取られたブロック
|
||||
- field: blks_hit
|
||||
type: 0
|
||||
unit: blocks per second
|
||||
i18n:
|
||||
zh-CN: 命中块
|
||||
en-US: Blocks Hit
|
||||
ja-JP: ヒットブロック
|
||||
- field: blk_read_time
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 读取时间
|
||||
en-US: Read Time
|
||||
ja-JP: 読み取られタイム
|
||||
- field: blk_write_time
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 写入时间
|
||||
en-US: Write Time
|
||||
ja-JP: 書き込まれタイム
|
||||
- field: stats_reset
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 统计重置
|
||||
en-US: Stats Reset
|
||||
ja-JP: 統計リセット
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -221,6 +245,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 活动信息
|
||||
en-US: Activity Info
|
||||
ja-JP: 活動情報
|
||||
priority: 2
|
||||
fields:
|
||||
- field: running
|
||||
@@ -229,6 +254,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 运行中
|
||||
en-US: Running
|
||||
ja-JP: 実行中
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -246,6 +272,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 资源配置
|
||||
en-US: Resource Config
|
||||
ja-JP: リソース設定
|
||||
priority: 3
|
||||
fields:
|
||||
- field: work_mem
|
||||
@@ -254,34 +281,40 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 工作内存
|
||||
en-US: Work Memory
|
||||
ja-JP: ワークメモリ
|
||||
- field: shared_buffers
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 共享缓冲区
|
||||
en-US: Shared Buffers
|
||||
ja-JP: 共有バッファ
|
||||
- field: autovacuum
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 自动清理
|
||||
en-US: Auto Vacuum
|
||||
ja-JP: オートバキューム
|
||||
- field: max_connections
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大连接数
|
||||
en-US: Max Connections
|
||||
ja-JP: 最大接続数
|
||||
- field: effective_cache_size
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 有效缓存大小
|
||||
en-US: Effective Cache Size
|
||||
ja-JP: キャッシュサイズ
|
||||
- field: wal_buffers
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: WAL缓冲区
|
||||
en-US: WAL Buffers
|
||||
ja-JP: WALバッファ
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -299,6 +332,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 连接信息
|
||||
en-US: Connection Info
|
||||
ja-JP: 接続情報
|
||||
priority: 4
|
||||
fields:
|
||||
- field: active
|
||||
@@ -306,6 +340,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 活动连接
|
||||
en-US: Active Connection
|
||||
ja-JP: 活躍的な接続
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -323,6 +358,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 连接状态
|
||||
en-US: Connection State
|
||||
ja-JP: 接続状態
|
||||
priority: 5
|
||||
fields:
|
||||
- field: state
|
||||
@@ -331,11 +367,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: State
|
||||
ja-JP: 状態
|
||||
- field: num
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 数量
|
||||
en-US: Num
|
||||
ja-JP: 数量
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -353,6 +391,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 连接数据库
|
||||
en-US: Connection Db
|
||||
ja-JP: 接続データベース
|
||||
priority: 6
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -361,11 +400,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: active
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活动连接
|
||||
en-US: Active Connection
|
||||
ja-JP: 活躍的な接続
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -383,6 +424,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 元组信息
|
||||
en-US: Tuple Info
|
||||
ja-JP: 組情報
|
||||
priority: 7
|
||||
fields:
|
||||
- field: fetched
|
||||
@@ -390,26 +432,31 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 获取次数
|
||||
en-US: Fetched
|
||||
ja-JP: フェッチ回数
|
||||
- field: returned
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 返回次数
|
||||
en-US: Returned
|
||||
ja-JP: 戻る回数
|
||||
- field: inserted
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 插入次数
|
||||
en-US: Inserted
|
||||
ja-JP: インサート回数
|
||||
- field: updated
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 更新次数
|
||||
en-US: Updated
|
||||
ja-JP: 更新回数
|
||||
- field: deleted
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 删除次数
|
||||
en-US: Deleted
|
||||
ja-JP: 削除回数
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -427,6 +474,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 临时文件
|
||||
en-US: Temp File
|
||||
ja-JP: 一時ファイル
|
||||
priority: 8
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -435,17 +483,20 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: num
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 次数
|
||||
en-US: Num
|
||||
- field: size
|
||||
ja-JP: 数量
|
||||
- field: Size
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
zh-CN: 大小
|
||||
en-US: Size
|
||||
ja-JP: サイズ
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -463,6 +514,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 锁信息
|
||||
en-US: Lock Info
|
||||
ja-JP: ロック情報
|
||||
priority: 9
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -471,18 +523,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: conflicts
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 冲突次数
|
||||
en-US: Conflicts
|
||||
ja-JP: コンフリクト回数
|
||||
- field: deadlocks
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 死锁次数
|
||||
en-US: Deadlocks
|
||||
ja-JP: デッドロック回数
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -500,6 +555,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 慢查询
|
||||
en-US: Slow Sql
|
||||
ja-JP: スローSQL
|
||||
priority: 10
|
||||
fields:
|
||||
- field: sql_text
|
||||
@@ -508,28 +564,33 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: SQL语句
|
||||
en-US: SQL Text
|
||||
ja-JP: SQL文のテキスト
|
||||
- field: calls
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 调用次数
|
||||
en-US: Calls
|
||||
ja-JP: コール回数
|
||||
- field: rows
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 行数
|
||||
en-US: Rows
|
||||
ja-JP: 行
|
||||
- field: avg_time
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 平均时间
|
||||
en-US: Avg Time
|
||||
ja-JP: 平均時間
|
||||
- field: total_time
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 总时间
|
||||
en-US: Total Time
|
||||
ja-JP: 合計時間
|
||||
aliasFields:
|
||||
- query
|
||||
- calls
|
||||
@@ -557,6 +618,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 事务信息
|
||||
en-US: Transaction Info
|
||||
ja-JP: トランザクション情報
|
||||
priority: 11
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -565,18 +627,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: commits
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 提交次数
|
||||
en-US: Commits
|
||||
ja-JP: コミット回数
|
||||
- field: rollbacks
|
||||
type: 0
|
||||
unit: times
|
||||
i18n:
|
||||
zh-CN: 回滚次数
|
||||
en-US: Rollbacks
|
||||
ja-JP: ロールバック回数
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -594,6 +659,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 冲突信息
|
||||
en-US: Conflicts Info
|
||||
ja-JP: コンフリクト情報
|
||||
priority: 12
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -602,31 +668,37 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: tablespace
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 表空间
|
||||
en-US: Tablespace
|
||||
ja-JP: 表領域
|
||||
- field: lock
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 锁
|
||||
en-US: Lock
|
||||
ja-JP: ロック
|
||||
- field: snapshot
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 快照
|
||||
en-US: Snapshot
|
||||
ja-JP: スナップショット
|
||||
- field: bufferpin
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 缓冲区
|
||||
en-US: Bufferpin
|
||||
ja-JP: バッファ
|
||||
- field: deadlock
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 死锁
|
||||
en-US: Deadlock
|
||||
ja-JP: デッドロック
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -644,6 +716,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 缓存命中率
|
||||
en-US: Cache Hit Ratio
|
||||
ja-JP: キャッシュ命中率
|
||||
priority: 13
|
||||
fields:
|
||||
- field: db_name
|
||||
@@ -652,12 +725,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 数据库名称
|
||||
en-US: Database Name
|
||||
ja-JP: データベース名
|
||||
- field: ratio
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 命中率
|
||||
en-US: Hit Ratio
|
||||
ja-JP: 命中率
|
||||
aliasFields:
|
||||
- blks_hit
|
||||
- blks_read
|
||||
@@ -681,6 +756,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Checkpoint信息
|
||||
en-US: Checkpoint Info
|
||||
ja-JP: チェックポイント情報
|
||||
priority: 14
|
||||
fields:
|
||||
- field: checkpoint_sync_time
|
||||
@@ -689,12 +765,14 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Checkpoint同步时间
|
||||
en-US: Checkpoint Sync Time
|
||||
ja-JP: チェックポイント同期時間
|
||||
- field: checkpoint_write_time
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: Checkpoint写入时间
|
||||
en-US: Checkpoint Write Time
|
||||
ja-JP: Checkpoint書き込まれた時間
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
@@ -712,6 +790,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Buffer信息
|
||||
en-US: Buffer Info
|
||||
ja-JP: バッファ情報
|
||||
priority: 15
|
||||
fields:
|
||||
- field: allocated
|
||||
@@ -719,26 +798,31 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 已分配
|
||||
en-US: Allocated
|
||||
ja-JP: 割り当てバッファ
|
||||
- field: fsync_calls_by_backend
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 后端进程直接执行的文件同步调用次数
|
||||
en-US: Fsync Calls By Backend
|
||||
ja-JP: バックエンド同期コール回数
|
||||
- field: written_directly_by_backend
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 后台写入到数据文件
|
||||
en-US: Written Directly By Backend
|
||||
ja-JP: バックエンドによる直接書き込まれたファイル
|
||||
- field: written_by_background_writer
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 后台写入
|
||||
en-US: Written By Background Writer
|
||||
ja-JP: バックグラウンドライターに書き込まれた
|
||||
- field: written_during_checkpoints
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 检查点期间写入
|
||||
en-US: Written During Checkpoints
|
||||
ja-JP: チェックポイント中の書き込み
|
||||
protocol: jdbc
|
||||
jdbc:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -21,11 +21,13 @@ app: windows
|
||||
name:
|
||||
zh-CN: Windows操作系统
|
||||
en-US: OS Windows
|
||||
ja-JP: Windowsオーエス
|
||||
# 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> 对 Windows操作系统 的通用指标(用户数、进程数量、响应时间等)进行采集监控。<br><span class='help_module_span'>注意⚠️:Windows 服务器需要开启 SNMP 服务,<a class='help_module_content' href='https://learn.microsoft.com/zh-cn/troubleshoot/windows-server/networking/configure-snmp-service'>点击查看开启步骤</a>。</span>您可以点击 “<i>新建 Windows操作系统</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 OS Windows general performance metrics such as number of users, number of processes, response time. <br><span class='help_module_span'>Note⚠️:Windows server need enable the SNMP services <a class='help_module_content' href='https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-snmp-service'>Click here to view the specific steps.</a></span> You can click the "<i>New OS Windows</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> 对 Windows操作系统 的通用指标(用户数、进程数量、响应时间等)进行采集监控。<br><span class='help_module_span'>注意⚠️:Windows 服务器需要开启 SNMP 服务,<a class='help_module_content' href='https://learn.microsoft.com/zh-cn/troubleshoot/windows-server/networking/configure-snmp-service'>点击查看开启步骤</a>。</span>您可以点击 “<i>新建 Windows操作系统</i>” 并进行配置SNMP相关参数添加,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-snmp'> SNMP プロトコルを介して</a> Windowsオーエスの一般的なメトリクスを監視します。<br><span class='help_module_span'>注意⚠️:Windowsサーバー で SNMP サービスを有効にする必要があります,<a class='help_module_content' href='https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-snmp-service'>クリックしてガイドを見ます</a>。<br>「<i>新規 Windowsオーエス</i>」をクリックしてSNMPなどのパラメタを設定した後、新規することができます。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/windows
|
||||
en-US: https://hertzbeat.apache.org/docs/help/windows
|
||||
@@ -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
|
||||
@@ -77,6 +82,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
|
||||
@@ -96,6 +102,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
|
||||
@@ -113,6 +120,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 系统
|
||||
en-US: System
|
||||
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
|
||||
@@ -122,47 +130,56 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 名称
|
||||
en-US: 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: numUsers
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 用户数
|
||||
en-US: Number of Users
|
||||
ja-JP: ユーザー数
|
||||
- field: services
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 服务数
|
||||
en-US: Number of Services
|
||||
ja-JP: サービス数
|
||||
- field: processes
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 进程数
|
||||
en-US: Number of Processes
|
||||
ja-JP: プロセス数
|
||||
- field: responseTime
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 响应时间
|
||||
en-US: Response Time
|
||||
ja-JP: 応答時間
|
||||
unit: ms
|
||||
- field: location
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 位置
|
||||
en-US: Location
|
||||
ja-JP: 位置
|
||||
- field: memory
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 内存
|
||||
en-US: Memory
|
||||
ja-JP: メモリ
|
||||
unit: GB
|
||||
units:
|
||||
- memory=KB->GB
|
||||
@@ -188,6 +205,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程
|
||||
en-US: Processes
|
||||
ja-JP: プロセス
|
||||
priority: 1
|
||||
fields:
|
||||
- field: hrSWRunIndex
|
||||
@@ -195,48 +213,57 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 编号
|
||||
en-US: Index
|
||||
ja-JP: 番号
|
||||
- field: hrSWRunName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 进程名称
|
||||
en-US: Process Name
|
||||
ja-JP: プロセス名
|
||||
label: true
|
||||
- field: hrSWRunID
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 进程 ID
|
||||
en-US: Process ID
|
||||
ja-JP: プロセスID
|
||||
- field: hrSWRunPath
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 进程路径
|
||||
en-US: Process Path
|
||||
ja-JP: プロセスパス
|
||||
- field: hrSWRunParameters
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 进程参数
|
||||
en-US: Process Parameters
|
||||
ja-JP: プロセスパラメータ
|
||||
- field: hrSWRunType
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 进程类型
|
||||
en-US: Process Type
|
||||
ja-JP: プロセスタイプ
|
||||
- field: hrSWRunStatus
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 进程状态
|
||||
en-US: Process Status
|
||||
ja-JP: プロセス状態
|
||||
- field: hrSWRunPerfCPU
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 进程占用 CPU
|
||||
en-US: Process CPU
|
||||
ja-JP: プロセスが使用したCPU
|
||||
unit: 's'
|
||||
- field: hrSWRunPerfMem
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 进程占用内存
|
||||
en-US: Process Memory
|
||||
ja-JP: プロセスが使用したメモリ
|
||||
unit: 'KB'
|
||||
calculates:
|
||||
- hrSWRunPerfCPU = hrSWRunPerfCPU / 100
|
||||
@@ -263,6 +290,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 服务
|
||||
en-US: Services
|
||||
ja-JP: サービス
|
||||
priority: 2
|
||||
fields:
|
||||
- field: svSvcName
|
||||
@@ -270,27 +298,32 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 服务名称
|
||||
en-US: Service Name
|
||||
ja-JP: サービス名
|
||||
label: true
|
||||
- field: svSvcInstalledState
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 服务安装状态
|
||||
en-US: Service Installed State
|
||||
ja-JP: サービスのインストール状態
|
||||
- field: svSvcOperatingState
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 服务运行状态
|
||||
en-US: Service Operating State
|
||||
ja-JP: サービスの実行状態
|
||||
- field: svSvcCanBeUninstalled
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 服务是否可以被卸载
|
||||
en-US: Service Can Be Uninstalled
|
||||
ja-JP: サービスはアンインストールできる
|
||||
- field: svSvcCanBePaused
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 服务是否可以被暂停
|
||||
en-US: Service Can Be Paused
|
||||
ja-JP: サービスは一時停止できる
|
||||
protocol: snmp
|
||||
snmp:
|
||||
host: ^_^host^_^
|
||||
@@ -310,29 +343,34 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 安装
|
||||
en-US: Installed
|
||||
ja-JP: インストール
|
||||
priority: 3
|
||||
fields:
|
||||
- field: hrSWInstalledIndex
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 编号
|
||||
en-US: 编号
|
||||
en-US: Index
|
||||
ja-JP: 番号
|
||||
- field: hrSWInstalledName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 安装名称
|
||||
en-US: Installed Name
|
||||
ja-JP: インストール名
|
||||
label: true
|
||||
- field: hrSWInstalledID
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 安装 ID
|
||||
en-US: Installed ID
|
||||
ja-JP: インストールID
|
||||
- field: hrSWInstalledType
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 安装类型
|
||||
en-US: Installed Type
|
||||
ja-JP: インストールタイプ
|
||||
protocol: snmp
|
||||
snmp:
|
||||
host: ^_^host^_^
|
||||
@@ -351,23 +389,27 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 存储
|
||||
en-US: Storages
|
||||
ja-JP: ストレージ
|
||||
priority: 5
|
||||
fields:
|
||||
- field: index
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 编号
|
||||
en-US: 编号
|
||||
en-US: Index
|
||||
ja-JP: 番号
|
||||
- field: descr
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 存储描述
|
||||
en-US: Storage Description
|
||||
ja-JP: ストレージ説明
|
||||
label: true
|
||||
- field: size
|
||||
- field: Size
|
||||
i18n:
|
||||
zh-CN: 存储大小
|
||||
en-US: Storage Size
|
||||
ja-JP: ストレージサイズ
|
||||
type: 0
|
||||
unit: Mb
|
||||
- field: free
|
||||
@@ -375,18 +417,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 存储空闲
|
||||
en-US: Storage Free
|
||||
ja-JP: 空きストレージ
|
||||
unit: Mb
|
||||
- field: used
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 存储占用
|
||||
en-US: Storage Used
|
||||
ja-JP: 使用したストレージ
|
||||
unit: Mb
|
||||
- field: usage
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 存储使用率
|
||||
en-US: Storage Usage
|
||||
ja-JP: ストレージ使用率
|
||||
unit: '%'
|
||||
# (Not required) Monitor indicator alias, which maps to the indicator name above. The field used to collect interface data is not directly the final indicator name, and this alias is required for mapping translation
|
||||
aliasFields:
|
||||
@@ -400,7 +445,7 @@ metrics:
|
||||
calculates:
|
||||
- index=hrStorageIndex
|
||||
- descr=hrStorageDescr
|
||||
- size=hrStorageSize * hrStorageAllocationUnits
|
||||
- Size=hrStorageSize * hrStorageAllocationUnits
|
||||
- free=(hrStorageSize - hrStorageUsed) * hrStorageAllocationUnits
|
||||
- used=hrStorageUsed * hrStorageAllocationUnits
|
||||
- usage= hrStorageUsed / hrStorageSize * 100
|
||||
@@ -428,6 +473,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 接口详情
|
||||
en-US: Interfaces Detail
|
||||
ja-JP: ネットワークカード詳細
|
||||
priority: 8
|
||||
fields:
|
||||
- field: index
|
||||
@@ -435,65 +481,77 @@ 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: speed
|
||||
type: 0
|
||||
unit: 'Mbps'
|
||||
i18n:
|
||||
zh-CN: 接口速率
|
||||
en-US: Interface Speed
|
||||
ja-JP: ネットワークカード速度
|
||||
- field: in_octets
|
||||
type: 0
|
||||
unit: 'Kbps'
|
||||
i18n:
|
||||
zh-CN: 入流量
|
||||
en-US: In Octets
|
||||
ja-JP: 受信されたバイト数
|
||||
- field: out_octets
|
||||
type: 0
|
||||
unit: 'Kbps'
|
||||
i18n:
|
||||
zh-CN: 出流量
|
||||
en-US: Out Octets
|
||||
ja-JP: 転送されたバイト数
|
||||
- field: admin_status
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 配置状态
|
||||
en-US: Config Status
|
||||
ja-JP: 設定ステータス
|
||||
- field: oper_status
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 当前状态
|
||||
en-US: Current Status
|
||||
ja-JP: 現在のステータス
|
||||
- field: mtu
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: MTU
|
||||
en-US: MTU
|
||||
ja-JP: MTU
|
||||
- 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_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: 転送された異常パケット数
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- ifIndex
|
||||
@@ -555,6 +613,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 设备
|
||||
en-US: Devices
|
||||
ja-JP: デバイス
|
||||
priority: 9
|
||||
fields:
|
||||
- field: index
|
||||
@@ -562,17 +621,20 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 编号
|
||||
en-US: Index
|
||||
ja-JP: 番号
|
||||
label: true
|
||||
- field: descr
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 描述
|
||||
en-US: Description
|
||||
ja-JP: 説明
|
||||
- field: status
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: Status
|
||||
ja-JP: 状態
|
||||
aliasFields:
|
||||
- hrDeviceIndex
|
||||
- hrDeviceDescr
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user