From ad1dad69d4fe6acbbf8abc72ce28ce3b843f9ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B7=9E=E7=AD=B1?= <105542329+a-little-fool@users.noreply.github.com> Date: Sun, 17 Dec 2023 21:10:18 +0800 Subject: [PATCH] feature: support monitoring pop3 metrics and add help doc (#1427) Co-authored-by: tomsun28 --- .../collect/pop3/Pop3CollectImpl.java | 183 ++++++++++++++ .../collector/dispatch/DispatchConstants.java | 4 + ...ertzbeat.collector.collect.AbstractCollect | 1 + .../hertzbeat/common/entity/job/Metrics.java | 6 +- .../entity/job/protocol/Pop3Protocol.java | 47 ++++ home/docs/help/nginx.md | 4 +- home/docs/help/pop3.md | 50 ++++ .../src/main/resources/define/app-pop3.yml | 225 ++++++++++++++++++ 8 files changed, 517 insertions(+), 3 deletions(-) create mode 100644 collector/src/main/java/org/dromara/hertzbeat/collector/collect/pop3/Pop3CollectImpl.java create mode 100644 common/src/main/java/org/dromara/hertzbeat/common/entity/job/protocol/Pop3Protocol.java create mode 100644 home/docs/help/pop3.md create mode 100644 manager/src/main/resources/define/app-pop3.yml diff --git a/collector/src/main/java/org/dromara/hertzbeat/collector/collect/pop3/Pop3CollectImpl.java b/collector/src/main/java/org/dromara/hertzbeat/collector/collect/pop3/Pop3CollectImpl.java new file mode 100644 index 00000000000..fb174c9676c --- /dev/null +++ b/collector/src/main/java/org/dromara/hertzbeat/collector/collect/pop3/Pop3CollectImpl.java @@ -0,0 +1,183 @@ +package org.dromara.hertzbeat.collector.collect.pop3; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.net.pop3.POP3MessageInfo; +import org.dromara.hertzbeat.collector.collect.AbstractCollect; +import org.dromara.hertzbeat.collector.dispatch.DispatchConstants; +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.Pop3Protocol; +import org.dromara.hertzbeat.common.entity.message.CollectRep; + +import org.apache.commons.net.pop3.POP3SClient; +import org.apache.commons.net.pop3.POP3Client; +import org.dromara.hertzbeat.common.util.CommonUtil; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * pop3 collect + * + */ +@Slf4j +public class Pop3CollectImpl extends AbstractCollect { + + private final static String EMAIL_COUNT = "email_count"; + private final static String MAILBOX_SIZE = "mailbox_size"; + + public Pop3CollectImpl() { + + } + + @Override + public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) { + long startTime = System.currentTimeMillis(); + + try { + validateParams(metrics); + } catch (Exception e) { + builder.setCode(CollectRep.Code.FAIL); + builder.setMsg(e.getMessage()); + return; + } + + Pop3Protocol pop3Protocol = metrics.getPop3(); + POP3Client pop3Client = null; + boolean ssl = Boolean.parseBoolean(pop3Protocol.getSsl()); + try { + pop3Client = createPOP3Client(pop3Protocol, ssl); + + if (pop3Client.isConnected()) { + long responseTime = System.currentTimeMillis() - startTime; + + obtainPop3Metrics(builder, pop3Client, metrics.getAliasFields(), + responseTime); + } else { + builder.setCode(CollectRep.Code.UN_CONNECTABLE); + builder.setMsg("Peer connect failed,Timeout " + pop3Protocol.getTimeout() + "ms"); + } + } catch (IOException e1) { + String errorMsg = CommonUtil.getMessageFromThrowable(e1); + log.info(errorMsg); + builder.setCode(CollectRep.Code.FAIL); + builder.setMsg(errorMsg); + } catch (Exception e2) { + String errorMsg = CommonUtil.getMessageFromThrowable(e2); + log.info(errorMsg); + builder.setCode(CollectRep.Code.FAIL); + builder.setMsg(errorMsg); + } finally { + if (pop3Client != null) { + try { + pop3Client.logout(); + pop3Client.disconnect(); + } catch (IOException e) { + String errorMsg = CommonUtil.getMessageFromThrowable(e); + log.info(errorMsg); + builder.setCode(CollectRep.Code.FAIL); + builder.setMsg(errorMsg); + } + } + } + } + + @Override + public String supportProtocol() { + return DispatchConstants.PROTOCOL_POP3; + } + + /** + * 校验参数 + * @param metrics + * @throws Exception + */ + private void validateParams(Metrics metrics) throws Exception { + Pop3Protocol pop3Protocol = metrics.getPop3(); + if (metrics == null || pop3Protocol == null || pop3Protocol.isInvalid()) { + throw new Exception("Pop3 collect must has pop3 params"); + } + } + + /** + * 创建POP3连接【支持SSL加密】 + * @param pop3Protocol + * @param ssl + * @return + * @throws IOException + */ + private POP3Client createPOP3Client(Pop3Protocol pop3Protocol, boolean ssl) throws Exception { + POP3Client pop3Client = null; + // 判断是否启用 SSL 加密连接 + if (ssl) { + pop3Client = new POP3SClient(true); + } else { + pop3Client = new POP3Client(); + } + // 设置超时时间 + int timeout = Integer.parseInt(pop3Protocol.getTimeout()); + if (timeout > 0) { + pop3Client.setConnectTimeout(timeout); + } + pop3Client.setCharset(StandardCharsets.UTF_8); + // 连接到POP3服务器 + String host = pop3Protocol.getHost(); + int port = Integer.parseInt(pop3Protocol.getPort()); + pop3Client.connect(host, port); + // 验证凭据 + String email = pop3Protocol.getEmail(); + String authorize = pop3Protocol.getAuthorize(); + boolean isAuthenticated = pop3Client.login(email, authorize); + if (!isAuthenticated) { + throw new Exception("Pop3 client authentication failed"); + } + return pop3Client; + } + + /** + * 获取Pop3指标信息 + * @param builder + * @param pop3Client + * @param aliasFields + * @param responseTime + */ + private void obtainPop3Metrics(CollectRep.MetricsData.Builder builder, POP3Client pop3Client, + List aliasFields, long responseTime) throws IOException { + Map pop3Metrics = parsePop3Metrics(pop3Client, aliasFields); + + CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder(); + for (String alias : aliasFields) { + Object value = pop3Metrics.get(alias); + if (value != null) { + valueRowBuilder.addColumns(String.valueOf(value)); + } else { + if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) { + valueRowBuilder.addColumns(String.valueOf(responseTime)); + } else { + valueRowBuilder.addColumns(CommonConstants.NULL_VALUE); + } + } + } + builder.addValues(valueRowBuilder); + } + + private Map parsePop3Metrics(POP3Client pop3Client, List aliasFields) throws IOException { + Map pop3Metrics = new HashMap<>(aliasFields.size()); + POP3MessageInfo status = pop3Client.status(); + int emailCount = 0; + double mailboxSize = 0.0; + if (status != null) { + emailCount = status.number; + // byte -> kb + mailboxSize = (double)status.size / 1024.0; + pop3Metrics.put(EMAIL_COUNT, emailCount); + pop3Metrics.put(MAILBOX_SIZE, mailboxSize); + } + return pop3Metrics; + } +} diff --git a/collector/src/main/java/org/dromara/hertzbeat/collector/dispatch/DispatchConstants.java b/collector/src/main/java/org/dromara/hertzbeat/collector/dispatch/DispatchConstants.java index 0e77f32a116..2bbb8918b09 100644 --- a/collector/src/main/java/org/dromara/hertzbeat/collector/dispatch/DispatchConstants.java +++ b/collector/src/main/java/org/dromara/hertzbeat/collector/dispatch/DispatchConstants.java @@ -107,6 +107,10 @@ public interface DispatchConstants { * protocol dns */ String PROTOCOL_DNS = "dns"; + /** + * protocol pop3 + */ + String PROTOCOL_POP3 = "pop3"; // Protocol type related - end // 协议类型相关 - end // diff --git a/collector/src/main/resources/META-INF/services/org.dromara.hertzbeat.collector.collect.AbstractCollect b/collector/src/main/resources/META-INF/services/org.dromara.hertzbeat.collector.collect.AbstractCollect index 796ca561afc..07a2fc05c6f 100644 --- a/collector/src/main/resources/META-INF/services/org.dromara.hertzbeat.collector.collect.AbstractCollect +++ b/collector/src/main/resources/META-INF/services/org.dromara.hertzbeat.collector.collect.AbstractCollect @@ -18,3 +18,4 @@ org.dromara.hertzbeat.collector.collect.push.PushCollectImpl org.dromara.hertzbeat.collector.collect.dns.DnsCollectImpl org.dromara.hertzbeat.collector.collect.nginx.NginxCollectImpl org.dromara.hertzbeat.collector.collect.memcached.MemcachedCollectImpl +org.dromara.hertzbeat.collector.collect.pop3.Pop3CollectImpl diff --git a/common/src/main/java/org/dromara/hertzbeat/common/entity/job/Metrics.java b/common/src/main/java/org/dromara/hertzbeat/common/entity/job/Metrics.java index e0def944e5d..b0a92f16f38 100644 --- a/common/src/main/java/org/dromara/hertzbeat/common/entity/job/Metrics.java +++ b/common/src/main/java/org/dromara/hertzbeat/common/entity/job/Metrics.java @@ -192,9 +192,13 @@ public class Metrics { */ private DnsProtocol dns; /** - * Monitoring configuration information using the public DNS protocol + * Monitoring configuration information using the public Nginx protocol */ private NginxProtocol nginx; + /** + * Monitoring configuration information using the public Nginx protocol + */ + private Pop3Protocol pop3; /** * collector use - Temporarily store subTask metrics response data diff --git a/common/src/main/java/org/dromara/hertzbeat/common/entity/job/protocol/Pop3Protocol.java b/common/src/main/java/org/dromara/hertzbeat/common/entity/job/protocol/Pop3Protocol.java new file mode 100644 index 00000000000..f71ee3903e6 --- /dev/null +++ b/common/src/main/java/org/dromara/hertzbeat/common/entity/job/protocol/Pop3Protocol.java @@ -0,0 +1,47 @@ +package org.dromara.hertzbeat.common.entity.job.protocol; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Pop3Protocol { + /** + * 接收服务器地址 + */ + private String host; + + /** + * 接收服务器端口 + */ + private String port; + + /** + * 超时时间 + */ + private String timeout; + + /** + * 是否开启SSL加密【邮箱传输】 + */ + private String ssl = "false"; + + /** + * pop邮箱地址 + */ + private String email; + + /** + * 授权码 + */ + private String authorize; + + public boolean isInvalid() { + return StringUtils.isAllBlank(host, port, timeout, ssl, email, authorize); + } +} diff --git a/home/docs/help/nginx.md b/home/docs/help/nginx.md index 76456eb650d..fa06c4cf759 100644 --- a/home/docs/help/nginx.md +++ b/home/docs/help/nginx.md @@ -2,7 +2,7 @@ id: nginx title: Monitoring Nginx sidebar_label: Nginx Monitor -keywords: [open source monitoring tool, open source java spark monitoring tool, monitoring nginx metrics] +keywords: [open source monitoring tool, open source java monitoring tool, monitoring nginx metrics] --- > Collect and monitor the general performance Metrics of Nginx. @@ -75,7 +75,7 @@ http { |---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Monitoring Host | Monitored IPV4, IPV6 or domain name. Note⚠️Without protocol header (eg: https://, http://) | | Monitoring name | Identify the name of this monitoring. The name needs to be unique | -| Port | Port provided by JMX | +| Port | Port provided by Nginx | | Timeout | Allow collection response time | | Collection interval | Interval time of monitor periodic data collection, unit: second, and the minimum interval that can be set is 30 seconds | | Whether to detect | Whether to detect and check the availability of monitoring before adding monitoring. Adding and modifying operations will continue only after the detection is successful | diff --git a/home/docs/help/pop3.md b/home/docs/help/pop3.md new file mode 100644 index 00000000000..822192ad66d --- /dev/null +++ b/home/docs/help/pop3.md @@ -0,0 +1,50 @@ +--- +id: pop3 +title: Monitoring POP3 +sidebar_label: POP3 Monitor +keywords: [open source monitoring tool, open source java monitoring tool, monitoring POP3 metrics] +--- + +> Collect and monitor the general performance Metrics of POP3. + +**Protocol Use:POP3** + +### Enable POP3 Service + +If you want to monitor information in 'POP3' with this monitoring type, you just need to open `POP3` service in your mail server. + +**1、Open `POP3` Service:** + +```text +以qq邮箱为例【其它邮箱类似】: + 1. 点击`设置`选项 + 2. 选择`账号` + 3. 找到开启SMTP/POP3/IMAP选项,并开启 + 4. 得到POP3服务器域名,端口号,以及授权码【开启SMTP/POP3/IMAP服务后,qq邮箱提供】 + 5. 通过POP3服务器域名,端口号,qq邮箱账号以及授权码连接POP3服务器,采集监控指标 +``` + + +### Configuration parameter + +| Parameter name | Parameter help description | +|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Monitoring Host | Monitored IPV4, IPV6 or domain name. Note⚠️Without protocol header (eg: https://, http://) | +| Monitoring name | Identify the name of this monitoring. The name needs to be unique | +| Port | Port provided by POP3 | +| SSL | POP3 If enabled SSL | +| Timeout | Allow collection response time | +| Collection interval | Interval time of monitor periodic data collection, unit: second, and the minimum interval that can be set is 30 seconds | +| Whether to detect | Whether to detect and check the availability of monitoring before adding monitoring. Adding and modifying operations will continue only after the detection is successful | +| Description remarks | For more information about identifying and describing this monitoring, users can note information here | + +### Collection Metrics + +#### Metrics Set:email_status + +| Metric name | Metric unit | Metric help description | +|--------------|-------------|------------------------------------------| +| email_count | | Number of emails | +| mailbox_size | kb | The total size of emails in the mailbox | + + diff --git a/manager/src/main/resources/define/app-pop3.yml b/manager/src/main/resources/define/app-pop3.yml new file mode 100644 index 00000000000..3452d0c65c5 --- /dev/null +++ b/manager/src/main/resources/define/app-pop3.yml @@ -0,0 +1,225 @@ +# 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. + +# 监控类型所属类别:service-应用服务 program-应用程序 db-数据库 custom-自定义 os-操作系统 bigdata-大数据 mid-中间件 webserver-web服务器 cache-缓存 cn-云原生 network-网络监控等等 +category: service +# 监控应用类型名称(与文件名保持一致) eg: linux windows tomcat mysql aws... +app: pop3 +# The app api i18n name +# app api国际化名称 +name: + zh-CN: POP3 + en-US: POP3 +# 监控类型的帮助描述信息 +help: + zh-CN: HertzBeat 使用 POP3 通过开启邮箱 pop3 服务 对 POP3服务器 的通用性能指标(email_count、mailbox_size)进行采集监控。
您可以点击“新建 POP3”并进行配置,或者选择“更多操作”,导入已有配置。 + en-US: HertzBeat uses POP3 to open pop3 service for collecting general metrics of POP3 Server (email_count, mailbox_size.).
You can click "New POP3" and configure it, or select "More Operations" to import the existing configuration. + zh-TW: HertzBeat 使用 POP3 通過开启邮箱 pop3 服务 對 POP3服务器 的通用性能指標(邮件数量、邮箱大小等)進行采集監控。
您可以點擊“新建 POP3”並進行配置,或者選擇“更多操作”,導入已有配置。 +helpLink: + zh-CN: https://hertzbeat.com/zh-cn/docs/help/pop3 + en-US: https://hertzbeat.com/docs/help/pop3 +# app api所需输入参数定义(根据定义渲染页面UI) +# Input params define for app api(render web ui by the definition) +params: + # field-param field key + # field-字段名称标识符 + - field: host + # name-param field display i18n name + # name-参数字段显示名称 + name: + zh-CN: 目标Host + en-US: Target Host + # 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: port + # name-param field display i18n name + # name-参数字段显示名称 + name: + zh-CN: 端口 + en-US: Port + # 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,65535]' + # required-true or false + # required-是否是必输项 true-必填 false-可选 + required: true + # default value + # 默认值 + defaultValue: 110 + # 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 + - field: ssl + # name-param field display i18n name + # name-参数字段显示名称 + name: + zh-CN: 启动SSL + en-US: SSL + # When the type is boolean, the frontend will display a switch for it. + # 当type为boolean时,前端用switch展示开关 + type: boolean + # required-true or false + # required-是否是必输项 true-必填 false-可选 + required: false + # field-param field key + # field-变量字段标识符 + - field: email + # name-param field display i18n name + # name-参数字段显示名称 + name: + zh-CN: POP邮箱地址 + en-US: Email + # type-param field type(most mapping the html input type) The type "text" belongs to a text input field. + # type-字段类型,样式(大部分映射input标签type属性) text类型属于文本输入框 + type: text + # required-true or false + # required-是否是必输项 true-必填 false-可选 + required: true + # field-param field key + # field-变量字段标识符 + - field: authorize + # name-param field display i18n name + # name-参数字段显示名称 + name: + zh-CN: 授权码 + en-US: Authorize Code + # type-param field type(most mapping the html input type) The type "text" belongs to a text input field. + # type-字段类型,样式(大部分映射input标签type属性) text类型属于文本输入框 + type: text + # required-true or false + # required-是否是必输项 true-必填 false-可选 + required: true + +# collect metrics config list +# 采集指标配置列表 +metrics: + # metrics - available + # 监控指标 - available + - name: available + i18n: + zh-CN: 通用指标 + en-US: Available + # 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 + # collect metrics content + # 具体监控指标列表 + fields: + # field-metric name, type-metric type(0-number,1-string), instance-is instance primary key, unit-metric unit + # 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位 + - field: responseTime + type: 0 + unit: ms + i18n: + zh-CN: 响应时间 + en-US: Response Time + # the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk + # 采集协议,目前支持sql,ssh,http,telnet,wmi,snmp,sdk + protocol: pop3 + # Specific collection configuration when protocol is http protocol + # 当protocol为http协议时具体的采集配置 + pop3: + # http host: ipv4 ipv6 domain + # 主机host: ipv4 ipv6 域名 + host: ^_^host^_^ + # http port + # 端口 + port: ^_^port^_^ + # timeout + # 超时时间 + timeout: ^_^timeout^_^ + # enable SSL/TLS, that is, whether it is http or https, the default is false + # 是否启用ssl/tls,即是http还是https,默认false + ssl: ^_^ssl^_^ + # email + # pop邮箱地址 + email: ^_^email^_^ + # password + # 授权码 + authorize: ^_^authorize^_^ + + - name: email_status + i18n: + zh-CN: 邮箱 状态信息 + en-US: Email Status + # 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: 1 + fields: + - field: email_count + type: 0 + i18n: + zh-CN: 邮箱数量 + en-US: Email Count + - field: mailbox_size + type: 0 + unit: KB + i18n: + zh-CN: 邮箱大小 + en-US: MailBox Size + # the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk + # 采集协议,目前支持sql,ssh,http,telnet,wmi,snmp,sdk + protocol: pop3 + # Specific collection configuration when protocol is http protocol + # 当protocol为http协议时具体的采集配置 + pop3: + # http host: ipv4 ipv6 domain + # 主机host: ipv4 ipv6 域名 + host: ^_^host^_^ + # http port + # 端口 + port: ^_^port^_^ + # timeout + # 超时时间 + timeout: ^_^timeout^_^ + # enable SSL/TLS, that is, whether it is http or https, the default is false + # 是否启用ssl/tls,即是http还是https,默认false + ssl: ^_^ssl^_^ + # email + # pop邮箱地址 + email: ^_^email^_^ + # password + # 授权码 + authorize: ^_^authorize^_^