实现celery中出现拥挤队列时,及时发邮件通知

时间:2023-03-08 20:52:31

里面有几个常用的功能,以后值得借鉴。

如获取脚本目录,IP,获取shell返回值,发送邮件等..

上午写完,中午测试,下午上线~~

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import smtplib
from email.mime.text import MIMEText
import socket
import fcntl
import struct
import sys
import os

#######################################
# 实现celery中出现拥挤队列时,及时发邮件通知 #
#             aguncn@163.com          #
#######################################

# 从系统命令中获取返回值
def run_cmd(cmd):
    try:
        import subprocess
    except ImportError:
        _, result_f, error_f = os.popen3(cmd)
    else:
        process = subprocess.Popen(cmd, shell = True,
        stdout = subprocess.PIPE, stderr = subprocess.PIPE)
        result_f, error_f = process.stdout, process.stderr  

    errors = error_f.read()
    if errors:
        pass
    result_str = result_f.read().strip()
    if result_f:
        result_f.close()
    if error_f:
        error_f.close()  

    return result_str

# 格式化命令,获取脚本绝对脚本,crontab也可执行
def format_cmd(cmd):
    filename = sys.argv[0]
    dirname = os.path.dirname(filename)
    abspath = os.path.abspath(dirname)
    return "python %s/manage_prd.py celery inspect %s -d celeryd@deploy" % (abspath, cmd)

# 获取指定网卡的IP
def get_ip(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))[20:24])  

#发送邮件
class PM(object):
    def __init__(self, msg_str=None):
        self.msg_str = msg_str

    def send_email(self, email_list):
        mail_host = "x.x.x.x"
        sender_email = "a@b.c"
        subject = "celery alert"
        msg = MIMEText(self.msg_str.encode('utf8'), _subtype='plain', _charset='utf8')
        msg['From'] = sender_email
        msg['Subject'] = u'%s' % subject
        msg['To'] = ",".join(email_list)

        try:
            s = smtplib.SMTP(mail_host, 25)
            s.sendmail(sender_email, receivers_list, msg.as_string())
            s.close()
        except Exception as e:
            print 'Exception: ', e

if __name__ == '__main__':
    active_cmd_str = format_cmd("active")
    revoked_cmd_str = format_cmd("revoked")
    reserved_cmd_str = format_cmd("reserved")
    reserved_return_str = run_cmd(reserved_cmd_str)
    if "empty" not in reserved_return_str:
        receivers_list = ["a@b.c", "a@b.c"]
        ip = get_ip('eth0')
        email_str = "http://%s:8000/" %(ip)
        email_str = email_str + "\n" + "active: " + "\n"
        email_str = email_str + run_cmd(active_cmd_str) + "\n"
        email_str = email_str + "reserved: " + "\n"
        email_str = email_str + run_cmd(reserved_cmd_str) + "\n"
        email_str = email_str + "revoked: " + "\n"
        email_str = email_str + run_cmd(revoked_cmd_str) + "\n"
        email_inst = PM(email_str)
        email_inst.send_email(receivers_list)
        print "send a alert email."
    else:
        print "all ok, no email send."