Skip to content

Commit

Permalink
add ntp protocol and support ntp monitoring (#1411)
Browse files Browse the repository at this point in the history
Co-authored-by: 东风 <1335799468@qq.com>
  • Loading branch information
2 people authored and tomsun28 committed Mar 10, 2024
1 parent 57f4f98 commit a7e7ed3
Show file tree
Hide file tree
Showing 6 changed files with 321 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package org.dromara.hertzbeat.collector.collect.ntp;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.NtpV3Packet;
import org.apache.commons.net.ntp.TimeInfo;
import org.apache.commons.net.ntp.TimeStamp;
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.NtpProtocol;
import org.dromara.hertzbeat.common.entity.message.CollectRep;
import org.dromara.hertzbeat.common.util.CommonUtil;

import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* @author dongfeng
*/
@Slf4j
public class NtpCollectImpl extends AbstractCollect {
public NtpCollectImpl() {
}

@Override
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) {
long startTime = System.currentTimeMillis();
if (metrics == null || metrics.getNtp() == null) {
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("NTP collect must have NTP params");
return;
}
NtpProtocol ntpProtocol = metrics.getNtp();
String host = ntpProtocol.getHost();
int timeout = CollectUtil.getTimeout(ntpProtocol.getTimeout());

NTPUDPClient client = null;

try {
client = new NTPUDPClient();
client.setDefaultTimeout(timeout);
client.open();
InetAddress serverAddress = InetAddress.getByName(host);
TimeInfo timeInfo = client.getTime(serverAddress);
long responseTime = System.currentTimeMillis() - startTime;

timeInfo.computeDetails();

// 获取ntp服务器信息
Map<String, String> resultMap = getNTPInfo(timeInfo);
resultMap.put(CollectorConstants.RESPONSE_TIME, Long.toString(responseTime));

List<String> aliasFields = metrics.getAliasFields();
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String field : aliasFields) {
String fieldValue = resultMap.get(field);
valueRowBuilder.addColumns(Objects.requireNonNullElse(fieldValue, CommonConstants.NULL_VALUE));
}
builder.addValues(valueRowBuilder.build());
client.close();
} catch (SocketException socketException) {
String errorMsg = CommonUtil.getMessageFromThrowable(socketException);
log.debug(errorMsg);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("NTPUDPClient open is fail: " + errorMsg);
} catch (UnknownHostException unknownHostException) {
String errorMsg = CommonUtil.getMessageFromThrowable(unknownHostException);
log.debug(errorMsg);
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg("NTPServerAddress is unknownHost: " + errorMsg);
} catch (IOException ioException) {
String errorMsg = CommonUtil.getMessageFromThrowable(ioException);
log.info(errorMsg);
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg("Receive timed out: " + timeout + "ms");
} catch (Exception e) {
String errorMsg = CommonUtil.getMessageFromThrowable(e);
log.warn(errorMsg, e);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
} finally {
if (client != null) {
try {
client.close();
} catch (Exception e) {
log.warn(e.getMessage());
}
}
}
}

private Map<String, String> getNTPInfo(TimeInfo timeInfo) {
Map<String, String> valueMap = new HashMap<>(16);

TimeStamp timeStamp = timeInfo.getMessage().getTransmitTimeStamp();
Date date = timeStamp.getDate();

NtpV3Packet message = timeInfo.getMessage();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
valueMap.put("time", Long.toString(timeStamp.getTime()));
valueMap.put("date", simpleDateFormat.format(date));
valueMap.put("offset", Long.toString(timeInfo.getOffset()));
valueMap.put("delay", Long.toString(timeInfo.getDelay()));
valueMap.put("version", Integer.toString(message.getVersion()));
valueMap.put("mode", Integer.toString(message.getMode()));
valueMap.put("stratum", Integer.toString(message.getStratum()));
valueMap.put("referenceId", String.valueOf(message.getReferenceId()));
valueMap.put("precision", Integer.toString(message.getPrecision()));
return valueMap;
}

