Python自动化运维监控——批量监听页面发邮件(自由配置ini文件+smtplib)

news2024/9/21 12:31:13

一、程序样式

1.listen.ini配置文件
listen.ini
2.监控页面
listen
3.日志
log

二、核心点

  1. smtplib库:这里使用了smtp.qq.comsmtp.163.com两个发送邮件的地址,使用邮箱用户名与授权码来实现登录,端口都使用465,最后抛出异常,finally里面最好判断一下srv这个变量存不存在,有可能断网就会导致登录失败,从而srv变量没有,最后srv.quit()最后报错
try:
    # 不能直接使用smtplib.SMTP来实例化,第三方邮箱会认为它是不安全的而报错
    # 使用加密过的SMTP_SSL来实例化,它负责让服务器做出具体操作,它有两个参数
    # 第一个是服务器地址,但它是bytes格式,所以需要编码
    # 第二个参数是服务器的接受访问端口,SMTP_SSL协议默认端口是465   25
        srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465)
    # 使用授权码登录邮箱
        srv.login(from_addr, from_pwd)
 
    # 使用sendmail方法来发送邮件,它有三个参数
    # 第一个是发送地址
    # 第二个是接受地址,是list格式,可以同时发送给多个邮箱
    # 第三个是发送内容,作为字符串发送
        for to_addr in to_addrs:
            srv.sendmail(from_addr, [to_addr], msg.as_string())
            # srv.sendmail(from_addr, [to_addr1], msg.as_string())
            logger.info(to_addr+'发送成功')
    except Exception as e:
        logger.error('发送失败  '+str(e))
    finally:
    #无论发送成功还是失败都要退出你的QQ邮箱 检测srv是否存在  不检测会程序报错
        if 'srv' in globals():
            srv.quit()

2.读取ini配置文件:实现已定义参数,配置发件人、邮件邮箱,选择邮箱地址smtp.qq.com/smtp.163.com、邮件标题、监控页面地址(批量)、邮件人邮箱(批量)等参数,这里获取linten.ini配置文件的绝对路径有个问题,需要使用 sys.agrv[0]获取真实路径,不然就可能获取的是打包的程序.exe的系统路径temp

    #获取当前目录路径
    proDir = os.path.dirname(os.path.realpath(sys.argv[0]))
import os
import configparser
import sys

# 读取配置文件
def getConfig(filename, section, option):
    """
    :param filename 文件名称
    :param section: 服务
    :param option: 配置参数
    :return:返回配置信息
    """
 	 # 获取当前目录路径
    proDir = os.path.dirname(os.path.realpath(sys.argv[0]))
    # print(proDir)

    # 拼接路径获取完整路径
    configPath = os.path.join(proDir, filename)
    # print(configPath)

    # 创建ConfigParser对象
    conf = configparser.ConfigParser()

    # 读取文件内容
    conf.read(configPath,'utf-8')
    config = conf.get(section, option)
    return config

 # 发件人
    from_name = getConfig('listen.ini','listen','from_name')
    # 发件邮箱
    from_addr = getConfig('listen.ini','listen','from_addr')
    # 发件邮箱授权码,注意不是QQ邮箱密码
    from_pwd = getConfig('listen.ini','listen','from_pwd')
    # 收件邮箱
    to_addrs = getConfig('listen.ini','listen','to_addrs')
    to_addrs = to_addrs.split(',')
    # 邮件标题
    my_title = getConfig('listen.ini','listen','my_title')
 

3.日志输入logger.error()、logger.info()、 logger.warning()、 logger.debug()

logger = logging.getLogger()
    logger.setLevel(logging.INFO) 
    #设置将日志输出到文件中,并且定义文件内容
    now = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    fileinfo = logging.FileHandler(f"listen_{now}.log")
    fileinfo.setLevel(logging.INFO) 
    #设置将日志输出到控制台
    controlshow = logging.StreamHandler()
    controlshow.setLevel(logging.INFO)
    #设置日志的格式
    formatter = logging.Formatter("%(asctime)s - %(levelname)s: %(message)s")
    fileinfo.setFormatter(formatter)
    controlshow.setFormatter(formatter)
    logger.addHandler(fileinfo)
    logger.addHandler(controlshow)


