Python脚本化监控 HTTP WEB服务端口状态和邮件告警

起因:

        自己的MC服务器需要一个监控告警的小脚本

优化:

        以后优化一下,用阿里云服务进行部署

代码实现:

# !/usr/bin/python3
# -*- coding=utf-8 -*-
# @Author  : 世界
# @file: PortMonitor.py
# @time: 2020-12-30  12:27:02


from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import time
import smtplib
import email
import socket
import logging

# 使用socket获取端口状态
def get_ip_status(server_ip, port):
    # 创建一个名为sk的socket连接
    sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # socket超时时间3秒
    sk.settimeout(3)
    try:
        # 尝试connect 服务的端口, 若成功则返回 True
        sk.connect((server_ip, port))
        return True
    except Exception:
        # 若是不成功或其他错误,都返回 False
        return False
    # 最后一定要记得结束掉socket,,否则会占用大量资源导致系统宕机
    sk.close()


# 邮件发送模块
# 这里设置你自己的邮件服务信息
def smtp_sendmail(Subj, Main_Body, To):
    mailserver = 'smxxtp.mxxxhichina.com'
    username = 'system@xxx.top'
    password = '123456'
    From = 'system@xxx.top'

    Tos = To.split(';')
    Date = email.utils.formatdate()
    msg = MIMEMultipart()
    msg["Subject"] = Subj
    msg["From"] = From
    msg["To"] = To
    msg["Date"] = Date

    part = MIMEText(Main_Body)
    msg.attach(part)

    server = smtplib.SMTP_SSL(mailserver, 465)
    server.login(username, password)
    failed = server.sendmail(From, Tos, msg.as_string())
    server.quit()

    if failed:
        print('Email sending failed ! The error message is as follows: ', failed)
        return 0 # 判断邮件发送状态,失败则返回0
    else:
        print('Email sent successfully ! ')
        return 1 # 成功则返回1


# 监控函数
def main():
    cu_time = time.asctime()
    host = '13.15.1.12'
    port = 9898
    second = 300  # 每300秒检查一次端口是否开放
    recipients = 'nxx@123.com'  # 收件人email地址
    logname = 'PortMonitoring.log'  #   # logging日志记录

    # logging 输出样式为 时间--告警等级--会话信息; error以下的info等信息不会显示在stdout上面
    LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
    # 格式化以下logging里面的时间显示格式
    DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"

    # logging 初始化
    logging.basicConfig(filename=logname, level=logging.DEBUG, format=LOG_FORMAT, datefmt=DATE_FORMAT)

    i_close = 0  # 端口关闭时邮件发送的次数累加器, 目前仅允许状态close时发送一次邮件
    i_open = 0  # 端口开启时邮件发送的次数累加器, 目前仅允许状态close时发送一次邮件
    while True:
        # 加入了仅在接口状态第一次Up Down改变时,自动发送邮件
        try:
            res = get_ip_status(host, port)  # 获取端口状态信息
            if int(res) == 0:
                # stdout打印下信息
                print('{2} >>> Error ! {0} port {1} is not open !'.format(host, port, cu_time))
                # logging 记录当前端口关闭信息
                logging.error('Error  >>>  {0} port {1} is not open !'.format(host, port))

                time.sleep(1)  # 间隔一秒钟
                reconfirm = get_ip_status(host, port)  # 再次获取端口的状态信息是否时close状态,
                if int(res) == 0 and reconfirm == 0 and i_close < 1:  # 再次获得的
                    Subj = 'Error! {0} port {1} is not open ! Time: {2}'.format(host, port, cu_time)
                    Main_Body = ''
                    To = recipients
                    # 发送告警邮件
                    smtp_sendmail(Subj, Main_Body, To)
                    i_close += 1  # 邮件发送后,将close计数器+1,配合前面的的if i_close < 1 可以仅发送第一次端口状态变化邮件
                    i_open = 0   # 将open的计数器 置0, 这样端口恢复正常后会执行elif int(res) == 1后面的代码,从而发送状态变法邮件
                    logging.error('Info  >>>  {0} port {1} is not open ! Email has been sent ! '.format(host, port))
                time.sleep(second)   # 执行一次后 休眠300秒
            elif int(res) == 1:
                print('{0} port {1} is open !'.format(host, port))
                logging.info('{0} port {1} is open !'.format(host, port))
                if i_open < 1:
                    Subj = 'Info! {0} port {1} is open ! Time: {2}'.format(host, port, cu_time)
                    Main_Body = ''
                    To = recipients
                    smtp_sendmail(Subj, Main_Body, To)
                    logging.error('Info  >>>  {0} port {1} is open ! Email has been sent ! '.format(host, port))
                    i_open += 1  # 邮件发送后,将open计数器+1,配合前面的的 if i_open < 1 可以仅发送第一次端口状态变化邮件
                    i_close = 0  # 将close的计数器 置0, 这样端口恢复正常后会执行if int(res) == 1后面的代码,从而发送状态变法邮件
                time.sleep(second)
        except Exception as e:
            # 异常日志 仅记录,不发送告警邮件
            print('Critica  >>>  An unexpected error occurred ! >>> Detail: {}'.format(e))
            logging.critical('An exception occurred while checking the port !   >>>   Detail: {}'.format(e))

            # Subj = 'Port Exception Error !'
            # Main_Body = '''
            #             Port Exception Error !\n\n\n
            #             {}\n\n
            #             {}
            #             '''.format(e, cu_time)
            # To = recipients
            # smtp_sendmail(Subj, Main_Body, To)


if __name__ == '__main__':
    # check_result = get_ip_status('139.155.91.142', 9898)
    # print(check_result[1])
    # 其实目前版本有一个bug ,在端口剧烈up down的时候无法自动识别,此时会频繁发送告警邮件
    main()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值