-
Notifications
You must be signed in to change notification settings - Fork 999
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add smtp protocol and support smtp monitoring (#1407)
Co-authored-by: 东风 <1335799468@qq.com>
- Loading branch information
Showing
6 changed files
with
342 additions
and
0 deletions.
There are no files selected for viewing
120 changes: 120 additions & 0 deletions
120
collector/src/main/java/org/dromara/hertzbeat/collector/collect/smtp/SmtpCollectImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package org.dromara.hertzbeat.collector.collect.smtp; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.net.smtp.SMTP; | ||
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.SmtpProtocol; | ||
import org.dromara.hertzbeat.common.entity.message.CollectRep; | ||
import org.dromara.hertzbeat.common.util.CommonUtil; | ||
|
||
import java.io.IOException; | ||
import java.net.SocketException; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
|
||
/** | ||
* @author dongfeng | ||
*/ | ||
@Slf4j | ||
public class SmtpCollectImpl extends AbstractCollect { | ||
public SmtpCollectImpl() { | ||
} | ||
|
||
@Override | ||
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) { | ||
long startTime = System.currentTimeMillis(); | ||
if (metrics == null || metrics.getSmtp() == null) { | ||
builder.setCode(CollectRep.Code.FAIL); | ||
builder.setMsg("Smtp collect must has Smtp params"); | ||
return; | ||
} | ||
SmtpProtocol smtpProtocol = metrics.getSmtp(); | ||
String host = smtpProtocol.getHost(); | ||
String port = smtpProtocol.getPort(); | ||
int timeout = CollectUtil.getTimeout(smtpProtocol.getTimeout()); | ||
SMTP smtp = null; | ||
try { | ||
smtp = new SMTP(); | ||
smtp.setConnectTimeout(timeout); | ||
smtp.setCharset(StandardCharsets.UTF_8); | ||
smtp.connect(host, Integer.parseInt(port)); | ||
if (smtp.isConnected()) { | ||
long responseTime = System.currentTimeMillis() - startTime; | ||
List<String> aliasFields = metrics.getAliasFields(); | ||
|
||
Map<String, String> resultMap = execCmdAndParseResult(smtp, smtpProtocol.getCmd(), smtpProtocol); | ||
resultMap.put(CollectorConstants.RESPONSE_TIME, Long.toString(responseTime)); | ||
if (resultMap.size() < aliasFields.size()) { | ||
log.error("smtp response data not enough: {}", resultMap); | ||
builder.setCode(CollectRep.Code.FAIL); | ||
builder.setMsg("The cmd execution results do not match the expected number of metrics."); | ||
return; | ||
} | ||
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()); | ||
} else { | ||
builder.setCode(CollectRep.Code.UN_CONNECTABLE); | ||
builder.setMsg("Peer connect failed,Timeout " + timeout + "ms"); | ||
return; | ||
} | ||
smtp.disconnect(); | ||
} catch (SocketException socketException) { | ||
String errorMsg = CommonUtil.getMessageFromThrowable(socketException); | ||
log.debug(errorMsg); | ||
builder.setCode(CollectRep.Code.UN_CONNECTABLE); | ||
builder.setMsg("The peer refused to connect: service port does not listening or firewall: " + errorMsg); | ||
} catch (IOException ioException) { | ||
String errorMsg = CommonUtil.getMessageFromThrowable(ioException); | ||
log.info(errorMsg); | ||
builder.setCode(CollectRep.Code.UN_CONNECTABLE); | ||
builder.setMsg("Peer connect failed: " + errorMsg); | ||
} catch (Exception e) { | ||
String errorMsg = CommonUtil.getMessageFromThrowable(e); | ||
log.warn(errorMsg, e); | ||
builder.setCode(CollectRep.Code.FAIL); | ||
builder.setMsg(errorMsg); | ||
} finally { | ||
if (smtp != null) { | ||
try { | ||
smtp.disconnect(); | ||
} catch (Exception e) { | ||
log.warn(e.getMessage()); | ||
} | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public String supportProtocol() { | ||
return DispatchConstants.PROTOCOL_SMTP; | ||
} | ||
|
||
private static Map<String, String> execCmdAndParseResult(SMTP smtp, String cmd, SmtpProtocol smtpProtocol) throws IOException { | ||
Map<String, String> result = new HashMap<>(8); | ||
// 存入smtp连接的响应 | ||
result.put("smtpBanner", smtp.getReplyString()); | ||
smtp.helo(smtpProtocol.getEmail()); | ||
// 获取helo的响应 | ||
String replyString = smtp.getReplyString(); | ||
result.put("heloInfo", replyString); | ||
String[] lines = replyString.split("\n"); | ||
for (String line : lines) { | ||
if (line.startsWith("250")) { | ||
result.put("response", "OK"); | ||
} | ||
} | ||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
common/src/main/java/org/dromara/hertzbeat/common/entity/job/protocol/SmtpProtocol.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
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 SmtpProtocol { | ||
/** | ||
* email主机ip或域名 | ||
*/ | ||
private String host; | ||
|
||
/** | ||
* email主机端口 | ||
*/ | ||
private String port; | ||
|
||
/** | ||
* 超时时间 | ||
*/ | ||
private String timeout; | ||
|
||
/** | ||
* helo命令的测试者(email) | ||
*/ | ||
private String email; | ||
|
||
/** | ||
* 发送的命令 | ||
*/ | ||
private String cmd; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
# 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: smtp | ||
# 监控类型国际化名称 | ||
name: | ||
zh-CN: SMTP监控 | ||
en-US: SMTP MONITORS | ||
# The description and help of this monitoring type | ||
# 监控类型的帮助描述信息 | ||
help: | ||
zh-CN: HertzBeat 对 SMTP 服务的(Banner,helo响应)相关指标进行监测。 | ||
en-US: HertzBeat monitors the banner and hello response related indicators of the SMTP service. | ||
zh-TW: HertzBeat對SMTP服務的(Banner,helo響應)相關名額進行監測。 | ||
# 监控所需输入参数定义(根据定义渲染页面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: SMTP的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 | ||
# 是否是必输项 true-必填 false-可选 | ||
required: true | ||
# default value 25 | ||
# 默认值 25 | ||
defaultValue: 25 | ||
# 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-param field key | ||
# field-字段名称标识符 | ||
- field: email | ||
name: | ||
zh-CN: email | ||
en-US: email | ||
type: text | ||
# required-true or false | ||
# 是否是必输项 true-必填 false-可选 | ||
required: true | ||
# 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: response | ||
type: 1 | ||
i18n: | ||
zh-CN: 响应状态 | ||
en-US: Response | ||
- field: smtpBanner | ||
type: 1 | ||
i18n: | ||
zh-CN: SMTP的Banner | ||
en-US: SMTPBanner | ||
- field: heloInfo | ||
type: 1 | ||
i18n: | ||
zh-CN: Helo日志 | ||
en-US: HeloInfo | ||
# - field: emailMaxSize | ||
# type: 0 | ||
# unit: byte | ||
# i18n: | ||
# zh-CN: 最大邮件大小 | ||
# en-US: EmailMaxSize | ||
# - field: serverInfo | ||
# type: 1 | ||
# i18n: | ||
# zh-CN: 服务器相关信息 | ||
# en-US: ServerInfo | ||
# - field: heloInfo | ||
# type: 1 | ||
# i18n: | ||
# zh-CN: Helo日志 | ||
# en-US: HeloInfo | ||
|
||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk | ||
# 采集协议, 目前支持sql, ssh, http, telnet, wmi, snmp, sdk | ||
protocol: smtp | ||
# Specific collection configuration when protocol is telnet protocol | ||
# 当protocol为telnet协议时具体的采集配置 | ||
smtp: | ||
# telnet host | ||
# 远程登录主机 | ||
host: ^_^host^_^ | ||
# port | ||
# 端口 | ||
port: ^_^port^_^ | ||
# timeout | ||
# 超时时间 | ||
timeout: ^_^timeout^_^ | ||
# email(helo命令所需) | ||
email: ^_^email^_^ |