4.requests监控页面这里我判断了status_code,如果不是200就会发邮件,并且写了几个异常情况,也同样会记录日志与发邮件,并且当邮件数量达到5封,就会延时30分钟后,在检测,如果依旧有问题,就再发五封。

    urls = getConfig('listen.ini','listen','urls')
    urls = urls.split(',')
    while True: 
        for url in urls:
            try:
                response = requests.get(url,timeout=5)
                code = response.status_code
                body = str(url) + ' 运行异常,状态码:' + str(code) + '  请检查服务运行情况'
                # 定义邮件数量5
                i = 0
                if code != 200:
                    i += 1
                    logger.error(body)
                    send_mail(body)
                    if i >= 5:
                        # 延时30分钟
                        time.sleep(1800) 
                        i = 0
            except exceptions.HTTPError as e:
                logger.error("发生HTTP错误,原因是:"+ str(e))
                send_mail("发生HTTP错误,原因是:"+ str(e))
                time.sleep(5)
            except exceptions.Timeout as e:
                logger.error("访问超时,原因是:"+ str(e))
                send_mail("访问超时,原因是:"+ str(e))
                time.sleep(5)
            except Exception as e:
                logger.error("未知错误,原因是:" + str(e))
                send_mail("未知错误,原因是:" + str(e))
                time.sleep(5)

三、完整代码

listen.py

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
import requests
import logging
import datetime
import time 
from requests import exceptions
from getConfig import getConfig

def send_mail(body):
    # 发件人
    from_name = getConfig('listen.ini','listen','from_name')
    # 发件邮箱
    from_addr = getConfig('listen.ini','listen','from_addr')
    # 发件邮箱授权码,注意不是QQ邮箱密码
    from_pwd = getConfig('listen.ini','listen','from_pwd')
    # 收件邮箱
    to_addrs = getConfig('listen.ini','listen','to_addrs')
    to_addrs = to_addrs.split(',')
    # 邮件标题
    my_title = getConfig('listen.ini','listen','my_title')
    # 邮件正文
    msg = MIMEText(body, 'plain', 'utf-8')
    msg['From'] = formataddr([from_name, from_addr])
    # 邮件的标题
    msg['Subject'] = my_title
    
    # SMTP服务器地址,QQ邮箱的SMTP地址是"smtp.qq.com"
    # smtp_srv = "smtp.qq.com"
    smtp_srv = getConfig('listen.ini','listen','smtp_srv')
 
    try:
    # 不能直接使用smtplib.SMTP来实例化,第三方邮箱会认为它是不安全的而报错
    # 使用加密过的SMTP_SSL来实例化,它负责让服务器做出具体操作,它有两个参数
    # 第一个是服务器地址,但它是bytes格式,所以需要编码
    # 第二个参数是服务器的接受访问端口,SMTP_SSL协议默认端口是465   25
        srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465)
    # 使用授权码登录QQ邮箱
        srv.login(from_addr, from_pwd)
 
    # 使用sendmail方法来发送邮件,它有三个参数
    # 第一个是发送地址
    # 第二个是接受地址,是list格式,可以同时发送给多个邮箱
    # 第三个是发送内容,作为字符串发送
        for to_addr in to_addrs:
            srv.sendmail(from_addr, [to_addr], msg.as_string())
            # srv.sendmail(from_addr, [to_addr1], msg.as_string())
            logger.info(to_addr+'发送成功')
    except Exception as e:
        logger.error('发送失败  '+str(e))
    finally:
    #无论发送成功还是失败都要退出你的QQ邮箱 检测srv是否存在  不检测会程序报错
        if 'srv' in globals():
            srv.quit()

