diff --git a/collector/server/src/main/java/com/usthe/collector/collect/http/HttpCollectImpl.java b/collector/server/src/main/java/com/usthe/collector/collect/http/HttpCollectImpl.java index a09244f..8d40f6b 100644 --- a/collector/server/src/main/java/com/usthe/collector/collect/http/HttpCollectImpl.java +++ b/collector/server/src/main/java/com/usthe/collector/collect/http/HttpCollectImpl.java @@ -74,7 +74,7 @@ public class HttpCollectImpl extends AbstractCollect { if (statusCode < HttpStatus.SC_OK || statusCode >= HttpStatus.SC_BAD_REQUEST) { // 1XX 3XX 4XX 5XX 状态码 失败 builder.setCode(CollectRep.Code.FAIL); - builder.setMsg("statusCode: " + statusCode); + builder.setMsg("StatusCode " + statusCode); return; } else { // 2xx 状态码 成功 diff --git a/collector/server/src/main/java/com/usthe/collector/collect/icmp/IcmpCollectImpl.java b/collector/server/src/main/java/com/usthe/collector/collect/icmp/IcmpCollectImpl.java new file mode 100644 index 0000000..d40c179 --- /dev/null +++ b/collector/server/src/main/java/com/usthe/collector/collect/icmp/IcmpCollectImpl.java @@ -0,0 +1,86 @@ +package com.usthe.collector.collect.icmp; + +import com.usthe.collector.collect.AbstractCollect; +import com.usthe.collector.util.CollectorConstants; +import com.usthe.common.entity.job.Metrics; +import com.usthe.common.entity.job.protocol.IcmpProtocol; +import com.usthe.common.entity.message.CollectRep; +import com.usthe.common.util.CommonConstants; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * icmp协议采集实现 - ping + * @author tom + * @date 2021/12/4 12:32 + */ +@Slf4j +public class IcmpCollectImpl extends AbstractCollect { + + private IcmpCollectImpl(){} + + public static IcmpCollectImpl getInstance() { + return IcmpCollectImpl.Singleton.INSTANCE; + } + + + @Override + public void collect(CollectRep.MetricsData.Builder builder, long appId, String app, Metrics metrics) { + long startTime = System.currentTimeMillis(); + // 简单校验必有参数 + if (metrics == null || metrics.getIcmp() == null) { + builder.setCode(CollectRep.Code.FAIL); + builder.setMsg("ICMP collect must has icmp params"); + return; + } + IcmpProtocol icmp = metrics.getIcmp(); + // 超时时间默认300毫秒 + int timeout = 300; + try { + timeout = Integer.parseInt(metrics.getIcmp().getTimeout()); + } catch (Exception e) { + log.warn(e.getMessage()); + } + try { + // todo 需要配置java虚拟机root权限从而使用ICMP,否则是判断telnet对端7号端口是否开通 + // https://stackoverflow.com/questions/11506321/how-to-ping-an-ip-address + boolean status = InetAddress.getByName(icmp.getHost()).isReachable(timeout); + long responseTime = System.currentTimeMillis() - startTime; + if (status) { + 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()); + } else { + builder.setCode(CollectRep.Code.UN_REACHABLE); + builder.setMsg("对端不可达,Timeout " + timeout + "ms"); + return; + } + } catch (UnknownHostException unknownHostException) { + builder.setCode(CollectRep.Code.UN_REACHABLE); + builder.setMsg("UnknownHost " + unknownHostException.getMessage()); + return; + } catch (IOException ioException) { + builder.setCode(CollectRep.Code.UN_REACHABLE); + builder.setMsg("IOException " + ioException.getMessage()); + return; + } catch (Exception e) { + log.error(e.getMessage(), e); + builder.setCode(CollectRep.Code.FAIL); + builder.setMsg("IllegalArgument " + e.getMessage()); + } + + } + + private static class Singleton { + private static final IcmpCollectImpl INSTANCE = new IcmpCollectImpl(); + } +} diff --git a/collector/server/src/main/java/com/usthe/collector/dispatch/MetricsCollect.java b/collector/server/src/main/java/com/usthe/collector/dispatch/MetricsCollect.java index ec1cf4d..508b1b1 100644 --- a/collector/server/src/main/java/com/usthe/collector/dispatch/MetricsCollect.java +++ b/collector/server/src/main/java/com/usthe/collector/dispatch/MetricsCollect.java @@ -4,6 +4,7 @@ import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.Expression; import com.usthe.collector.collect.AbstractCollect; import com.usthe.collector.collect.http.HttpCollectImpl; +import com.usthe.collector.collect.icmp.IcmpCollectImpl; import com.usthe.collector.dispatch.timer.Timeout; import com.usthe.collector.dispatch.timer.WheelTimerTask; import com.usthe.common.entity.job.Job; @@ -98,6 +99,8 @@ public class MetricsCollect implements Runnable, Comparable { case DispatchConstants.PROTOCOL_HTTP: abstractCollect = HttpCollectImpl.getInstance(); break; + case DispatchConstants.PROTOCOL_ICMP: + abstractCollect = IcmpCollectImpl.getInstance(); // todo default: break; } diff --git a/common/src/main/java/com/usthe/common/entity/job/protocol/IcmpProtocol.java b/common/src/main/java/com/usthe/common/entity/job/protocol/IcmpProtocol.java index f9ba6d4..b31bc43 100644 --- a/common/src/main/java/com/usthe/common/entity/job/protocol/IcmpProtocol.java +++ b/common/src/main/java/com/usthe/common/entity/job/protocol/IcmpProtocol.java @@ -15,9 +15,15 @@ import lombok.NoArgsConstructor; @AllArgsConstructor @NoArgsConstructor public class IcmpProtocol { + /** * 对端主机ip或域名 */ private String host; + /** + * 超时时间 + */ + private String timeout; + } diff --git a/manager/src/main/resources/define/app/A-example.yml b/manager/src/main/resources/define/app/A-example.yml index 801642e..534b33b 100644 --- a/manager/src/main/resources/define/app/A-example.yml +++ b/manager/src/main/resources/define/app/A-example.yml @@ -1,5 +1,5 @@ # 监控应用类型名称(与文件名保持一致) eg: linux windows tomcat mysql aws... -app: exapmle_type +app: exapmle # 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串 # 强制固定必须参数 - host configmap: diff --git a/manager/src/main/resources/define/app/ping.yml b/manager/src/main/resources/define/app/ping.yml new file mode 100644 index 0000000..1746a54 --- /dev/null +++ b/manager/src/main/resources/define/app/ping.yml @@ -0,0 +1,28 @@ +# 监控应用类型名称(与文件名保持一致) eg: linux windows tomcat mysql aws... +app: ping +# 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串 +# 强制固定必须参数 - host +configmap: + - key: host + type: 1 + - key: timeout + type: 0 +metrics: + # 第一个监控指标组 cpu + # 注意:内置监控指标有 (responseTime - 响应时间) + - name: summary + # 指标组调度优先级(0-127)越小优先级越高,优先级低的指标组会等优先级高的指标组采集完成后才会被调度,相同优先级的指标组会并行调度采集 + # 优先级为0的指标组为可用性指标组,即它会被首先调度,采集成功才会继续调度其它指标组,采集失败则中断调度 + priority: 0 + # 指标组中的具体监控指标 + fields: + # 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位 + - field: responseTime + type: 0 + unit: ms +# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk + protocol: icmp +# 当protocol为ping协议时具体的采集配置 + icmp: + host: ^_^host^_^ + timeout: ^_^timeout^_^ \ No newline at end of file diff --git a/manager/src/main/resources/define/param/A-example.yml b/manager/src/main/resources/define/param/A-example.yml index 842c8f8..cda945b 100644 --- a/manager/src/main/resources/define/param/A-example.yml +++ b/manager/src/main/resources/define/param/A-example.yml @@ -1,5 +1,5 @@ # 监控应用类型名称(与文件名保持一致) eg: linux windows tomcat mysql aws... -app: exapmle_type +app: exapmle # 强制固定必须参数 - host(ipv4,ipv6,域名) param: # field-字段名称标识符 diff --git a/manager/src/main/resources/define/param/api.yml b/manager/src/main/resources/define/param/api.yml index 90b670d..751f5ad 100644 --- a/manager/src/main/resources/define/param/api.yml +++ b/manager/src/main/resources/define/param/api.yml @@ -24,10 +24,18 @@ param: required: true - field: method name: 请求方式 - type: text - # 当type为text时,用limit表示字符串限制大小 - limit: 20 + type: radio required: true + # 当type为radio单选框,checkbox复选框时,option表示可选项值列表 {name1:value1,name2:value2} + options: + - label: GET请求 + value: GET + - label: POST请求 + value: POST + - label: PUT请求 + value: PUT + - label: DELETE请求 + value: DELETE - field: username name: 用户名 type: text @@ -40,8 +48,6 @@ param: required: false - field: ssl name: 使用SSL + # 当type为boolean时,前端用switch展示开关 type: boolean required: true - # 当type为boolean时,前端用switch展示开关 - # 当type为radio单选框,checkbox复选框时,option表示可选项值列表 - # option: Yes,No \ No newline at end of file diff --git a/manager/src/main/resources/define/param/ping.yml b/manager/src/main/resources/define/param/ping.yml new file mode 100644 index 0000000..491c16d --- /dev/null +++ b/manager/src/main/resources/define/param/ping.yml @@ -0,0 +1,20 @@ +# 监控应用类型名称(与文件名保持一致) eg: linux windows tomcat mysql aws... +app: ping +# 强制固定必须参数 - host(ipv4,ipv6,域名) +param: + # field-字段名称标识符 + - field: host + # name-参数字段显示名称 + name: 主机Host + # type-字段类型,样式(大部分映射input标签type属性) + type: host + # 是否是必输项 true-必填 false-可选 + required: true + - field: timeout + name: Ping超时时间 + type: number + # 当type为number时,用range表示范围 + range: '[0,100000]' + required: true + placeholder: '请输入超时时间,单位毫秒' + defaultValue: 3000 \ No newline at end of file diff --git a/web-app/src/assets/tmp/app-data.json b/web-app/src/assets/tmp/app-data.json index 7b05de1..6ee4dff 100644 --- a/web-app/src/assets/tmp/app-data.json +++ b/web-app/src/assets/tmp/app-data.json @@ -42,7 +42,7 @@ { "text": "api", "link": "/monitors?app=api", - "i18n": "monitor.app.http" + "i18n": "monitor.app.api" }, { "text": "ping", @@ -51,7 +51,7 @@ }, { "text": "telnet", - "link": "/monitors", + "link": "/monitors?app=telnet", "i18n": "monitor.app.telnet" } ]