@Override
public String supportProtocol() {
return DispatchConstants.PROTOCOL_NTP;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public interface DispatchConstants {
* protocol smtp
*/
String PROTOCOL_SMTP = "smtp";
/**
* protocol ntp
*/
String PROTOCOL_NTP = "ntp";
/**
* protocol udp
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ org.dromara.hertzbeat.collector.collect.snmp.SnmpCollectImpl
org.dromara.hertzbeat.collector.collect.ssh.SshCollectImpl
org.dromara.hertzbeat.collector.collect.telnet.TelnetCollectImpl
org.dromara.hertzbeat.collector.collect.smtp.SmtpCollectImpl
org.dromara.hertzbeat.collector.collect.ntp.NtpCollectImpl
org.dromara.hertzbeat.collector.collect.ftp.FtpCollectImpl
org.dromara.hertzbeat.collector.collect.mq.RocketmqSingleCollectImpl
org.dromara.hertzbeat.collector.collect.udp.UdpCollectImpl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ public class Metrics {
* 使用smtp协议的监控配置信息
*/
private SmtpProtocol smtp;
/**
* Monitoring configuration information using the public ntp protocol
* 使用ntp协议的监控配置信息
*/
private NtpProtocol ntp;
/**
* Use udp implemented by socket for service port detection configuration information
* 使用socket实现的udp进行服务端口探测配置信息
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.dromara.hertzbeat.common.entity.job.protocol;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* @author dongfeng
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class NtpProtocol {
/**
* NTP主机ip或域名
*/
private String host;

/**
* NTP主机端口
*/
private String port;

/**
* 超时时间
*/
private String timeout;
}
153 changes: 153 additions & 0 deletions manager/src/main/resources/define/app-ntp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# The monitoring type category:service-application service monitoring db-database monitoring mid-middleware custom-custom monitoring os-operating system monitoring
# 监控类型所属类别:service-应用服务 program-应用程序 db-数据库 custom-自定义 os-操作系统 bigdata-大数据 mid-中间件 webserver-web服务器 cache-缓存 cn-云原生 network-网络监控等等
category: service
# The monitoring type eg: linux windows tomcat mysql aws...
# 监控类型 eg: linux windows tomcat mysql aws...
app: ntp
# 监控类型国际化名称
name:
zh-CN: NTP监控
en-US: NTP MONITORS
# The description and help of this monitoring type
# 监控类型的帮助描述信息
help:
zh-CN: HertzBeat 对 NTP 服务的(响应时间、时间戳、时间、偏移量、延迟、版本号、模式、层级、参考ID、精度)相关指标进行监测。
en-US: HertzBeat monitors the relevant indicators of NTP services, including response time, timestamp, time, offset, delay, version number, mode, hierarchy, reference ID, and accuracy.
zh-TW: HertzBeat對NTP服務的(回應時間、時間戳記、時間、偏移量、延遲、版本號、模式、層級、參攷ID、精度)相關名額進行監測。
# 监控所需输入参数定义(根据定义渲染页面UI)
# Input params define for monitoring(render web ui by the definition)
params:
# field-param field key
# field-字段名称标识符
- field: host
# name-param field display i18n name
# name-参数字段显示名称
name:
zh-CN: NTP服务的Host
en-US: Host of NTP service
# type-param field type(most mapping the html input type)
# type-字段类型,样式(大部分映射input标签type属性)
type: host
# required-true or false
# 是否是必输项 true-必填 false-可选
required: true
# field-param field key
# field-字段名称标识符
- field: timeout
# name-param field display i18n name
# name-参数字段显示名称
name:
zh-CN: 连接超时时间(ms)
en-US: Connect Timeout(ms)
# type-param field type(most mapping the html input type)
# type-字段类型,样式(大部分映射input标签type属性)
type: number
# when type is number, range is required
# 当type为number时,用range表示范围
range: '[0,100000]'
# required-true or false
# 是否是必输项 true-必填 false-可选
required: true
# default value 6000
# 默认值 6000
defaultValue: 6000
# collect metrics config list
# 采集指标配置列表
metrics:
# metrics - summary
# 监控指标 - summary
- name: summary
i18n:
zh-CN: 概要
en-US: Summary
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
# 指标采集调度优先级(0->127)->(优先级高->低) 优先级低的指标会等优先级高的指标采集完成后才会被调度, 相同优先级的指标会并行调度采集
# 优先级为0的指标为可用性指标,即它会被首先调度,采集成功才会继续调度其它指标,采集失败则中断调度
priority: 0
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 label-是否是指标标签字段 unit:指标单位
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
# field-指标名称, type-指标类型(0-number数字,1-string字符串), unit-指标单位('%','ms','MB'), label-是否是指标标签字段
fields:
- field: responseTime
type: 0
unit: ms
i18n:
zh-CN: 响应时间
en-US: ResponseTime
- field: time
type: 0
unit: ms
i18n:
zh-CN: 时间戳
en-US: time
- field: date
type: 1
i18n:
zh-CN: 时间
en-US: date
- field: offset
type: 0
unit: ms
i18n:
zh-CN: 偏移量
en-US: offset
- field: delay
type: 0
unit: ms
i18n:
zh-CN: 延迟
en-US: delay
- field: version
type: 0
i18n:
zh-CN: 版本号
en-US: version
- field: mode
type: 0
i18n:
zh-CN: 模式
en-US: mode
- field: stratum
type: 0
i18n:
zh-CN: 层级
en-US: stratum
- field: referenceId
type: 1
i18n:
zh-CN: 参考ID
en-US: referenceId
- field: precision
type: 0
i18n:
zh-CN: 精度
en-US: precision

# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
# 采集协议, 目前支持sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ntp
# Specific collection configuration when protocol is telnet protocol
# 当protocol为telnet协议时具体的采集配置
ntp:
# telnet host
# 远程登录主机
host: ^_^host^_^
# timeout
# 超时时间
timeout: ^_^timeout^_^

0 comments on commit a7e7ed3

Please sign in to comment.