if __name__ == '__main__':
    logger = logging.getLogger()
    logger.setLevel(logging.INFO) 
    #设置将日志输出到文件中,并且定义文件内容
    now = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    fileinfo = logging.FileHandler(f"listen_{now}.log")
    fileinfo.setLevel(logging.INFO) 
    #设置将日志输出到控制台
    controlshow = logging.StreamHandler()
    controlshow.setLevel(logging.INFO)
    #设置日志的格式
    formatter = logging.Formatter("%(asctime)s - %(levelname)s: %(message)s")
    fileinfo.setFormatter(formatter)
    controlshow.setFormatter(formatter)
    logger.addHandler(fileinfo)
    logger.addHandler(controlshow)


    
    # os.system('pause')
    print(  " ...............正在监听V8移动端wechat...............")
    print(	" .....................阿弥陀佛.......................")
    print(	"                       _oo0oo_                      ")
    print(	"                      o8888888o                     ")
    print(	'                      88" . "88                     ')
    print(	"                      (| -_- |)                     ")
    print(	"                      0\\  =  /0                    ")
    print(	"                   ___/‘---’\\___                   ")
    print(	"                  .' \\|       |/ '.                ")
    print(	"                 / \\\\|||  :  |||// \\             ")  
    print(	"                / _||||| -卍-|||||_ \\              ")
    print(	"               |   | \\\\\\  -  /// |   |           ")  
    print(	"               | \\_|  ''\\---/''  |_/ |            ") 
    print(	"               \\  .-\\__  '-'  ___/-. /            ") 
    print(	"             ___'. .'  /--.--\\  '. .'___           ")
    print(	"         ."" ‘<  ‘.___\\_<|>_/___.’>’ "".           ")
    print(	"       | | :  ‘- \\‘.;‘\\ _ /’;.’/ - ’ : | |        ")
    print(	"         \\  \\ ‘_.   \\_ __\\ /__ _/   .-’ /  /    ")   
    print(	"    =====‘-.____‘.___ \\_____/___.-’___.-’=====     ")
    print(	"                       ‘=---=’                      ")
    print(	"                                                    ")
    print(	"..................佛祖保佑, 一直监听..................")

    urls = getConfig('listen.ini','listen','urls')
    urls = urls.split(',')
    while True: 
        for url in urls:
            try:
                response = requests.get(url,timeout=5)
                code = response.status_code
                body = str(url) + ' 运行异常,状态码:' + str(code) + '  请检查服务运行情况'
                # 定义邮件数量5
                i = 0
                if code != 200:
                    i += 1
                    logger.error(body)
                    send_mail(body)
                    if i >= 5:
                        # 延时30分钟
                        time.sleep(1800) 
                        i = 0
            except exceptions.HTTPError as e:
                logger.error("发生HTTP错误,原因是:"+ str(e))
                send_mail("发生HTTP错误,原因是:"+ str(e))
                time.sleep(5)
            except exceptions.Timeout as e:
                logger.error("访问超时,原因是:"+ str(e))
                send_mail("访问超时,原因是:"+ str(e))
                time.sleep(5)
            except Exception as e:
                logger.error("未知错误,原因是:" + str(e))
                send_mail("未知错误,原因是:" + str(e))
                time.sleep(5)

getConfig.py

import os
import configparser
import sys

# 读取配置文件
def getConfig(filename, section, option):
    """
    :param filename 文件名称
    :param section: 服务
    :param option: 配置参数
    :return:返回配置信息
    """
 	 # 获取当前目录路径
    proDir = os.path.dirname(os.path.realpath(sys.argv[0]))
    # print(proDir)

    # 拼接路径获取完整路径
    configPath = os.path.join(proDir, filename)
    # print(configPath)

    # 创建ConfigParser对象
    conf = configparser.ConfigParser()

    # 读取文件内容
    conf.read(configPath,'utf-8')
    config = conf.get(section, option)
    return config

