mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 18:19:02 +00:00
Compare commits
29
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a923a42b0 | ||
|
|
36ad5a6a31 | ||
|
|
a6c79d2699 | ||
|
|
eebfa81627 | ||
|
|
0f9fab646f | ||
|
|
ef7a058770 | ||
|
|
573c7aaa11 | ||
|
|
fb348b3d34 | ||
|
|
6ad20d3848 | ||
|
|
2bcdf4fb1e | ||
|
|
07058fdfb6 | ||
|
|
24a6deb636 | ||
|
|
475e4a3288 | ||
|
|
8b42f574fe | ||
|
|
e8d2f9fb69 | ||
|
|
5f0132a8d6 | ||
|
|
4835960827 | ||
|
|
5716e21f1f | ||
|
|
9ca7dc0945 | ||
|
|
d787a582d5 | ||
|
|
495f037ead | ||
|
|
c3fda15036 | ||
|
|
c516b3689c | ||
|
|
d01f3e2263 | ||
|
|
6fc5d81dae | ||
|
|
ab48fc7c34 | ||
|
|
4f6ca71471 | ||
|
|
61ab3d4114 | ||
|
|
4a9aa91130 |
+49
-159
@@ -18,14 +18,11 @@
|
||||
package org.apache.hertzbeat.collector.collect.http;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.SignConstants.RIGHT_DASH;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.StringReader;
|
||||
import java.net.ConnectException;
|
||||
@@ -37,7 +34,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.net.ssl.SSLException;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
@@ -45,14 +44,13 @@ import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
import org.apache.hertzbeat.collector.collect.common.http.CommonHttpClient;
|
||||
import org.apache.hertzbeat.collector.collect.http.promethus.AbstractPrometheusParse;
|
||||
import org.apache.hertzbeat.collector.collect.http.promethus.PrometheusParseCreator;
|
||||
import org.apache.hertzbeat.collector.collect.prometheus.parser.MetricFamily;
|
||||
import org.apache.hertzbeat.collector.collect.prometheus.parser.OnlineParser;
|
||||
import org.apache.hertzbeat.collector.collect.http.promethus.exporter.ExporterParser;
|
||||
import org.apache.hertzbeat.collector.collect.http.promethus.exporter.MetricFamily;
|
||||
import org.apache.hertzbeat.collector.constants.CollectorConstants;
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.collector.util.CollectUtil;
|
||||
@@ -93,25 +91,18 @@ import org.xml.sax.InputSource;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.HashSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics.Field;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* http https collect
|
||||
*/
|
||||
@Slf4j
|
||||
public class HttpCollectImpl extends AbstractCollect {
|
||||
private final Set<Integer> defaultSuccessStatusCodes = Set.of(
|
||||
HttpStatus.SC_OK,
|
||||
HttpStatus.SC_CREATED,
|
||||
HttpStatus.SC_ACCEPTED,
|
||||
HttpStatus.SC_MULTIPLE_CHOICES,
|
||||
HttpStatus.SC_MOVED_PERMANENTLY,
|
||||
HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
private static final Map<Long, ExporterParser> EXPORTER_PARSER_TABLE = new ConcurrentHashMap<>();
|
||||
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());
|
||||
|
||||
@Override
|
||||
public void preCheck(Metrics metrics) throws IllegalArgumentException {
|
||||
@@ -132,7 +123,7 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
if (CollectionUtils.isEmpty(httpProtocol.getSuccessCodes())) {
|
||||
httpProtocol.setSuccessCodes(List.of(HttpStatus.SC_OK + ""));
|
||||
}
|
||||
|
||||
|
||||
HttpContext httpContext = createHttpContext(metrics.getHttp());
|
||||
HttpUriRequest request = createHttpRequest(metrics.getHttp());
|
||||
try (CloseableHttpResponse response = CommonHttpClient.getHttpClient().execute(request, httpContext)) {
|
||||
@@ -144,11 +135,10 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
builder.setMsg(NetworkConstants.STATUS_CODE + SignConstants.BLANK + statusCode);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
this could create large objects, potentially impacting JVM memory space significantly.
|
||||
Option 1: Parse using InputStream, but this requires significant code changes;
|
||||
Option 2: Manually trigger garbage collection, similar to how it's done in Dubbo for large inputs.
|
||||
*/
|
||||
// todo This code converts an InputStream directly to a String. For large data in Prometheus exporters,
|
||||
// this could create large objects, potentially impacting JVM memory space significantly.
|
||||
// Option 1: Parse using InputStream, but this requires significant code changes;
|
||||
// Option 2: Manually trigger garbage collection, similar to how it's done in Dubbo for large inputs.
|
||||
String resp = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
||||
if (!StringUtils.hasText(resp)) {
|
||||
log.info("http response entity is empty, status: {}.", statusCode);
|
||||
@@ -162,7 +152,7 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
case DispatchConstants.PARSE_PROM_QL ->
|
||||
parseResponseByPromQl(resp, metrics.getAliasFields(), metrics.getHttp(), builder);
|
||||
case DispatchConstants.PARSE_PROMETHEUS ->
|
||||
parseResponseByPrometheusExporter(response.getEntity().getContent(), metrics.getAliasFields(), builder);
|
||||
parseResponseByPrometheusExporter(resp, metrics.getAliasFields(), builder);
|
||||
case DispatchConstants.PARSE_XML_PATH ->
|
||||
parseResponseByXmlPath(resp, metrics, builder, responseTime);
|
||||
case DispatchConstants.PARSE_WEBSITE ->
|
||||
@@ -171,8 +161,6 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
parseResponseBySiteMap(resp, metrics.getAliasFields(), builder);
|
||||
case DispatchConstants.PARSE_HEADER ->
|
||||
parseResponseByHeader(builder, metrics.getAliasFields(), response);
|
||||
case DispatchConstants.PARSE_CONFIG ->
|
||||
parseResponseByConfig(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||
default ->
|
||||
parseResponseByDefault(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||
}
|
||||
@@ -394,6 +382,9 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Field> fieldMap = metrics.getFields().stream()
|
||||
.collect(Collectors.toMap(Field::getField, Function.identity(), (field1, field2) -> field1));
|
||||
|
||||
for (int i = 0; i < nodeList.getLength(); i++) {
|
||||
Node node = nodeList.item(i);
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
@@ -404,11 +395,19 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(Integer.toString(keywordNum));
|
||||
} else {
|
||||
Field field = fieldMap.get(alias);
|
||||
if (field == null || !StringUtils.hasText(field.getXpath())) {
|
||||
log.warn("No field definition or xpath found for alias '{}' in XML path parsing.", alias);
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
continue;
|
||||
}
|
||||
|
||||
String relativeXpath = field.getXpath();
|
||||
try {
|
||||
String value = (String) xpath.evaluate(alias, node, XPathConstants.STRING);
|
||||
String value = (String) xpath.evaluate(relativeXpath, node, XPathConstants.STRING);
|
||||
valueRowBuilder.addColumn(StringUtils.hasText(value) ? value : CommonConstants.NULL_VALUE);
|
||||
} catch (XPathExpressionException e) {
|
||||
log.warn("Failed to evaluate XPath '{}' for node [{}]: {}", alias, node.getNodeName(), e.getMessage());
|
||||
log.warn("Failed to evaluate relative XPath '{}' (from field definition) for node [{}]: {}", relativeXpath, node.getNodeName(), e.getMessage());
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
}
|
||||
@@ -423,129 +422,6 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Parses the response body in Properties/Config format.
|
||||
* Two modes are supported:
|
||||
* 1. single-object mode: if http.parseScript is null, aliasFields are treated as indicator names.
|
||||
* - If there is a locator in the indicator definition, use the locator as the key of the Properties.
|
||||
* - Otherwise, use aliasField (metric name) as the key for Properties.
|
||||
* Generate a single row of data.
|
||||
* 2. array mode: if http.parseScript is not empty (e.g. “users”), treat it as an array base path.
|
||||
* Treat aliasFields as the attribute name of an array element, and generate a single row of data for each array index. locator is invalid in this mode.
|
||||
*
|
||||
* @param resp Response body string
|
||||
* @param aliasFields List of metrics aliases (i.e., the list of fields in metrics.fields).
|
||||
* @param http http protocol configuration
|
||||
* @param builder The metrics data builder.
|
||||
* @param responseTime response time
|
||||
*/
|
||||
private void parseResponseByConfig(String resp, List<String> aliasFields, HttpProtocol http,
|
||||
CollectRep.MetricsData.Builder builder, Long responseTime) {
|
||||
if (!StringUtils.hasText(resp)) {
|
||||
log.warn("Http collect parse type is config, but response body is empty.");
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg("Response body is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
Properties properties = new Properties();
|
||||
try (StringReader reader = new StringReader(resp)) {
|
||||
properties.load(reader);
|
||||
} catch (IOException e) {
|
||||
log.warn("Failed to parse config response: {}", e.getMessage(), e);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg("Failed to parse config response: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
String arrayBasePath = http.getParseScript();
|
||||
int keywordNum = CollectUtil.countMatchKeyword(resp, http.getKeyword());
|
||||
|
||||
if (!StringUtils.hasText(arrayBasePath)) {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String alias : aliasFields) {
|
||||
if (NetworkConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(responseTime.toString());
|
||||
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(Integer.toString(keywordNum));
|
||||
} else {
|
||||
String value = properties.getProperty(alias);
|
||||
valueRowBuilder.addColumn(value != null ? value : CommonConstants.NULL_VALUE);
|
||||
}
|
||||
}
|
||||
CollectRep.ValueRow valueRow = valueRowBuilder.build();
|
||||
if (hasMeaningfulDataInRow(valueRow, aliasFields)) {
|
||||
builder.addValueRow(valueRow);
|
||||
} else {
|
||||
log.warn("No meaningful data found in single config object response for aliasFields: {}", aliasFields);
|
||||
}
|
||||
} else {
|
||||
Pattern pattern = Pattern.compile("^" + Pattern.quote(arrayBasePath) + "\\[(\\d+)]\\.");
|
||||
Set<Integer> existingIndices = new HashSet<>();
|
||||
for (String key : properties.stringPropertyNames()) {
|
||||
Matcher matcher = pattern.matcher(key);
|
||||
if (matcher.find()) {
|
||||
try {
|
||||
int index = Integer.parseInt(matcher.group(1));
|
||||
existingIndices.add(index);
|
||||
} catch (NumberFormatException e) {
|
||||
log.error("Could not parse index from key: {}", key);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (existingIndices.isEmpty()) {
|
||||
log.warn("Could not find any array elements for base path '{}' in config response.", arrayBasePath);
|
||||
return;
|
||||
}
|
||||
List<Integer> sortedIndices = new ArrayList<>(existingIndices);
|
||||
Collections.sort(sortedIndices);
|
||||
for (int i : sortedIndices) {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String alias : aliasFields) {
|
||||
if (NetworkConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(responseTime.toString());
|
||||
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(Integer.toString(keywordNum));
|
||||
} else {
|
||||
String currentKey = arrayBasePath + "[" + i + "]." + alias;
|
||||
String value = properties.getProperty(currentKey);
|
||||
valueRowBuilder.addColumn(value != null ? value : CommonConstants.NULL_VALUE);
|
||||
}
|
||||
}
|
||||
CollectRep.ValueRow valueRow = valueRowBuilder.build();
|
||||
if (hasMeaningfulDataInRow(valueRow, aliasFields)) {
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasMeaningfulDataInRow(CollectRep.ValueRow valueRow, List<String> aliasFields) {
|
||||
if (valueRow.getColumnsCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (valueRow.getColumnsCount() != aliasFields.size()) {
|
||||
log.error("Column count ({}) mismatch with aliasFields size ({}) when checking meaningful data.",
|
||||
valueRow.getColumnsCount(), aliasFields.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean hasMeaningfulData = false;
|
||||
for (int i = 0; i < valueRow.getColumnsCount(); i++) {
|
||||
String columnValue = valueRow.getColumns(i);
|
||||
String alias = aliasFields.get(i);
|
||||
if (!CommonConstants.NULL_VALUE.equals(columnValue) && (!NetworkConstants.RESPONSE_TIME.equalsIgnoreCase(alias) && !CollectorConstants.KEYWORD.equalsIgnoreCase(alias))) {
|
||||
hasMeaningfulData = true;
|
||||
break;
|
||||
}
|
||||
if ((NetworkConstants.RESPONSE_TIME.equalsIgnoreCase(alias) || CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) && !CommonConstants.NULL_VALUE.equals(columnValue)) {
|
||||
hasMeaningfulData = true;
|
||||
}
|
||||
}
|
||||
return hasMeaningfulData;
|
||||
}
|
||||
|
||||
private void parseResponseByJsonPath(String resp, List<String> aliasFields, HttpProtocol http,
|
||||
CollectRep.MetricsData.Builder builder, Long responseTime) {
|
||||
List<Object> results = JsonPathParser.parseContentWithJsonPath(resp, http.getParseScript());
|
||||
@@ -600,22 +476,36 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
prometheusParser.handle(resp, aliasFields, http, builder);
|
||||
}
|
||||
|
||||
private void parseResponseByPrometheusExporter(InputStream content, List<String> aliasFields, CollectRep.MetricsData.Builder builder) throws IOException {
|
||||
Map<String, MetricFamily> metricFamilyMap = OnlineParser.parseMetrics(content);
|
||||
if (metricFamilyMap == null || metricFamilyMap.isEmpty()) {
|
||||
return;
|
||||
private void parseResponseByPrometheusExporter(String resp, List<String> aliasFields,
|
||||
CollectRep.MetricsData.Builder builder) {
|
||||
if (!EXPORTER_PARSER_TABLE.containsKey(builder.getId())) {
|
||||
EXPORTER_PARSER_TABLE.put(builder.getId(), new ExporterParser());
|
||||
}
|
||||
ExporterParser parser = EXPORTER_PARSER_TABLE.get(builder.getId());
|
||||
Map<String, MetricFamily> metricFamilyMap = parser.textToMetric(resp);
|
||||
String metrics = builder.getMetrics();
|
||||
if (metricFamilyMap.containsKey(metrics)) {
|
||||
MetricFamily metricFamily = metricFamilyMap.get(metrics);
|
||||
for (MetricFamily.Metric metric : metricFamily.getMetricList()) {
|
||||
Map<String, String> labelMap = metric.getLabels()
|
||||
Map<String, String> labelMap = metric.getLabelPair()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(MetricFamily.Label::getName, MetricFamily.Label::getValue));
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String aliasField : aliasFields) {
|
||||
if ("value".equals(aliasField)) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getValue()));
|
||||
if (metric.getCounter() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getCounter().getValue()));
|
||||
} else if (metric.getGauge() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getGauge().getValue()));
|
||||
} else if (metric.getUntyped() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getUntyped().getValue()));
|
||||
} else if (metric.getInfo() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getInfo().getValue()));
|
||||
} else if (metric.getSummary() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getSummary().getValue()));
|
||||
} else if (metric.getHistogram() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getHistogram().getValue()));
|
||||
}
|
||||
} else {
|
||||
String columnValue = labelMap.get(aliasField);
|
||||
valueRowBuilder.addColumn(columnValue == null ? CommonConstants.NULL_VALUE : columnValue);
|
||||
|
||||
+432
@@ -0,0 +1,432 @@
|
||||
/*
|
||||
* 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.http.promethus.exporter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.http.promethus.ParseException;
|
||||
import org.apache.hertzbeat.common.util.StrBuffer;
|
||||
|
||||
/**
|
||||
* Resolves the data passed by prometheus's exporter interface http:xxx/metrics
|
||||
* Reference: prometheus text_parse.go code, entry: TextToMetricFamilies
|
||||
*/
|
||||
@Slf4j
|
||||
public class ExporterParser {
|
||||
private static final String HELP = "HELP";
|
||||
private static final String TYPE = "TYPE";
|
||||
private static final String EOF = "EOF";
|
||||
private static final String METRIC_NAME_LABEL = ".name";
|
||||
private static final String QUANTILE_LABEL = "quantile";
|
||||
private static final String BUCKET_LABEL = "le";
|
||||
private static final String NAME_LABEL = "__name__";
|
||||
private static final String SUM_SUFFIX = "_sum";
|
||||
private static final String COUNT_SUFFIX = "_count";
|
||||
|
||||
private static final char LEFT_CURLY_BRACKET = '{';
|
||||
private static final char RIGHT_CURLY_BRACKET = '}';
|
||||
private static final char EQUALS = '=';
|
||||
private static final char QUOTES = '"';
|
||||
private static final char ENTER = '\n';
|
||||
private static final char SPACE = ' ';
|
||||
private static final char COMMA = ',';
|
||||
private final Lock lock = new ReentrantLock();
|
||||
private MetricFamily currentMetricFamily;
|
||||
private String currentQuantile;
|
||||
private String currentBucket;
|
||||
|
||||
public Map<String, MetricFamily> textToMetric(String resp) {
|
||||
// key: metric name, value: metric family
|
||||
Map<String, MetricFamily> metricMap = new ConcurrentHashMap<>(10);
|
||||
lock.lock();
|
||||
try {
|
||||
String[] lines = resp.split("\n");
|
||||
for (String line : lines) {
|
||||
this.parseLine(metricMap, new StrBuffer(line));
|
||||
}
|
||||
return metricMap;
|
||||
} catch (Exception e) {
|
||||
log.error("parse prometheus exporter data error, msg: {}", e.getMessage());
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
return metricMap;
|
||||
}
|
||||
|
||||
private void parseLine(Map<String, MetricFamily> metricMap, StrBuffer buffer) {
|
||||
buffer.skipBlankTabs();
|
||||
if (buffer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
switch (buffer.charAt(0)) {
|
||||
case '#' -> {
|
||||
buffer.read();
|
||||
this.currentMetricFamily = null;
|
||||
this.parseComment(metricMap, buffer);
|
||||
}
|
||||
case ENTER -> {
|
||||
}
|
||||
default -> {
|
||||
this.currentBucket = null;
|
||||
this.currentQuantile = null;
|
||||
this.parseMetric(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseComment(Map<String, MetricFamily> metricMap, StrBuffer buffer) {
|
||||
buffer.skipBlankTabs();
|
||||
if (buffer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String token = this.readTokenUnitWhitespace(buffer);
|
||||
if (EOF.equals(token)) {
|
||||
return;
|
||||
}
|
||||
if (!HELP.equals(token) && !TYPE.equals(token)) {
|
||||
log.error("parse comment error {}, start without {} or {}", buffer.toStr(), HELP, TYPE);
|
||||
return;
|
||||
}
|
||||
String metricName = this.readTokenAsMetricName(buffer);
|
||||
this.currentMetricFamily = metricMap.computeIfAbsent(metricName, key -> new MetricFamily());
|
||||
this.currentMetricFamily.setName(metricName);
|
||||
switch (token) {
|
||||
case HELP -> this.parseHelp(buffer);
|
||||
case TYPE -> this.parseType(buffer);
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseHelp(StrBuffer line) {
|
||||
line.skipBlankTabs();
|
||||
this.currentMetricFamily.setHelp(line.toStr());
|
||||
}
|
||||
|
||||
private void parseType(StrBuffer line) {
|
||||
line.skipBlankTabs();
|
||||
String type = line.toStr().toLowerCase();
|
||||
MetricType metricType = MetricType.getType(type);
|
||||
if (metricType == null) {
|
||||
throw new ParseException("pare type error");
|
||||
}
|
||||
this.currentMetricFamily.setMetricType(metricType);
|
||||
}
|
||||
|
||||
private void parseMetric(StrBuffer buffer) {
|
||||
String metricName = this.readTokenAsMetricName(buffer);
|
||||
MetricFamily.Label label = new MetricFamily.Label();
|
||||
label.setName(METRIC_NAME_LABEL);
|
||||
label.setValue(metricName);
|
||||
|
||||
if (metricName.isEmpty()) {
|
||||
log.error("error parse metric, metric name is null, line: {}", buffer.toStr());
|
||||
return;
|
||||
}
|
||||
|
||||
List<MetricFamily.Metric> metricList = this.currentMetricFamily.getMetricList();
|
||||
if (metricList == null) {
|
||||
metricList = new ArrayList<>();
|
||||
this.currentMetricFamily.setMetricList(metricList);
|
||||
}
|
||||
|
||||
// TODO For the time being, the data is displayed in the form of labels. If there is a better chart display method in the future, we will optimize it.
|
||||
MetricFamily.Metric metric = new MetricFamily.Metric();
|
||||
metricList.add(metric);
|
||||
|
||||
metric.setLabelPair(new ArrayList<>());
|
||||
metric.getLabelPair().add(label);
|
||||
this.readLabels(metric, buffer);
|
||||
}
|
||||
|
||||
private void readLabels(MetricFamily.Metric metric, StrBuffer buffer) {
|
||||
buffer.skipBlankTabs();
|
||||
if (buffer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (buffer.charAt(0) == LEFT_CURLY_BRACKET) {
|
||||
buffer.read();
|
||||
this.startReadLabelName(metric, buffer);
|
||||
} else {
|
||||
this.readLabelValue(metric, null, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private void startReadLabelName(MetricFamily.Metric metric, StrBuffer buffer) {
|
||||
buffer.skipBlankTabs();
|
||||
if (buffer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (buffer.charAt(0) == RIGHT_CURLY_BRACKET) {
|
||||
buffer.read();
|
||||
buffer.skipBlankTabs();
|
||||
if (buffer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
this.readLabelValue(metric, new MetricFamily.Label(), buffer);
|
||||
return;
|
||||
}
|
||||
String labelName = this.readTokenAsLabelName(buffer);
|
||||
if (labelName.isEmpty() || labelName.equals(NAME_LABEL)) {
|
||||
throw new ParseException("invalid label name" + labelName + ", label name size = 0 or label name equals " + NAME_LABEL);
|
||||
}
|
||||
MetricFamily.Label label = new MetricFamily.Label();
|
||||
label.setName(labelName);
|
||||
if (buffer.read() != EQUALS) {
|
||||
throw new ParseException("parse error, not match the format of labelName=labelValue");
|
||||
}
|
||||
this.startReadLabelValue(metric, label, buffer);
|
||||
}
|
||||
|
||||
private void startReadLabelValue(MetricFamily.Metric metric, MetricFamily.Label label, StrBuffer buffer) {
|
||||
buffer.skipBlankTabs();
|
||||
if (buffer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
char c = buffer.read();
|
||||
if (c != QUOTES) {
|
||||
throw new ParseException("expected '\"' at start of label value, line: " + buffer.toStr());
|
||||
}
|
||||
String labelValue = this.readTokenAsLabelValue(buffer);
|
||||
label.setValue(labelValue);
|
||||
if (!this.isValidLabelValue(labelValue)) {
|
||||
throw new ParseException("no valid label value: " + labelValue);
|
||||
}
|
||||
if (this.currentMetricFamily.getMetricType().equals(MetricType.SUMMARY) && label.getName().equals(QUANTILE_LABEL)) {
|
||||
this.currentQuantile = labelValue;
|
||||
} else if (this.currentMetricFamily.getMetricType().equals(MetricType.HISTOGRAM) && label.getName().equals(BUCKET_LABEL)) {
|
||||
this.currentBucket = labelValue;
|
||||
}
|
||||
metric.getLabelPair().add(label);
|
||||
|
||||
if (buffer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
c = buffer.read();
|
||||
switch (c) {
|
||||
case COMMA -> this.startReadLabelName(metric, buffer);
|
||||
case RIGHT_CURLY_BRACKET -> this.readLabelValue(metric, label, buffer);
|
||||
default -> throw new ParseException("expected '}' or ',' at end of label value, line: " + buffer.toStr());
|
||||
}
|
||||
}
|
||||
|
||||
private void readLabelValue(MetricFamily.Metric metric, MetricFamily.Label label, StrBuffer buffer) {
|
||||
buffer.skipBlankTabs();
|
||||
if (buffer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
switch (this.currentMetricFamily.getMetricType()) {
|
||||
case INFO -> {
|
||||
MetricFamily.Info info = new MetricFamily.Info();
|
||||
info.setValue(buffer.toDouble());
|
||||
metric.setInfo(info);
|
||||
}
|
||||
case COUNTER -> {
|
||||
MetricFamily.Counter counter = new MetricFamily.Counter();
|
||||
counter.setValue(buffer.toDouble());
|
||||
metric.setCounter(counter);
|
||||
}
|
||||
case GAUGE -> {
|
||||
MetricFamily.Gauge gauge = new MetricFamily.Gauge();
|
||||
gauge.setValue(buffer.toDouble());
|
||||
metric.setGauge(gauge);
|
||||
}
|
||||
case UNTYPED -> {
|
||||
MetricFamily.Untyped untyped = new MetricFamily.Untyped();
|
||||
untyped.setValue(buffer.toDouble());
|
||||
metric.setUntyped(untyped);
|
||||
}
|
||||
case SUMMARY -> {
|
||||
// For the time being, the data is displayed in the form of labels. If there is a better chart display method in the future, we will optimize it.
|
||||
MetricFamily.Summary summary = new MetricFamily.Summary();
|
||||
summary.setValue(buffer.toDouble());
|
||||
metric.setSummary(summary);
|
||||
}
|
||||
case HISTOGRAM -> {
|
||||
// For the time being, the data is displayed in the form of labels. If there is a better chart display method in the future, we will optimize it.
|
||||
MetricFamily.Histogram histogram = new MetricFamily.Histogram();
|
||||
histogram.setValue(buffer.toDouble());
|
||||
metric.setHistogram(histogram);
|
||||
}
|
||||
default -> throw new ParseException("no such type in metricFamily");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the token before the first whitespace
|
||||
*
|
||||
* @param buffer A line data object
|
||||
* @return token unit
|
||||
*/
|
||||
private String readTokenUnitWhitespace(StrBuffer buffer) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
while (!buffer.isEmpty()) {
|
||||
char c = buffer.read();
|
||||
if (c == SPACE) {
|
||||
break;
|
||||
}
|
||||
builder.append(c);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the metric
|
||||
*
|
||||
* @param buffer A line data object
|
||||
* @return token name
|
||||
*/
|
||||
private String readTokenAsMetricName(StrBuffer buffer) {
|
||||
buffer.skipBlankTabs();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (this.isValidMetricNameStart(buffer.charAt(0))) {
|
||||
while (!buffer.isEmpty()) {
|
||||
char c = buffer.read();
|
||||
if (!this.isValidMetricNameContinuation(c)) {
|
||||
buffer.rollback();
|
||||
break;
|
||||
}
|
||||
builder.append(c);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
throw new ParseException("parse metric name error");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the label
|
||||
*
|
||||
* @param buffer A line data object
|
||||
* @return label name
|
||||
*/
|
||||
private String readTokenAsLabelName(StrBuffer buffer) {
|
||||
buffer.skipBlankTabs();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
char c = buffer.read();
|
||||
if (this.isValidLabelNameStart(c)) {
|
||||
builder.append(c);
|
||||
while (!buffer.isEmpty()) {
|
||||
c = buffer.read();
|
||||
if (!this.isValidLabelNameContinuation(c)) {
|
||||
buffer.rollback();
|
||||
break;
|
||||
}
|
||||
builder.append(c);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
throw new ParseException("parse label name error");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the label
|
||||
*
|
||||
* @param buffer A line data object
|
||||
* @return label value
|
||||
*/
|
||||
private String readTokenAsLabelValue(StrBuffer buffer) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean escaped = false;
|
||||
while (!buffer.isEmpty()) {
|
||||
char c = buffer.read();
|
||||
// Handle '\\' escape sequences
|
||||
if (escaped) {
|
||||
switch (c) {
|
||||
case QUOTES, '\\' -> builder.append(c);
|
||||
case 'n' -> builder.append('\n');
|
||||
default -> throw new ParseException("parse label value error");
|
||||
}
|
||||
escaped = false;
|
||||
} else {
|
||||
switch (c) {
|
||||
case QUOTES -> {
|
||||
return builder.toString();
|
||||
}
|
||||
case ENTER -> throw new ParseException("parse label value error, next line");
|
||||
case '\\' -> escaped = true;
|
||||
default -> builder.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a character conforms to the first character rule for metric names
|
||||
*
|
||||
* @param c metric character
|
||||
* @return true/false
|
||||
*/
|
||||
private boolean isValidMetricNameStart(char c) {
|
||||
return isValidLabelNameStart(c) || c == ':';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a character conforms to rules for metric name characters other than the first
|
||||
*
|
||||
* @param c metric character
|
||||
* @return true/false
|
||||
*/
|
||||
private boolean isValidMetricNameContinuation(char c) {
|
||||
return isValidLabelNameContinuation(c) || c == ':';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a character conforms to the first character rule for label names
|
||||
*
|
||||
* @param c metric character
|
||||
* @return true/false
|
||||
*/
|
||||
private boolean isValidLabelNameStart(char c) {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a character conforms to rules for label name characters other than the first
|
||||
*
|
||||
* @param c metric character
|
||||
* @return true/false
|
||||
*/
|
||||
private boolean isValidLabelNameContinuation(char c) {
|
||||
return isValidLabelNameStart(c) || (c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string is a valid UTF-8 encoded string
|
||||
*
|
||||
* @param s label value
|
||||
* @return true/false
|
||||
*/
|
||||
private boolean isValidLabelValue(String s) {
|
||||
return s != null;
|
||||
}
|
||||
|
||||
private boolean isSum(String s) {
|
||||
return s != null && s.endsWith(SUM_SUFFIX);
|
||||
}
|
||||
|
||||
private boolean isCount(String s) {
|
||||
return s != null && s.endsWith(COUNT_SUFFIX);
|
||||
}
|
||||
|
||||
}
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* 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.http.promethus.exporter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* MetricFamily.
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
public class MetricFamily {
|
||||
/**
|
||||
* metric name
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* metric help
|
||||
*/
|
||||
private String help;
|
||||
|
||||
/**
|
||||
* metric type
|
||||
*/
|
||||
private MetricType metricType;
|
||||
|
||||
/**
|
||||
* Specific metric
|
||||
*/
|
||||
private List<Metric> metricList;
|
||||
|
||||
/**
|
||||
* Metric
|
||||
*/
|
||||
@Data
|
||||
public static class Metric {
|
||||
|
||||
/**
|
||||
* Label data, mainly corresponding to the content within {}
|
||||
*/
|
||||
private List<Label> labelPair;
|
||||
|
||||
/**
|
||||
* info
|
||||
*/
|
||||
private Info info;
|
||||
|
||||
/**
|
||||
* gauge
|
||||
*/
|
||||
private Gauge gauge;
|
||||
|
||||
/**
|
||||
* counter
|
||||
*/
|
||||
private Counter counter;
|
||||
|
||||
/**
|
||||
* summary
|
||||
*/
|
||||
private Summary summary;
|
||||
|
||||
/**
|
||||
* untyped
|
||||
*/
|
||||
private Untyped untyped;
|
||||
|
||||
/**
|
||||
* histogram
|
||||
*/
|
||||
private Histogram histogram;
|
||||
|
||||
/**
|
||||
* timestampMs
|
||||
*/
|
||||
private Long timestampMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
@Data
|
||||
public static class Label {
|
||||
|
||||
/**
|
||||
* name
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* value
|
||||
*/
|
||||
private String value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Info
|
||||
*/
|
||||
@Data
|
||||
public static class Info {
|
||||
|
||||
/**
|
||||
* value
|
||||
*/
|
||||
private double value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Counter
|
||||
*/
|
||||
@Data
|
||||
public static class Counter {
|
||||
|
||||
/**
|
||||
* value
|
||||
*/
|
||||
private double value;
|
||||
|
||||
// Exemplar
|
||||
}
|
||||
|
||||
/**
|
||||
* Gauge
|
||||
*/
|
||||
@Data
|
||||
public static class Gauge {
|
||||
|
||||
/**
|
||||
* value
|
||||
*/
|
||||
private double value;
|
||||
}
|
||||
|
||||
/**
|
||||
* untyped
|
||||
*/
|
||||
@Data
|
||||
public static class Untyped {
|
||||
|
||||
/**
|
||||
* value
|
||||
*/
|
||||
private double value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary
|
||||
*/
|
||||
@Data
|
||||
public static class Summary {
|
||||
|
||||
/**
|
||||
* value
|
||||
*/
|
||||
private double value;
|
||||
|
||||
/**
|
||||
* count
|
||||
*/
|
||||
private long count;
|
||||
|
||||
/**
|
||||
* sum
|
||||
*/
|
||||
private double sum;
|
||||
|
||||
/**
|
||||
* quantileList
|
||||
*/
|
||||
private List<Quantile> quantileList = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Quantile
|
||||
*/
|
||||
@Data
|
||||
public static class Quantile {
|
||||
/**
|
||||
* Corresponding to the quantile field in Prometheus
|
||||
*/
|
||||
private double xLabel;
|
||||
|
||||
/**
|
||||
* value
|
||||
*/
|
||||
private double value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Histogram
|
||||
*/
|
||||
@Data
|
||||
public static class Histogram {
|
||||
|
||||
/**
|
||||
* value
|
||||
*/
|
||||
private double value;
|
||||
|
||||
/**
|
||||
* count
|
||||
*/
|
||||
private long count;
|
||||
|
||||
/**
|
||||
* sum
|
||||
*/
|
||||
private double sum;
|
||||
|
||||
/**
|
||||
* bucketList
|
||||
*/
|
||||
private List<Bucket> bucketList = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bucket
|
||||
*/
|
||||
@Data
|
||||
public static class Bucket {
|
||||
|
||||
/**
|
||||
* cumulativeCount
|
||||
*/
|
||||
private long cumulativeCount;
|
||||
|
||||
/**
|
||||
* upperBound
|
||||
*/
|
||||
private double upperBound;
|
||||
}
|
||||
}
|
||||
+52
@@ -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.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.http.promethus.exporter;
|
||||
|
||||
/**
|
||||
* prometheus metrics type
|
||||
*/
|
||||
public enum MetricType {
|
||||
// for string metric info
|
||||
INFO("info"),
|
||||
// Represents a monotonically increasing counter, e.g., counting occurrences
|
||||
COUNTER("counter"),
|
||||
// A metric type that can fluctuate up and down, e.g., CPU usage rate
|
||||
GAUGE("gauge"),
|
||||
SUMMARY("summary"),
|
||||
UNTYPED("untyped"),
|
||||
HISTOGRAM("histogram");
|
||||
|
||||
private final String value;
|
||||
|
||||
MetricType(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static MetricType getType(String value) {
|
||||
for (MetricType metricType : values()) {
|
||||
if (metricType.getValue().equals(value)) {
|
||||
return metricType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+24
-13
@@ -19,7 +19,6 @@ package org.apache.hertzbeat.collector.collect.prometheus;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.SignConstants.RIGHT_DASH;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.UnknownHostException;
|
||||
@@ -34,7 +33,8 @@ import java.util.stream.Stream;
|
||||
import javax.net.ssl.SSLException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.common.http.CommonHttpClient;
|
||||
import org.apache.hertzbeat.collector.collect.prometheus.parser.MetricFamily;
|
||||
import org.apache.hertzbeat.common.entity.dto.MetricFamily;
|
||||
import org.apache.hertzbeat.collector.collect.prometheus.parser.TextParser;
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.collector.util.CollectUtil;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
@@ -46,7 +46,6 @@ 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.hertzbeat.collector.collect.prometheus.parser.OnlineParser;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpStatus;
|
||||
@@ -65,6 +64,7 @@ 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;
|
||||
|
||||
@@ -99,12 +99,25 @@ public class PrometheusAutoCollectImpl {
|
||||
builder.setMsg(NetworkConstants.STATUS_CODE + SignConstants.BLANK + statusCode);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return parseResponseByPrometheusExporter(response.getEntity().getContent(), builder);
|
||||
} catch (Exception e) {
|
||||
log.info("parse error: {}.", e.getMessage(), e);
|
||||
// todo: The InputStream is directly converted to a String here
|
||||
// For large data in the Prometheus exporter, this can generate large objects, which could severely impact JVM memory space
|
||||
// todo: Option one: Use InputStream for parsing, but this requires significant code changes
|
||||
// Option two: Manually trigger garbage collection, which can be referenced from Dubbo for long i
|
||||
String resp = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
||||
long collectTime = System.currentTimeMillis();
|
||||
builder.setTime(collectTime);
|
||||
if (resp == null || !StringUtils.hasText(resp)) {
|
||||
log.error("http response content is empty, status: {}.", statusCode);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg("parse response data error:" + e.getMessage());
|
||||
builder.setMsg("http response content is empty");
|
||||
} else {
|
||||
try {
|
||||
return parseResponseByPrometheusExporter(resp, metrics.getAliasFields(), builder);
|
||||
} catch (Exception e) {
|
||||
log.info("parse error: {}.", e.getMessage(), e);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg("parse response data error:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
} catch (ClientProtocolException e1) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e1);
|
||||
@@ -155,12 +168,10 @@ public class PrometheusAutoCollectImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private List<CollectRep.MetricsData> parseResponseByPrometheusExporter(InputStream inputStream, CollectRep.MetricsData.Builder builder) throws IOException {
|
||||
Map<String, MetricFamily> metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
private List<CollectRep.MetricsData> parseResponseByPrometheusExporter(String resp, List<String> aliasFields,
|
||||
CollectRep.MetricsData.Builder builder) {
|
||||
Map<String, MetricFamily> metricFamilyMap = TextParser.textToMetricFamilies(resp);
|
||||
List<CollectRep.MetricsData> metricsDataList = new LinkedList<>();
|
||||
if (metricFamilyMap == null) {
|
||||
return metricsDataList;
|
||||
}
|
||||
for (Map.Entry<String, MetricFamily> entry : metricFamilyMap.entrySet()) {
|
||||
builder.clearFields();
|
||||
builder.clearValues();
|
||||
|
||||
+2
-2
@@ -24,15 +24,14 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.http.promethus.ParseException;
|
||||
import org.apache.hertzbeat.common.entity.dto.MetricFamily;
|
||||
import org.apache.hertzbeat.common.util.StrBuffer;
|
||||
|
||||
/**
|
||||
* Resolves the data passed by prometheus's exporter interface http:xxx/metrics
|
||||
* Reference: prometheus text_parse.go code, entry: TextToMetricFamilies
|
||||
* recommend use OnlineParser
|
||||
*/
|
||||
@Slf4j
|
||||
@Deprecated(since = "1.7.0")
|
||||
public class TextParser {
|
||||
private static final String NAME_LABEL = "__name__";
|
||||
private static final char LEFT_CURLY_BRACKET = '{';
|
||||
@@ -46,6 +45,7 @@ public class TextParser {
|
||||
|
||||
/**
|
||||
* parser prometheus exporter text metrics data
|
||||
* todo use inputStream bytebuffer instead of resp string
|
||||
* @param resp txt data
|
||||
* @return metrics family
|
||||
*/
|
||||
|
||||
+6
-6
@@ -58,13 +58,13 @@ public class PushCollectImpl extends AbstractCollect {
|
||||
private static final Map<Long, Long> timeMap = new ConcurrentHashMap<>();
|
||||
|
||||
// ms
|
||||
private static final Integer DEFAULT_TIMEOUT = 3000;
|
||||
private static final Integer timeout = 3000;
|
||||
|
||||
private static final Integer SUCCESS_CODE = 200;
|
||||
|
||||
// It's hard to determine how long ago the first data collection was, because there's no way to know when the last collection occurred.
|
||||
// This makes it difficult to avoid re-collecting data after a restart. The default is 30 seconds
|
||||
private static final Integer FIRST_COLLECT_INTERVAL = 30000;
|
||||
private static final Integer firstCollectInterval = 30000;
|
||||
|
||||
@Override
|
||||
public void preCheck(Metrics metrics) throws IllegalArgumentException {
|
||||
@@ -80,7 +80,7 @@ public class PushCollectImpl extends AbstractCollect {
|
||||
long monitorId = builder.getId();
|
||||
PushProtocol pushProtocol = metrics.getPush();
|
||||
|
||||
Long time = timeMap.getOrDefault(monitorId, curTime - FIRST_COLLECT_INTERVAL);
|
||||
Long time = timeMap.getOrDefault(monitorId, curTime - firstCollectInterval);
|
||||
timeMap.put(monitorId, curTime);
|
||||
|
||||
HttpContext httpContext = createHttpContext(pushProtocol);
|
||||
@@ -145,10 +145,10 @@ public class PushCollectImpl extends AbstractCollect {
|
||||
|
||||
//requestBuilder.setUri(pushProtocol.getUri());
|
||||
|
||||
if (DEFAULT_TIMEOUT > 0) {
|
||||
if (timeout > 0) {
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(DEFAULT_TIMEOUT)
|
||||
.setSocketTimeout(DEFAULT_TIMEOUT)
|
||||
.setConnectTimeout(timeout)
|
||||
.setSocketTimeout(timeout)
|
||||
.setRedirectsEnabled(true)
|
||||
.build();
|
||||
requestBuilder.setConfig(requestConfig);
|
||||
|
||||
+14
-14
@@ -99,26 +99,26 @@ class HttpCollectImplTest {
|
||||
</server>
|
||||
</root>
|
||||
""";
|
||||
|
||||
|
||||
// Set up HttpProtocol with XML path parsing
|
||||
HttpProtocol http = HttpProtocol.builder()
|
||||
.parseType(DispatchConstants.PARSE_XML_PATH)
|
||||
.parseScript("//server") // XPath to select all server nodes
|
||||
.build();
|
||||
|
||||
|
||||
// Set up Metrics with fields that have XPath expressions
|
||||
List<Metrics.Field> fields = new ArrayList<>();
|
||||
fields.add(Metrics.Field.builder().field("name").build());
|
||||
fields.add(Metrics.Field.builder().field("status").build());
|
||||
fields.add(Metrics.Field.builder().field("metrics/cpu").build());
|
||||
fields.add(Metrics.Field.builder().field("metrics/memory").build());
|
||||
|
||||
fields.add(Metrics.Field.builder().field("name").xpath("name").build());
|
||||
fields.add(Metrics.Field.builder().field("status").xpath("status").build());
|
||||
fields.add(Metrics.Field.builder().field("cpu").xpath("metrics/cpu").build());
|
||||
fields.add(Metrics.Field.builder().field("memory").xpath("metrics/memory").build());
|
||||
|
||||
Metrics metrics = Metrics.builder()
|
||||
.http(http)
|
||||
.fields(fields)
|
||||
.aliasFields(Arrays.asList("name", "status", "metrics/cpu", "metrics/memory"))
|
||||
.aliasFields(Arrays.asList("name", "status", "cpu", "memory"))
|
||||
.build();
|
||||
|
||||
|
||||
// Create a custom builder that captures added rows
|
||||
List<CollectRep.ValueRow> capturedRows = new ArrayList<>();
|
||||
CollectRep.MetricsData.Builder builder = new CollectRep.MetricsData.Builder() {
|
||||
@@ -128,7 +128,7 @@ class HttpCollectImplTest {
|
||||
return super.addValueRow(valueRow);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Use reflection to access the private parseResponseByXmlPath method
|
||||
Method parseMethod = HttpCollectImpl.class.getDeclaredMethod(
|
||||
"parseResponseByXmlPath",
|
||||
@@ -137,13 +137,13 @@ class HttpCollectImplTest {
|
||||
CollectRep.MetricsData.Builder.class,
|
||||
Long.class);
|
||||
parseMethod.setAccessible(true);
|
||||
|
||||
|
||||
// Call the method
|
||||
parseMethod.invoke(httpCollectImpl, xmlResponse, metrics, builder, 100L);
|
||||
|
||||
|
||||
// Verify the results
|
||||
assertEquals(2, capturedRows.size(), "Should have parsed 2 server nodes");
|
||||
|
||||
|
||||
// Check first server
|
||||
CollectRep.ValueRow firstRow = capturedRows.get(0);
|
||||
assertEquals(4, firstRow.getColumnsCount(), "First row should have 4 columns");
|
||||
@@ -151,7 +151,7 @@ class HttpCollectImplTest {
|
||||
assertEquals("Running", firstRow.getColumns(1), "First server status should be Running");
|
||||
assertEquals("75.5", firstRow.getColumns(2), "First server CPU should be 75.5");
|
||||
assertEquals("1024", firstRow.getColumns(3), "First server memory should be 1024");
|
||||
|
||||
|
||||
// Check second server
|
||||
CollectRep.ValueRow secondRow = capturedRows.get(1);
|
||||
assertEquals(4, secondRow.getColumnsCount(), "Second row should have 4 columns");
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.http.promethus.exporter;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test case for {@link ExporterParser}
|
||||
*/
|
||||
class ExporterParserTest {
|
||||
|
||||
@Test
|
||||
void textToMetric() {
|
||||
String resp = """
|
||||
# HELP disk_total_bytes Total space for path
|
||||
# TYPE disk_total_bytes gauge
|
||||
disk_total_bytes{path="C:\\\\hertzbeat\\\\repo\\\\testpath",} 4.29496725504E11
|
||||
# HELP go_gc_cycles_automatic_gc_cycles_total Count of completed GC cycles generated by the Go runtime.
|
||||
# TYPE go_gc_cycles_automatic_gc_cycles_total counter
|
||||
go_gc_cycles_automatic_gc_cycles_total 0
|
||||
# HELP go_gc_cycles_forced_gc_cycles_total Count of completed GC cycles forced by the application.
|
||||
# TYPE go_gc_cycles_forced_gc_cycles_total counter
|
||||
go_gc_cycles_forced_gc_cycles_total 0
|
||||
# HELP go_gc_cycles_total_gc_cycles_total Count of all completed GC cycles.
|
||||
# TYPE go_gc_cycles_total_gc_cycles_total counter
|
||||
go_gc_cycles_total_gc_cycles_total 0
|
||||
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
|
||||
# TYPE go_gc_duration_seconds summary
|
||||
go_gc_duration_seconds{quantile="0"} 0
|
||||
go_gc_duration_seconds{quantile="0.25"} 0
|
||||
go_gc_duration_seconds{quantile="0.5"} 0
|
||||
go_gc_duration_seconds{quantile="0.75"} 0
|
||||
go_gc_duration_seconds{quantile="1"} 0
|
||||
# TYPE jvm info
|
||||
# HELP jvm VM version info
|
||||
jvm_info{runtime="OpenJDK Runtime Environment",vendor="Azul Systems, Inc.",version="11.0.13+8-LTS"} 1.0
|
||||
# TYPE jvm_gc_collection_seconds summary
|
||||
# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.
|
||||
jvm_gc_collection_seconds_count{gc="G1 Young Generation"} 10.0
|
||||
jvm_gc_collection_seconds_sum{gc="G1 Young Generation"} 0.051
|
||||
jvm_gc_collection_seconds_count{gc="G1 Old Generation"} 0.0
|
||||
jvm_gc_collection_seconds_sum{gc="G1 Old Generation"} 0.0
|
||||
# TYPE resource_group_aggregate_usage_secs summary
|
||||
resource_group_aggregate_usage_secs{cluster="standalone",quantile="0.5"} 2.69245E-4
|
||||
resource_group_aggregate_usage_secs{cluster="standalone",quantile="0.9"} 3.49601E-4
|
||||
resource_group_aggregate_usage_secs_count{cluster="standalone"} 13.0
|
||||
resource_group_aggregate_usage_secs_sum{cluster="standalone"} 0.004832498
|
||||
resource_group_aggregate_usage_secs_created{cluster="standalone"} 1.715842140749E9
|
||||
# TYPE metadata_store_ops_latency_ms histogram
|
||||
metadata_store_ops_latency_ms_bucket{cluster="standalone",name="metadata-store",type="get",status="success",le="1.0"} 59.0
|
||||
metadata_store_ops_latency_ms_bucket{cluster="standalone",name="metadata-store",type="get",status="success",le="3.0"} 61.0
|
||||
metadata_store_ops_latency_ms_bucket{cluster="standalone",name="metadata-store",type="get",status="success",le="5.0"} 61.0
|
||||
# EOF""";
|
||||
|
||||
ExporterParser parser = new ExporterParser();
|
||||
Map<String, MetricFamily> metricFamilyMap = parser.textToMetric(resp);
|
||||
assertEquals(5, metricFamilyMap.get("resource_group_aggregate_usage_secs").getMetricList().size());
|
||||
assertEquals(3, metricFamilyMap.get("metadata_store_ops_latency_ms").getMetricList().size());
|
||||
assertEquals(5, metricFamilyMap.get("go_gc_duration_seconds").getMetricList().size());
|
||||
assertEquals(9, metricFamilyMap.size());
|
||||
}
|
||||
}
|
||||
+9
-30
@@ -17,6 +17,8 @@
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.prometheus.parser;
|
||||
|
||||
import org.apache.hertzbeat.common.entity.dto.MetricFamily;
|
||||
import org.apache.hertzbeat.common.util.OnlineParser;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -25,12 +27,8 @@ import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
class OnlineParserTest {
|
||||
|
||||
@@ -48,13 +46,13 @@ class OnlineParserTest {
|
||||
String str = """
|
||||
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
|
||||
# TYPE go_gc_duration_seconds summary
|
||||
go_gc_duration_seconds{quantile="0"} 2.0209e-05
|
||||
go_gc_duration_seconds{quantile="0.25"} 6.6917e-05
|
||||
go_gc_duration_seconds { quantile="0"} 2.0209e-05 321312
|
||||
go_gc_duration_seconds{ quantile = "0.25" } 6.6917e-05
|
||||
go_gc_duration_seconds{quantile="0.5"} -Inf
|
||||
go_gc_duration_seconds{quantile="0.75"} +Inf
|
||||
go_gc_duration_seconds{ quantile = "0.75"} +Inf
|
||||
go_gc_duration_seconds{quantile="1"} NaN
|
||||
go_gc_duration_seconds_sum 0.001134793
|
||||
go_gc_duration_seconds_count 5
|
||||
go_gc_duration_seconds_sum 0.001134793 321314
|
||||
go_gc_duration_seconds_count 5 43
|
||||
# HELP go_goroutines Number of goroutines that currently exist.
|
||||
# TYPE go_goroutines gauge
|
||||
go_goroutines 32
|
||||
@@ -77,26 +75,7 @@ class OnlineParserTest {
|
||||
# TYPE go_memstats_gc_sys_bytes gauge
|
||||
go_memstats_gc_sys_bytes 4.614808e+06""";
|
||||
InputStream inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||
Map<String, MetricFamily> metricFamilyMap1 = OnlineParser.parseMetrics(inputStream);
|
||||
Map<String, MetricFamily> metricFamilyMap2 = TextParser.textToMetricFamilies(str);
|
||||
assertNotNull(metricFamilyMap1);
|
||||
assertNotNull(metricFamilyMap2);
|
||||
assertEquals(metricFamilyMap1.size(), metricFamilyMap2.size());
|
||||
metricFamilyMap2.forEach((metricFamilyName, metricFamily2) -> {
|
||||
if (!metricFamilyMap1.containsKey(metricFamilyName)) {
|
||||
fail("parse failed, different result from two parser.");
|
||||
}
|
||||
MetricFamily metricFamily1 = metricFamilyMap1.get(metricFamilyName);
|
||||
assertEquals(metricFamily1.getName(), metricFamily1.getName());
|
||||
Set<Double> metricValueSet = metricFamily2.getMetricList().stream().map(MetricFamily.Metric::getValue).collect(Collectors.toSet());
|
||||
metricFamily1.getMetricList().forEach(metric -> {
|
||||
// this is for something different between two algorithms above, and both of them is current on this parsing behavior.
|
||||
if (!(metric.getValue() == Double.POSITIVE_INFINITY || metric.getValue() == Double.NEGATIVE_INFINITY)) {
|
||||
if (!metricValueSet.contains(metric.getValue())) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
Map<String, MetricFamily> metricFamilyMap = OnlineParser.parseMetrics(inputStream);
|
||||
assertNotNull(metricFamilyMap);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -302,7 +302,7 @@ public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
|
||||
value = String.valueOf(objValue);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("[calculates execute warning, use original value.] {}", e.getMessage());
|
||||
log.info("[calculates execute warning] {}.", e.getMessage());
|
||||
value = Optional.ofNullable(fieldValueMap.get(expression.getSourceText()))
|
||||
.map(String::valueOf)
|
||||
.orElse(null);
|
||||
|
||||
-4
@@ -202,10 +202,6 @@ public interface DispatchConstants {
|
||||
* Parsing method prometheus exporter data
|
||||
*/
|
||||
String PARSE_PROMETHEUS = "prometheus";
|
||||
/**
|
||||
* Parse response body as config/properties format
|
||||
*/
|
||||
String PARSE_CONFIG = "config";
|
||||
/**
|
||||
* prometheus accept header
|
||||
*/
|
||||
|
||||
+7
-3
@@ -613,8 +613,9 @@ public class HashedWheelTimer implements Timer {
|
||||
HashedWheelBucket bucket = this.bucket;
|
||||
if (bucket != null) {
|
||||
bucket.remove(this);
|
||||
} else {
|
||||
timer.pendingTimeouts.decrementAndGet();
|
||||
}
|
||||
timer.pendingTimeouts.decrementAndGet();
|
||||
}
|
||||
|
||||
public boolean compareAndSetState(int expected, int state) {
|
||||
@@ -641,7 +642,6 @@ public class HashedWheelTimer implements Timer {
|
||||
}
|
||||
|
||||
try {
|
||||
remove();
|
||||
task.run(this);
|
||||
} catch (Throwable t) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
@@ -718,6 +718,7 @@ public class HashedWheelTimer implements Timer {
|
||||
while (timeout != null) {
|
||||
HashedWheelTimeout next = timeout.next;
|
||||
if (timeout.remainingRounds <= 0) {
|
||||
next = remove(timeout);
|
||||
if (timeout.deadline <= deadline) {
|
||||
timeout.expire();
|
||||
} else {
|
||||
@@ -725,7 +726,9 @@ public class HashedWheelTimer implements Timer {
|
||||
throw new IllegalStateException(String.format(
|
||||
"timeout.deadline (%d) > deadline (%d)", timeout.deadline, deadline));
|
||||
}
|
||||
} else if (!timeout.isCancelled()) {
|
||||
} else if (timeout.isCancelled()) {
|
||||
next = remove(timeout);
|
||||
} else {
|
||||
timeout.remainingRounds--;
|
||||
}
|
||||
timeout = next;
|
||||
@@ -758,6 +761,7 @@ public class HashedWheelTimer implements Timer {
|
||||
timeout.prev = null;
|
||||
timeout.next = null;
|
||||
timeout.bucket = null;
|
||||
timeout.timer.pendingTimeouts.decrementAndGet();
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
-2
@@ -65,8 +65,6 @@ public interface ConfigConstants {
|
||||
String INFO = "info";
|
||||
|
||||
String GRAFANA = "grafana";
|
||||
|
||||
String LOG = "log";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.prometheus.parser;
|
||||
package org.apache.hertzbeat.common.entity.dto;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
-59
@@ -1,59 +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.common.entity.dto.query;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Metric History Range Query Data
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Schema(description = "Query Request Data")
|
||||
public class DatasourceQuery {
|
||||
|
||||
@Schema(title = "Ref Id, unique id for the query")
|
||||
private String refId;
|
||||
|
||||
@Schema(title = "datasource name")
|
||||
private String datasource;
|
||||
|
||||
@Schema(title = "query expr, like prometheus query")
|
||||
private String expr;
|
||||
|
||||
@Schema(title = "query expr type, like promql or sql or influxql")
|
||||
private String exprType;
|
||||
|
||||
@Schema(title = "query range type, like range or instant")
|
||||
private String timeType;
|
||||
|
||||
@Schema(title = "query range start time")
|
||||
private Long start;
|
||||
|
||||
@Schema(title = "query range end time")
|
||||
private Long end;
|
||||
|
||||
@Schema(title = "query time step, like 5m or 1h")
|
||||
private String step;
|
||||
}
|
||||
+12
-33
@@ -18,13 +18,14 @@
|
||||
package org.apache.hertzbeat.common.entity.dto.query;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Metric History Range Query Data
|
||||
*/
|
||||
@@ -33,36 +34,14 @@ import lombok.NoArgsConstructor;
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Schema(description = "Metric Query Data")
|
||||
public class DatasourceQueryData {
|
||||
public class MetricQueryData {
|
||||
|
||||
@Schema(title = "Metric Schema")
|
||||
private MetricSchema schema;
|
||||
|
||||
@Schema(title = "Ref Id, unique id for the query")
|
||||
private String refId;
|
||||
|
||||
@Schema(title = "query status code, 200 for success, other for error")
|
||||
private Integer status;
|
||||
|
||||
@Schema(title = "query error message")
|
||||
private String msg;
|
||||
|
||||
@Schema(title = "query result data frames")
|
||||
private List<SchemaData> frames;
|
||||
|
||||
/**
|
||||
* Schema Data
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public static final class SchemaData {
|
||||
@Schema(title = "metrics row values, first is the timestamp-ts", example = "[[29,32,44],[32,34,true]]")
|
||||
private List<List<Object>> values;
|
||||
|
||||
@Schema(title = "Metric Schema")
|
||||
private MetricSchema schema;
|
||||
|
||||
@Schema(title = "metrics row values, first is the timestamp-ts", example = "[[29,32,44],[32,34,true]]")
|
||||
private List<Object[]> data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metric Schema
|
||||
*/
|
||||
@@ -75,9 +54,6 @@ public class DatasourceQueryData {
|
||||
@Schema(title = "Metrics Field")
|
||||
private List<MetricField> fields;
|
||||
|
||||
@Schema(title = "This frame labels")
|
||||
private Map<String, String> labels;
|
||||
|
||||
@Schema(title = "Meta Information")
|
||||
private Map<String, String> meta;
|
||||
}
|
||||
@@ -99,5 +75,8 @@ public class DatasourceQueryData {
|
||||
|
||||
@Schema(title = "Field Unit: %, Mb, Kbps etc.")
|
||||
private String unit;
|
||||
|
||||
@Schema(title = "Whether is a label")
|
||||
private Boolean label;
|
||||
}
|
||||
}
|
||||
@@ -377,5 +377,10 @@ public class Metrics {
|
||||
* Metric unit
|
||||
*/
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* when parse type is xmlParse, use it, like NetPortStatusList/NetPortStatus[id='1']/workSpeed
|
||||
*/
|
||||
private String xpath;
|
||||
}
|
||||
}
|
||||
|
||||
+44
-33
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.prometheus.parser;
|
||||
package org.apache.hertzbeat.common.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -23,6 +23,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.common.entity.dto.MetricFamily;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -37,7 +38,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
@Slf4j
|
||||
public class OnlineParser {
|
||||
|
||||
private static final Map<Integer, Integer> escapeMap = new HashMap<>(8);
|
||||
private static final Map<Integer, Integer> escapeMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
escapeMap.put((int) 'n', (int) '\n');
|
||||
@@ -50,30 +51,6 @@ public class OnlineParser {
|
||||
escapeMap.put((int) '\\', (int) '\\');
|
||||
}
|
||||
|
||||
private OnlineParser() {
|
||||
}
|
||||
|
||||
public static Map<String, MetricFamily> parseMetrics(InputStream inputStream) throws IOException {
|
||||
Map<String, MetricFamily> metricFamilyMap = new ConcurrentHashMap<>(10);
|
||||
try {
|
||||
int i = getChar(inputStream);
|
||||
while (i != -1) {
|
||||
if (i == '#' || i == '\n') {
|
||||
skipToLineEnd(inputStream).maybeEol().maybeEof().noElse();
|
||||
} else {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append((char) i);
|
||||
parseMetric(inputStream, metricFamilyMap, stringBuilder);
|
||||
}
|
||||
i = getChar(inputStream);
|
||||
}
|
||||
} catch (FormatException e) {
|
||||
log.error("prometheus parser failed because of wrong input format. {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
return metricFamilyMap;
|
||||
}
|
||||
|
||||
private static class FormatException extends Exception {
|
||||
|
||||
public FormatException() {
|
||||
@@ -156,7 +133,7 @@ public class OnlineParser {
|
||||
return this.i;
|
||||
}
|
||||
|
||||
private int getInt() {
|
||||
private int getInt() throws FormatException {
|
||||
return this.i;
|
||||
}
|
||||
|
||||
@@ -176,9 +153,14 @@ public class OnlineParser {
|
||||
}
|
||||
}
|
||||
|
||||
private static CharChecker parseOneChar(InputStream inputStream) throws IOException, FormatException {
|
||||
int i = getChar(inputStream);
|
||||
return new CharChecker(i);
|
||||
}
|
||||
|
||||
private static CharChecker parseOneDouble(InputStream inputStream, StringBuilder stringBuilder) throws IOException, FormatException {
|
||||
int i = getChar(inputStream);
|
||||
while (i >= '0' && i <= '9' || i >= 'a' && i <= 'z' || i >= 'A' && i <= 'Z' || i == '-' || i == '+' || i == '.') {
|
||||
while ((i >= '0' && i <= '9') || (i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z') || i == '-' || i == '+' || i == 'e' || i == '.') {
|
||||
stringBuilder.append((char) i);
|
||||
i = getChar(inputStream);
|
||||
}
|
||||
@@ -217,10 +199,17 @@ public class OnlineParser {
|
||||
if (i == '\\') {
|
||||
i = getChar(inputStream);
|
||||
switch (i) {
|
||||
case 'n' -> stringBuilder.append('\n');
|
||||
case '\\' -> stringBuilder.append('\\');
|
||||
case '\"' -> stringBuilder.append('\"');
|
||||
default -> throw new FormatException();
|
||||
case 'n':
|
||||
stringBuilder.append('\n');
|
||||
break;
|
||||
case '\\':
|
||||
stringBuilder.append('\\');
|
||||
break;
|
||||
case '\"':
|
||||
stringBuilder.append('\"');
|
||||
break;
|
||||
default:
|
||||
throw new FormatException();
|
||||
}
|
||||
} else {
|
||||
stringBuilder.append((char) i);
|
||||
@@ -296,7 +285,7 @@ public class OnlineParser {
|
||||
}
|
||||
|
||||
private static CharChecker parseMetric(InputStream inputStream, Map<String, MetricFamily> metricFamilyMap, StringBuilder stringBuilder) throws IOException, FormatException {
|
||||
MetricFamily metricFamily;
|
||||
MetricFamily metricFamily = null;
|
||||
MetricFamily.Metric metric = new MetricFamily.Metric();
|
||||
int i = parseMetricName(inputStream, stringBuilder).maybeSpace().maybeLeftBracket().noElse();
|
||||
String metricName = stringBuilder.toString();
|
||||
@@ -344,4 +333,26 @@ public class OnlineParser {
|
||||
metricFamily.getMetricList().add(metric);
|
||||
return new CharChecker(i);
|
||||
}
|
||||
|
||||
public static Map<String, MetricFamily> parseMetrics(InputStream inputStream) throws IOException {
|
||||
Map<String, MetricFamily> metricFamilyMap = new ConcurrentHashMap<>(10);
|
||||
try {
|
||||
int i = getChar(inputStream);
|
||||
while (i != -1) {
|
||||
if (i == '#' || i == '\n') {
|
||||
skipToLineEnd(inputStream).maybeEol().maybeEof().noElse();
|
||||
} else {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append((char) i);
|
||||
parseMetric(inputStream, metricFamilyMap, stringBuilder);
|
||||
}
|
||||
i = getChar(inputStream);
|
||||
}
|
||||
} catch (FormatException e) {
|
||||
log.error("prometheus parser failed because of wrong input format. {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
return metricFamilyMap;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,46 +49,4 @@ public final class TimePeriodUtil {
|
||||
return Duration.parse("PT" + tokenTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* transform any timestamp to milliseconds
|
||||
* @param timestamp timestamp
|
||||
* @return milliseconds
|
||||
*/
|
||||
public static long normalizeToMilliseconds(Object timestamp) {
|
||||
if (timestamp instanceof String timestampStr) {
|
||||
// string type, may be second, millisecond or decimal second
|
||||
// eg: "1672531199000", "1672531199", "1672531199.123"
|
||||
if (timestampStr.contains(".")) {
|
||||
// contains decimal point, parse as second timestamp
|
||||
double seconds = Double.parseDouble(timestampStr);
|
||||
return (long) (seconds * 1000);
|
||||
} else {
|
||||
// integer form, determine second or millisecond
|
||||
long numericTimestamp = Long.parseLong(timestampStr);
|
||||
return convertNumericTimestamp(numericTimestamp);
|
||||
}
|
||||
} else if (timestamp instanceof Number) {
|
||||
// number eg Integer、Long、Double
|
||||
if (timestamp instanceof Double || timestamp instanceof Float) {
|
||||
// float type, treat as second timestamp
|
||||
double seconds = ((Number) timestamp).doubleValue();
|
||||
return (long) (seconds * 1000);
|
||||
} else {
|
||||
// integer type, directly determine second or millisecond
|
||||
long numericTimestamp = ((Number) timestamp).longValue();
|
||||
return convertNumericTimestamp(numericTimestamp);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Not support this timestamp type: " + timestamp.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static long convertNumericTimestamp(long numericTimestamp) {
|
||||
if (String.valueOf(numericTimestamp).length() <= 10) {
|
||||
return numericTimestamp * 1000;
|
||||
} else {
|
||||
return numericTimestamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-12
@@ -40,7 +40,6 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@@ -72,11 +71,6 @@ public class DashboardService {
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseEntity<?> createOrUpdateDashboard(String dashboardJson, Long monitorId) {
|
||||
if (!grafanaProperties.enabled()) {
|
||||
log.info("HertzBeat Grafana config not enabled");
|
||||
throw new RuntimeException("HertzBeat Grafana config not enabled");
|
||||
}
|
||||
|
||||
String token = serviceAccountService.getToken();
|
||||
String url = grafanaProperties.getPrefix() + grafanaProperties.getUrl() + CREATE_DASHBOARD_API;
|
||||
|
||||
@@ -109,12 +103,6 @@ public class DashboardService {
|
||||
log.error("create dashboard error: {}", response.getStatusCode());
|
||||
throw new RuntimeException("create dashboard error");
|
||||
}
|
||||
} catch (HttpClientErrorException.Forbidden ex) {
|
||||
log.error("Grafana Access denied to save dashboard", ex);
|
||||
throw new RuntimeException("Grafana Access denied to save dashboard", ex);
|
||||
} catch (HttpClientErrorException.NotFound ex){
|
||||
log.error("Grafana Dashboard not found", ex);
|
||||
throw new RuntimeException("Grafana Dashboard not found", ex);
|
||||
} catch (Exception ex) {
|
||||
log.error("create dashboard error", ex);
|
||||
throw new RuntimeException("create dashboard error", ex);
|
||||
|
||||
-5
@@ -61,11 +61,6 @@ public class DatasourceService {
|
||||
* Create a new datasource in Grafana.
|
||||
*/
|
||||
public void existOrCreateDatasource(String token) {
|
||||
if (!warehouseProperties.enabled()) {
|
||||
log.info("HertzBeat VictoriaMetrics config not enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setBearerAuth(token);
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat</artifactId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hertzbeat-log</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
<properties>
|
||||
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
|
||||
<maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- hertzbeat common -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-common</artifactId>
|
||||
</dependency>
|
||||
<!-- hertzbeat warehouse -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-warehouse</artifactId>
|
||||
</dependency>
|
||||
<!-- OpenTelemetry -->
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-sdk</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-sdk-logs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-exporter-otlp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry.instrumentation</groupId>
|
||||
<artifactId>opentelemetry-logback-appender-1.0</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,35 +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.log.config;
|
||||
|
||||
import org.apache.hertzbeat.common.constants.ConfigConstants;
|
||||
import org.apache.hertzbeat.common.constants.SignConstants;
|
||||
import org.apache.hertzbeat.warehouse.store.history.greptime.GreptimeProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
* Log auto configuration.
|
||||
*/
|
||||
@ComponentScan(basePackages = ConfigConstants.PkgConstant.PKG
|
||||
+ SignConstants.DOT
|
||||
+ ConfigConstants.FunctionModuleConstants.LOG
|
||||
)
|
||||
@EnableConfigurationProperties(GreptimeProperties.class)
|
||||
public class LogAutoConfiguration {
|
||||
}
|
||||
@@ -1,117 +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.log.config;
|
||||
|
||||
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
|
||||
import io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
|
||||
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.warehouse.store.history.greptime.GreptimeProperties;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* OpenTelemetryConfig is responsible for initializing OpenTelemetry with the specified service name and GrepTimeDB endpoint.
|
||||
* It ensures that the initialization is done in a thread-safe manner and includes authentication for GrepTimeDB.
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class OpenTelemetryConfig {
|
||||
|
||||
@Autowired
|
||||
private GreptimeProperties greptimeProperties;
|
||||
|
||||
/**
|
||||
* Initializes OpenTelemetry with the given service name and GrepTimeDB endpoint.
|
||||
* Includes authentication if configured in GreptimeProperties.
|
||||
*/
|
||||
@PostConstruct
|
||||
public void initializeOpenTelemetry() {
|
||||
if (greptimeProperties == null || !greptimeProperties.enabled()) {
|
||||
log.info("GrepTimeDB logging is disabled, skipping OpenTelemetry configuration.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Resource resource = Resource.getDefault()
|
||||
.merge(Resource.builder()
|
||||
.put(SERVICE_NAME, "HertzBeat")
|
||||
.build());
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
|
||||
headers.put("X-Greptime-DB-Name", "public");
|
||||
headers.put("X-Greptime-Log-Table-Name", "hzb_log");
|
||||
|
||||
addAuthenticationHeaders(headers);
|
||||
|
||||
OtlpHttpLogRecordExporter logExporter = OtlpHttpLogRecordExporter.builder()
|
||||
.setEndpoint(greptimeProperties.httpEndpoint() + "/v1/otlp/v1/logs")
|
||||
.setHeaders(()-> headers)
|
||||
.setTimeout(10, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
SdkLoggerProvider loggerProvider = SdkLoggerProvider.builder()
|
||||
.setResource(resource)
|
||||
.addLogRecordProcessor(
|
||||
BatchLogRecordProcessor.builder(logExporter)
|
||||
.setScheduleDelay(1000, TimeUnit.MILLISECONDS)
|
||||
.setMaxExportBatchSize(512)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
|
||||
.setLoggerProvider(loggerProvider)
|
||||
.build();
|
||||
|
||||
OpenTelemetryAppender.install(openTelemetry);
|
||||
log.info("OpenTelemetry successfully configured with GrepTimeDB exporter.");
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to initialize OpenTelemetry with GrepTimeDB", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds authentication headers to the provided map if username and password are configured.
|
||||
*
|
||||
* @param headers the map to which authentication headers will be added
|
||||
*/
|
||||
private void addAuthenticationHeaders(Map<String, String> headers) {
|
||||
if (StringUtils.isNotBlank(greptimeProperties.username())
|
||||
&& StringUtils.isNotBlank(greptimeProperties.password())) {
|
||||
String credentials = greptimeProperties.username() + ":" + greptimeProperties.password();
|
||||
String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes());
|
||||
headers.put("Authorization", "Basic " + encodedCredentials);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,17 +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.
|
||||
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.apache.hertzbeat.log.config.LogAutoConfiguration
|
||||
@@ -89,11 +89,6 @@
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-grafana</artifactId>
|
||||
</dependency>
|
||||
<!-- log -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-log</artifactId>
|
||||
</dependency>
|
||||
<!-- spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
-1
@@ -427,7 +427,6 @@ public class CollectorJobScheduler implements CollectorScheduling, CollectJobSch
|
||||
if (jobId == null) {
|
||||
return;
|
||||
}
|
||||
jobContentCache.remove(jobId);
|
||||
for (ConsistentHash.Node node : consistentHash.getAllNodes().values()) {
|
||||
AssignJobs assignJobs = node.getAssignJobs();
|
||||
if (assignJobs.getPinnedJobs().remove(jobId)
|
||||
|
||||
@@ -1,247 +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.
|
||||
|
||||
# The monitoring type category:service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
|
||||
category: server
|
||||
# The monitoring type eg: linux windows tomcat mysql aws...
|
||||
app: dahua
|
||||
# The monitoring i18n name
|
||||
name:
|
||||
zh-CN: 大华
|
||||
en-US: Dahua
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: 通过http接口监控大华设备状态,获取设备健康数据。
|
||||
en-US: Monitor Dahua devices through http interface to collect health data.
|
||||
|
||||
# Input params define for monitoring(render web ui by the definition)
|
||||
params:
|
||||
- field: host
|
||||
name:
|
||||
zh-CN: 主机Host
|
||||
en-US: Host
|
||||
type: host
|
||||
required: true
|
||||
- field: port
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
type: number
|
||||
range: '[0,65535]'
|
||||
required: true
|
||||
defaultValue: 80
|
||||
- field: timeout
|
||||
name:
|
||||
zh-CN: 超时时间(ms)
|
||||
en-US: Timeout(ms)
|
||||
type: number
|
||||
range: '[1000,60000]'
|
||||
required: true
|
||||
defaultValue: 5000
|
||||
- field: username
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
type: text
|
||||
required: true
|
||||
- field: password
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
type: password
|
||||
required: true
|
||||
- field: ssl
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: SSL
|
||||
type: boolean
|
||||
required: false
|
||||
defaultValue: false
|
||||
|
||||
# collect metrics config list
|
||||
metrics:
|
||||
- name: network_info # 指标集合名称
|
||||
i18n:
|
||||
zh-CN: 网络信息
|
||||
en-US: Network Info
|
||||
priority: 0
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
ssl: ^_^ssl^_^
|
||||
url: /cgi-bin/configManager.cgi?action=getConfig&name=Network
|
||||
method: GET
|
||||
timeout: ^_^timeout^_^
|
||||
authorization:
|
||||
type: Digest Auth
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: config
|
||||
fields:
|
||||
- field: default_interface
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 默认网卡
|
||||
en-US: Default Interface
|
||||
- field: domain_name
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 域名
|
||||
en-US: Domain Name
|
||||
- field: hostname
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 主机名
|
||||
en-US: Hostname
|
||||
- field: eth0_ip_address
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 网卡 eth0 IP地址
|
||||
en-US: Interface eth0 IP Address
|
||||
- field: eth0_gateway
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 网卡 eth0 默认网关
|
||||
en-US: Interface eth0 Default Gateway
|
||||
- field: eth0_mac_address
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 网卡 eth0 物理地址
|
||||
en-US: Interface eth0 Physical Address
|
||||
- field: eth0_subnet_mask
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 网卡 eth0 子网掩码
|
||||
en-US: Interface eth0 Subnet Mask
|
||||
- field: eth0_mtu
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 网卡 eth0 MTU
|
||||
en-US: Interface eth0 MTU
|
||||
- field: eth0_dns1
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 网卡 eth0 DNS服务器1
|
||||
en-US: Interface eth0 DNS Server 1
|
||||
- field: eth0_dns2
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 网卡 eth0 DNS服务器2
|
||||
en-US: Interface eth0 DNS Server 2
|
||||
aliasFields:
|
||||
- table.Network.DefaultInterface
|
||||
- table.Network.Domain
|
||||
- table.Network.Hostname
|
||||
- table.Network.eth0.IPAddress
|
||||
- table.Network.eth0.DefaultGateway
|
||||
- table.Network.eth0.PhysicalAddress
|
||||
- table.Network.eth0.SubnetMask
|
||||
- table.Network.eth0.MTU
|
||||
- table.Network.eth0.DnsServers[0]
|
||||
- table.Network.eth0.DnsServers[1]
|
||||
calculates:
|
||||
- default_interface=table.Network.DefaultInterface
|
||||
- domain_name=table.Network.Domain
|
||||
- hostname=table.Network.Hostname
|
||||
- eth0_ip_address=table.Network.eth0.IPAddress
|
||||
- eth0_gateway=table.Network.eth0.DefaultGateway
|
||||
- eth0_mac_address=table.Network.eth0.PhysicalAddress
|
||||
- eth0_subnet_mask=table.Network.eth0.SubnetMask
|
||||
- eth0_mtu=table.Network.eth0.MTU
|
||||
- eth0_dns1=table.Network.eth0.DnsServers[0]
|
||||
- eth0_dns2=table.Network.eth0.DnsServers[1]
|
||||
- name: user_info
|
||||
i18n:
|
||||
zh-CN: 用户信息
|
||||
en-US: User Info
|
||||
priority: 0
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
ssl: ^_^ssl^_^
|
||||
url: /cgi-bin/userManager.cgi?action=getActiveUserInfoAll
|
||||
method: GET
|
||||
timeout: ^_^timeout^_^
|
||||
authorization:
|
||||
type: Digest Auth
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: config
|
||||
parseScript: users
|
||||
fields:
|
||||
- field: ClientAddress
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 客户端地址
|
||||
en-US: ClientAddress
|
||||
- field: Name
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 客户端用户
|
||||
en-US: Name
|
||||
- field: ClientType
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 客户端登录类型
|
||||
en-US: ClientType
|
||||
- field: LoginTime
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 客户端登录时间
|
||||
en-US: LoginTime
|
||||
- name: ntp_info
|
||||
i18n:
|
||||
zh-CN: 校时信息
|
||||
en-US: Ntp Info
|
||||
priority: 0
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
ssl: ^_^ssl^_^
|
||||
url: /cgi-bin/configManager.cgi?action=getConfig&name=NTP
|
||||
method: GET
|
||||
timeout: ^_^timeout^_^
|
||||
authorization:
|
||||
type: Digest Auth
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: config
|
||||
fields:
|
||||
- field: ntp_address
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 校时服务器
|
||||
en-US: Ntp Address
|
||||
- field: ntp_port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 校时端口
|
||||
en-US: Ntp Port
|
||||
- field: ntp_update_period
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 校时间隔
|
||||
en-US: Ntp Update Period
|
||||
aliasFields:
|
||||
- table.NTP.Address
|
||||
- table.NTP.Port
|
||||
- table.NTP.UpdatePeriod
|
||||
calculates:
|
||||
- ntp_address=table.NTP.Address
|
||||
- ntp_port=table.NTP.Port
|
||||
- ntp_update_period=table.NTP.UpdatePeriod
|
||||
@@ -90,38 +90,39 @@ metrics:
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: xmlPath
|
||||
parseScript: //DeviceInfo
|
||||
parseScript: 'DeviceInfo'
|
||||
fields:
|
||||
- field: deviceName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备名称
|
||||
en-US: Device Name
|
||||
xpath: deviceName
|
||||
- field: deviceID
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备ID
|
||||
en-US: Device ID
|
||||
xpath: deviceID
|
||||
- field: firmwareVersion
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 固件版本
|
||||
en-US: Firmware Version
|
||||
xpath: firmwareVersion
|
||||
- field: model
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备型号
|
||||
en-US: Device Model
|
||||
xpath: model
|
||||
- field: macAddress
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: mac地址
|
||||
en-US: Mac Address
|
||||
xpath: macAddress
|
||||
- name: status
|
||||
i18n:
|
||||
zh-CN: 设备状态
|
||||
en-US: Status
|
||||
priority: 0
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
@@ -135,134 +136,115 @@ metrics:
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: xmlPath
|
||||
parseScript: //DeviceStatus
|
||||
parseScript: 'DeviceStatus'
|
||||
fields:
|
||||
- field: CPU_utilization
|
||||
- field: cpuUtilization
|
||||
i18n:
|
||||
zh-CN: CPU 利用率
|
||||
en-US: CPU Utilization
|
||||
type: 0
|
||||
unit: '%'
|
||||
- field: memory_usage
|
||||
xpath: CPUList/CPU/cpuUtilization
|
||||
- field: memoryUsage
|
||||
i18n:
|
||||
zh-CN: 内存使用量
|
||||
en-US: Memory Usage
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: memory_available
|
||||
xpath: MemoryList/Memory/memoryUsage
|
||||
- field: memoryAvailable
|
||||
i18n:
|
||||
zh-CN: 可用内存
|
||||
en-US: Memory Available
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: cache_size
|
||||
xpath: MemoryList/Memory/memoryAvailable
|
||||
- field: cacheSize
|
||||
i18n:
|
||||
zh-CN: 缓存大小
|
||||
en-US: Cache Size
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: net_port_1_speed
|
||||
xpath: MemoryList/Memory/cacheSize
|
||||
- field: netPort1Speed
|
||||
i18n:
|
||||
zh-CN: 网口1速度
|
||||
en-US: Net Port 1 Speed
|
||||
type: 0
|
||||
unit: Mbps
|
||||
- field: net_port_2_speed
|
||||
xpath: NetPortStatusList/NetPortStatus[id='1']/workSpeed
|
||||
- field: netPort2Speed
|
||||
i18n:
|
||||
zh-CN: 网口2速度
|
||||
en-US: Net Port 2 Speed
|
||||
type: 0
|
||||
unit: Mbps
|
||||
- field: boot_time
|
||||
xpath: NetPortStatusList/NetPortStatus[id='2']/workSpeed
|
||||
- field: bootTime
|
||||
i18n:
|
||||
zh-CN: 启动时间
|
||||
en-US: Boot Time
|
||||
type: 1
|
||||
- field: device_uptime
|
||||
xpath: bootTime
|
||||
- field: deviceUpTime
|
||||
i18n:
|
||||
zh-CN: 运行时长
|
||||
en-US: Device Uptime
|
||||
type: 1
|
||||
- field: last_calibration_time
|
||||
xpath: deviceUpTime
|
||||
- field: lastCalibrationTime
|
||||
i18n:
|
||||
zh-CN: 上次校时时间
|
||||
en-US: Last Calibration Time
|
||||
type: 1
|
||||
- field: last_calibration_time_diff
|
||||
xpath: lastCalibrationTime
|
||||
- field: lastCalibrationTimeDiff
|
||||
i18n:
|
||||
zh-CN: 上次校时时间差
|
||||
en-US: Last Calibration Time Diff
|
||||
type: 0
|
||||
unit: s
|
||||
- field: avg_upload_time
|
||||
xpath: lastCalibrationTimeDiff
|
||||
- field: avgUploadTime
|
||||
i18n:
|
||||
zh-CN: 平均上传耗时
|
||||
en-US: Avg Upload Time
|
||||
type: 0
|
||||
unit: ms
|
||||
- field: max_upload_time
|
||||
xpath: uploadTimeConsumingList/avgTime
|
||||
- field: maxUploadTime
|
||||
i18n:
|
||||
zh-CN: 最大上传耗时
|
||||
en-US: Max Upload Time
|
||||
type: 0
|
||||
unit: ms
|
||||
- field: min_upload_time
|
||||
xpath: uploadTimeConsumingList/maxTime
|
||||
- field: minUploadTime
|
||||
i18n:
|
||||
zh-CN: 最小上传耗时
|
||||
en-US: Min Upload Time
|
||||
type: 0
|
||||
unit: ms
|
||||
- field: last_calibration_mode
|
||||
xpath: uploadTimeConsumingList/minTime
|
||||
- field: lastCalibrationMode
|
||||
i18n:
|
||||
zh-CN: 上次校时模式
|
||||
en-US: Last Calibration Mode
|
||||
type: 1
|
||||
- field: last_calibration_address
|
||||
xpath: lastCalibrationTimeMode
|
||||
- field: lastCalibrationAddress
|
||||
i18n:
|
||||
zh-CN: 上次校时地址
|
||||
en-US: Last Calibration Address
|
||||
type: 1
|
||||
- field: response_time
|
||||
xpath: lastCalibrationTimeAddress
|
||||
- field: responseTime
|
||||
i18n:
|
||||
zh-CN: 响应时间
|
||||
en-US: Response Time
|
||||
type: 0
|
||||
unit: ms
|
||||
aliasFields:
|
||||
- CPUList/CPU/cpuUtilization
|
||||
- MemoryList/Memory/memoryUsage
|
||||
- MemoryList/Memory/memoryAvailable
|
||||
- MemoryList/Memory/cacheSize
|
||||
- NetPortStatusList/NetPortStatus[id='1']/workSpeed
|
||||
- NetPortStatusList/NetPortStatus[id='2']/workSpeed
|
||||
- bootTime
|
||||
- deviceUpTime
|
||||
- lastCalibrationTime
|
||||
- lastCalibrationTimeDiff
|
||||
- uploadTimeConsumingList/avgTime
|
||||
- uploadTimeConsumingList/maxTime
|
||||
- uploadTimeConsumingList/minTime
|
||||
- lastCalibrationTimeMode
|
||||
- lastCalibrationTimeAddress
|
||||
- responseTime
|
||||
calculates:
|
||||
- CPU_utilization=CPUList/CPU/cpuUtilization
|
||||
- memory_usage=MemoryList/Memory/memoryUsage
|
||||
- memory_available=MemoryList/Memory/memoryAvailable
|
||||
- cache_size=MemoryList/Memory/cacheSize
|
||||
- net_port_1_speed=NetPortStatusList/NetPortStatus[id='1']/workSpeed
|
||||
- net_port_2_speed=NetPortStatusList/NetPortStatus[id='2']/workSpeed
|
||||
- boot_time=bootTime
|
||||
- device_uptime=deviceUpTime
|
||||
- last_calibration_time=lastCalibrationTime
|
||||
- last_calibration_time_diff=lastCalibrationTimeDiff
|
||||
- avg_upload_time=uploadTimeConsumingList/avgTime
|
||||
- max_upload_time=uploadTimeConsumingList/maxTime
|
||||
- min_upload_time=uploadTimeConsumingList/minTime
|
||||
- last_calibration_mode=lastCalibrationTimeMode
|
||||
- last_calibration_address=lastCalibrationTimeAddress
|
||||
- response_time=responseTime
|
||||
units:
|
||||
- memory_usage=KB->MB
|
||||
- memory_available=KB->MB
|
||||
- cache_size=KB->MB
|
||||
- memoryUsage=KB->MB
|
||||
- memoryAvailable=KB->MB
|
||||
- cacheSize=KB->MB
|
||||
@@ -1,154 +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.
|
||||
|
||||
# The monitoring type category:service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
|
||||
category: server
|
||||
# The monitoring type eg: linux windows tomcat mysql aws...
|
||||
app: uniview
|
||||
# The monitoring i18n name
|
||||
name:
|
||||
zh-CN: 宇视
|
||||
en-US: Uniview
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: 通过HTTP接口监控宇视设备状态,获取设备健康数据。
|
||||
en-US: Monitor Uniview devices through HTTP interface to collect health data.
|
||||
|
||||
# Input params define for monitoring(render web ui by the definition)
|
||||
params:
|
||||
- field: host
|
||||
name:
|
||||
zh-CN: 主机Host
|
||||
en-US: Host
|
||||
type: host
|
||||
required: true
|
||||
- field: port
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
type: number
|
||||
range: '[0,65535]'
|
||||
required: true
|
||||
defaultValue: 80
|
||||
- field: timeout
|
||||
name:
|
||||
zh-CN: 超时时间(ms)
|
||||
en-US: Timeout(ms)
|
||||
type: number
|
||||
range: '[1000,60000]'
|
||||
required: true
|
||||
defaultValue: 5000
|
||||
- field: username
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
type: text
|
||||
required: true
|
||||
- field: password
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
type: password
|
||||
required: true
|
||||
- field: ssl
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: SSL
|
||||
type: boolean
|
||||
required: false
|
||||
defaultValue: false
|
||||
|
||||
# collect metrics config list
|
||||
metrics:
|
||||
- name: system_info
|
||||
i18n:
|
||||
zh-CN: 系统信息
|
||||
en-US: System Info
|
||||
priority: 0
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
ssl: ^_^ssl^_^
|
||||
url: /LAPI/V1.0/System/DeviceInfo
|
||||
method: GET
|
||||
timeout: ^_^timeout^_^
|
||||
authorization:
|
||||
type: Digest Auth
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: jsonPath
|
||||
parseScript: '$.Response.Data'
|
||||
fields:
|
||||
- field: DeviceName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备名称
|
||||
en-US: Device Name
|
||||
- field: SerialNumber
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 序列号
|
||||
en-US: SerialNumber
|
||||
- field: FirmwareVersion
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 固件版本
|
||||
en-US: Firmware Version
|
||||
- field: DeviceModel
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备型号
|
||||
en-US: Device Model
|
||||
- name: ntp_info
|
||||
i18n:
|
||||
zh-CN: 校时信息
|
||||
en-US: NTP Info
|
||||
priority: 0
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
ssl: ^_^ssl^_^
|
||||
url: /LAPI/V1.0/System/Time/NTP
|
||||
method: GET
|
||||
timeout: ^_^timeout^_^
|
||||
authorization:
|
||||
type: Digest Auth
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: jsonPath
|
||||
parseScript: '$.Response.Data.NTPServerInfos[0]'
|
||||
fields:
|
||||
- field: IPAddress
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: IP地址
|
||||
en-US: IPAddress
|
||||
- field: Port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 端口号
|
||||
en-US: Port
|
||||
- field: SynchronizeInterval
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 同步间隔
|
||||
en-US: SynchronizeInterval
|
||||
- field: Enabled
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 是否启用
|
||||
en-US: Enabled
|
||||
@@ -76,26 +76,6 @@
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- OpenTelemetry Appender for shipping logs to GrepTimeDB -->
|
||||
<appender name="OpenTelemetryAppender" class="io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender">
|
||||
<!-- Capture source code information (class name, method name, line number) -->
|
||||
<captureCodeAttributes>true</captureCodeAttributes>
|
||||
|
||||
<!-- Capture MDC context values -->
|
||||
<captureMdcAttributes>
|
||||
<pattern>.*</pattern>
|
||||
</captureMdcAttributes>
|
||||
|
||||
<!-- Capture experimental attributes like exception details -->
|
||||
<captureExperimentalAttributes>true</captureExperimentalAttributes>
|
||||
|
||||
<!-- Capture marker attributes -->
|
||||
<captureMarkerAttribute>true</captureMarkerAttribute>
|
||||
|
||||
<!-- Capture logger context attributes -->
|
||||
<captureLoggerContext>true</captureLoggerContext>
|
||||
</appender>
|
||||
|
||||
<!-- Settings for this logger: for example, all output logs under the org.springframework package must be at level info or above to be output! -->
|
||||
<!-- This can avoid outputting many common debug information of the spring framework! -->
|
||||
<logger name="org.springframework" level="info"/>
|
||||
@@ -110,14 +90,12 @@
|
||||
<logger name="org.mongodb" level="warn"/>
|
||||
<logger name="io.greptime" level="warn"/>
|
||||
<logger name="org.apache.kafka" level="warn"/>
|
||||
<logger name="io.opentelemetry" level="info"/>
|
||||
|
||||
<!-- Production environment configuration -->
|
||||
<springProfile name="prod">
|
||||
<root level="INFO">
|
||||
<appender-ref ref="SystemOutFileAppender"/>
|
||||
<appender-ref ref="ErrOutFileAppender"/>
|
||||
<appender-ref ref="OpenTelemetryAppender"/>
|
||||
</root>
|
||||
<!-- North log -->
|
||||
<Logger name="com.obs.services.AbstractClient" level="OFF"
|
||||
@@ -140,7 +118,6 @@
|
||||
<appender-ref ref="ConsoleAppender"/>
|
||||
<appender-ref ref="SystemOutFileAppender"/>
|
||||
<appender-ref ref="ErrOutFileAppender"/>
|
||||
<appender-ref ref="OpenTelemetryAppender"/>
|
||||
</root>
|
||||
</springProfile>
|
||||
|
||||
@@ -150,7 +127,6 @@
|
||||
<appender-ref ref="ConsoleAppender"/>
|
||||
<appender-ref ref="SystemOutFileAppender"/>
|
||||
<appender-ref ref="ErrOutFileAppender"/>
|
||||
<appender-ref ref="OpenTelemetryAppender"/>
|
||||
</root>
|
||||
</springProfile>
|
||||
|
||||
@@ -160,8 +136,7 @@
|
||||
<appender-ref ref="ConsoleAppender"/>
|
||||
<appender-ref ref="SystemOutFileAppender"/>
|
||||
<appender-ref ref="ErrOutFileAppender"/>
|
||||
<appender-ref ref="OpenTelemetryAppender"/>
|
||||
</root>
|
||||
</springProfile>
|
||||
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
||||
@@ -29,11 +29,10 @@
|
||||
<name>${project.artifactId}</name>
|
||||
|
||||
<dependencies>
|
||||
<!-- collector basic -->
|
||||
<!-- common -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-collector-basic</artifactId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
<artifactId>hertzbeat-common</artifactId>
|
||||
</dependency>
|
||||
<!-- spring -->
|
||||
<dependency>
|
||||
|
||||
+2
-2
@@ -28,12 +28,12 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.prometheus.parser.MetricFamily;
|
||||
import org.apache.hertzbeat.collector.collect.prometheus.parser.OnlineParser;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.dto.MetricFamily;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.queue.CommonDataQueue;
|
||||
import org.apache.hertzbeat.common.util.OnlineParser;
|
||||
import org.apache.hertzbeat.common.util.SnowFlakeIdGenerator;
|
||||
import org.apache.hertzbeat.push.dao.PushMonitorDao;
|
||||
import org.apache.hertzbeat.push.service.PushGatewayService;
|
||||
|
||||
-4
@@ -60,8 +60,4 @@ public interface WarehouseConstants {
|
||||
|
||||
String SQL = "sql";
|
||||
|
||||
String RANGE = "range";
|
||||
|
||||
String INSTANT = "instant";
|
||||
|
||||
}
|
||||
|
||||
-53
@@ -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.warehouse.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQuery;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQueryData;
|
||||
import org.apache.hertzbeat.warehouse.service.DatasourceQueryService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Metrics Data Query API
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(produces = {APPLICATION_JSON_VALUE})
|
||||
@Tag(name = "Metrics Data Query API")
|
||||
public class DataQueryController {
|
||||
|
||||
@Autowired(required = false)
|
||||
private DatasourceQueryService datasourceQueryService;
|
||||
|
||||
@PostMapping("/api/warehouse/query")
|
||||
@Operation(summary = "Warehouse Query")
|
||||
public ResponseEntity<Message<List<DatasourceQueryData>>> query(
|
||||
@Parameter(description = "Query Expr") @RequestBody List<DatasourceQuery> queries) {
|
||||
return ResponseEntity.ok(Message.success(datasourceQueryService.query(queries)));
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.warehouse.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.MetricQueryData;
|
||||
import org.apache.hertzbeat.warehouse.service.MetricsDataQueryService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
|
||||
/**
|
||||
* Metrics Data Query API
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(produces = {APPLICATION_JSON_VALUE})
|
||||
@Tag(name = "Metrics Data Query API")
|
||||
public class MetricsDataQueryController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private MetricsDataQueryService queryService;
|
||||
|
||||
|
||||
@GetMapping("/api/warehouse/query")
|
||||
@Operation(summary = "Query Real Time Metrics Data")
|
||||
public ResponseEntity<Message<List<MetricQueryData>>> queryMetricsData(
|
||||
@Parameter(description = "Query PromQL expr list", example = "cpu")
|
||||
@RequestParam List<String> queries,
|
||||
@Parameter(description = "Query type", example = "promql")
|
||||
@RequestParam String type,
|
||||
@Parameter(description = "Query timestamp", example = "1725854804451")
|
||||
@RequestParam long time) {
|
||||
return ResponseEntity.ok(Message.success(queryService.query(queries, type, time)));
|
||||
}
|
||||
|
||||
@GetMapping("/api/warehouse/query/range")
|
||||
@Operation(summary = "Query Range Metrics Data")
|
||||
public ResponseEntity<Message<List<MetricQueryData>>> queryMetricsDataRange(
|
||||
@Parameter(description = "Query PromQL expr list", example = "cpu")
|
||||
@RequestParam List<String> queries,
|
||||
@Parameter(description = "Query type", example = "promql")
|
||||
@RequestParam String type,
|
||||
@Parameter(description = "Query start timestamp", example = "1725854804451")
|
||||
@RequestParam long start,
|
||||
@Parameter(description = "Query end timestamp", example = "1733630804452")
|
||||
@RequestParam long end,
|
||||
@Parameter(description = "Query step", example = "4m")
|
||||
@RequestParam String step
|
||||
) {
|
||||
return ResponseEntity.ok(Message.success(queryService.queryRange(queries, type, start, end, step)));
|
||||
}
|
||||
}
|
||||
+1
-9
@@ -33,9 +33,7 @@ import org.springframework.web.client.RestTemplate;
|
||||
@Slf4j
|
||||
public class GreptimePromqlQueryExecutor extends PromqlQueryExecutor {
|
||||
|
||||
private static final String QUERY_PATH = "/v1/prometheus";
|
||||
|
||||
private static final String Datasource = "Greptime";
|
||||
private static final String QUERY_PATH = "/v1/prometheus/api/v1/query";
|
||||
|
||||
private final GreptimeProperties greptimeProperties;
|
||||
|
||||
@@ -44,10 +42,4 @@ public class GreptimePromqlQueryExecutor extends PromqlQueryExecutor {
|
||||
greptimeProperties.username(), greptimeProperties.password()));
|
||||
this.greptimeProperties = greptimeProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatasource() {
|
||||
return Datasource;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+46
-97
@@ -20,16 +20,10 @@
|
||||
package org.apache.hertzbeat.warehouse.db;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.hertzbeat.common.constants.NetworkConstants;
|
||||
import org.apache.hertzbeat.common.constants.SignConstants;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQuery;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQueryData;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.MetricQueryData;
|
||||
import org.apache.hertzbeat.common.util.Base64Util;
|
||||
import org.apache.hertzbeat.common.util.TimePeriodUtil;
|
||||
import static org.apache.hertzbeat.warehouse.constants.WarehouseConstants.INSTANT;
|
||||
import static org.apache.hertzbeat.warehouse.constants.WarehouseConstants.PROMQL;
|
||||
import static org.apache.hertzbeat.warehouse.constants.WarehouseConstants.RANGE;
|
||||
import org.apache.hertzbeat.warehouse.store.history.vm.PromQlQueryContent;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpEntity;
|
||||
@@ -41,12 +35,15 @@ import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.hertzbeat.warehouse.constants.WarehouseConstants.PROMQL;
|
||||
|
||||
/**
|
||||
* abstract class for promql query executor
|
||||
*/
|
||||
@@ -54,15 +51,11 @@ import java.util.Map;
|
||||
public abstract class PromqlQueryExecutor implements QueryExecutor {
|
||||
|
||||
private static final String supportQueryLanguage = PROMQL;
|
||||
private static final String QUERY_RANGE_PATH = "/api/v1/query_range";
|
||||
private static final String QUERY_PATH = "/api/v1/query";
|
||||
protected static final String HTTP_QUERY_PARAM = "query";
|
||||
protected static final String HTTP_TIME_PARAM = "time";
|
||||
protected static final String HTTP_START_PARAM = "start";
|
||||
protected static final String HTTP_END_PARAM = "end";
|
||||
protected static final String HTTP_STEP_PARAM = "step";
|
||||
private static final String INNER_KEY_TIME = "__ts__";
|
||||
private static final String INNER_KEY_VALUE = "__value__";
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
@@ -76,15 +69,14 @@ public abstract class PromqlQueryExecutor implements QueryExecutor {
|
||||
/**
|
||||
* record class for promql http connection
|
||||
*/
|
||||
protected record HttpPromqlProperties(
|
||||
String url,
|
||||
String username,
|
||||
String password
|
||||
) {
|
||||
}
|
||||
protected record HttpPromqlProperties (
|
||||
String url,
|
||||
String username,
|
||||
String password
|
||||
){}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> execute(String queryString) {
|
||||
protected List<Map<String, Object>> http_promql(Map<String, Object> params) {
|
||||
// http run the promql query
|
||||
List<Map<String, Object>> results = new LinkedList<>();
|
||||
try {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
@@ -94,12 +86,13 @@ public abstract class PromqlQueryExecutor implements QueryExecutor {
|
||||
&& StringUtils.hasText(httpPromqlProperties.password())) {
|
||||
String authStr = httpPromqlProperties.username() + ":" + httpPromqlProperties.password();
|
||||
String encodedAuth = Base64Util.encode(authStr);
|
||||
headers.add(HttpHeaders.AUTHORIZATION, NetworkConstants.BASIC + SignConstants.BLANK + encodedAuth);
|
||||
headers.add(HttpHeaders.AUTHORIZATION, NetworkConstants.BASIC + SignConstants.BLANK + encodedAuth);
|
||||
}
|
||||
HttpEntity<Void> httpEntity = new HttpEntity<>(headers);
|
||||
|
||||
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(httpPromqlProperties.url);
|
||||
uriComponentsBuilder.queryParam(HTTP_QUERY_PARAM, queryString);
|
||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||
uriComponentsBuilder.queryParam(entry.getKey(), entry.getValue());
|
||||
}
|
||||
URI uri = uriComponentsBuilder.build(true).toUri();
|
||||
ResponseEntity<PromQlQueryContent> responseEntity = restTemplate.exchange(uri,
|
||||
HttpMethod.GET, httpEntity, PromQlQueryContent.class);
|
||||
@@ -133,85 +126,41 @@ public abstract class PromqlQueryExecutor implements QueryExecutor {
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatasourceQueryData query(DatasourceQuery datasourceQuery) {
|
||||
DatasourceQueryData.DatasourceQueryDataBuilder queryDataBuilder = DatasourceQueryData.builder()
|
||||
.refId(datasourceQuery.getRefId()).status(200);
|
||||
public MetricQueryData convertToMetricQueryData(Object object) {
|
||||
MetricQueryData metricQueryData = new MetricQueryData();
|
||||
try {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
|
||||
if (StringUtils.hasText(httpPromqlProperties.username())
|
||||
&& StringUtils.hasText(httpPromqlProperties.password())) {
|
||||
String authStr = httpPromqlProperties.username() + ":" + httpPromqlProperties.password();
|
||||
String encodedAuth = new String(Base64.encodeBase64(authStr.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
headers.add(HttpHeaders.AUTHORIZATION, NetworkConstants.BASIC + " " + encodedAuth);
|
||||
}
|
||||
HttpEntity<Void> httpEntity = new HttpEntity<>(headers);
|
||||
URI uri;
|
||||
if (datasourceQuery.getTimeType().equals(RANGE)) {
|
||||
uri = UriComponentsBuilder.fromHttpUrl(httpPromqlProperties.url() + QUERY_RANGE_PATH)
|
||||
.queryParam(HTTP_QUERY_PARAM, datasourceQuery.getExpr())
|
||||
.queryParam(HTTP_START_PARAM, datasourceQuery.getStart())
|
||||
.queryParam(HTTP_END_PARAM, datasourceQuery.getEnd())
|
||||
.queryParam(HTTP_STEP_PARAM, datasourceQuery.getStep())
|
||||
.build().toUri();
|
||||
} else if (datasourceQuery.getTimeType().equals(INSTANT)) {
|
||||
uri = UriComponentsBuilder.fromHttpUrl(httpPromqlProperties.url() + QUERY_PATH)
|
||||
.queryParam(HTTP_QUERY_PARAM, datasourceQuery.getExpr())
|
||||
.build().toUri();
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format("no such time type for query id {}.", datasourceQuery.getRefId()));
|
||||
}
|
||||
ResponseEntity<PromQlQueryContent> responseEntity = restTemplate.exchange(uri, HttpMethod.GET, httpEntity,
|
||||
PromQlQueryContent.class);
|
||||
if (responseEntity.getStatusCode().is2xxSuccessful()) {
|
||||
log.debug("query metrics data from promql http api success. {}", uri);
|
||||
if (responseEntity.getBody() != null && responseEntity.getBody().getData() != null
|
||||
&& responseEntity.getBody().getData().getResult() != null) {
|
||||
List<PromQlQueryContent.ContentData.Content> contents = responseEntity.getBody().getData().getResult();
|
||||
List<DatasourceQueryData.SchemaData> schemaDataList = new LinkedList<>();
|
||||
for (PromQlQueryContent.ContentData.Content content : contents) {
|
||||
DatasourceQueryData.MetricSchema.MetricSchemaBuilder schemaBuilder = DatasourceQueryData.MetricSchema
|
||||
.builder().fields(List.of(
|
||||
// todo: unit?
|
||||
DatasourceQueryData.MetricField.builder().name(INNER_KEY_TIME)
|
||||
.type("time").build(),
|
||||
DatasourceQueryData.MetricField.builder().name(INNER_KEY_VALUE)
|
||||
.type("number").build()
|
||||
)).labels(content.getMetric());
|
||||
List<Object[]> values;
|
||||
if (datasourceQuery.getTimeType().equals(RANGE)) {
|
||||
values = content.getValues();
|
||||
}
|
||||
else {
|
||||
values = List.<Object[]>of(content.getValue());
|
||||
}
|
||||
values.forEach(objects -> {
|
||||
objects[0] = TimePeriodUtil.normalizeToMilliseconds(objects[0]);
|
||||
});
|
||||
DatasourceQueryData.SchemaData.SchemaDataBuilder schemaData = DatasourceQueryData.SchemaData.builder()
|
||||
.schema(schemaBuilder.build()).data(values);
|
||||
schemaDataList.add(schemaData.build());
|
||||
}
|
||||
queryDataBuilder.frames(schemaDataList);
|
||||
}
|
||||
} else {
|
||||
log.error("query metrics data from victoria-metrics failed. {}", responseEntity);
|
||||
queryDataBuilder.msg("query metrics data from victoria-metrics failed. ");
|
||||
queryDataBuilder.status(responseEntity.getStatusCode().value());
|
||||
}
|
||||
List<Map<String, Object>> metrics = (List<Map<String, Object>>) object;
|
||||
// todo
|
||||
} catch (Exception e) {
|
||||
log.error("query metrics data from victoria-metrics error. {}.", e.getMessage(), e);
|
||||
queryDataBuilder.msg("query metrics data from victoria-metrics error: " + e.getMessage());
|
||||
queryDataBuilder.status(400);
|
||||
log.error("converting to metric query data failed.");
|
||||
}
|
||||
return queryDataBuilder.build();
|
||||
return metricQueryData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean support(String queryLanguage) {
|
||||
return StringUtils.hasText(queryLanguage) && queryLanguage.equalsIgnoreCase(supportQueryLanguage);
|
||||
|
||||
public List<Map<String, Object>> execute(String queryString) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put(HTTP_QUERY_PARAM, URLEncoder.encode(queryString, StandardCharsets.UTF_8));
|
||||
return http_promql(params);
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> query(String queryString, long time) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put(HTTP_QUERY_PARAM, URLEncoder.encode(queryString, StandardCharsets.UTF_8));
|
||||
params.put(HTTP_TIME_PARAM, time);
|
||||
return http_promql(params);
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> query_range(String queryString, long start, long end, String step) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put(HTTP_QUERY_PARAM, URLEncoder.encode(queryString, StandardCharsets.UTF_8));
|
||||
params.put(HTTP_START_PARAM, start);
|
||||
params.put(HTTP_END_PARAM, end);
|
||||
params.put(HTTP_STEP_PARAM, step);
|
||||
return http_promql(params);
|
||||
}
|
||||
|
||||
public boolean support(String datasource) {
|
||||
return supportQueryLanguage.equals(datasource);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-7
@@ -17,8 +17,7 @@
|
||||
|
||||
package org.apache.hertzbeat.warehouse.db;
|
||||
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQuery;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQueryData;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.MetricQueryData;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -28,11 +27,13 @@ import java.util.Map;
|
||||
*/
|
||||
public interface QueryExecutor {
|
||||
|
||||
MetricQueryData convertToMetricQueryData(Object object);
|
||||
|
||||
List<Map<String, Object>> execute(String query);
|
||||
|
||||
List<Map<String, Object>> query(String query, long time);
|
||||
|
||||
List<Map<String, Object>> query_range(String query, long start, long end, String step);
|
||||
|
||||
DatasourceQueryData query(DatasourceQuery datasourceQuery);
|
||||
|
||||
String getDatasource();
|
||||
|
||||
boolean support(String queryLanguage);
|
||||
boolean support(String datasource);
|
||||
}
|
||||
|
||||
+24
-17
@@ -20,15 +20,13 @@
|
||||
package org.apache.hertzbeat.warehouse.db;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQuery;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQueryData;
|
||||
|
||||
import static org.apache.hertzbeat.warehouse.constants.WarehouseConstants.SQL;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.MetricQueryData;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.hertzbeat.warehouse.constants.WarehouseConstants.SQL;
|
||||
|
||||
/**
|
||||
* abstract class for sql query executor
|
||||
*/
|
||||
@@ -42,19 +40,28 @@ public abstract class SqlQueryExecutor implements QueryExecutor {
|
||||
*/
|
||||
protected record ConnectorSqlProperties () {}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> execute(String query) {
|
||||
return null;
|
||||
protected abstract List<Map<String, Object>> do_sql(Map<String, Object> params);
|
||||
|
||||
public MetricQueryData convertToMetricQueryData(Object object) {
|
||||
MetricQueryData metricQueryData = new MetricQueryData();
|
||||
try {
|
||||
List<Map<String, Object>> metrics = (List<Map<String, Object>>) object;
|
||||
// todo
|
||||
} catch (Exception e) {
|
||||
log.error("converting to metric query data failed.");
|
||||
}
|
||||
return metricQueryData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatasourceQueryData query(DatasourceQuery datasourceQuery) {
|
||||
return null;
|
||||
public abstract List<Map<String, Object>> execute(String query);
|
||||
|
||||
public abstract List<Map<String, Object>> query(String query, long time);
|
||||
|
||||
public abstract List<Map<String, Object>> query_range(String query, long start, long end, String step);
|
||||
|
||||
|
||||
public boolean support(String datasource) {
|
||||
return supportQueryLanguage.equals(datasource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean support(String queryLanguage) {
|
||||
return StringUtils.hasText(queryLanguage) && queryLanguage.equalsIgnoreCase(supportQueryLanguage);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+3
-7
@@ -31,19 +31,15 @@ import org.springframework.web.client.RestTemplate;
|
||||
@ConditionalOnProperty(prefix = "warehouse.store.victoria-metrics", name = "enabled", havingValue = "true")
|
||||
@Slf4j
|
||||
public class VictoriaMetricsQueryExecutor extends PromqlQueryExecutor {
|
||||
private static final String Datasource = "VictoriaMetrics";
|
||||
|
||||
private static final String QUERY_PATH = "/api/v1/query";
|
||||
|
||||
private final VictoriaMetricsProperties victoriaMetricsProp;
|
||||
|
||||
public VictoriaMetricsQueryExecutor(VictoriaMetricsProperties victoriaMetricsProp, RestTemplate restTemplate) {
|
||||
super(restTemplate, new HttpPromqlProperties(victoriaMetricsProp.url(),
|
||||
super(restTemplate, new HttpPromqlProperties(victoriaMetricsProp.url() + QUERY_PATH,
|
||||
victoriaMetricsProp.username(), victoriaMetricsProp.password()));
|
||||
this.victoriaMetricsProp = victoriaMetricsProp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatasource() {
|
||||
return Datasource;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
-5
@@ -17,19 +17,30 @@
|
||||
|
||||
package org.apache.hertzbeat.warehouse.service;
|
||||
|
||||
import org.apache.hertzbeat.common.entity.dto.query.MetricQueryData;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQuery;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQueryData;
|
||||
|
||||
/**
|
||||
* metrics data query service
|
||||
*/
|
||||
public interface DatasourceQueryService {
|
||||
|
||||
public interface MetricsDataQueryService {
|
||||
|
||||
/**
|
||||
* Query metrics data
|
||||
* @param queries query expr
|
||||
* @param time time
|
||||
* @return data
|
||||
*/
|
||||
List<DatasourceQueryData> query(List<DatasourceQuery> queries);
|
||||
List<MetricQueryData> query(List<String> queries, String queryType, long time);
|
||||
|
||||
/**
|
||||
* Query metrics data range
|
||||
* @param queries query expr
|
||||
* @param start start
|
||||
* @param end end
|
||||
* @param step step
|
||||
* @return data
|
||||
*/
|
||||
List<MetricQueryData> queryRange(List<String> queries, String queryType, long start, long end, String step);
|
||||
}
|
||||
-60
@@ -1,60 +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.warehouse.service.impl;
|
||||
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQuery;
|
||||
import org.apache.hertzbeat.common.entity.dto.query.DatasourceQueryData;
|
||||
import org.apache.hertzbeat.warehouse.db.QueryExecutor;
|
||||
import org.apache.hertzbeat.warehouse.service.DatasourceQueryService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* datasource query service impl
|
||||
*/
|
||||
@Service
|
||||
public class DatasourceQueryServiceImpl implements DatasourceQueryService {
|
||||
Map<String, QueryExecutor> executorMap;
|
||||
|
||||
DatasourceQueryServiceImpl(List<QueryExecutor> executors) {
|
||||
executorMap = executors.stream().collect(Collectors.toMap(QueryExecutor::getDatasource, executor -> executor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasourceQueryData> query(List<DatasourceQuery> queries) {
|
||||
if (queries == null) {
|
||||
throw new IllegalArgumentException("No query found");
|
||||
}
|
||||
List<DatasourceQueryData> datasourceQueryDataList = new ArrayList<>();
|
||||
for (DatasourceQuery datasourceQuery : queries) {
|
||||
QueryExecutor executor = executorMap.get(datasourceQuery.getDatasource());
|
||||
if (executor == null) {
|
||||
throw new IllegalArgumentException("Unsupported datasource: " + datasourceQuery.getDatasource());
|
||||
}
|
||||
datasourceQueryDataList.add(executor.query(datasourceQuery));
|
||||
}
|
||||
|
||||
return datasourceQueryDataList;
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.warehouse.service.impl;
|
||||
|
||||
import org.apache.hertzbeat.common.entity.dto.query.MetricQueryData;
|
||||
import org.apache.hertzbeat.warehouse.db.QueryExecutor;
|
||||
import org.apache.hertzbeat.warehouse.service.MetricsDataQueryService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class MetricsDataQueryServiceImpl implements MetricsDataQueryService {
|
||||
@Autowired(required = false)
|
||||
List<QueryExecutor> executors;
|
||||
|
||||
@Override
|
||||
public List<MetricQueryData> query(List<String> queries, String queryType, long time) {
|
||||
if (queries == null || executors.isEmpty()) {
|
||||
throw new IllegalArgumentException("No query executor found");
|
||||
}
|
||||
QueryExecutor executor = executors.stream().filter(e -> e.support(queryType)).findFirst().orElse(null);
|
||||
if (executor == null) {
|
||||
throw new IllegalArgumentException("Unsupported datasource: " + queryType);
|
||||
}
|
||||
List<MetricQueryData> metricQueryDataList = new ArrayList<>();
|
||||
for (String query : queries) {
|
||||
metricQueryDataList.add(executor.convertToMetricQueryData(executor.query(query, time)));
|
||||
}
|
||||
return metricQueryDataList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetricQueryData> queryRange(List<String> queries, String queryType, long start, long end, String step) {
|
||||
if (queries == null || executors.isEmpty()) {
|
||||
throw new IllegalArgumentException("No query executor found");
|
||||
}
|
||||
QueryExecutor executor = executors.stream().filter(e -> e.support(queryType)).findFirst().orElse(null);
|
||||
if (executor == null) {
|
||||
throw new IllegalArgumentException("Unsupported datasource: " + queryType);
|
||||
}
|
||||
List<MetricQueryData> metricQueryDataList = new ArrayList<>();
|
||||
for (String query : queries) {
|
||||
metricQueryDataList.add(executor.convertToMetricQueryData(executor.query_range(query, start, end, step)));
|
||||
}
|
||||
return metricQueryDataList;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
---
|
||||
title: From Commiter to PMC: The Journey of Growth at Apache Hertzbeat
|
||||
author: zhangshenghang
|
||||
author_title: zhangshenghang
|
||||
author_url: https://github.com/zhangshenghang
|
||||
author_image_url: https://avatars.githubusercontent.com/u/29418975?s=400&v=4
|
||||
tags: [opensource, practice]
|
||||
keywords: [open source monitoring system, alerting system]
|
||||
---
|
||||
|
||||
## From Committer to PMC: The Transformation and Growth of Roles
|
||||
|
||||
A year ago, when I received the notification of becoming an Apache HertzBeat **Committer**, the joy and sense of mission I felt are still vivid in my memory. At that time, I was more focused on specific technical implementations and feature developments. Now, being invited to join the **PMC** means that I need to view the project's development from a more comprehensive perspective. This is not only an acknowledgment of my participation in open source but also a call for future responsibilities.
|
||||
|
||||
### In-depth Participation: Accumulation during the Committer Period
|
||||
|
||||
After becoming a Committer, my daily work changed significantly:
|
||||
|
||||
- **Code review became the norm**: From the initial simple PR reviews to the ability to systematically evaluate code quality, the rationality of the architecture, and consistency with the overall project direction.
|
||||
- **Tighter community collaboration**: I started to regularly participate in community meetings, assist new contributors in solving problems, and even take the lead in the development and implementation of certain features.
|
||||
- **Participation in technical decision-making**: On key issues such as monitoring protocol support and storage engine optimization, I began to put forward my own opinions and jointly develop implementation plans with the core team.
|
||||
|
||||
During this period, I deeply realized that **the vitality of an open source project lies not only in the code but also in community collaboration and trust**. Every code merge and every problem discussion are minor adjustments to the project's direction, and the role of the Committer gave me the opportunity to be involved.
|
||||
|
||||
## Becoming a PMC: The Upgrade of Responsibilities and Challenges
|
||||
|
||||
The responsibilities of the PMC go far beyond the code level. It requires members to have a deeper understanding and thinking about the project's **technical direction, community governance, and long-term development**. When I received the PMC invitation, I felt excited but also realized that I needed to face new challenges:
|
||||
|
||||
### 1. Participation in Technical Strategy
|
||||
|
||||
As a PMC, I need to jointly plan the long-term roadmap of HertzBeat with other members. For example:
|
||||
|
||||
- **Performance optimization**: In the face of large-scale monitoring scenarios, how to optimize storage and query efficiency.
|
||||
- **Enhanced scalability**: How to design a more flexible plugin mechanism to facilitate the community to contribute new monitoring types.
|
||||
|
||||
These issues are no longer simple code implementations but involve in-depth discussions on technical selection, community resource allocation, and even project positioning.
|
||||
|
||||
### 2. Community Governance and Health
|
||||
|
||||
The PMC needs to pay attention to the long-term healthy development of the community, including:
|
||||
|
||||
- **Contributor experience**: How to optimize the documentation and lower the entry threshold for new members.
|
||||
- **Community culture**: Ensure a friendly discussion atmosphere and that conflicts can be properly resolved.
|
||||
- **Sustainable development**: Motivate long-term contributors while attracting new blood.
|
||||
|
||||
## Personal Growth: The Transformation of Skills and Mentality
|
||||
|
||||
This year's experience has improved me in multiple dimensions:
|
||||
|
||||
- **Technical breadth**: From focusing on specific functions to understanding the overall architecture of the distributed monitoring system.
|
||||
- **Soft skills**: Learned how to communicate effectively, coordinate different opinions, and promote community consensus.
|
||||
- **Project management**: Understood the operation mode of open source projects and balanced the ideal and practical constraints.
|
||||
|
||||
The most profound realization is that **in the open source community, technical ability is just the foundation, and the real value lies in whether you can create achievements greater than the individual through collaboration**.
|
||||
|
||||
## Future Prospects: Moving Forward with HertzBeat
|
||||
|
||||
As a newly appointed PMC, I have several key directions for the future:
|
||||
|
||||
1. **Promote HertzBeat to become an important choice in the field of cloud-native monitoring**, especially to form a differentiated advantage in terms of lightweight and ease of use.
|
||||
2. **Build a more active contributor community** and cultivate core contributors through mentorship programs, regular activities, and other means.
|
||||
3. **Improve the project governance process** to make decision-making more transparent and participation smoother.
|
||||
|
||||
## Acknowledgments and Encouragement
|
||||
|
||||
I would like to especially thank **Tom** for his guidance and all community partners for their support. The Apache Way emphasizes that "community is more important than code", and this concept has deeply influenced my way of working.
|
||||
|
||||
Finally, I want to share with you who are reading this: **Open source is a long-lasting and warm journey. There is no need to pursue quick success. Just keep contributing, and the rewards will come naturally**. I look forward to meeting more like-minded friends in the HertzBeat community!
|
||||
|
||||
As we often say: **"Participating in open source is to make technology better, not to make life busier"** —— Let's encourage each other 😊
|
||||
@@ -1,316 +0,0 @@
|
||||
---
|
||||
title: Announcement of Apache Hertzbeat 1.7.0 Release
|
||||
author: tomsun28
|
||||
author_title: tomsun28
|
||||
author_url: https://github.com/zhangshenghang
|
||||
author_image_url: https://avatars.githubusercontent.com/u/24788200?s=400&v=4
|
||||
tags: [opensource, release]
|
||||
keywords: [open source monitoring system, alerting system, Hertzbeat, release]
|
||||
---
|
||||
|
||||
Dear Community Members,
|
||||
|
||||
We are thrilled to announce the official release of Apache Hertzbeat version 1.7.0!
|
||||
|
||||
## Downloads and Documentation
|
||||
|
||||
- **Apache Hertzbeat 1.7.0 Download Link**: <https://hertzbeat.apache.org/docs/download>
|
||||
- **Apache Hertzbeat Documentation**: <https://hertzbeat.apache.org/docs/>
|
||||
|
||||
## Major Updates
|
||||
|
||||
### New Features and Enhancements
|
||||
|
||||
- **Custom Refresh Interval**: Supports custom refresh intervals for each group of metrics to meet monitoring needs in different scenarios.
|
||||
- **Task Auto Discovery**: Supports automatic task discovery via `http_sd`, enhancing task flexibility and manageability.
|
||||
- **New Alarm Module**: Supports real-time threshold and scheduled threshold, grouped convergence, alarm suppression, alarm silencing, and more.
|
||||
- **Kafka Monitoring Enhancement**: Optimized Kafka monitoring features, including improved Kafka chart displays and added Kafka consumer group monitoring metrics.
|
||||
- **Support for Multiple Protocols and Monitoring Types**: Added support for monitoring `Plc` protocol, further expanding the monitoring scope.
|
||||
- **Alarm Function Enhancement**: Supports replacing Tencent Cloud SDK with HTTP API for sending SMS notifications, increasing the flexibility and scalability of alarm notifications. Additionally, it supports multi-query expression threshold alarms and periodic alarm thresholds.
|
||||
- **Multilingual Support**: Added support for languages such as Japanese and Traditional Chinese, enhancing the international user experience.
|
||||
- **Monitoring Function Enhancement**: Supports monitoring for more types such as `StarRocks FE`, providing users with more monitoring options.
|
||||
- **E2E Testing Enhancement**: Added multiple E2E test codes, including for Kafka, SSH, and API, improving test coverage and stability.
|
||||
- **Data Storage Optimization**: Updated `VictoriaMetrics` and `Greptime` storage to improve data storage performance and stability.
|
||||
- **More New Features**
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **Fix Docker Build Errors**: Fixed the collector Docker build errors, ensuring normal Docker image builds.
|
||||
- **Fix Linux Process Monitoring Issue**: Fixed an issue where Linux process monitoring failed without warning when a process exited abnormally, improving monitoring stability.
|
||||
- **Fix Windows Chinese Encoding Issue**: Fixed the issue with Chinese encoding on Windows, ensuring normal operation in Windows environments.
|
||||
- **Fix Grafana Configuration Issue**: Fixed issues related to Grafana configuration, improving the Grafana integration experience.
|
||||
- **Fix Windows Metric Configuration Issue**: Updated Windows metric YAML files to resolve related issues.
|
||||
- **Fix Flyway Location Detection Issue**: Fixed the issue where Flyway could not automatically detect vendor locations, improving database migration reliability.
|
||||
- **Fix Data Storage Issues**: Fixed issues related to data storage, including Prometheus data storage issues and data update logic issues, ensuring data accuracy and integrity.
|
||||
- **Fix Alarm Notification Issues**: Fixed issues related to alarm notifications, including duplicate sending and configuration problems, improving alarm notification accuracy and reliability.
|
||||
- **Fix Monitoring Status Update Issue**: Fixed the issue where monitoring status wasn't updated, ensuring real-time and accurate monitoring status.
|
||||
- **And Other Bug Fixes**
|
||||
|
||||
### Refactoring and Optimization
|
||||
|
||||
- **Memory Structure Optimization**: Used `Apache Arrow` as the in-memory data structure, improving memory usage efficiency and performance.
|
||||
- **Code Standard Optimization**: Optimized the code according to coding standards, improving code quality and readability.
|
||||
- **Cache Optimization**: Added an `LRU` local cache based on the Singleton pattern, improving cache efficiency and performance.
|
||||
- **Memory Leak Fix**: Fixed potential memory leak issues, improving system stability and reliability.
|
||||
- **And Other Optimizations**
|
||||
|
||||
### Documentation Enhancements
|
||||
|
||||
- **Updated Deployment Documentation**: Updated deployment documentation with more detailed deployment guidance.
|
||||
- **Updated Security Model Documentation**: Updated the security model documentation.
|
||||
- **Updated Grafana Configuration Documentation**: Updated Grafana configuration methods and documentation for exposing URLs, enhancing user experience.
|
||||
- **Updated Windows Monitoring Documentation**: Updated Windows system monitoring documentation with more detailed monitoring guidance.
|
||||
- **Updated Monitoring Metrics Documentation**: Updated documentation for multiple monitoring metrics, including Kafka, Linux processes, etc., improving the accuracy and completeness of the documentation.
|
||||
- **Updated Developer Documentation**: Added documentation for custom collector development, helping developers with secondary development.
|
||||
- **More Documentation Updates**
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Special thanks to the following community members for their collaborative efforts:
|
||||
|
||||
> @ghyghoo8 @kerwin612 @pjfanning @helei1030 @shinestare @simonsigre @myangle1120 @MasamiYui @Craaaaazy77 @tomsun28 @Aias00 @zhangshenghang @wanhao23 @zqr10159 @LiuTianyou
|
||||
> @hasimmollah @lixiaobaivv @LL-LIN @JuJinPark @ponfee @starryCoder @NikhilMurugesan @leo-934 @Rancho-7 @MonsterChenzhuo @zuobiao-zhou @pwallk @bigcyy @ZY945 @sarthakeash
|
||||
> @All-The-Best-for @TJxiaobao @yyahang @yunfan24 @a-little-fool @yasminvo @Yanshuming1 @ayu-v0 @jonasHanhan @Calvin979 @Suvrat1629 @Vedant7789 @notbugggg @lctking @po-168 @doveLin0818
|
||||
|
||||
## What's Changed
|
||||
|
||||
```markdown
|
||||
* [doc](download): update for v1.6.1 release by @zqr10159 in https://github.com/apache/hertzbeat/pull/2794
|
||||
* [Doc] improve website by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2795
|
||||
* [doc] update deploy doc by @tomsun28 in https://github.com/apache/hertzbeat/pull/2796
|
||||
* [Task][OSPP] HertzBeat Official Template Marketplace by @All-The-Best-for in https://github.com/apache/hertzbeat/pull/2641
|
||||
* [improve]:Improve the way Ai is entered and requested by @Yanshuming1 in https://github.com/apache/hertzbeat/pull/2762
|
||||
* [bugfix] fix collector docker build error by @tomsun28 in https://github.com/apache/hertzbeat/pull/2799
|
||||
* [fix]Remove the duplicate declaration of commons-net by @shinestare in https://github.com/apache/hertzbeat/pull/2801
|
||||
* [doc] update new contributors by @tomsun28 in https://github.com/apache/hertzbeat/pull/2802
|
||||
* [Improve] Improve module name by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2805
|
||||
* [improve] code according to code specifications by @po-168 in https://github.com/apache/hertzbeat/pull/2809
|
||||
* [feature] Support custom refresh intervals for each group of metrics by @zuobiao-zhou in https://github.com/apache/hertzbeat/pull/2718
|
||||
* [improve] Fix error links caused by module name changes. by @zuobiao-zhou in https://github.com/apache/hertzbeat/pull/2807
|
||||
* [fix] fix the Linux process monitoring process exits abnormally without warning by @LiuTianyou in https://github.com/apache/hertzbeat/pull/2810
|
||||
* [Doc] Add blog by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2812
|
||||
* [Improve] improve kafka monitor by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2813
|
||||
* [Feature] add e2e code by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2811
|
||||
* [improve] modify e2e test by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2814
|
||||
* [improve] update windows metrics yml by @tomsun28 in https://github.com/apache/hertzbeat/pull/2816
|
||||
* [improve] update grafana auth method and add expose url by @tomsun28 in https://github.com/apache/hertzbeat/pull/2818
|
||||
* Fixed the omissions in #2805 by @kerwin612 in https://github.com/apache/hertzbeat/pull/2826
|
||||
* [refactor] change name from http_sd to registry by @Calvin979 in https://github.com/apache/hertzbeat/pull/2827
|
||||
* [fix]fix windows chinese encoding by @starryCoder in https://github.com/apache/hertzbeat/pull/2831
|
||||
* [doc] Added custom development collector documentation by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2833
|
||||
* [improve] update and fix template yml priority by @tomsun28 in https://github.com/apache/hertzbeat/pull/2829
|
||||
* [chore] Delete redundant Spaces by @ayu-v0 in https://github.com/apache/hertzbeat/pull/2834
|
||||
* [doc]: update sidebar category label and plugin documentation by @zqr10159 in https://github.com/apache/hertzbeat/pull/2837
|
||||
* [fix] bugfix flyway location can not auto detect vendor when not h2 by @tomsun28 in https://github.com/apache/hertzbeat/pull/2835
|
||||
* [improve] update victoriametrics and greptime store by @tomsun28 in https://github.com/apache/hertzbeat/pull/2836
|
||||
* [feature] support managing tasks by using http_sd by @Calvin979 in https://github.com/apache/hertzbeat/pull/2830
|
||||
* [fix] auto generated by protocol buffer by @tomsun28 in https://github.com/apache/hertzbeat/pull/2842
|
||||
* [Feature] Add ssh e2e code by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2843
|
||||
* [bugfix]Fix wrong app name by @zqr10159 in https://github.com/apache/hertzbeat/pull/2845
|
||||
* [doc] add security model doc and update contributors by @tomsun28 in https://github.com/apache/hertzbeat/pull/2846
|
||||
* [improve] improve dependency by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2855
|
||||
* [doc] update security doc and some by @tomsun28 in https://github.com/apache/hertzbeat/pull/2856
|
||||
* A bug fix by @TJxiaobao in https://github.com/apache/hertzbeat/pull/2853
|
||||
* [doc] Add ',' separator between monitoring types by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2865
|
||||
* [doc]improve-windows-monitoring:Update Windows system monitoring docu… by @starryCoder in https://github.com/apache/hertzbeat/pull/2869
|
||||
* [Optimize] Add a reminder about potential collection issues caused by the Docker deployment method of collector. by @zuobiao-zhou in https://github.com/apache/hertzbeat/pull/2844
|
||||
* [improve]Add more helpful messages when adding a Kafka monitor by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2876
|
||||
* modified:add a small change. by @TJxiaobao in https://github.com/apache/hertzbeat/pull/2878
|
||||
* [Fix] fix clickhouse monitor by @LiuTianyou in https://github.com/apache/hertzbeat/pull/2874
|
||||
* [chore] Delete the redundant else by @ayu-v0 in https://github.com/apache/hertzbeat/pull/2881
|
||||
* [improve]Remove stack property from line charts by @zqr10159 in https://github.com/apache/hertzbeat/pull/2888
|
||||
* [improve]improve linux process by @LiuTianyou in https://github.com/apache/hertzbeat/pull/2889
|
||||
* [Improve]Beautify Charts by @zqr10159 in https://github.com/apache/hertzbeat/pull/2891
|
||||
* [doc] Add more hints when users are switching data source. by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2880
|
||||
* [collector]feature:Add monitoring metrics for consumer groups in Kafka client by @doveLin0818 in https://github.com/apache/hertzbeat/pull/2887
|
||||
* [Improve] Improve Kafka chart display by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2894
|
||||
* [collector]bugfix:fix the issue of reusing the `adminClient` in the Kafka client. by @doveLin0818 in https://github.com/apache/hertzbeat/pull/2895
|
||||
* [improve]add Plc protocol , Modbus monitor by @ZY945 in https://github.com/apache/hertzbeat/pull/2850
|
||||
* [Improve] add notification when port number changes automatically due to HTTPS toggle.(#2779) by @yunfan24 in https://github.com/apache/hertzbeat/pull/2896
|
||||
* [feature] integrate with Apache Arrow by @Calvin979 in https://github.com/apache/hertzbeat/pull/2864
|
||||
* [Doc] update doc by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2900
|
||||
* [Imporve] Support Kafka internal topic configuration by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2901
|
||||
* [fix](flink): update calculate metrics definitions by @zqr10159 in https://github.com/apache/hertzbeat/pull/2905
|
||||
* [feature] Add a new Singleton-pattern-based LRU local cache by @doveLin0818 in https://github.com/apache/hertzbeat/pull/2907
|
||||
* add an online parser for prometheus. by @leo-934 in https://github.com/apache/hertzbeat/pull/2851
|
||||
* [Improve] Improve OBS by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2909
|
||||
* [improve] fix import of CollectRep by @Calvin979 in https://github.com/apache/hertzbeat/pull/2910
|
||||
* [feature](web-app): Add Alarm Voice Alerts by @zqr10159 in https://github.com/apache/hertzbeat/pull/2906
|
||||
* [bugfix] Fix the bug where canceling an edit on a record still updates the page values. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2911
|
||||
* [bugfix] Fix docker container name unable to display problem by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2914
|
||||
* [improve] Optimize CacheService and add relevant unit test by @lctking in https://github.com/apache/hertzbeat/pull/2912
|
||||
* [improve] Add required field indicators and form validation prompts for convergence strategies and silent strategies in the form. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2913
|
||||
* [Feture]Add docker e2e test by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2916
|
||||
* [bugfix]: fix setColumns method in CollectRep class by @zqr10159 in https://github.com/apache/hertzbeat/pull/2918
|
||||
* [improve](warehouse): replace empty json object key with empty string by @zqr10159 in https://github.com/apache/hertzbeat/pull/2919
|
||||
* [bugfix] Bug fix for alarm voice. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2920
|
||||
* Update app-windows_script.yml by @simonsigre in https://github.com/apache/hertzbeat/pull/2922
|
||||
* [bugfix] Fixed the 'java.lang.UnsupportedOperationException' exception caused by getCurrentMetricsData by @lixiaobaivv in https://github.com/apache/hertzbeat/pull/2923
|
||||
* [Improve] Optimize the e2e code structure by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2926
|
||||
* [improve] optimize website navbar css(#2928) by @ponfee in https://github.com/apache/hertzbeat/pull/2929
|
||||
* [feature] Adding CPU Temperature Check Into Default Ubuntu Checks by @simonsigre in https://github.com/apache/hertzbeat/pull/2930
|
||||
* [improve] Improve the synchronization of the mute status. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2927
|
||||
* [bugfix] Corrected case 'DashBoard' is a lower case 'B' by @simonsigre in https://github.com/apache/hertzbeat/pull/2935
|
||||
* [bugfix] Modify the doris_be.md document into an English version by @Craaaaazy77 in https://github.com/apache/hertzbeat/pull/2936
|
||||
* [improve] Refactor and Split the Message Notification Component. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2924
|
||||
* [home] updated navbar css #2928 by @Vedant7789 in https://github.com/apache/hertzbeat/pull/2934
|
||||
* [Improve]Improve e2e code by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2945
|
||||
* [refactor] refactoring methods replaceCryPlaceholder and replaceSmilingPlace by @hasimmollah in https://github.com/apache/hertzbeat/pull/2832
|
||||
* [alarm] refactor new alarm by @tomsun28 in https://github.com/apache/hertzbeat/pull/2902
|
||||
* [bugfix](db): optimize column update. by @zqr10159 in https://github.com/apache/hertzbeat/pull/2947
|
||||
* [doc] Add Supported MySQL Versions. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2949
|
||||
* [Feature] Support customized JMX monitoring through the Factory Pattern. by @doveLin0818 in https://github.com/apache/hertzbeat/pull/2932
|
||||
* [Improve]Modify Chinese comments by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2950
|
||||
* [improve] fix some alarm relate bug, update alarm center ui by @tomsun28 in https://github.com/apache/hertzbeat/pull/2951
|
||||
* 【Improve】adjust log level from INFO to WARN. by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2952
|
||||
* [Doc]:Add English version of documentation for Kafka Consumer Detail by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2953
|
||||
* [Imporve] Improve Huaweicloud by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2954
|
||||
* [improve] update alarm inhibit rule and alarm ui by @tomsun28 in https://github.com/apache/hertzbeat/pull/2957
|
||||
* [bufix] fix collector job scheduler error by @tomsun28 in https://github.com/apache/hertzbeat/pull/2966
|
||||
* [Improve]:Standardize Kafka metric naming by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2961
|
||||
* [BUG] "Advanced Settings" is all white in dark mode by @Suvrat1629 in https://github.com/apache/hertzbeat/pull/2965
|
||||
* [Improve] add no popup option after next login by @LiuTianyou in https://github.com/apache/hertzbeat/pull/2969
|
||||
* [feature] replace googletagmanager to matomo by @Aias00 in https://github.com/apache/hertzbeat/pull/2877
|
||||
* Fix the search functionality issue. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2970
|
||||
* [bugfix](warehouse): add metrics data update logic in memory storage by @zqr10159 in https://github.com/apache/hertzbeat/pull/2973
|
||||
* [Improve] Add more test cases for Kafka junit tests by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2976
|
||||
* [feature] alert integration extern source by @tomsun28 in https://github.com/apache/hertzbeat/pull/2978
|
||||
* [bugfix] Fix NullPointerException by @ayu-v0 in https://github.com/apache/hertzbeat/pull/2849
|
||||
* [webapp] key-value-input component hover effect fixed by @ghyghoo8 in https://github.com/apache/hertzbeat/pull/2972
|
||||
* [bugfix] fix alert integration extern source bug by @tomsun28 in https://github.com/apache/hertzbeat/pull/2979
|
||||
* [Feature] Support copy monitoring by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2981
|
||||
* [bugfix] fix hbase dashboard display anomalies and turn on HTTPS by @MonsterChenzhuo in https://github.com/apache/hertzbeat/pull/2980
|
||||
* [improve] update i18n json stru and update search ui by @tomsun28 in https://github.com/apache/hertzbeat/pull/2986
|
||||
* [MINOR UPDATE] improve xml parsing code by @pjfanning in https://github.com/apache/hertzbeat/pull/2988
|
||||
* [docs]doc:Added spark Chinese documents and changed the original spar… by @helei1030 in https://github.com/apache/hertzbeat/pull/2987
|
||||
* [type:improve] fix dependencies vulnerabilites by @Aias00 in https://github.com/apache/hertzbeat/pull/2989
|
||||
* [feature] Add privateKey passphrase config for linux monitor by @MasamiYui in https://github.com/apache/hertzbeat/pull/2982
|
||||
* [type:fix] remove matomo ip by @Aias00 in https://github.com/apache/hertzbeat/pull/2990
|
||||
* [feature] Added multilingual defaults for forms by @wanhao23 in https://github.com/apache/hertzbeat/pull/2991
|
||||
* [Improve]Add Copy token button by @zqr10159 in https://github.com/apache/hertzbeat/pull/2992
|
||||
* [MINOR UPDATE] close HttpResponse in HttpCollectImpl by @pjfanning in https://github.com/apache/hertzbeat/pull/2993
|
||||
* [MINOR UPDATE] close http response in PrometheusAutoCollectImpl by @pjfanning in https://github.com/apache/hertzbeat/pull/2994
|
||||
* [MINOR UPDATE] fix more instances of unclosed Http Responses by @pjfanning in https://github.com/apache/hertzbeat/pull/2995
|
||||
* [bugfix] fix wrong http user-agent content by @tomsun28 in https://github.com/apache/hertzbeat/pull/2996
|
||||
* [feature] Support monitoring for StarRocks FE and StarRocks BE. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2997
|
||||
* [MINOR UPDATE] refactor base64 code to simplify the conversions by @pjfanning in https://github.com/apache/hertzbeat/pull/2999
|
||||
* [webapp] bugfix edit monitor http query params error by @tomsun28 in https://github.com/apache/hertzbeat/pull/3001
|
||||
* [feature] Complete multiple languages by @wanhao23 in https://github.com/apache/hertzbeat/pull/3002
|
||||
* [feature] Add alerter_zh_TW.properties configuration to adapt to mult… by @jonasHanhan in https://github.com/apache/hertzbeat/pull/3004
|
||||
* [bugfix] fix some unit tests that failed to run by @NikhilMurugesan in https://github.com/apache/hertzbeat/pull/3007
|
||||
* [feature](alert): implement drag-and-drop functionality for alert templates by @zqr10159 in https://github.com/apache/hertzbeat/pull/3005
|
||||
* [improve] Freeze the 'Operate' column on the right side of the list. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3009
|
||||
* [MINOR UPDATE] always specify the char encoding in getBytes by @pjfanning in https://github.com/apache/hertzbeat/pull/3011
|
||||
* [bugfix]Fix page not found by @zqr10159 in https://github.com/apache/hertzbeat/pull/3014
|
||||
* [bugfix] Modify mask issue by @myangle1120 in https://github.com/apache/hertzbeat/pull/3018
|
||||
* [issue-2998] remove invalid check in isValidLabelValue by @pjfanning in https://github.com/apache/hertzbeat/pull/3015
|
||||
* [MINOR UPDATE] Use Encode to string when possible (Base64) by @pjfanning in https://github.com/apache/hertzbeat/pull/3016
|
||||
* [Improve] update english doc by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3028
|
||||
* [Feature] Add API e2e code by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3029
|
||||
* [doc] update new contributor wall by @tomsun28 in https://github.com/apache/hertzbeat/pull/3025
|
||||
* OnlineParserTest doesn't test anything by @pjfanning in https://github.com/apache/hertzbeat/pull/3010
|
||||
* [feature] periodic alert threshold by @tomsun28 in https://github.com/apache/hertzbeat/pull/3024
|
||||
* [bugfix] fix and enable some unit tests. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3031
|
||||
* [feature] Add pagination and name-based search functionality in notification module by @yunfan24 in https://github.com/apache/hertzbeat/pull/2948
|
||||
* [bugfix] Fixed the bug in the threshold rules search box. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3034
|
||||
* [improve] Replaced hardcoded text with internationalized string. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3035
|
||||
* [update] upgrade actions/upload-artifact to v4 by @yunfan24 in https://github.com/apache/hertzbeat/pull/3046
|
||||
* [improve] Search ignores case sensitivity. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3042
|
||||
* Add sse support for alert center, no need to manually refresh the page, add slide-in animation by @zqr10159 in https://github.com/apache/hertzbeat/pull/3051
|
||||
* [alert] support multi query expr threshold by @tomsun28 in https://github.com/apache/hertzbeat/pull/3054
|
||||
* [improve](alert-center): enhance alert card animations and interactions by @zqr10159 in https://github.com/apache/hertzbeat/pull/3055
|
||||
* [improve] update theme ui color by @tomsun28 in https://github.com/apache/hertzbeat/pull/3057
|
||||
* [bugfix] Fix the issue where the monitoring status is not updated. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3056
|
||||
* [bugfix]style(alert-center): enhance 3D transformation and z-index layers by @zqr10159 in https://github.com/apache/hertzbeat/pull/3059
|
||||
* [Feature]Add zookeeper e2e code by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3030
|
||||
* [feature] Add Sftp config for monitor by @MasamiYui in https://github.com/apache/hertzbeat/pull/3038
|
||||
* [feature] Add Japanese by @wanhao23 in https://github.com/apache/hertzbeat/pull/3013
|
||||
* [bugfix] fix singleton not support remove, search id error, audio fetch 401 by @tomsun28 in https://github.com/apache/hertzbeat/pull/3062
|
||||
* [API DOC] Change Swagger description by @pwallk in https://github.com/apache/hertzbeat/pull/3061
|
||||
* [webapp] update ui theme by @tomsun28 in https://github.com/apache/hertzbeat/pull/3064
|
||||
* [feature] Support SSH Tunnel by @pwallk in https://github.com/apache/hertzbeat/pull/3060
|
||||
* [improve] Complete the missing labels in the i18n file. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3065
|
||||
* [Feature]Add Chinese check by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3066
|
||||
* [improve] Refactor SMS sending and replace Tencent Cloud SDK with HTTP API. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3063
|
||||
* [Bugfix] fix when the monitor is modified, the status is erroneously changed by @pwallk in https://github.com/apache/hertzbeat/pull/3067
|
||||
* [improve](web-app): update monitor chart configuration and springboot GreptimeDB version by @zqr10159 in https://github.com/apache/hertzbeat/pull/3071
|
||||
* [doc] Update the SMS configuration document. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3073
|
||||
* [feature] SMS notification supports unisms. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3077
|
||||
* [webapp] update and fix alert ui when theme dark by @tomsun28 in https://github.com/apache/hertzbeat/pull/3082
|
||||
* [improve] Improve and unify the search. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3085
|
||||
* [feature] supports alibaba SMS. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3084
|
||||
* [improve] optimize kafka collect test by @Rancho-7 in https://github.com/apache/hertzbeat/pull/3093
|
||||
* correct home's new_committer_process by @a-little-fool in https://github.com/apache/hertzbeat/pull/3094
|
||||
* [bugfix] kafka client detect error by @Rancho-7 in https://github.com/apache/hertzbeat/pull/3088
|
||||
* [Doc]Improve openai doc by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3097
|
||||
* [Improve] Message notification prompt optimization by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3095
|
||||
* [webapp] fix web oom crash when backend api can not access by @tomsun28 in https://github.com/apache/hertzbeat/pull/3100
|
||||
* [Feature] Add deepseek Api Monitor by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3096
|
||||
* feat/adding-ptBR-translation by @yasminvo in https://github.com/apache/hertzbeat/pull/3098
|
||||
* [bugfix] fix alert sse illegal state exception by @tomsun28 in https://github.com/apache/hertzbeat/pull/3106
|
||||
* [bugfix] Fix exception thrown when searching for CollectRep.Field in the list by @JuJinPark in https://github.com/apache/hertzbeat/pull/3109
|
||||
* [type: fix] #3090 garbled characters by @notbugggg in https://github.com/apache/hertzbeat/pull/3113
|
||||
* [doc]fix link by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3123
|
||||
* [doc] Add GSOC doc by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3122
|
||||
* [doc] Add alibaba SMS and unisms documentation. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3114
|
||||
* [improve] support reuse jdbc connection switch by @tomsun28 in https://github.com/apache/hertzbeat/pull/3101
|
||||
* [webapp] fix monitor define param wrong placeholder tip by @tomsun28 in https://github.com/apache/hertzbeat/pull/3118
|
||||
* [bugfix] Fix swagger opening exception that Failed to load API definition. (#3127) by @yyahang in https://github.com/apache/hertzbeat/pull/3129
|
||||
* [doc] welcome new committer and contributor by @tomsun28 in https://github.com/apache/hertzbeat/pull/3132
|
||||
* [feature] add smslocal sms notification by @a-little-fool in https://github.com/apache/hertzbeat/pull/3135
|
||||
* [improve] Optimize the progress display of monitoring imports by @MasamiYui in https://github.com/apache/hertzbeat/pull/3120
|
||||
* [improve] fix potential memory leakage and content length issues. by @tomsun28 in https://github.com/apache/hertzbeat/pull/3128
|
||||
* [bugfix] fix overflow arrow buffer index by @tomsun28 in https://github.com/apache/hertzbeat/pull/3137
|
||||
* [improve] improve plugin upload by @LiuTianyou in https://github.com/apache/hertzbeat/pull/3139
|
||||
* [doc] Add new committer blog by @yunfan24 in https://github.com/apache/hertzbeat/pull/3140
|
||||
* Configuring gitpod with java by @kerwin612 in https://github.com/apache/hertzbeat/pull/3141
|
||||
* Fix the issue of the empty dropdown menu on the Kanban board page. by @kerwin612 in https://github.com/apache/hertzbeat/pull/3142
|
||||
* [feature] Add AWS sms client by @JuJinPark in https://github.com/apache/hertzbeat/pull/3134
|
||||
* [feature] Support skywalking alert source by @MasamiYui in https://github.com/apache/hertzbeat/pull/3144
|
||||
* [feature] support SSH proxy jump connections by @LL-LIN in https://github.com/apache/hertzbeat/pull/3138
|
||||
* [improve] support bind metrics label and others into alert by @tomsun28 in https://github.com/apache/hertzbeat/pull/3146
|
||||
* [bugfix] Fixed #3112, disappear left menu tree item when restart service by @notbugggg in https://github.com/apache/hertzbeat/pull/3116
|
||||
* [bugfix] fix collect dispatch error by @tomsun28 in https://github.com/apache/hertzbeat/pull/3150
|
||||
* [improve] Merge SMS configuration class. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3148
|
||||
* [webapp] fix less style file over max build error by @tomsun28 in https://github.com/apache/hertzbeat/pull/3151
|
||||
* [bugfix] fix nightly docker build github action by @tomsun28 in https://github.com/apache/hertzbeat/pull/3153
|
||||
* [feature] Supports sending messages to a specific Telegram group topic.(#3079) by @bigcyy in https://github.com/apache/hertzbeat/pull/3143
|
||||
* Abstract Redundant Input Components into ConfigurableFieldComponent for Unified Management by @kerwin612 in https://github.com/apache/hertzbeat/pull/3152
|
||||
* [feature] Support TencentCloud alert source by @bigcyy in https://github.com/apache/hertzbeat/pull/3149
|
||||
* [bugfix]: fix incomplete class documentation in AppServiceImpl by @bigcyy in https://github.com/apache/hertzbeat/pull/3162
|
||||
* [bugfix] Fix http header being incorrectly encoded. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3108
|
||||
* [bugfix] retain sorting state after monitor list auto-refresh by @LL-LIN in https://github.com/apache/hertzbeat/pull/3156
|
||||
* [feature] add twilio sms client support by @sarthakeash in https://github.com/apache/hertzbeat/pull/3159
|
||||
* [doc] Add alert integration japanese i18 by @MasamiYui in https://github.com/apache/hertzbeat/pull/3164
|
||||
* [release] update release version 1.7.0 version and docs by @tomsun28 in https://github.com/apache/hertzbeat/pull/3165
|
||||
* [feature] implement labels-based monitors filtering in bulletin creation flow by @LL-LIN in https://github.com/apache/hertzbeat/pull/3161
|
||||
* [bugfix] fix postgre mount error, use mariadb instead of mysql in compose by @tomsun28 in https://github.com/apache/hertzbeat/pull/3168
|
||||
* [bugfix] fix bind Labels are not updated when the Alarm Severity switches by @bigcyy in https://github.com/apache/hertzbeat/pull/3170
|
||||
* [improve] update git archive export ignore by @tomsun28 in https://github.com/apache/hertzbeat/pull/3172
|
||||
* [improve] update notice copyright years by @tomsun28 in https://github.com/apache/hertzbeat/pull/3171
|
||||
```
|
||||
|
||||
## Apache Hertzbeat
|
||||
|
||||
**Repository URL:**
|
||||
|
||||
<https://github.com/apache/hertzbeat>
|
||||
|
||||
**Official Website:**
|
||||
|
||||
<https://hertzbeat.apache.org/>
|
||||
|
||||
**Apache Hertzbeat Download Link:**
|
||||
|
||||
<https://hertzbeat.apache.org/docs/download>
|
||||
|
||||
**Apache Hertzbeat Docker Images:**
|
||||
|
||||
Apache Hertzbeat provides Docker images for each release, available on Docker Hub:
|
||||
|
||||
- HertzBeat: <https://hub.docker.com/r/apache/hertzbeat>
|
||||
- HertzBeat Collector: <https://hub.docker.com/r/apache/hertzbeat-collector>
|
||||
|
||||
**How to Contribute to the Apache Hertzbeat Open Source Community?**
|
||||
|
||||
<https://hertzbeat.apache.org/docs/community/contribution>
|
||||
@@ -130,56 +130,7 @@ params:
|
||||
|
||||
# collect metrics config list
|
||||
metrics:
|
||||
- name: system_info
|
||||
i18n:
|
||||
zh-CN: 系统信息
|
||||
en-US: System Info
|
||||
priority: 0
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
ssl: ^_^ssl^_^
|
||||
url: /ISAPI/System/deviceInfo
|
||||
method: GET
|
||||
timeout: ^_^timeout^_^
|
||||
authorization:
|
||||
type: Digest Auth
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: xmlPath
|
||||
parseScript: //DeviceInfo
|
||||
fields:
|
||||
- field: deviceName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备名称
|
||||
en-US: Device Name
|
||||
- field: deviceID
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备ID
|
||||
en-US: Device ID
|
||||
- field: firmwareVersion
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 固件版本
|
||||
en-US: Firmware Version
|
||||
- field: model
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备型号
|
||||
en-US: Device Model
|
||||
- field: macAddress
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: mac地址
|
||||
en-US: Mac Address
|
||||
- name: status
|
||||
i18n:
|
||||
zh-CN: 设备状态
|
||||
en-US: Status
|
||||
priority: 0
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
@@ -193,134 +144,115 @@ metrics:
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: xmlPath
|
||||
parseScript: //DeviceStatus
|
||||
parseScript: 'DeviceStatus'
|
||||
fields:
|
||||
- field: CPU_utilization
|
||||
- field: cpuUtilization
|
||||
i18n:
|
||||
zh-CN: CPU 利用率
|
||||
en-US: CPU Utilization
|
||||
type: 0
|
||||
unit: '%'
|
||||
- field: memory_usage
|
||||
xpath: CPUList/CPU/cpuUtilization
|
||||
- field: memoryUsage
|
||||
i18n:
|
||||
zh-CN: 内存使用量
|
||||
en-US: Memory Usage
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: memory_available
|
||||
xpath: MemoryList/Memory/memoryUsage
|
||||
- field: memoryAvailable
|
||||
i18n:
|
||||
zh-CN: 可用内存
|
||||
en-US: Memory Available
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: cache_size
|
||||
xpath: MemoryList/Memory/memoryAvailable
|
||||
- field: cacheSize
|
||||
i18n:
|
||||
zh-CN: 缓存大小
|
||||
en-US: Cache Size
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: net_port_1_speed
|
||||
xpath: MemoryList/Memory/cacheSize
|
||||
- field: netPort1Speed
|
||||
i18n:
|
||||
zh-CN: 网口1速度
|
||||
en-US: Net Port 1 Speed
|
||||
type: 0
|
||||
unit: Mbps
|
||||
- field: net_port_2_speed
|
||||
xpath: NetPortStatusList/NetPortStatus[id='1']/workSpeed
|
||||
- field: netPort2Speed
|
||||
i18n:
|
||||
zh-CN: 网口2速度
|
||||
en-US: Net Port 2 Speed
|
||||
type: 0
|
||||
unit: Mbps
|
||||
- field: boot_time
|
||||
xpath: NetPortStatusList/NetPortStatus[id='2']/workSpeed
|
||||
- field: bootTime
|
||||
i18n:
|
||||
zh-CN: 启动时间
|
||||
en-US: Boot Time
|
||||
type: 1
|
||||
- field: device_uptime
|
||||
xpath: bootTime
|
||||
- field: deviceUpTime
|
||||
i18n:
|
||||
zh-CN: 运行时长
|
||||
en-US: Device Uptime
|
||||
type: 1
|
||||
- field: last_calibration_time
|
||||
xpath: deviceUpTime
|
||||
- field: lastCalibrationTime
|
||||
i18n:
|
||||
zh-CN: 上次校时时间
|
||||
en-US: Last Calibration Time
|
||||
type: 1
|
||||
- field: last_calibration_time_diff
|
||||
xpath: lastCalibrationTime
|
||||
- field: lastCalibrationTimeDiff
|
||||
i18n:
|
||||
zh-CN: 上次校时时间差
|
||||
en-US: Last Calibration Time Diff
|
||||
type: 0
|
||||
unit: s
|
||||
- field: avg_upload_time
|
||||
xpath: lastCalibrationTimeDiff
|
||||
- field: avgUploadTime
|
||||
i18n:
|
||||
zh-CN: 平均上传耗时
|
||||
en-US: Avg Upload Time
|
||||
type: 0
|
||||
unit: ms
|
||||
- field: max_upload_time
|
||||
xpath: uploadTimeConsumingList/avgTime
|
||||
- field: maxUploadTime
|
||||
i18n:
|
||||
zh-CN: 最大上传耗时
|
||||
en-US: Max Upload Time
|
||||
type: 0
|
||||
unit: ms
|
||||
- field: min_upload_time
|
||||
xpath: uploadTimeConsumingList/maxTime
|
||||
- field: minUploadTime
|
||||
i18n:
|
||||
zh-CN: 最小上传耗时
|
||||
en-US: Min Upload Time
|
||||
type: 0
|
||||
unit: ms
|
||||
- field: last_calibration_mode
|
||||
xpath: uploadTimeConsumingList/minTime
|
||||
- field: lastCalibrationMode
|
||||
i18n:
|
||||
zh-CN: 上次校时模式
|
||||
en-US: Last Calibration Mode
|
||||
type: 1
|
||||
- field: last_calibration_address
|
||||
xpath: lastCalibrationTimeMode
|
||||
- field: lastCalibrationAddress
|
||||
i18n:
|
||||
zh-CN: 上次校时地址
|
||||
en-US: Last Calibration Address
|
||||
type: 1
|
||||
- field: response_time
|
||||
xpath: lastCalibrationTimeAddress
|
||||
- field: responseTime
|
||||
i18n:
|
||||
zh-CN: 响应时间
|
||||
en-US: Response Time
|
||||
type: 0
|
||||
unit: ms
|
||||
aliasFields:
|
||||
- CPUList/CPU/cpuUtilization
|
||||
- MemoryList/Memory/memoryUsage
|
||||
- MemoryList/Memory/memoryAvailable
|
||||
- MemoryList/Memory/cacheSize
|
||||
- NetPortStatusList/NetPortStatus[id='1']/workSpeed
|
||||
- NetPortStatusList/NetPortStatus[id='2']/workSpeed
|
||||
- bootTime
|
||||
- deviceUpTime
|
||||
- lastCalibrationTime
|
||||
- lastCalibrationTimeDiff
|
||||
- uploadTimeConsumingList/avgTime
|
||||
- uploadTimeConsumingList/maxTime
|
||||
- uploadTimeConsumingList/minTime
|
||||
- lastCalibrationTimeMode
|
||||
- lastCalibrationTimeAddress
|
||||
- responseTime
|
||||
calculates:
|
||||
- CPU_utilization=CPUList/CPU/cpuUtilization
|
||||
- memory_usage=MemoryList/Memory/memoryUsage
|
||||
- memory_available=MemoryList/Memory/memoryAvailable
|
||||
- cache_size=MemoryList/Memory/cacheSize
|
||||
- net_port_1_speed=NetPortStatusList/NetPortStatus[id='1']/workSpeed
|
||||
- net_port_2_speed=NetPortStatusList/NetPortStatus[id='2']/workSpeed
|
||||
- boot_time=bootTime
|
||||
- device_uptime=deviceUpTime
|
||||
- last_calibration_time=lastCalibrationTime
|
||||
- last_calibration_time_diff=lastCalibrationTimeDiff
|
||||
- avg_upload_time=uploadTimeConsumingList/avgTime
|
||||
- max_upload_time=uploadTimeConsumingList/maxTime
|
||||
- min_upload_time=uploadTimeConsumingList/minTime
|
||||
- last_calibration_mode=lastCalibrationTimeMode
|
||||
- last_calibration_address=lastCalibrationTimeAddress
|
||||
- response_time=responseTime
|
||||
units:
|
||||
- memory_usage=KB->MB
|
||||
- memory_available=KB->MB
|
||||
- cache_size=KB->MB
|
||||
- memoryUsage=KB->MB
|
||||
- memoryAvailable=KB->MB
|
||||
- cacheSize=KB->MB
|
||||
|
||||
@@ -64,8 +64,8 @@ limitations under the License.
|
||||
### 2.2 Document style check
|
||||
|
||||
1. Install `markdownlint-cli2` and run `npm install markdownlint-cli2 --global`
|
||||
2. Run `markdownlint-cli2 "home/**/*.md"` in the project to automatically detect the Markdown file format.
|
||||
3. Run `markdownlint-cli2 --fix "home/**/*.md"` in the project to automatically format the Markdown file format to ensure that all documents meet the specifications.
|
||||
2. Run `markdownlint "home/**/*.md"` in the project to automatically detect the Markdown file format.
|
||||
3. Run `markdownlint --fix "home/**/*.md"` in the project to automatically format the Markdown file format to ensure that all documents meet the specifications.
|
||||
|
||||
Error code description:
|
||||
|
||||
|
||||
@@ -20,11 +20,11 @@ sidebar_label: Download
|
||||
Previous releases of HertzBeat may be affected by security issues, please use the latest one.
|
||||
:::
|
||||
|
||||
| Version | Date | Download | Release |
|
||||
| ------- | ---------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------|
|
||||
| v1.7.0 | 2025.04.02 | [apache-hertzbeat-1.7.0-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz) (Server) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz) (Collector) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.7.0-incubating-src.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz) (Source Code) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz) (Docker Compose) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz.sha512) ) | [note](https://github.com/apache/hertzbeat/releases/tag/v1.7.0) |
|
||||
| v1.6.1 | 2024.10.29 | [apache-hertzbeat-1.6.1-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz) (Server) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz) (Collector) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.1-incubating-src.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz) (Source Code) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz) (Docker Compose) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz.sha512) ) | [note](https://github.com/apache/hertzbeat/releases/tag/v1.6.1) |
|
||||
| v1.6.0 | 2024.06.10 | [apache-hertzbeat-1.6.0-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz) (Server) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz) (Collector) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.0-incubating-src.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz) (Source Code) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz.sha512) ) | [note](https://github.com/apache/hertzbeat/releases/tag/v1.6.0) |
|
||||
| Version | Date | Download | Release Notes |
|
||||
| ------- | ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| v1.7.0 | 2025.04.02 | [apache-hertzbeat-1.7.0-incubating-bin.tar.gz](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz) (HertzBeat) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz) (HertzBeat Collector) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.7.0-incubating-src.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz) (HertzBeat Source) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz) (docker-compose) ( [signature](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz.asc) , [sha512](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz.sha512) ) | [release note](https://github.com/apache/hertzbeat/releases/tag/v1.7.0) |
|
||||
| v1.6.1 | 2024.10.29 | [apache-hertzbeat-1.6.1-incubating-bin.tar.gz](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz) (HertzBeat) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz) (HertzBeat Collector) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.1-incubating-src.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz) (HertzBeat Source) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz) (docker-compose) ( [signature](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz.asc) , [sha512](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz.sha512) ) | [release note](https://github.com/apache/hertzbeat/releases/tag/v1.6.1) |
|
||||
| v1.6.0 | 2024.06.10 | [apache-hertzbeat-1.6.0-incubating-bin.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz) (HertzBeat) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz) (HertzBeat Collector) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.0-incubating-src.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz) (HertzBeat Source) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz.sha512) ) | [release note](https://github.com/apache/hertzbeat/releases/tag/v1.6.0) |
|
||||
|
||||
## Release Docker Image
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
id: alarm_silence
|
||||
title: Alert Silence
|
||||
sidebar_label: Alert Silence
|
||||
keywords: [ Open Source Monitoring System, Alert Silence ]
|
||||
---
|
||||
|
||||
> The alert silence management allows you to configure silence policies to suppress alert notifications during specified time periods, such as during system maintenance or when you don’t want to be disturbed by alerts at night or on weekends. Alert silence rules support both one-time and periodic time periods, and can match specific alerts using labels and alert levels.
|
||||
|
||||
## One-Time Time Period Silence Configuration
|
||||
|
||||
- Silence Strategy Name: A unique name to identify the silence policy;
|
||||
- Match All: Whether to enable this silence policy for all alerts;
|
||||
- Label Match: When "Apply to All" is disabled, you can match alerts to be silenced based on specified labels;
|
||||
- Silence Type: Select "One Time Silence";
|
||||
- Silence Period: After selecting "One Time Silence", the silence period configuration is shown in the following image, which can be configured as needed
|
||||

|
||||
- Enable: Enable or disable the silence policy.
|
||||
|
||||
## Periodic Time Period Silence Configuration
|
||||
|
||||
- Silence Strategy Name: A unique name to identify the silence policy;
|
||||
- Match All: Whether to enable this silence policy for all alerts;
|
||||
- Label Match: When "Apply to All" is disabled, you can match alerts to be silenced based on specified labels;
|
||||
- Silence Type: Select "Periodic Silence";
|
||||
- Choose Date: After selecting "Periodic Silence", you can configure the dates when alerts should be silenced;
|
||||
- Silence Period: After selecting "Periodic Silence", the silence period configuration is shown in the following image, which can be configured as needed (e.g., silencing alerts during weekends)
|
||||

|
||||
- Enable: Enable or disable the silence policy.
|
||||
@@ -1,60 +0,0 @@
|
||||
---
|
||||
id: dahua
|
||||
title: Monitor Dahua Devices
|
||||
sidebar_label: Dahua
|
||||
keywords: [ monitor, dahua ]
|
||||
---
|
||||
|
||||
> Monitor Dahua devices through HTTP interface to collect health data.
|
||||
|
||||
## Configuration
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------- | ----------- |
|
||||
| Host | Target IP/Domain |
|
||||
| Name | Unique monitor name |
|
||||
| Port | Network port (default 80) |
|
||||
| Timeout | Request timeout in ms |
|
||||
| Username | Device username |
|
||||
| Password | Device password |
|
||||
| SSL | Enable HTTPS |
|
||||
| Interval | Collection interval (≥30s) |
|
||||
|
||||
## Metrics
|
||||
|
||||
### Network Info
|
||||
|
||||
- Default Interface
|
||||
- Domain Name
|
||||
- Hostname
|
||||
- eth0 IP Address
|
||||
- eth0 Gateway
|
||||
- eth0 MAC
|
||||
- eth0 Subnet Mask
|
||||
- eth0 MTU
|
||||
- DNS Servers
|
||||
|
||||
### User Info
|
||||
|
||||
- Client Address
|
||||
- Username
|
||||
- Login Type
|
||||
- Login Time
|
||||
|
||||
### NTP Info
|
||||
|
||||
- NTP Server
|
||||
- NTP Port
|
||||
- Sync Interval
|
||||
|
||||
## Implementation
|
||||
|
||||
Access device APIs via:
|
||||
|
||||
1. Network: `/cgi-bin/configManager.cgi?action=getConfig&name=Network`
|
||||
|
||||
2. Users: `/cgi-bin/userManager.cgi?action=getActiveUserInfoAll`
|
||||
|
||||
3. NTP: `/cgi-bin/configManager.cgi?action=getConfig&name=NTP`
|
||||
|
||||
Using Digest Auth and parsing config format responses.
|
||||
@@ -9,7 +9,7 @@ keywords: [Grafana, Historical Dashboard]
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- We recommend using the latest version of Grafana. Earlier versions may not support the exposed API.
|
||||
- The `Grafana` version 8.1.0 or later is installed and running.
|
||||
- The `Grafana` service is started and the account password is configured.
|
||||
- The `HertzBeat` service is started and the `VictoriaMetrics` time-series database is configured (note: the `VictoriaMetrics` data source is required).
|
||||
|
||||
@@ -22,10 +22,6 @@ keywords: [Grafana, Historical Dashboard]
|
||||
ref: <https://grafana.com/blog/2023/10/10/how-to-embed-grafana-dashboards-into-web-applications/>
|
||||
In the `Grafana` configuration file `grafana.ini`, set the `allow_embedding = true`.
|
||||
In the `Grafana` configuration file `grafana.ini`, set the `[auth.anonymous]` option to `true`.
|
||||
Or run `Grafana` with the following command via `docker`:
|
||||
|
||||
```bash
|
||||
docker run -itd --name grafana -p 3000:3000 -e "GF_AUTH_PROXY_ENABLED=true" -e "GF_AUTH_ANONYMOUS_ENABLED=true" -e "GF_SECURITY_ALLOW_EMBEDDING=true" grafana/grafana:latest
|
||||
|
||||
```ini
|
||||
allow_embedding = true
|
||||
|
||||
@@ -28,7 +28,7 @@ management:
|
||||
web:
|
||||
exposure:
|
||||
include: '*'
|
||||
enabled-by-default: true
|
||||
enabled-by-default: on
|
||||
```
|
||||
|
||||
*Note: If your project also introduces authentication related dependencies, such as springboot security, the interfaces exposed by SpringBoot Actor may be intercepted. In this case, you need to manually release these interfaces. Taking springboot security as an example, you should add the following code to the Security Configuration class:*
|
||||
|
||||
@@ -28,7 +28,7 @@ management:
|
||||
web:
|
||||
exposure:
|
||||
include: '*'
|
||||
enabled-by-default: true
|
||||
enabled-by-default: on
|
||||
```
|
||||
|
||||
*Note: If your project also introduces authentication related dependencies, such as springboot security, the interfaces exposed by SpringBoot Actor may be intercepted. In this case, you need to manually release these interfaces. Taking springboot security as an example, you should add the following code to the Security Configuration class:*
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
id: uniview
|
||||
title: Monitor Uniview Devices
|
||||
sidebar_label: Uniview
|
||||
keywords: [ monitor, uniview ]
|
||||
---
|
||||
|
||||
> Monitor Uniview devices through HTTP interface.
|
||||
|
||||
## Configuration
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------- | ----------- |
|
||||
| Host | Device IP/Domain |
|
||||
| Name | Unique identifier |
|
||||
| Port | Default 80 |
|
||||
| Timeout | Milliseconds |
|
||||
| Username | Auth username |
|
||||
| Password | Auth password |
|
||||
| SSL | HTTPS Enable |
|
||||
| Interval | ≥30 seconds |
|
||||
|
||||
## Metrics
|
||||
|
||||
### System Info
|
||||
|
||||
- Device Name
|
||||
- Serial Number
|
||||
- Firmware Version
|
||||
- Device Model
|
||||
|
||||
### NTP Info
|
||||
|
||||
- NTP Server IP
|
||||
- NTP Port
|
||||
- Sync Interval
|
||||
- NTP Status
|
||||
|
||||
## Implementation
|
||||
|
||||
Access device APIs:
|
||||
|
||||
1. System: `/LAPI/V1.0/System/DeviceInfo`
|
||||
|
||||
2. NTP: `/LAPI/V1.0/System/Time/NTP`
|
||||
|
||||
Using Digest Authentication and parsing JSON responses.
|
||||
@@ -1,70 +0,0 @@
|
||||
---
|
||||
title: 从 Committer 到 PMC:在 Apache HertzBeat 的持续成长与蜕变之旅
|
||||
author: zhangshenghang
|
||||
author_title: zhangshenghang
|
||||
author_url: https://github.com/zhangshenghang
|
||||
author_image_url: https://avatars.githubusercontent.com/u/29418975?s=400&v=4
|
||||
tags: [opensource, practice]
|
||||
keywords: [open source monitoring system, alerting system]
|
||||
---
|
||||
|
||||
## 从 Committer 到 PMC:角色的转变与成长
|
||||
|
||||
一年前,当我收到成为 Apache HertzBeat **Committer** 的通知时,那种喜悦和使命感至今记忆犹新。那时的我,更多是专注于具体的技术实现和功能开发。而如今,被邀请加入 **PMC**,意味着我需要以更全局的视角来看待项目的发展,这既对我参与开源的认可,更是对未来责任的召唤。
|
||||
|
||||
### 深入参与:Committer 时期的积累
|
||||
|
||||
成为 Committer 后,我的日常工作发生了显著变化:
|
||||
|
||||
- **代码审查成为常态**:从最初的简单 PR 审核,到后来能够系统性评估代码质量、架构合理性以及与项目整体方向的一致性。
|
||||
- **社区协作更加紧密**:我开始定期参与社区例会,协助新贡献者解决问题,甚至主导某些功能的开发与落地。
|
||||
- **技术决策的参与**:在监控协议支持、存储引擎优化等关键议题上,我开始提出自己的见解,并与核心团队共同制定实施方案。
|
||||
|
||||
这段时间让我深刻体会到,**开源项目的生命力不仅在于代码,更在于社区的协作与信任**。每一次代码合并、每一次问题讨论,都是对项目方向的微小调整,而 Committer 的角色让我有机会参与其中。
|
||||
|
||||
## 成为 PMC:责任与挑战的升级
|
||||
|
||||
PMC 的职责远超代码层面,它要求成员对项目的**技术方向、社区治理、长期发展**有更深入的思考。当我收到 PMC 邀请时,既感到兴奋,也意识到需要迎接新的挑战:
|
||||
|
||||
### 1. **技术战略的参与**
|
||||
|
||||
作为 PMC,我需要与其他成员共同规划 HertzBeat 的长期路线图。例如:
|
||||
|
||||
- **性能优化**:面对大规模监控场景,如何优化存储和查询效率。
|
||||
- **可扩展性增强**:如何设计更灵活的插件机制,方便社区贡献新的监控类型。
|
||||
|
||||
这些议题不再是单纯的代码实现,而是涉及技术选型、社区资源分配甚至项目定位的深层次讨论。
|
||||
|
||||
### 2. **社区治理与健康**
|
||||
|
||||
PMC 需要关注社区的长期健康发展,包括:
|
||||
|
||||
- **贡献者体验**:如何优化文档、降低新人的参与门槛。
|
||||
- **社区文化**:确保讨论氛围友好,冲突能够得到妥善解决。
|
||||
- **可持续发展**:激励长期贡献者,同时吸引新鲜血液。
|
||||
|
||||
## 个人成长:技能与心态的蜕变
|
||||
|
||||
这一年的经历让我在多个维度得到提升:
|
||||
|
||||
- **技术广度**:从专注具体功能到理解分布式监控系统的整体架构。
|
||||
- **软技能**:学会如何有效沟通、协调不同意见,推动社区共识。
|
||||
- **项目管理**:理解开源项目的运作模式,平衡理想与现实约束。
|
||||
|
||||
最深刻的感悟是:**在开源社区,技术能力只是基础,真正的价值在于能否通过协作创造大于个人的成果**。
|
||||
|
||||
## 未来展望:与 HertzBeat 共同前行
|
||||
|
||||
作为新晋 PMC,我对未来有几个重点方向:
|
||||
|
||||
1. **推动 HertzBeat 成为云原生监控领域的重要选择**,特别是在轻量级、易用性方面形成差异化优势。
|
||||
2. **建设更活跃的贡献者社区**,通过导师计划、定期活动等方式培养核心贡献者。
|
||||
3. **完善项目治理流程**,使决策更透明,参与更顺畅。
|
||||
|
||||
## 致谢与共勉
|
||||
|
||||
特别感谢 **Tom** 的指导,以及所有社区伙伴的支持。Apache 之道强调"社区重于代码",这一理念已深深影响我的工作方式。
|
||||
|
||||
最后,想对正在阅读的你分享:**开源是一场持久而温暖的旅程,不必追求速成,只需持续贡献,收获自会水到渠成**。期待在 HertzBeat 社区见到更多志同道合的朋友!
|
||||
|
||||
(正如我们常说的:**"参与开源是为了让技术更美好,而不是让生活更忙碌"** —— 共勉 😊)
|
||||
@@ -1,316 +0,0 @@
|
||||
---
|
||||
title: Apache Hertzbeat 1.7.0 发布公告
|
||||
author: tomsun28
|
||||
author_title: tomsun28
|
||||
author_url: https://github.com/zhangshenghang
|
||||
author_image_url: https://avatars.githubusercontent.com/u/24788200?s=400&v=4
|
||||
tags: [opensource, release]
|
||||
keywords: [open source monitoring system, alerting system, Hertzbeat, release]
|
||||
---
|
||||
|
||||
亲爱的社区小伙伴们,
|
||||
|
||||
我们很高兴地宣布 Apache Hertzbeat 1.7.0 版本正式发布!
|
||||
|
||||
## Downloads and Documentation
|
||||
|
||||
- **Apache Hertzbeat 1.7.0 Download Link**: <https://hertzbeat.apache.org/zh-cn/docs/download>
|
||||
- **Apache Hertzbeat Documentation**: <https://hertzbeat.apache.org/zh-cn/docs/>
|
||||
|
||||
## Major Updates
|
||||
|
||||
### New Features and Enhancements
|
||||
|
||||
- **自定义刷新间隔**:支持为每组指标设置自定义刷新间隔,满足不同场景下的监控需求。
|
||||
- **任务自动发现**:通过 http_sd 支持自动发现任务,提升了任务的灵活性和可管理性。
|
||||
- **新的告警模块**:支持实时阈值和计划阈值,分组收敛,告警抑制,告警静默等。
|
||||
- **Kafka 监控增强**:优化了 Kafka 监控功能,包括改进 Kafka 图表显示、添加 Kafka 消费者组监控指标等。
|
||||
- **支持多种协议和监控类型**:新增了对 Plc 协议监控的支持,进一步丰富了监控范围。
|
||||
- **报警功能增强**:支持通过 HTTP API 替换腾讯云 SDK 发送短信通知,增强了报警通知的灵活性和扩展性。同时,还支持了多查询表达式阈值报警、周期性报警阈值等功能。
|
||||
- **多语言支持**:新增了日语、繁体中文等多语言支持,提升了国际化体验。
|
||||
- **监控功能增强**:支持 StarRocks FE 等多种类型的监控,为用户提供了更多的监控选项。
|
||||
- **E2E 测试增强**:新增了多个 E2E 测试代码,包括 Kafka、SSH、API 等,提升了测试覆盖率和稳定性。
|
||||
- **数据存储优化**:更新了 VictoriaMetrics 和 Greptime 存储,提升了数据存储的性能和稳定性。
|
||||
- **更多的新功能特性**
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **修复 Docker 构建错误**:修复了 collector Docker 构建错误,确保了 Docker 镜像的正常构建。
|
||||
- **修复 Linux 进程监控问题**:修复了 Linux 进程监控进程异常退出且无警告的问题,提升了监控的稳定性。
|
||||
- **修复 Windows 中文编码问题**:修复了 Windows 中文编码问题,确保了在 Windows 环境下的正常运行。
|
||||
- **修复 Grafana 配置问题**:修复了 Grafana 配置相关的问题,提升了 Grafana 的集成体验。
|
||||
- **修复 Windows 指标配置问题**:更新了 Windows 指标 yml 文件,解决了相关问题。
|
||||
- **修复 flyway 位置检测问题**:修复了 flyway 位置无法自动检测供应商的问题,提升了数据库迁移的可靠性。
|
||||
- **修复数据存储问题**:修复了数据存储相关的问题,包括修复了 Prometheus 数据存储问题、修复了数据存储更新逻辑问题等,确保了数据的准确性和完整性。
|
||||
- **修复报警通知问题**:修复了报警通知相关的问题,包括修复了报警通知重复发送问题、修复了报警通知配置问题等,提升了报警通知的准确性和可靠性。
|
||||
- **修复监控状态更新问题**:修复了监控状态未更新的问题,确保了监控状态的实时性和准确性。
|
||||
- **和其它的BUG修复**
|
||||
|
||||
### Refactoring and Optimization
|
||||
|
||||
- **内存结构优化**:使用Apache Arrow作为数据内存数据结构,提升了内存使用效率和性能。
|
||||
- **代码规范优化**:根据代码规范对代码进行了优化,提升了代码质量和可读性。
|
||||
- **缓存优化**:新增了基于 Singleton 模式的 LRU 本地缓存,提升了缓存的效率和性能。
|
||||
- **内存泄漏修复**:修复了潜在的内存泄漏问题,提升了系统的稳定性和可靠性。
|
||||
- **和其它的优化**
|
||||
|
||||
### Documentation Enhancements
|
||||
|
||||
- **更新部署文档**:更新了部署文档,提供了更详细的部署指导。
|
||||
- **更新安全模型文档**:更新了安全模型文档。
|
||||
- **更新 Grafana 配置文档**:更新了 Grafana 配置方法和添加暴露 URL 的文档,提升了用户体验。
|
||||
- **更新 Windows 监控文档**:更新了 Windows 系统监控文档,提供了更详细的监控指导。
|
||||
- **更新监控指标文档**:更新了多个监控指标的文档,包括 Kafka、Linux 进程等,提升了文档的准确性和完整性。
|
||||
- **更新开发者文档**:新增了自定义开发采集器的文档,方便开发者进行二次开发。
|
||||
- **更多的文档更新**
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
感谢以下社区成员的共同努力:
|
||||
|
||||
> @ghyghoo8 @kerwin612 @pjfanning @helei1030 @shinestare @simonsigre @myangle1120 @MasamiYui @Craaaaazy77 @tomsun28 @Aias00 @zhangshenghang @wanhao23 @zqr10159 @LiuTianyou
|
||||
> @hasimmollah @lixiaobaivv @LL-LIN @JuJinPark @ponfee @starryCoder @NikhilMurugesan @leo-934 @Rancho-7 @MonsterChenzhuo @zuobiao-zhou @pwallk @bigcyy @ZY945 @sarthakeash
|
||||
> @All-The-Best-for @TJxiaobao @yyahang @yunfan24 @a-little-fool @yasminvo @Yanshuming1 @ayu-v0 @jonasHanhan @Calvin979 @Suvrat1629 @Vedant7789 @notbugggg @lctking @po-168 @doveLin0818
|
||||
|
||||
## What's Changed
|
||||
|
||||
```markdown
|
||||
* [doc](download): update for v1.6.1 release by @zqr10159 in https://github.com/apache/hertzbeat/pull/2794
|
||||
* [Doc] improve website by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2795
|
||||
* [doc] update deploy doc by @tomsun28 in https://github.com/apache/hertzbeat/pull/2796
|
||||
* [Task][OSPP] HertzBeat Official Template Marketplace by @All-The-Best-for in https://github.com/apache/hertzbeat/pull/2641
|
||||
* [improve]:Improve the way Ai is entered and requested by @Yanshuming1 in https://github.com/apache/hertzbeat/pull/2762
|
||||
* [bugfix] fix collector docker build error by @tomsun28 in https://github.com/apache/hertzbeat/pull/2799
|
||||
* [fix]Remove the duplicate declaration of commons-net by @shinestare in https://github.com/apache/hertzbeat/pull/2801
|
||||
* [doc] update new contributors by @tomsun28 in https://github.com/apache/hertzbeat/pull/2802
|
||||
* [Improve] Improve module name by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2805
|
||||
* [improve] code according to code specifications by @po-168 in https://github.com/apache/hertzbeat/pull/2809
|
||||
* [feature] Support custom refresh intervals for each group of metrics by @zuobiao-zhou in https://github.com/apache/hertzbeat/pull/2718
|
||||
* [improve] Fix error links caused by module name changes. by @zuobiao-zhou in https://github.com/apache/hertzbeat/pull/2807
|
||||
* [fix] fix the Linux process monitoring process exits abnormally without warning by @LiuTianyou in https://github.com/apache/hertzbeat/pull/2810
|
||||
* [Doc] Add blog by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2812
|
||||
* [Improve] improve kafka monitor by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2813
|
||||
* [Feature] add e2e code by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2811
|
||||
* [improve] modify e2e test by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2814
|
||||
* [improve] update windows metrics yml by @tomsun28 in https://github.com/apache/hertzbeat/pull/2816
|
||||
* [improve] update grafana auth method and add expose url by @tomsun28 in https://github.com/apache/hertzbeat/pull/2818
|
||||
* Fixed the omissions in #2805 by @kerwin612 in https://github.com/apache/hertzbeat/pull/2826
|
||||
* [refactor] change name from http_sd to registry by @Calvin979 in https://github.com/apache/hertzbeat/pull/2827
|
||||
* [fix]fix windows chinese encoding by @starryCoder in https://github.com/apache/hertzbeat/pull/2831
|
||||
* [doc] Added custom development collector documentation by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2833
|
||||
* [improve] update and fix template yml priority by @tomsun28 in https://github.com/apache/hertzbeat/pull/2829
|
||||
* [chore] Delete redundant Spaces by @ayu-v0 in https://github.com/apache/hertzbeat/pull/2834
|
||||
* [doc]: update sidebar category label and plugin documentation by @zqr10159 in https://github.com/apache/hertzbeat/pull/2837
|
||||
* [fix] bugfix flyway location can not auto detect vendor when not h2 by @tomsun28 in https://github.com/apache/hertzbeat/pull/2835
|
||||
* [improve] update victoriametrics and greptime store by @tomsun28 in https://github.com/apache/hertzbeat/pull/2836
|
||||
* [feature] support managing tasks by using http_sd by @Calvin979 in https://github.com/apache/hertzbeat/pull/2830
|
||||
* [fix] auto generated by protocol buffer by @tomsun28 in https://github.com/apache/hertzbeat/pull/2842
|
||||
* [Feature] Add ssh e2e code by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2843
|
||||
* [bugfix]Fix wrong app name by @zqr10159 in https://github.com/apache/hertzbeat/pull/2845
|
||||
* [doc] add security model doc and update contributors by @tomsun28 in https://github.com/apache/hertzbeat/pull/2846
|
||||
* [improve] improve dependency by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2855
|
||||
* [doc] update security doc and some by @tomsun28 in https://github.com/apache/hertzbeat/pull/2856
|
||||
* A bug fix by @TJxiaobao in https://github.com/apache/hertzbeat/pull/2853
|
||||
* [doc] Add ',' separator between monitoring types by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2865
|
||||
* [doc]improve-windows-monitoring:Update Windows system monitoring docu… by @starryCoder in https://github.com/apache/hertzbeat/pull/2869
|
||||
* [Optimize] Add a reminder about potential collection issues caused by the Docker deployment method of collector. by @zuobiao-zhou in https://github.com/apache/hertzbeat/pull/2844
|
||||
* [improve]Add more helpful messages when adding a Kafka monitor by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2876
|
||||
* modified:add a small change. by @TJxiaobao in https://github.com/apache/hertzbeat/pull/2878
|
||||
* [Fix] fix clickhouse monitor by @LiuTianyou in https://github.com/apache/hertzbeat/pull/2874
|
||||
* [chore] Delete the redundant else by @ayu-v0 in https://github.com/apache/hertzbeat/pull/2881
|
||||
* [improve]Remove stack property from line charts by @zqr10159 in https://github.com/apache/hertzbeat/pull/2888
|
||||
* [improve]improve linux process by @LiuTianyou in https://github.com/apache/hertzbeat/pull/2889
|
||||
* [Improve]Beautify Charts by @zqr10159 in https://github.com/apache/hertzbeat/pull/2891
|
||||
* [doc] Add more hints when users are switching data source. by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2880
|
||||
* [collector]feature:Add monitoring metrics for consumer groups in Kafka client by @doveLin0818 in https://github.com/apache/hertzbeat/pull/2887
|
||||
* [Improve] Improve Kafka chart display by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2894
|
||||
* [collector]bugfix:fix the issue of reusing the `adminClient` in the Kafka client. by @doveLin0818 in https://github.com/apache/hertzbeat/pull/2895
|
||||
* [improve]add Plc protocol , Modbus monitor by @ZY945 in https://github.com/apache/hertzbeat/pull/2850
|
||||
* [Improve] add notification when port number changes automatically due to HTTPS toggle.(#2779) by @yunfan24 in https://github.com/apache/hertzbeat/pull/2896
|
||||
* [feature] integrate with Apache Arrow by @Calvin979 in https://github.com/apache/hertzbeat/pull/2864
|
||||
* [Doc] update doc by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2900
|
||||
* [Imporve] Support Kafka internal topic configuration by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2901
|
||||
* [fix](flink): update calculate metrics definitions by @zqr10159 in https://github.com/apache/hertzbeat/pull/2905
|
||||
* [feature] Add a new Singleton-pattern-based LRU local cache by @doveLin0818 in https://github.com/apache/hertzbeat/pull/2907
|
||||
* add an online parser for prometheus. by @leo-934 in https://github.com/apache/hertzbeat/pull/2851
|
||||
* [Improve] Improve OBS by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2909
|
||||
* [improve] fix import of CollectRep by @Calvin979 in https://github.com/apache/hertzbeat/pull/2910
|
||||
* [feature](web-app): Add Alarm Voice Alerts by @zqr10159 in https://github.com/apache/hertzbeat/pull/2906
|
||||
* [bugfix] Fix the bug where canceling an edit on a record still updates the page values. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2911
|
||||
* [bugfix] Fix docker container name unable to display problem by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2914
|
||||
* [improve] Optimize CacheService and add relevant unit test by @lctking in https://github.com/apache/hertzbeat/pull/2912
|
||||
* [improve] Add required field indicators and form validation prompts for convergence strategies and silent strategies in the form. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2913
|
||||
* [Feture]Add docker e2e test by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2916
|
||||
* [bugfix]: fix setColumns method in CollectRep class by @zqr10159 in https://github.com/apache/hertzbeat/pull/2918
|
||||
* [improve](warehouse): replace empty json object key with empty string by @zqr10159 in https://github.com/apache/hertzbeat/pull/2919
|
||||
* [bugfix] Bug fix for alarm voice. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2920
|
||||
* Update app-windows_script.yml by @simonsigre in https://github.com/apache/hertzbeat/pull/2922
|
||||
* [bugfix] Fixed the 'java.lang.UnsupportedOperationException' exception caused by getCurrentMetricsData by @lixiaobaivv in https://github.com/apache/hertzbeat/pull/2923
|
||||
* [Improve] Optimize the e2e code structure by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2926
|
||||
* [improve] optimize website navbar css(#2928) by @ponfee in https://github.com/apache/hertzbeat/pull/2929
|
||||
* [feature] Adding CPU Temperature Check Into Default Ubuntu Checks by @simonsigre in https://github.com/apache/hertzbeat/pull/2930
|
||||
* [improve] Improve the synchronization of the mute status. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2927
|
||||
* [bugfix] Corrected case 'DashBoard' is a lower case 'B' by @simonsigre in https://github.com/apache/hertzbeat/pull/2935
|
||||
* [bugfix] Modify the doris_be.md document into an English version by @Craaaaazy77 in https://github.com/apache/hertzbeat/pull/2936
|
||||
* [improve] Refactor and Split the Message Notification Component. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2924
|
||||
* [home] updated navbar css #2928 by @Vedant7789 in https://github.com/apache/hertzbeat/pull/2934
|
||||
* [Improve]Improve e2e code by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2945
|
||||
* [refactor] refactoring methods replaceCryPlaceholder and replaceSmilingPlace by @hasimmollah in https://github.com/apache/hertzbeat/pull/2832
|
||||
* [alarm] refactor new alarm by @tomsun28 in https://github.com/apache/hertzbeat/pull/2902
|
||||
* [bugfix](db): optimize column update. by @zqr10159 in https://github.com/apache/hertzbeat/pull/2947
|
||||
* [doc] Add Supported MySQL Versions. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2949
|
||||
* [Feature] Support customized JMX monitoring through the Factory Pattern. by @doveLin0818 in https://github.com/apache/hertzbeat/pull/2932
|
||||
* [Improve]Modify Chinese comments by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2950
|
||||
* [improve] fix some alarm relate bug, update alarm center ui by @tomsun28 in https://github.com/apache/hertzbeat/pull/2951
|
||||
* 【Improve】adjust log level from INFO to WARN. by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2952
|
||||
* [Doc]:Add English version of documentation for Kafka Consumer Detail by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2953
|
||||
* [Imporve] Improve Huaweicloud by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2954
|
||||
* [improve] update alarm inhibit rule and alarm ui by @tomsun28 in https://github.com/apache/hertzbeat/pull/2957
|
||||
* [bufix] fix collector job scheduler error by @tomsun28 in https://github.com/apache/hertzbeat/pull/2966
|
||||
* [Improve]:Standardize Kafka metric naming by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2961
|
||||
* [BUG] "Advanced Settings" is all white in dark mode by @Suvrat1629 in https://github.com/apache/hertzbeat/pull/2965
|
||||
* [Improve] add no popup option after next login by @LiuTianyou in https://github.com/apache/hertzbeat/pull/2969
|
||||
* [feature] replace googletagmanager to matomo by @Aias00 in https://github.com/apache/hertzbeat/pull/2877
|
||||
* Fix the search functionality issue. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2970
|
||||
* [bugfix](warehouse): add metrics data update logic in memory storage by @zqr10159 in https://github.com/apache/hertzbeat/pull/2973
|
||||
* [Improve] Add more test cases for Kafka junit tests by @Rancho-7 in https://github.com/apache/hertzbeat/pull/2976
|
||||
* [feature] alert integration extern source by @tomsun28 in https://github.com/apache/hertzbeat/pull/2978
|
||||
* [bugfix] Fix NullPointerException by @ayu-v0 in https://github.com/apache/hertzbeat/pull/2849
|
||||
* [webapp] key-value-input component hover effect fixed by @ghyghoo8 in https://github.com/apache/hertzbeat/pull/2972
|
||||
* [bugfix] fix alert integration extern source bug by @tomsun28 in https://github.com/apache/hertzbeat/pull/2979
|
||||
* [Feature] Support copy monitoring by @zhangshenghang in https://github.com/apache/hertzbeat/pull/2981
|
||||
* [bugfix] fix hbase dashboard display anomalies and turn on HTTPS by @MonsterChenzhuo in https://github.com/apache/hertzbeat/pull/2980
|
||||
* [improve] update i18n json stru and update search ui by @tomsun28 in https://github.com/apache/hertzbeat/pull/2986
|
||||
* [MINOR UPDATE] improve xml parsing code by @pjfanning in https://github.com/apache/hertzbeat/pull/2988
|
||||
* [docs]doc:Added spark Chinese documents and changed the original spar… by @helei1030 in https://github.com/apache/hertzbeat/pull/2987
|
||||
* [type:improve] fix dependencies vulnerabilites by @Aias00 in https://github.com/apache/hertzbeat/pull/2989
|
||||
* [feature] Add privateKey passphrase config for linux monitor by @MasamiYui in https://github.com/apache/hertzbeat/pull/2982
|
||||
* [type:fix] remove matomo ip by @Aias00 in https://github.com/apache/hertzbeat/pull/2990
|
||||
* [feature] Added multilingual defaults for forms by @wanhao23 in https://github.com/apache/hertzbeat/pull/2991
|
||||
* [Improve]Add Copy token button by @zqr10159 in https://github.com/apache/hertzbeat/pull/2992
|
||||
* [MINOR UPDATE] close HttpResponse in HttpCollectImpl by @pjfanning in https://github.com/apache/hertzbeat/pull/2993
|
||||
* [MINOR UPDATE] close http response in PrometheusAutoCollectImpl by @pjfanning in https://github.com/apache/hertzbeat/pull/2994
|
||||
* [MINOR UPDATE] fix more instances of unclosed Http Responses by @pjfanning in https://github.com/apache/hertzbeat/pull/2995
|
||||
* [bugfix] fix wrong http user-agent content by @tomsun28 in https://github.com/apache/hertzbeat/pull/2996
|
||||
* [feature] Support monitoring for StarRocks FE and StarRocks BE. by @yunfan24 in https://github.com/apache/hertzbeat/pull/2997
|
||||
* [MINOR UPDATE] refactor base64 code to simplify the conversions by @pjfanning in https://github.com/apache/hertzbeat/pull/2999
|
||||
* [webapp] bugfix edit monitor http query params error by @tomsun28 in https://github.com/apache/hertzbeat/pull/3001
|
||||
* [feature] Complete multiple languages by @wanhao23 in https://github.com/apache/hertzbeat/pull/3002
|
||||
* [feature] Add alerter_zh_TW.properties configuration to adapt to mult… by @jonasHanhan in https://github.com/apache/hertzbeat/pull/3004
|
||||
* [bugfix] fix some unit tests that failed to run by @NikhilMurugesan in https://github.com/apache/hertzbeat/pull/3007
|
||||
* [feature](alert): implement drag-and-drop functionality for alert templates by @zqr10159 in https://github.com/apache/hertzbeat/pull/3005
|
||||
* [improve] Freeze the 'Operate' column on the right side of the list. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3009
|
||||
* [MINOR UPDATE] always specify the char encoding in getBytes by @pjfanning in https://github.com/apache/hertzbeat/pull/3011
|
||||
* [bugfix]Fix page not found by @zqr10159 in https://github.com/apache/hertzbeat/pull/3014
|
||||
* [bugfix] Modify mask issue by @myangle1120 in https://github.com/apache/hertzbeat/pull/3018
|
||||
* [issue-2998] remove invalid check in isValidLabelValue by @pjfanning in https://github.com/apache/hertzbeat/pull/3015
|
||||
* [MINOR UPDATE] Use Encode to string when possible (Base64) by @pjfanning in https://github.com/apache/hertzbeat/pull/3016
|
||||
* [Improve] update english doc by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3028
|
||||
* [Feature] Add API e2e code by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3029
|
||||
* [doc] update new contributor wall by @tomsun28 in https://github.com/apache/hertzbeat/pull/3025
|
||||
* OnlineParserTest doesn't test anything by @pjfanning in https://github.com/apache/hertzbeat/pull/3010
|
||||
* [feature] periodic alert threshold by @tomsun28 in https://github.com/apache/hertzbeat/pull/3024
|
||||
* [bugfix] fix and enable some unit tests. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3031
|
||||
* [feature] Add pagination and name-based search functionality in notification module by @yunfan24 in https://github.com/apache/hertzbeat/pull/2948
|
||||
* [bugfix] Fixed the bug in the threshold rules search box. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3034
|
||||
* [improve] Replaced hardcoded text with internationalized string. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3035
|
||||
* [update] upgrade actions/upload-artifact to v4 by @yunfan24 in https://github.com/apache/hertzbeat/pull/3046
|
||||
* [improve] Search ignores case sensitivity. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3042
|
||||
* Add sse support for alert center, no need to manually refresh the page, add slide-in animation by @zqr10159 in https://github.com/apache/hertzbeat/pull/3051
|
||||
* [alert] support multi query expr threshold by @tomsun28 in https://github.com/apache/hertzbeat/pull/3054
|
||||
* [improve](alert-center): enhance alert card animations and interactions by @zqr10159 in https://github.com/apache/hertzbeat/pull/3055
|
||||
* [improve] update theme ui color by @tomsun28 in https://github.com/apache/hertzbeat/pull/3057
|
||||
* [bugfix] Fix the issue where the monitoring status is not updated. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3056
|
||||
* [bugfix]style(alert-center): enhance 3D transformation and z-index layers by @zqr10159 in https://github.com/apache/hertzbeat/pull/3059
|
||||
* [Feature]Add zookeeper e2e code by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3030
|
||||
* [feature] Add Sftp config for monitor by @MasamiYui in https://github.com/apache/hertzbeat/pull/3038
|
||||
* [feature] Add Japanese by @wanhao23 in https://github.com/apache/hertzbeat/pull/3013
|
||||
* [bugfix] fix singleton not support remove, search id error, audio fetch 401 by @tomsun28 in https://github.com/apache/hertzbeat/pull/3062
|
||||
* [API DOC] Change Swagger description by @pwallk in https://github.com/apache/hertzbeat/pull/3061
|
||||
* [webapp] update ui theme by @tomsun28 in https://github.com/apache/hertzbeat/pull/3064
|
||||
* [feature] Support SSH Tunnel by @pwallk in https://github.com/apache/hertzbeat/pull/3060
|
||||
* [improve] Complete the missing labels in the i18n file. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3065
|
||||
* [Feature]Add Chinese check by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3066
|
||||
* [improve] Refactor SMS sending and replace Tencent Cloud SDK with HTTP API. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3063
|
||||
* [Bugfix] fix when the monitor is modified, the status is erroneously changed by @pwallk in https://github.com/apache/hertzbeat/pull/3067
|
||||
* [improve](web-app): update monitor chart configuration and springboot GreptimeDB version by @zqr10159 in https://github.com/apache/hertzbeat/pull/3071
|
||||
* [doc] Update the SMS configuration document. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3073
|
||||
* [feature] SMS notification supports unisms. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3077
|
||||
* [webapp] update and fix alert ui when theme dark by @tomsun28 in https://github.com/apache/hertzbeat/pull/3082
|
||||
* [improve] Improve and unify the search. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3085
|
||||
* [feature] supports alibaba SMS. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3084
|
||||
* [improve] optimize kafka collect test by @Rancho-7 in https://github.com/apache/hertzbeat/pull/3093
|
||||
* correct home's new_committer_process by @a-little-fool in https://github.com/apache/hertzbeat/pull/3094
|
||||
* [bugfix] kafka client detect error by @Rancho-7 in https://github.com/apache/hertzbeat/pull/3088
|
||||
* [Doc]Improve openai doc by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3097
|
||||
* [Improve] Message notification prompt optimization by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3095
|
||||
* [webapp] fix web oom crash when backend api can not access by @tomsun28 in https://github.com/apache/hertzbeat/pull/3100
|
||||
* [Feature] Add deepseek Api Monitor by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3096
|
||||
* feat/adding-ptBR-translation by @yasminvo in https://github.com/apache/hertzbeat/pull/3098
|
||||
* [bugfix] fix alert sse illegal state exception by @tomsun28 in https://github.com/apache/hertzbeat/pull/3106
|
||||
* [bugfix] Fix exception thrown when searching for CollectRep.Field in the list by @JuJinPark in https://github.com/apache/hertzbeat/pull/3109
|
||||
* [type: fix] #3090 garbled characters by @notbugggg in https://github.com/apache/hertzbeat/pull/3113
|
||||
* [doc]fix link by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3123
|
||||
* [doc] Add GSOC doc by @zhangshenghang in https://github.com/apache/hertzbeat/pull/3122
|
||||
* [doc] Add alibaba SMS and unisms documentation. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3114
|
||||
* [improve] support reuse jdbc connection switch by @tomsun28 in https://github.com/apache/hertzbeat/pull/3101
|
||||
* [webapp] fix monitor define param wrong placeholder tip by @tomsun28 in https://github.com/apache/hertzbeat/pull/3118
|
||||
* [bugfix] Fix swagger opening exception that Failed to load API definition. (#3127) by @yyahang in https://github.com/apache/hertzbeat/pull/3129
|
||||
* [doc] welcome new committer and contributor by @tomsun28 in https://github.com/apache/hertzbeat/pull/3132
|
||||
* [feature] add smslocal sms notification by @a-little-fool in https://github.com/apache/hertzbeat/pull/3135
|
||||
* [improve] Optimize the progress display of monitoring imports by @MasamiYui in https://github.com/apache/hertzbeat/pull/3120
|
||||
* [improve] fix potential memory leakage and content length issues. by @tomsun28 in https://github.com/apache/hertzbeat/pull/3128
|
||||
* [bugfix] fix overflow arrow buffer index by @tomsun28 in https://github.com/apache/hertzbeat/pull/3137
|
||||
* [improve] improve plugin upload by @LiuTianyou in https://github.com/apache/hertzbeat/pull/3139
|
||||
* [doc] Add new committer blog by @yunfan24 in https://github.com/apache/hertzbeat/pull/3140
|
||||
* Configuring gitpod with java by @kerwin612 in https://github.com/apache/hertzbeat/pull/3141
|
||||
* Fix the issue of the empty dropdown menu on the Kanban board page. by @kerwin612 in https://github.com/apache/hertzbeat/pull/3142
|
||||
* [feature] Add AWS sms client by @JuJinPark in https://github.com/apache/hertzbeat/pull/3134
|
||||
* [feature] Support skywalking alert source by @MasamiYui in https://github.com/apache/hertzbeat/pull/3144
|
||||
* [feature] support SSH proxy jump connections by @LL-LIN in https://github.com/apache/hertzbeat/pull/3138
|
||||
* [improve] support bind metrics label and others into alert by @tomsun28 in https://github.com/apache/hertzbeat/pull/3146
|
||||
* [bugfix] Fixed #3112, disappear left menu tree item when restart service by @notbugggg in https://github.com/apache/hertzbeat/pull/3116
|
||||
* [bugfix] fix collect dispatch error by @tomsun28 in https://github.com/apache/hertzbeat/pull/3150
|
||||
* [improve] Merge SMS configuration class. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3148
|
||||
* [webapp] fix less style file over max build error by @tomsun28 in https://github.com/apache/hertzbeat/pull/3151
|
||||
* [bugfix] fix nightly docker build github action by @tomsun28 in https://github.com/apache/hertzbeat/pull/3153
|
||||
* [feature] Supports sending messages to a specific Telegram group topic.(#3079) by @bigcyy in https://github.com/apache/hertzbeat/pull/3143
|
||||
* Abstract Redundant Input Components into ConfigurableFieldComponent for Unified Management by @kerwin612 in https://github.com/apache/hertzbeat/pull/3152
|
||||
* [feature] Support TencentCloud alert source by @bigcyy in https://github.com/apache/hertzbeat/pull/3149
|
||||
* [bugfix]: fix incomplete class documentation in AppServiceImpl by @bigcyy in https://github.com/apache/hertzbeat/pull/3162
|
||||
* [bugfix] Fix http header being incorrectly encoded. by @yunfan24 in https://github.com/apache/hertzbeat/pull/3108
|
||||
* [bugfix] retain sorting state after monitor list auto-refresh by @LL-LIN in https://github.com/apache/hertzbeat/pull/3156
|
||||
* [feature] add twilio sms client support by @sarthakeash in https://github.com/apache/hertzbeat/pull/3159
|
||||
* [doc] Add alert integration japanese i18 by @MasamiYui in https://github.com/apache/hertzbeat/pull/3164
|
||||
* [release] update release version 1.7.0 version and docs by @tomsun28 in https://github.com/apache/hertzbeat/pull/3165
|
||||
* [feature] implement labels-based monitors filtering in bulletin creation flow by @LL-LIN in https://github.com/apache/hertzbeat/pull/3161
|
||||
* [bugfix] fix postgre mount error, use mariadb instead of mysql in compose by @tomsun28 in https://github.com/apache/hertzbeat/pull/3168
|
||||
* [bugfix] fix bind Labels are not updated when the Alarm Severity switches by @bigcyy in https://github.com/apache/hertzbeat/pull/3170
|
||||
* [improve] update git archive export ignore by @tomsun28 in https://github.com/apache/hertzbeat/pull/3172
|
||||
* [improve] update notice copyright years by @tomsun28 in https://github.com/apache/hertzbeat/pull/3171
|
||||
```
|
||||
|
||||
## Apache Hertzbeat
|
||||
|
||||
**仓库地址:**
|
||||
|
||||
<https://github.com/apache/hertzbeat>
|
||||
|
||||
**网址:**
|
||||
|
||||
<https://hertzbeat.apache.org/>
|
||||
|
||||
**Apache Hertzbeat 下载地址:**
|
||||
|
||||
<https://hertzbeat.apache.org/zh-cn/docs/download>
|
||||
|
||||
**Apache Hertzbeat Docker 镜像版本:**
|
||||
|
||||
> Apache HertzBeat 为每个版本制作了 Docker 镜像. 你可以从 Docker Hub 拉取使用.
|
||||
|
||||
- HertzBeat <https://hub.docker.com/r/apache/hertzbeat>
|
||||
- HertzBeat Collector <https://hub.docker.com/r/apache/hertzbeat-collector>
|
||||
|
||||
**Apache Hertzbeat 开源社区如何参与?**
|
||||
|
||||
<https://hertzbeat.apache.org/zh-cn/docs/community/contribution>
|
||||
+35
-103
@@ -130,56 +130,7 @@ params:
|
||||
|
||||
# collect metrics config list
|
||||
metrics:
|
||||
- name: system_info
|
||||
i18n:
|
||||
zh-CN: 系统信息
|
||||
en-US: System Info
|
||||
priority: 0
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
port: ^_^port^_^
|
||||
ssl: ^_^ssl^_^
|
||||
url: /ISAPI/System/deviceInfo
|
||||
method: GET
|
||||
timeout: ^_^timeout^_^
|
||||
authorization:
|
||||
type: Digest Auth
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: xmlPath
|
||||
parseScript: //DeviceInfo
|
||||
fields:
|
||||
- field: deviceName
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备名称
|
||||
en-US: Device Name
|
||||
- field: deviceID
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备ID
|
||||
en-US: Device ID
|
||||
- field: firmwareVersion
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 固件版本
|
||||
en-US: Firmware Version
|
||||
- field: model
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 设备型号
|
||||
en-US: Device Model
|
||||
- field: macAddress
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: mac地址
|
||||
en-US: Mac Address
|
||||
- name: status
|
||||
i18n:
|
||||
zh-CN: 设备状态
|
||||
en-US: Status
|
||||
priority: 0
|
||||
protocol: http
|
||||
http:
|
||||
host: ^_^host^_^
|
||||
@@ -193,134 +144,115 @@ metrics:
|
||||
digestAuthUsername: ^_^username^_^
|
||||
digestAuthPassword: ^_^password^_^
|
||||
parseType: xmlPath
|
||||
parseScript: //DeviceStatus
|
||||
parseScript: 'DeviceStatus'
|
||||
fields:
|
||||
- field: CPU_utilization
|
||||
- field: cpuUtilization
|
||||
i18n:
|
||||
zh-CN: CPU 利用率
|
||||
en-US: CPU Utilization
|
||||
type: 0
|
||||
unit: '%'
|
||||
- field: memory_usage
|
||||
xpath: CPUList/CPU/cpuUtilization
|
||||
- field: memoryUsage
|
||||
i18n:
|
||||
zh-CN: 内存使用量
|
||||
en-US: Memory Usage
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: memory_available
|
||||
xpath: MemoryList/Memory/memoryUsage
|
||||
- field: memoryAvailable
|
||||
i18n:
|
||||
zh-CN: 可用内存
|
||||
en-US: Memory Available
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: cache_size
|
||||
xpath: MemoryList/Memory/memoryAvailable
|
||||
- field: cacheSize
|
||||
i18n:
|
||||
zh-CN: 缓存大小
|
||||
en-US: Cache Size
|
||||
type: 0
|
||||
unit: MB
|
||||
- field: net_port_1_speed
|
||||
xpath: MemoryList/Memory/cacheSize
|
||||
- field: netPort1Speed
|
||||
i18n:
|
||||
zh-CN: 网口1速度
|
||||
en-US: Net Port 1 Speed
|
||||
type: 0
|
||||
unit: Mbps
|
||||
- field: net_port_2_speed
|
||||
xpath: NetPortStatusList/NetPortStatus[id='1']/workSpeed
|
||||
- field: netPort2Speed
|
||||
i18n:
|
||||
zh-CN: 网口2速度
|
||||
en-US: Net Port 2 Speed
|
||||
type: 0
|
||||
unit: Mbps
|
||||
- field: boot_time
|
||||
xpath: NetPortStatusList/NetPortStatus[id='2']/workSpeed
|
||||
- field: bootTime
|
||||
i18n:
|
||||
zh-CN: 启动时间
|
||||
en-US: Boot Time
|
||||
type: 1
|
||||
- field: device_uptime
|
||||
xpath: bootTime
|
||||
- field: deviceUpTime
|
||||
i18n:
|
||||
zh-CN: 运行时长
|
||||
en-US: Device Uptime
|
||||
type: 1
|
||||
- field: last_calibration_time
|
||||
xpath: deviceUpTime
|
||||
- field: lastCalibrationTime
|
||||
i18n:
|
||||
zh-CN: 上次校时时间
|
||||
en-US: Last Calibration Time
|
||||
type: 1
|
||||
- field: last_calibration_time_diff
|
||||
xpath: lastCalibrationTime
|
||||
- field: lastCalibrationTimeDiff
|
||||
i18n:
|
||||
zh-CN: 上次校时时间差
|
||||
en-US: Last Calibration Time Diff
|
||||
type: 0
|
||||
unit: s
|
||||
- field: avg_upload_time
|
||||
xpath: lastCalibrationTimeDiff
|
||||
- field: avgUploadTime
|
||||
i18n:
|
||||
zh-CN: 平均上传耗时
|
||||
en-US: Avg Upload Time
|
||||
type: 0
|
||||
unit: ms
|
||||
- field: max_upload_time
|
||||
xpath: uploadTimeConsumingList/avgTime
|
||||
- field: maxUploadTime
|
||||
i18n:
|
||||
zh-CN: 最大上传耗时
|
||||
en-US: Max Upload Time
|
||||
type: 0
|
||||
unit: ms
|
||||
- field: min_upload_time
|
||||
xpath: uploadTimeConsumingList/maxTime
|
||||
- field: minUploadTime
|
||||
i18n:
|
||||
zh-CN: 最小上传耗时
|
||||
en-US: Min Upload Time
|
||||
type: 0
|
||||
unit: ms
|
||||
- field: last_calibration_mode
|
||||
xpath: uploadTimeConsumingList/minTime
|
||||
- field: lastCalibrationMode
|
||||
i18n:
|
||||
zh-CN: 上次校时模式
|
||||
en-US: Last Calibration Mode
|
||||
type: 1
|
||||
- field: last_calibration_address
|
||||
xpath: lastCalibrationTimeMode
|
||||
- field: lastCalibrationAddress
|
||||
i18n:
|
||||
zh-CN: 上次校时地址
|
||||
en-US: Last Calibration Address
|
||||
type: 1
|
||||
- field: response_time
|
||||
xpath: lastCalibrationTimeAddress
|
||||
- field: responseTime
|
||||
i18n:
|
||||
zh-CN: 响应时间
|
||||
en-US: Response Time
|
||||
type: 0
|
||||
unit: ms
|
||||
aliasFields:
|
||||
- CPUList/CPU/cpuUtilization
|
||||
- MemoryList/Memory/memoryUsage
|
||||
- MemoryList/Memory/memoryAvailable
|
||||
- MemoryList/Memory/cacheSize
|
||||
- NetPortStatusList/NetPortStatus[id='1']/workSpeed
|
||||
- NetPortStatusList/NetPortStatus[id='2']/workSpeed
|
||||
- bootTime
|
||||
- deviceUpTime
|
||||
- lastCalibrationTime
|
||||
- lastCalibrationTimeDiff
|
||||
- uploadTimeConsumingList/avgTime
|
||||
- uploadTimeConsumingList/maxTime
|
||||
- uploadTimeConsumingList/minTime
|
||||
- lastCalibrationTimeMode
|
||||
- lastCalibrationTimeAddress
|
||||
- responseTime
|
||||
calculates:
|
||||
- CPU_utilization=CPUList/CPU/cpuUtilization
|
||||
- memory_usage=MemoryList/Memory/memoryUsage
|
||||
- memory_available=MemoryList/Memory/memoryAvailable
|
||||
- cache_size=MemoryList/Memory/cacheSize
|
||||
- net_port_1_speed=NetPortStatusList/NetPortStatus[id='1']/workSpeed
|
||||
- net_port_2_speed=NetPortStatusList/NetPortStatus[id='2']/workSpeed
|
||||
- boot_time=bootTime
|
||||
- device_uptime=deviceUpTime
|
||||
- last_calibration_time=lastCalibrationTime
|
||||
- last_calibration_time_diff=lastCalibrationTimeDiff
|
||||
- avg_upload_time=uploadTimeConsumingList/avgTime
|
||||
- max_upload_time=uploadTimeConsumingList/maxTime
|
||||
- min_upload_time=uploadTimeConsumingList/minTime
|
||||
- last_calibration_mode=lastCalibrationTimeMode
|
||||
- last_calibration_address=lastCalibrationTimeAddress
|
||||
- response_time=responseTime
|
||||
units:
|
||||
- memory_usage=KB->MB
|
||||
- memory_available=KB->MB
|
||||
- cache_size=KB->MB
|
||||
- memoryUsage=KB->MB
|
||||
- memoryAvailable=KB->MB
|
||||
- cacheSize=KB->MB
|
||||
|
||||
+2
-2
@@ -64,8 +64,8 @@ limitations under the License.
|
||||
### 2.2 文档样式检查
|
||||
|
||||
1. 安装`markdownlint-cli2`,运行`npm install markdownlint-cli2 --global`
|
||||
2. 在项目中运行`markdownlint-cli2 "home/**/*.md"`,会执行Markdown文件格式自动检测。
|
||||
3. 在项目中运行`markdownlint-cli2 --fix "home/**/*.md"`,会执行Markdown文件格式自动格式化,以确保所有文档都符合规范。
|
||||
2. 在项目中运行`markdownlint "home/**/*.md"`,会执行Markdown文件格式自动检测。
|
||||
3. 在项目中运行`markdownlint --fix "home/**/*.md"`,会执行Markdown文件格式自动格化,以确保所有文档都符合规范。
|
||||
|
||||
> 提示: 修复只能修复部分问题,根据检查后的错误信息,手动调整。
|
||||
|
||||
|
||||
@@ -20,11 +20,11 @@ sidebar_label: Download
|
||||
以前版本的 HertzBeat 可能会受到安全问题的影响,请考虑使用最新版本。
|
||||
:::
|
||||
|
||||
| 版本 | 日期 | 下载 | Release |
|
||||
|--------|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------|
|
||||
| v1.7.0 | 2025.04.02 | [apache-hertzbeat-1.7.0-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz) (主程序) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz) (采集器) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.7.0-incubating-src.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz) (源代码) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz) (Docker Compose) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz.sha512) ) | [note](https://github.com/apache/hertzbeat/releases/tag/v1.7.0) |
|
||||
| v1.6.1 | 2024.10.29 | [apache-hertzbeat-1.6.1-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz) (主程序) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz) (采集器) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.1-incubating-src.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz) (源代码) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz) (Docker Compose) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz.sha512) ) | [note](https://github.com/apache/hertzbeat/releases/tag/v1.6.1) |
|
||||
| v1.6.0 | 2024.06.10 | [apache-hertzbeat-1.6.0-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz) (主程序) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz) (采集器) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.0-incubating-src.tar.gz](https://www.apache.org/dyn/closer.lua/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz) (源代码) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz.sha512) ) | [note](https://github.com/apache/hertzbeat/releases/tag/v1.6.0) |
|
||||
| 版本 | 日期 | 下载 | Release Notes |
|
||||
|--------|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------|
|
||||
| v1.7.0 | 2025.04.02 | [apache-hertzbeat-1.7.0-incubating-bin.tar.gz](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz) (HertzBeat 主程序) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz) (HertzBeat 采集器) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-collector-1.7.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.7.0-incubating-src.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz) (HertzBeat 源代码) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-src.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz) (docker-compose) ( [signature](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz.asc) , [sha512](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.7.0/apache-hertzbeat-1.7.0-incubating-docker-compose.tar.gz.sha512) ) | [release note](https://github.com/apache/hertzbeat/releases/tag/v1.7.0) |
|
||||
| v1.6.1 | 2024.10.29 | [apache-hertzbeat-1.6.1-incubating-bin.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz) (HertzBeat 主程序) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz) (HertzBeat 采集器) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-collector-1.6.1-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.1-incubating-src.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz) (HertzBeat 源代码包) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-src.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz) (docker-compose) ( [signature](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz.asc) , [sha512](https://dist.apache.org/repos/dist/release/incubator/hertzbeat/1.6.1/apache-hertzbeat-1.6.1-incubating-docker-compose.tar.gz.sha512) ) | [release note](https://github.com/apache/hertzbeat/releases/tag/v1.6.1) |
|
||||
| v1.6.0 | 2024.06.10 | [apache-hertzbeat-1.6.0-incubating-bin.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz) (HertzBeat 主程序) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz) (HertzBeat 采集器) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-collector-1.6.0-incubating-bin.tar.gz.sha512) ) <br/> [apache-hertzbeat-1.6.0-incubating-src.tar.gz](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz) (HertzBeat 源代码包) ( [signature](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz.asc) , [sha512](https://downloads.apache.org/incubator/hertzbeat/1.6.0/apache-hertzbeat-1.6.0-incubating-src.tar.gz.sha512) ) | [release note](https://github.com/apache/hertzbeat/releases/tag/v1.6.0) |
|
||||
|
||||
## Docker 镜像版本
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
id: alarm_silence
|
||||
title: 告警静默
|
||||
sidebar_label: 告警静默
|
||||
keywords: [ 开源监控系统, 告警静默 ]
|
||||
---
|
||||
|
||||
> 告警静默管理用于您在系统维护期间或夜晚周末不想受到告警打扰时,可以配置系统静默策略,设置指定时间段内屏蔽告警通知。告警静默规则支持一次性时间段或周期性时间段,支持标签匹配和告警级别匹配部分告警。
|
||||
|
||||
## 一次性时间段静默配置
|
||||
|
||||
- 策略名称:唯一标识静默策略的名称;
|
||||
- 应用所有:是否对所有告警启用该静默策略;
|
||||
- 匹配标签:当 `应用所有` 配置关闭时,可根据匹配标签匹配需要静默的告警;
|
||||
- 静默类型:选择 `一次性静默` ;
|
||||
- 静默时段:选择 `一次性静默` 类型后,静默时段设置如下图所示,可自行配置
|
||||

|
||||
- 启用状态:启用或禁用该静默策略。
|
||||
|
||||
## 周期性时间段静默配置
|
||||
|
||||
- 策略名称:唯一标识静默策略的名称;
|
||||
- 应用所有:是否对所有告警启用该静默策略;
|
||||
- 匹配标签:当 `应用所有` 配置关闭时,可根据匹配标签匹配需要静默的告警;
|
||||
- 静默类型:选择 `周期性静默` ;
|
||||
- 选择日期: 选择 `周期性静默` 类型后,可以配置需要静默的日期;
|
||||
- 静默时段:选择 `周期性静默` 类型后,静默时段设置如下图所示,可自行配置,比如在周末时间静默
|
||||

|
||||
- 启用状态:启用或禁用该静默策略。
|
||||
@@ -1,60 +0,0 @@
|
||||
---
|
||||
id: dahua
|
||||
title: 监控 大华设备
|
||||
sidebar_label: 大华
|
||||
keywords: [ monitor, dahua, 大华 ]
|
||||
---
|
||||
|
||||
> 通过HTTP接口监控大华设备状态,获取设备健康数据。
|
||||
|
||||
## 监控配置参数
|
||||
|
||||
| 参数名称 | 参数帮助描述 |
|
||||
| ----------- | ----------- |
|
||||
| 监控Host | 被监控的对端IP或域名 |
|
||||
| 监控名称 | 标识此监控的唯一名称 |
|
||||
| 端口 | 网络请求端口,默认80 |
|
||||
| 超时时间 | 请求超时时间,单位毫秒 |
|
||||
| 用户名 | 设备登录用户名 |
|
||||
| 密码 | 设备登录密码 |
|
||||
| 启用HTTPS | 是否启用HTTPS协议 |
|
||||
| 采集间隔 | 数据采集周期(≥30秒) |
|
||||
|
||||
## 采集指标
|
||||
|
||||
### 网络信息
|
||||
|
||||
- 默认网卡
|
||||
- 域名
|
||||
- 主机名
|
||||
- 网卡 eth0 IP地址
|
||||
- 网卡 eth0 默认网关
|
||||
- 网卡 eth0 物理地址
|
||||
- 网卡 eth0 子网掩码
|
||||
- 网卡 eth0 MTU
|
||||
- DNS服务器1/2
|
||||
|
||||
### 用户信息
|
||||
|
||||
- 客户端地址
|
||||
- 客户端用户
|
||||
- 客户端登录类型
|
||||
- 客户端登录时间
|
||||
|
||||
### 校时信息
|
||||
|
||||
- 校时服务器
|
||||
- 校时端口
|
||||
- 校时间隔
|
||||
|
||||
## 实现原理
|
||||
|
||||
通过大华设备HTTP接口获取数据:
|
||||
|
||||
1. 网络信息:`/cgi-bin/configManager.cgi?action=getConfig&name=Network`
|
||||
|
||||
2. 用户信息:`/cgi-bin/userManager.cgi?action=getActiveUserInfoAll`
|
||||
|
||||
3. 校时信息:`/cgi-bin/configManager.cgi?action=getConfig&name=NTP`
|
||||
|
||||
使用Digest认证方式,解析设备返回的配置数据格式。
|
||||
@@ -9,7 +9,7 @@ keywords: [Grafana, 历史图表]
|
||||
|
||||
### 前提条件
|
||||
|
||||
- 我们推荐使用最新的`Grafana`版本,早期的版本可能不支持暴露 api。
|
||||
- `Grafana`版本为8.1.0或以上。
|
||||
- `Grafana`服务已经启动,并配置好了账号密码。
|
||||
- `HertzBeat`服务已经启动,并配置好了`VictoriaMetrics`时序数据库(注意: `VictoriaMetrics`数据源是必须的)。
|
||||
|
||||
@@ -22,10 +22,6 @@ keywords: [Grafana, 历史图表]
|
||||
参考: <https://grafana.com/blog/2023/10/10/how-to-embed-grafana-dashboards-into-web-applications/>
|
||||
修改配置文件`grafana.ini`中的`allow_embedding = true`
|
||||
修改配置文件`grafana.ini`中的`[auth.anonymous]` 为 `true`
|
||||
或者通过`docker`运行`Grafana`,使用以下命令:
|
||||
|
||||
```bash
|
||||
docker run -itd --name grafana -p 3000:3000 -e "GF_AUTH_PROXY_ENABLED=true" -e "GF_AUTH_ANONYMOUS_ENABLED=true" -e "GF_SECURITY_ALLOW_EMBEDDING=true" grafana/grafana:latest
|
||||
|
||||
```ini
|
||||
allow_embedding = true
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
id: uniview
|
||||
title: 监控 宇视设备
|
||||
sidebar_label: 宇视
|
||||
keywords: [ monitor, uniview, 宇视 ]
|
||||
---
|
||||
|
||||
> 通过HTTP接口监控宇视设备状态,获取设备健康数据。
|
||||
|
||||
## 监控配置参数
|
||||
|
||||
| 参数名称 | 参数帮助描述 |
|
||||
| ----------- | ----------- |
|
||||
| 监控Host | 设备IP/域名 |
|
||||
| 监控名称 | 唯一标识名称 |
|
||||
| 端口 | 默认80端口 |
|
||||
| 超时时间 | 毫秒级超时设置 |
|
||||
| 用户名 | 认证用户名 |
|
||||
| 密码 | 认证密码 |
|
||||
| 启用HTTPS | HTTPS开关 |
|
||||
| 采集间隔 | ≥30秒采集周期 |
|
||||
|
||||
## 采集指标
|
||||
|
||||
### 系统信息
|
||||
|
||||
- 设备名称
|
||||
- 序列号
|
||||
- 固件版本
|
||||
- 设备型号
|
||||
|
||||
### 校时信息
|
||||
|
||||
- NTP服务器IP
|
||||
- 校时端口
|
||||
- 同步间隔
|
||||
- 校时启用状态
|
||||
|
||||
## 实现原理
|
||||
|
||||
通过宇视HTTP API接口:
|
||||
|
||||
1. 系统信息:`/LAPI/V1.0/System/DeviceInfo`
|
||||
|
||||
2. 校时信息:`/LAPI/V1.0/System/Time/NTP`
|
||||
|
||||
使用Digest认证,解析JSON格式响应数据。
|
||||
+1
-4
@@ -147,9 +147,7 @@
|
||||
"label": "server",
|
||||
"items": [
|
||||
"help/ipmi",
|
||||
"help/hikvision_isapi",
|
||||
"help/dahua",
|
||||
"help/uniview"
|
||||
"help/hikvision_isapi"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -237,7 +235,6 @@
|
||||
"label": "reduce",
|
||||
"items": ["help/alarm_group","help/alarm_inhibit"]
|
||||
},
|
||||
"help/alarm_silence",
|
||||
{
|
||||
"type": "category",
|
||||
"label": "notice",
|
||||
|
||||
@@ -142,16 +142,3 @@ article thead {
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (min-width: 1440px) {
|
||||
.container {
|
||||
max-width: 100%;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
.container {
|
||||
max-width: 100%;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 174 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 62 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 125 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 39 KiB |
@@ -431,14 +431,10 @@ The text of each license is the standard Apache 2.0 license.
|
||||
https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml/4.1.1 Apache-2.0
|
||||
https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas/4.1.1 Apache-2.0
|
||||
https://mvnrepository.com/artifact/xml-apis/xml-apis/1.4.01 Apache-2.0
|
||||
https://mvnrepository.com/artifact/org.webjars/swagger-ui/5.10.3 Apache-2.0
|
||||
https://mvnrepository.com/artifact/com.google.flatbuffers/flatbuffers-java/1.12.0 Apache-2.0
|
||||
https://mvnrepository.com/artifact/com.vesoft/client/3.6.0 Apache-2.0
|
||||
https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-api/1.49.0 Apache-2.0
|
||||
https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-sdk/1.49.0 Apache-2.0
|
||||
https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-sdk-logs/1.49.0 Apache-2.0
|
||||
https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-exporter-otlp/1.49.0 Apache-2.0
|
||||
https://mvnrepository.com/artifact/io.opentelemetry.instrumentation/opentelemetry-logback-appender-1.0 Apache-2.0
|
||||
https://mvnrepository.com/artifact/org.webjars/swagger-ui/5.10.3
|
||||
https://mvnrepository.com/artifact/com.google.flatbuffers/flatbuffers-java/1.12.0
|
||||
https://mvnrepository.com/artifact/com.vesoft/client/3.6.0
|
||||
|
||||
|
||||
========================================================================
|
||||
BSD-2-Clause licenses
|
||||
|
||||
@@ -88,7 +88,6 @@
|
||||
<module>hertzbeat-push</module>
|
||||
<module>hertzbeat-plugin</module>
|
||||
<module>hertzbeat-grafana</module>
|
||||
<module>hertzbeat-log</module>
|
||||
<module>hertzbeat-e2e</module>
|
||||
<module>hertzbeat-base</module>
|
||||
</modules>
|
||||
@@ -174,8 +173,6 @@
|
||||
<arrow.version>18.1.0</arrow.version>
|
||||
<snappy-java.version>1.1.10.7</snappy-java.version>
|
||||
<sshd-sftp.version>2.13.1</sshd-sftp.version>
|
||||
<opentelemetry-api.version>1.43.0</opentelemetry-api.version>
|
||||
<opentelemetry-logback.version>2.14.0-alpha</opentelemetry-logback.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -234,12 +231,6 @@
|
||||
<artifactId>hertzbeat-grafana</artifactId>
|
||||
<version>${hertzbeat.version}</version>
|
||||
</dependency>
|
||||
<!-- log -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-log</artifactId>
|
||||
<version>${hertzbeat.version}</version>
|
||||
</dependency>
|
||||
<!-- collector-basic -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
@@ -250,6 +241,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<version>${spring-boot-dependencies.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -475,34 +467,6 @@
|
||||
<artifactId>sshd-sftp</artifactId>
|
||||
<version>${sshd-sftp.version}</version>
|
||||
</dependency>
|
||||
<!-- OpenTelemetry -->
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-api</artifactId>
|
||||
<version>${opentelemetry-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-sdk</artifactId>
|
||||
<version>${opentelemetry-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-sdk-logs</artifactId>
|
||||
<version>${opentelemetry-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-exporter-otlp</artifactId>
|
||||
<version>${opentelemetry-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry.instrumentation</groupId>
|
||||
<artifactId>opentelemetry-logback-appender-1.0</artifactId>
|
||||
<version>${opentelemetry-logback.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
@@ -24,6 +24,4 @@
|
||||
./home/i18n/zh-cn/docusaurus-plugin-content-docs/version-v1.5.x/community/contact.md
|
||||
./home/i18n/zh-cn/docusaurus-plugin-content-docs/version-v1.5.x/introduce.md
|
||||
./home/docs/introduce.md
|
||||
./home/docs/community/contact.md
|
||||
./home/i18n/zh-cn/docusaurus-plugin-content-blog/2024-06-15-hertzbeat-v1.6.0.md
|
||||
./home/blog/2024-06-15-hertzbeat-v1.6.0.md
|
||||
./home/docs/community/contact.md
|
||||
Submodule script/helm/hertzbeat-helm-chart updated: bdb57c002b...9ce6a771c1
Reference in New Issue
Block a user