python 脚本 bug 报警通知 的代码设计 邮件, 钉钉,报警,计时

使用场景:

监控脚本或某个方法是否正常运行, 若BUG,则报警, 有多种方式,目前我用到钉钉和邮件报警

使用提示:

不建议直接 copy代码使用, 因为这是从我的框架里抠出来的代码, 脱离我的框架不能保证正常运行.

  1. 为什么会有if debug: 这样的语句
    我配置的环境有生产环境产品环境两个, 生产环境下debug=Ture, 产品环境下debug=False ,所有报警只在产品环境下起作用., 你肯定不想一边调试代码一边在群里被疯狂@

邮件报警:

可以将这个方法做为装饰器使用会非常方便:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @File    :   mailsender.py
# @Time    :   2019/09/26 14:44:50
# @Author  :   liuzhanghong
# @Contact :   liuzhanghong@bj-cib.com
# @Version :   2.0
# @Desc    :   发邮件的组件, 已封装CIBsender, 可以登录后直接使用.


import os, sys
import smtplib  
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.header import Header
from email import encoders
import traceback
import logging

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


class MailSender(object):
    """
    发邮件, 支持中文名字的附件目录
    """
    
    def __init__(self, smtpSvr, port, user, pwd, is_ssl=False):
        """
        初始化
        smtp: string SMTP服务器地址
        port: int SMTP端口号
        user: string 发件人邮箱地址
        pwd: string 发件人邮箱密码
        """
        print('SMTP server init...')
        if not is_ssl:
            self.smtp = smtplib.SMTP()
        else:
            self.smtp = smtplib.SMTP_SSL()
        self.smtp.connect(smtpSvr, port)
        self._from = user
        print('loging...')
        self.smtp.login(user, pwd)
        print('logined, get ready data...')

    def send(self, subject, content, to_addrs, cc_addrs=None, attachs=None):
        """
        发送邮件
        subject: string 邮件标题
        content: string 邮件正文
        to_addrs: [] 收件人列表
        cc_addrs: [] 抄送人列表
        attachs: [] 附件的绝对路径列表
        """
        if cc_addrs is None:
            cc_addrs = []
        if attachs is None:
            attachs = []
        to_addrs.extend(cc_addrs)
        msg = MIMEMultipart('alternative')
        contents = MIMEText(content, "html", _charset='utf-8')
        msg.attach(contents)
        msg['Subject'] = subject
        msg['From'] = self._from
        msg['Cc'] = Header(','.join(cc_addrs))
        msg['To'] = Header(','.join(to_addrs))
        for file in attachs:
            basename = os.path.basename(file)
            att = MIMEText(open(file, 'rb').read(), 'base64', 'utf-8')
            att["Content-Type"] = 'application/octet-stream'
            att.add_header('Content-Disposition', 'attachment', filename=('gbk', '', basename))
            # encoders.encode_base64(att)  # 去掉注释后,中文内容会显示乱码
            msg.attach(att)
        try:
            self.smtp.sendmail(self._from, to_addrs, msg.as_string())
            logger.info(f'{subject} send sucess')
        except Exception as e:
            traceback.print_exc()
            logger.info(f'{subject} send fail')

    def close(self):
        self.smtp.quit()


class Sender(MailSender):
    """可以定制为公司专用发邮件组件,这里已经封装腾讯企业邮配置, 但需要登录自己的邮箱"""
    def __init__(self, user='test@test.com', pwd='test', smtpSvr='smtp.exmail.qq.com', port=465, is_ssl=True):
        """
        user: string 发件人邮箱地址
        pwd: string 发件人邮箱密码
        """
        if not is_ssl:
            self.smtp = smtplib.SMTP()
        else:
            self.smtp = smtplib.SMTP_SSL()
        self.smtp.connect(smtpSvr, port)
        self._from = user
        self.smtp.ehlo()
        self.smtp.login(user, pwd)
        
    def __str__(self):
        return '已封装腾讯企业邮 需要用户名和密码进行登录初始化...'
        

if __name__ == "__main__":
    Sender().send('this is a test subject', 'content for test', ['liuzhanghong@bj-cib.com'])

import mail
mail = mail.Sendmail(from_email='myemail@example.com', from_email_pwd='pwd')

def debug_timeit(code_path):
    """
    该装饰器主要功能用捕捉异常后发送报警邮件:
    code_path 为代码路径,用于报错时,提示文件的位置
    """
    def _deco(func):
        def wrapper(*args, **kw):
            try:
                startTime = int(round(time.time() * 1000))
                result = func(*args, **kw)
                endTime = int(round(time.time() * 1000))
                seconds = (endTime - startTime)/1000
                print('start_time:{} end_time: {}, cost: {}'.format(startTime,endTime,seconds))
            except Exception as e:
                if debug:
                    print('DEBUG = True,正在调试代码,不需发DEBUG邮件')
                else:
                    print('DEBUG = False, 若报错,将收到报错邮件')
                    error_text = '<p>' + traceback.format_exc() + '</p>'
                    mail.sendmail(title='错误! 代码文件为:{}'.format(code_path), content=error_text,
		                                     to_emails=['test@163.com'])
            return result 
        return wrapper
    return _deco


# 具体的使用方法如下:

@ debug_timeit(code_path=__file__)
def test_debug(test):
	return int(test)

钉钉报警

import requests
import traceback


def dingding(at_mobiles, content, group_name='dingding_group'):
    """
    目前钉钉通知仅支持将报警消息发到钉钉群里, 不能钉钉到个人,
    请将你的钉钉群的token 更新到tokens里.
    """
    try:
        tokens = {
        'dingding_group': 'group_token'
        }
        access_token = tokens.get(group_name, tokens['dingding_group'])
        dd_api = f'https://oapi.dingtalk.com/robot/send?access_token={access_token}' 
        dd_json = {
            "msgtype": "text",
            "text": {
                "content": content
            },
            "at": {
                "atMobiles": at_mobiles,
                "isAtAll": False
            }
        }
        requests.post(dd_api, json=dd_json)
    except Exception as e:
        traceback.print_exc()



def debug_ding(at_mobiles, content, group_name='dingding_group'):
    """
    正式例行化时使用
    该装饰器主要功能用捕捉异常后发送到钉钉群里:
    """

    def _deco(func):
        def wrapper(*args, **kw):
            try:
                startTime = int(round(time.time() * 1000))
                result = func(*args, **kw)
                endTime = int(round(time.time() * 1000))
                seconds = (endTime - startTime)/1000
                print('start_time:{} end_time: {}, cost: {}'.format(startTime, endTime, seconds))
            except Exception as e:
                if debug:
                    print('DEBUG = True,正在调试代码,不需发dingding')
                else:
                    print('DEBUG = False,请注意查收dingding通知')
                    dingding(at_mobiles=at_mobiles, content=content, group_name=group_name )
            return result
        return wrapper
    return _deco


# 具体的使用方法如下:

@ debug_ding(['18111181112', '18711171117'], '这里有BUG了, 快来看看呀', 'dingding_group')
def test_debug(test):
	return int(test)

我知道微信也是OK的. 只是我工作中钉钉比较多.😃

欢迎沟通指正

end

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值