listen.ini

[listen]
#发件人
from_name = XXX
#登录邮箱地址 smtp.qq.com   smtp.163.com
smtp_srv = smtp.163.com
#发件邮箱
from_addr = xxxxxxxxxx@163.com
#发件邮箱授权码,请在qq 163邮箱账户选项里面查询
from_pwd = xxxxxxxxxxxx
#收件邮箱
to_addrs = xxxxx@dingtalk.com
#邮件标题
my_title = XXXXXXX异常告警

#监控地址
urls = http://ecard.swpu.edu.com,127.0.0.1:80,xxxxxxxxx

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1153263.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分享一下微信小程序抽奖链接怎么做

标题&#xff1a;微信小程序抽奖链接制作全攻略&#xff0c;轻松玩转营销抽奖活动 一、引言 在当今的数字化时代&#xff0c;抽奖活动已经成为一种高效的市场营销策略&#xff0c;而微信小程序作为一个功能强大的移动端平台&#xff0c;为企业和个人提供了制作抽奖链接的便捷…

如何能够根据现有业务,结合代码清晰的知道技术实现是如何去实现的,方法论和切入点是什么?

要深入了解现有业务系统的技术实现&#xff0c;特别是当你想要准确理解某个具体功能或组件是如何实现的时候&#xff0c;你可以采取以下的方法论和切入点&#xff1a; 1. 文档和设计说明 首先查阅相关的技术文档和设计说明&#xff0c;这些文档通常会详细描述系统的架构、各个…

STM32———USART串口控制LED灯亮灭

1.硬件设计流程 2.程序设计流程 1.串口初始化时钟使能&#xff1a;RCC_APBxPeriphClockCmd(); GPIO初始化时钟使能&#xff1a;RCC_AHBxPeriphClockCmd();2.GPIO端口模式配置&#xff1a;GPIO_Init();3.串口参数初始化&#xff1a;USART_Init();4.串口使能&#xff1a;USART_C…

如何在React项目中引用less

安装less npm install less less-loader --save-dev暴露 webpack 文件 利用 npx create-react-app 搭建的 React 项目&#xff0c;默认隐藏 webpack 配置文件&#xff0c;引入 less 需要修改 webpack 配置文件&#xff0c;因此我们需要执行命令暴露 webpack 配置文件。 请先将…

SRM系统采购功能

SRM系统采购是企业为了优化供应链管理而采购的一种信息系统。它旨在帮助企业与供应商之间建立良好的合作关系&#xff0c;提供全面的供应商管理功能&#xff0c;以实现采购的效率和效益最大化。 首先&#xff0c;SRM系统采购在企业供应链管理中具有重要的意义。供应链是企业与供…

2023最新版本 FreeRTOS教程 -1-标准库移植FreeRTOS

源码下载 官网下载驱动 点击直达 源码剪裁 剪裁之后的图片,找我免费获取 添加进MDK 配置滴答定时器 全部工程获取 查看下方头像

pycharm使用ssh连接远程jupyter

1. 安装jupyter pip install jupyter2. 生成jupyter_notebook_config.py文件 jupyter notebook --generate-config3. 设置命令参数 jupyter notebook --no-browser --allow-root --port 8900配置Jupyter服务器 将上面的代码复制到命令行实参中&#xff1a;

[NISACTF 2022]is secret RC4加密执行SSTI

这里结合了加密 记录一下 首先获取 啥都没得 扫一下目录 都看看 后面发现 http://node5.anna.nssctf.cn:28378/secret 这个页面 Tell me 是不是就是传参 我们get传递一个看看 http://node5.anna.nssctf.cn:28378/secret?secret{{49}} 发生报错 出现了 框架 这…

企业内部外网向内网传输文件如何实现高效安全?

