Skip to content

Commit

Permalink
feature:support monitoring udp port availability (#1295)
Browse files Browse the repository at this point in the history
Signed-off-by: tomsun28 <tomsun28@outlook.com>
  • Loading branch information
tomsun28 authored Oct 26, 2023
1 parent c487115 commit 6aa74d7
Show file tree
Hide file tree
Showing 14 changed files with 296 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public void collect(CollectRep.MetricsData.Builder builder, long appId, String a
builder.addValues(valueRowBuilder.build());
} else {
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg("对端连接失败,Timeout " + timeout + "ms");
builder.setMsg("Peer connect failed,Timeout " + timeout + "ms");
return;
}
telnetClient.disconnect();
Expand All @@ -100,7 +100,7 @@ public void collect(CollectRep.MetricsData.Builder builder, long appId, String a
String errorMsg = CommonUtil.getMessageFromThrowable(ioException);
log.info(errorMsg);
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg("Peer connection failed: " + errorMsg);
builder.setMsg("Peer connect failed: " + errorMsg);
} catch (Exception e) {
String errorMsg = CommonUtil.getMessageFromThrowable(e);
log.warn(errorMsg, e);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* 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.dromara.hertzbeat.collector.collect.udp;

import lombok.extern.slf4j.Slf4j;
import org.dromara.hertzbeat.collector.collect.AbstractCollect;
import org.dromara.hertzbeat.collector.dispatch.DispatchConstants;
import org.dromara.hertzbeat.collector.util.CollectUtil;
import org.dromara.hertzbeat.common.constants.CollectorConstants;
import org.dromara.hertzbeat.common.constants.CommonConstants;
import org.dromara.hertzbeat.common.entity.job.Metrics;
import org.dromara.hertzbeat.common.entity.job.protocol.UdpProtocol;
import org.dromara.hertzbeat.common.entity.message.CollectRep;
import org.dromara.hertzbeat.common.util.CommonUtil;

import java.net.*;
import java.nio.charset.StandardCharsets;

/**
* udp探测协议采集实现
*
* @author tom
*/
@Slf4j
public class UdpCollectImpl extends AbstractCollect {

private static final byte[] HELLO = "hello".getBytes(StandardCharsets.UTF_8);

public UdpCollectImpl() {
}

@Override
public void collect(CollectRep.MetricsData.Builder builder, long appId, String app, Metrics metrics) {
long startTime = System.currentTimeMillis();
// 简单校验必有参数
if (metrics == null || metrics.getUdp() == null) {
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("Udp collect must has udp params");
return;
}
UdpProtocol udpProtocol = metrics.getUdp();
// 超时时间默认6000毫秒
int timeout = CollectUtil.getTimeout(udpProtocol.getTimeout());
try (DatagramSocket socket = new DatagramSocket()) {
socket.setSoTimeout(timeout);
String content = udpProtocol.getContent();
byte[] buffer = CollectUtil.fromHexString(content);
buffer = buffer == null ? HELLO : buffer;
SocketAddress socketAddress = new InetSocketAddress(udpProtocol.getHost(), Integer.parseInt(udpProtocol.getPort()));
DatagramPacket request = new DatagramPacket(buffer, buffer.length, socketAddress);
socket.send(request);
byte[] responseBuffer = new byte[1];
DatagramPacket response = new DatagramPacket(responseBuffer, responseBuffer.length);
socket.receive(response);
long responseTime = System.currentTimeMillis() - startTime;
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String alias : metrics.getAliasFields()) {
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(Long.toString(responseTime));
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
}
builder.addValues(valueRowBuilder.build());
} catch (SocketTimeoutException timeoutException) {
String errorMsg = CommonUtil.getMessageFromThrowable(timeoutException);
log.info(errorMsg);
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg("Peer connect failed: " + errorMsg);
} catch (PortUnreachableException portUnreachableException) {
String errorMsg = CommonUtil.getMessageFromThrowable(portUnreachableException);
log.info(errorMsg);
builder.setCode(CollectRep.Code.UN_AVAILABLE);
builder.setMsg("Peer port unreachable");
} catch (Exception exception) {
String errorMsg = CommonUtil.getMessageFromThrowable(exception);
log.warn(errorMsg, exception);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
}
}

@Override
public String supportProtocol() {
return DispatchConstants.PROTOCOL_UDP;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public interface DispatchConstants {
* protocol telnet
*/
String PROTOCOL_TELNET = "telnet";
/**
* protocol udp
*/
String PROTOCOL_UDP = "udp";
/**
* protocol jdbc
*/
Expand All @@ -47,15 +51,10 @@ public interface DispatchConstants {
* protocol redis
*/
String PROTOCOL_REDIS = "redis";

/**
* protocol mongodb
*/
String PROTOCOL_MONGODB = "mongodb";
/**
* protocol
*/
String PROTOCOL_DM = "dm";
/**
* protocol jmx
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
public class CollectUtil {

private static final int DEFAULT_TIMEOUT = 60000;
private static final int HEX_STR_WIDTH = 2;
private static final String SMILING_PLACEHOLDER = "^_^";
private static final String SMILING_PLACEHOLDER_REX = "\\^_\\^";
private static final String SMILING_PLACEHOLDER_REGEX = "(\\^_\\^)(\\w|-|$|\\.)+(\\^_\\^)";
Expand Down Expand Up @@ -413,4 +414,27 @@ public static void replaceFieldsForPushStyleMonitor(Metrics metrics, Map<String,
});
metrics.setFields(pushFieldList);
}

/**
* 将16进制字符串转换为byte[]
* eg: 302c0201010409636f6d6d756e697479a11c020419e502e7020100020100300e300c06082b060102010102000500
* 16进制字符串不区分大小写,返回的数组相同
* @param hexString 16进制字符串
* @return byte[]
*/
public static byte[] fromHexString(String hexString) {
if (null == hexString || "".equals(hexString.trim())) {
return null;
}
byte[] bytes = new byte[hexString.length() / HEX_STR_WIDTH];
// 16进制字符串
String hex;
for (int i = 0; i < hexString.length() / HEX_STR_WIDTH; i++) {
// 每次截取2位
hex = hexString.substring(i * HEX_STR_WIDTH, i * HEX_STR_WIDTH + HEX_STR_WIDTH);
// 16进制 --> 十进制
bytes[i] = (byte) Integer.parseInt(hex, 16);
}
return bytes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ org.dromara.hertzbeat.collector.collect.ssh.SshCollectImpl
org.dromara.hertzbeat.collector.collect.telnet.TelnetCollectImpl
org.dromara.hertzbeat.collector.collect.ftp.FtpCollectImpl
org.dromara.hertzbeat.collector.collect.mq.RocketmqSingleCollectImpl
org.dromara.hertzbeat.collector.collect.push.PushCollectImpl
org.dromara.hertzbeat.collector.collect.udp.UdpCollectImpl
org.dromara.hertzbeat.collector.collect.push.PushCollectImpl
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ public class Metrics {
*/
private TelnetProtocol telnet;
/**
* Use tcp or ucp implemented by socket for service port detection configuration information
* 使用socket实现的tcp或ucp进行服务端口探测配置信息
* Use udp implemented by socket for service port detection configuration information
* 使用socket实现的udp进行服务端口探测配置信息
*/
private TcpUdpProtocol tcpUdp;
private UdpProtocol udp;
/**
* Database configuration information implemented using the public jdbc specification
* 使用公共的jdbc规范实现的数据库配置信息
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,32 @@
import lombok.NoArgsConstructor;

/**
* 使用socket实现的tcp或ucp进行服务端口可用性探测
* 使用socket实现的udp进行服务端口可用性探测
* @author tomsun28
*
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TcpUdpProtocol {
/**
* 具体协议类型 tcp, udp
*/
private String protocol;
public class UdpProtocol {
/**
* 对端主机ip或域名
*/
private String host;

/**
* 端口号
*/
private Integer port;
private String port;

/**
* 超时时间
*/
private String timeout;

/**
* 自定义协议数据包 hexString 16进制字符串
*/
private String content;
}
2 changes: 1 addition & 1 deletion manager/src/main/resources/define/app-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ name:
help:
zh-CN: HertzBeat 对 Docker 容器的通用性能指标(system、containers、stats)进行采集监控 <br><span class='help_module_span'>⚠️注意:为了监控 Docker 中的容器信息,您需要打开端口,让采集请求获取到对应的信息, <a class='help_module_content' href='https://hertzbeat.com/zh-cn/docs/help/docker#%E7%9B%91%E6%8E%A7%E5%89%8D%E6%93%8D%E4%BD%9C'>点击查看开启步骤</a>。</span>
en-US: "HertzBeat monitors Docker through general performance metrics such as containers, status, <br><span class='help_module_span'>⚠️Note: In order to monitor container information of Docker, you need to enable the port so that the collection request can obtain the corresponding information.<a class='help_module_content' href='https://hertzbeat.com/docs/help/docker#%E7%9B%91%E6%8E%A7%E5%89%8D%E6%93%8D%E4%BD%9C'>Click here to view the specific steps.</a></span>"
zh-TW: HertzBeat對Docker容器的通用性能指標(system、containers、stats)進行採集監控<br><span class='help_ module_ span'> ⚠️ 注意:為了監控Docker中的容器資訊,您需要打開埠,讓採集請求獲取到對應的資訊,<a class='help_ module_ content' href='https://hertzbeat.com/zh-cn/docs/help/docker#%E7%9B%91%E6%8E%A7%E5%89%8D%E6%93%8D%E4%BD%9C '>點擊查看開啟步驟</a>。</span>
zh-TW: HertzBeat對Docker容器的通用性能指標(system、containers、stats)進行採集監控<br><span class='help_ module_ span'> ⚠️ 注意:為了監控Docker中的容器指標,您需要打開埠,讓採集請求獲取到對應的指標,<a class='help_ module_ content' href='https://hertzbeat.com/zh-cn/docs/help/docker#%E7%9B%91%E6%8E%A7%E5%89%8D%E6%93%8D%E4%BD%9C '>點擊查看開啟步驟</a>。</span>
helpLink:
zh-CN: https://hertzbeat.com/zh-cn/docs/help/docker/
en-US: https://hertzbeat.com/docs/help/docker/
Expand Down
2 changes: 1 addition & 1 deletion manager/src/main/resources/define/app-kubernetes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ name:
help:
zh-CN: HertzBeat 对 kubernetes 的通用性能指标(nodes、namespaces、pods、services)进行采集监控。<br><span class='help_module_span'>⚠️注意:为了监控 Kubernetes 中的信息,则需要获取到可访问 Api Server 的授权 TOKEN,让采集请求获取到对应的信息,<a class='help_module_content' href='https://hertzbeat.com/zh-cn/docs/help/kubernetes#%E7%9B%91%E6%8E%A7%E5%89%8D%E6%93%8D%E4%BD%9C'>点击查看获取步骤</a>。</span>
en-US: "HertzBeat monitors kubernetes through general performance metrics such as nodes, namespaces and pods. <br><span class='help_module_span'>⚠️Note: In order to monitor the information of Kubernetes, Hertzbeat need to obtain the authorized TOKEN that can access Api Server. <a class='help_module_content' href='https://hertzbeat.com/zh-cn/docs/help/kubernetes#%E7%9B%91%E6%8E%A7%E5%89%8D%E6%93%8D%E4%BD%9C'>Click here to view the specific steps.</a></span>"
zh-TW: HertzBeat對kubernetes的通用性能指標(nodes、namespaces、pods、services)進行採集監控。<br><span class='help_ module_ span'> ⚠️ 注意:為了監控Kubernetes中的資訊,則需要獲取到可訪問Api Server的授權TOKEN,讓採集請求獲取到對應的資訊,<a class='help_ module_ content' href='https://hertzbeat.com/zh-cn/docs/help/kubernetes#%E7%9B%91%E6%8E%A7%E5%89%8D%E6%93%8D%E4%BD%9C'>點擊查看獲取步驟</a>。</span>
zh-TW: HertzBeat對kubernetes的通用性能指標(nodes、namespaces、pods、services)進行採集監控。<br><span class='help_ module_ span'> ⚠️ 注意:為了監控Kubernetes中的指標,則需要獲取到可訪問Api Server的授權TOKEN,讓採集請求獲取到對應的指標,<a class='help_ module_ content' href='https://hertzbeat.com/zh-cn/docs/help/kubernetes#%E7%9B%91%E6%8E%A7%E5%89%8D%E6%93%8D%E4%BD%9C'>點擊查看獲取步驟</a>。</span>
helpLink:
zh-CN: https://hertzbeat.com/zh-cn/docs/help/kubernetes
en-US: https://hertzbeat.com/docs/help/kubernetes
Expand Down
6 changes: 3 additions & 3 deletions manager/src/main/resources/define/app-port.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ name:
# The description and help of this monitoring type
# 监控类型的帮助描述信息
help:
zh-CN: HertzBeat 通过判断对端服务中暴露的端口是否可用,进而判断对端服务是否可用。同时以ms为指标,对响应时间等指标进行监测。您可以点击“<i>新建 端口可用性</i>”并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
en-US: HertzBeat determines whether the exposed ports in the peer service are available, thereby determining whether the peer service is available. Simultaneously monitoring response time and other metrics using ms as metric unit. You could click the "<i>New port</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: HertzBeat通過判斷對端服務中暴露的埠是否可用,進而判斷對端服務是否可用。 同時以ms為名額,對回應時間等名額進行監測。 您可以點擊“<i>新建埠可用性</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
zh-CN: HertzBeat 通过判断对端服务中暴露的TCP端口是否可用,进而判断对端服务是否可用。同时以ms为指标,对响应时间等指标进行监测。您可以点击“<i>新建 端口可用性</i>”并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
en-US: HertzBeat determines whether the exposed tcp ports in the peer service are available, thereby determining whether the peer service is available. Simultaneously monitoring response time and other metrics using ms as metric unit. You could click the "<i>New port</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: HertzBeat 通過判斷對端服務中暴露的TCP端口是否可用,進而判斷對端服務是否可用。 同時以ms為指标,對回應時間等指标進行監測。 您可以點擊“<i>新建埠可用性</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
helpLink:
zh-CN: https://hertzbeat.com/zh-cn/docs/help/port
en-US: https://hertzbeat.com/docs/help/port
Expand Down
2 changes: 1 addition & 1 deletion manager/src/main/resources/define/app-springboot2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ name:
help:
zh-CN: HertzBeat对 <a class='help_module_content' href='http://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot2.0 Actuator </a> 暴露的通用性能指标(health、environment、threads、memory_used)进行采集监控。<span class='help_module_span'>⚠️注意:如果要监控 SpringBoot 中的信息,需要您的 SpringBoot 应用集成并开启 SpringBoot Actuator, <a class='help_module_content' href='https://hertzbeat.com/zh-cn/docs/help/springboot2'>点击查看具体步骤</a>。</span>
en-US: "HertzBeat collects and monitors SpringBoot through general performance metric(health, environment, threads, memory_used) that exposed by the SpringBoot2.0 Actuator. <br><span class='help_module_span'>⚠️Note: You should make sure that your SpringBoot application have already integrated and enabled the SpringBoot Actuator, <a class='help_module_content' href='https://hertzbeat.com/docs/help/springboot2'>click here to see the specific steps.</a></span>"
zh-TW: HertzBeat對<a class='help_module_content' href='http://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot2.0 Actuator </a>暴露的通用性能指標(health、environment、threads、memory_used)進行採集監控。< span class='help_module_span'> ⚠️ 注意:如果要監控SpringBoot中的資訊,需要您的SpringBoot應用集成並開啟SpringBoot Actuator,<a class='help_module_content' href='https://hertzbeat.com/zh-cn/docs/help/springboot2'>點擊查看具體步驟</a>。</span>
zh-TW: HertzBeat對<a class='help_module_content' href='http://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot2.0 Actuator </a>暴露的通用性能指標(health、environment、threads、memory_used)進行採集監控。< span class='help_module_span'> ⚠️ 注意:如果要監控SpringBoot中的指標,需要您的SpringBoot應用集成並開啟SpringBoot Actuator,<a class='help_module_content' href='https://hertzbeat.com/zh-cn/docs/help/springboot2'>點擊查看具體步驟</a>。</span>
helpLink:
zh-CN: https://hertzbeat.com/zh-cn/docs/help/springboot2
en-US: https://hertzbeat.com/docs/help/springboot2
Expand Down
2 changes: 1 addition & 1 deletion manager/src/main/resources/define/app-springboot3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ name:
help:
zh-CN: HertzBeat对 <a class='help_module_content' href='http://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot3.0 Actuator </a> 暴露的通用性能指标(health、environment、threads、memory_used)进行采集监控。<span class='help_module_span'>⚠️注意:如果要监控 SpringBoot 中的信息,需要您的 SpringBoot 应用集成并开启 SpringBoot Actuator, <a class='help_module_content' href='https://hertzbeat.com/zh-cn/docs/help/springboot2'>点击查看具体步骤</a>。</span>
en-US: "HertzBeat collect and monitors SpringBoot through general performance metric that exposed by the SpringBoot3.0 Actuator. <br><span class='help_module_span'><br>⚠️Note: You should make sure that your SpringBoot application have already integrated and enabled the SpringBoot Actuator, <a class='help_module_content' href='https://hertzbeat.com/docs/help/springboot2'>click here to see the specific steps.</a></span>"
zh-TW: HertzBeat對<a class='help_module_content' href='http://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot3.0 Actuator </a>暴露的通用性能指標(health、environment、threads、memory_used)進行採集監控。< span class='help_module_span'> ⚠️ 注意:如果要監控SpringBoot中的資訊,需要您的SpringBoot應用集成並開啟SpringBoot Actuator,<a class='help_module_content' href='https://hertzbeat.com/zh-cn/docs/help/springboot2'>點擊查看具體步驟</a>。</span>
zh-TW: HertzBeat對<a class='help_module_content' href='http://www.tutorialspoint.com/spring_boot/spring_boot_actuator.htm'> SpringBoot3.0 Actuator </a>暴露的通用性能指標(health、environment、threads、memory_used)進行採集監控。< span class='help_module_span'> ⚠️ 注意:如果要監控SpringBoot中的指標,需要您的SpringBoot應用集成並開啟SpringBoot Actuator,<a class='help_module_content' href='https://hertzbeat.com/zh-cn/docs/help/springboot2'>點擊查看具體步驟</a>。</span>
helpLink:
zh-CN: https://hertzbeat.com/zh-cn/docs/help/springboot3
en-US: https://hertzbeat.com/docs/help/springboot3
Expand Down
Loading

0 comments on commit 6aa74d7

Please sign in to comment.