随着信息技术的发展&#xff0c;企业内部外网隔离已成为一种常见的网络安全措施&#xff0c;旨在防止外部攻击者入侵内部网络&#xff0c;保护企业的核心数据和业务系统。然而&#xff0c;企业内外网隔离也带来了一些问题&#xff0c;其中之一就是如何实现内外网之间的文件传输…

数据库查询语句字段不匹配不报错,删除语句字段不匹配报错?

使用了很多的mybatisplus导致了遇到mybatis有点忘记了。工作遇到了这样的一个错误&#xff1a; Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column userId in where clause at sun.reflect.NativeConstructorAccessorImpl.newInstance0(…

大模型该被知道的技术实现-面向垂直领域

一个高度清晰的思维导图截图奉上&#xff08;下载&#xff1a;需3积分&#xff09; 内容截图

【HDFS】Client写三副本数据pipeline恢复的一些总结

一、前言&闲聊 我们知道,HDFS客户端在写三副本的情况下,会建立一个pipeline,然后client不断地把数据发送到pipeline里的第一个datanode,然后第一个datanode再顺着pipeline往下游datanode传递数据。写pipeline的过程模型图如下所示: 这里HDFS有个优化,如果pipeline里…

MySQL系列-架构体系、日志、事务

MySQL架构 server 层 &#xff1a;层包括连接器、查询缓存、分析器、优化器、执行器等&#xff0c;涵盖 MySQL 的大多数核心服务功能&#xff0c;以及所有的内置函数&#xff08;如日期、时间、数学和加密函数等&#xff09;&#xff0c;所有跨存储引擎的功能都在这一层实现&am…

okcc呼叫系统运行模式及特点

okcc呼叫中心外呼系统是系统供应商打造的一款专为营销类坐席提供外呼功能的软件&#xff0c;也就是常见的外呼系统&#xff0c;操作简单功能比较单一。 okcc呼叫中心外呼系统是一种SaaS租用模式的外呼系统&#xff0c;成本比较低&#xff0c;运营商部署在公有云服务器上&#x…

跨境电商卖家必备:自养号测评的显著优势与多重功能解析!

自养号测评&#xff0c;对于跨境电商卖家而言&#xff0c;是一种至关重要的运营手段。通过这种方式&#xff0c;卖家能够迅速增加产品销量、评论数量&#xff0c;提升在平台中的排名&#xff0c;进而促进产品的流量转化和订单增长。与传统机刷方式不同&#xff0c;自养号测评采…

②【MySQL表操作】 数据库表的创建、查询、修改、删除

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ ②【表操作】 数据库表的创建、查询、修改、删…

Inspeckage,动态分析安卓 APP 的 Xposed 模块

前提 我在不久前写过《 APP 接口拦截与参数破解》的博文&#xff1b;最近爬取APP数据时又用到了相关技术&#xff0c;故在此详细描述一下 Inspeckage 的功能。&#xff08;环境准备本文不再赘述&#xff09; 功能 在电脑上访问 http://127.0.0.1:8008 就可以看到 inspeckage…

win11系统自带便利签

步骤如下&#xff1a; 在搜索框输入 便笺 2. 打开及用。

实现基于 Azure DevOps 的数据库 CI/CD 最佳实践

数据库变更一直是整个应用发布过程中效率最低、流程最复杂、风险最高的环节&#xff0c;也是 DevOps 流程中最难以攻克的阵地。那我们是否能在具体的 CI/CD 流程中&#xff0c;像处理代码那样处理数据库变更呢&#xff1f; DORA 调研报告 DORA&#xff08;DevOps Research &am…

图纸管理制度《七》

1、目的&#xff1a; 明确技术图样与文件的签署、更改及标准化等内容&#xff0c;对技术图样与文件进行有效的控制。技术文化是公司的核心秘密&#xff0c;是公司能够持续发展并在市场上保持强势竞争力的有力保障&#xff0c;公司的技术文件属于公司所有&#xff0c;公司的每一…