设为首页 收藏本站
查看: 972|回复: 0

[经验分享] python脚本发送报警邮件

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-1-7 10:27:14 | 显示全部楼层 |阅读模式
最近在搞把nagios报警邮箱换到163、sina这种免费邮箱上边,之前用过msmtp搞过也可以发送邮件,现在估计是他们系统都升级了,只能使用TSL加密连接,而msmtp怎么配置都配不通,无奈只能转移战术,正好最近在学习Python,也不知道从哪瞄到过有个email的模块,所以准备试试自己搞个脚本。
  (新手,无编程基础,希望多多指教)
-----2016.1.4 修改----
前提:
更改nagios/etc/object/command.cfg里发送邮件的command配置,例如我这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
# 'notify-host-by-email' command definition
define command{
        command_name    notify-host-by-email
        command_line    /usr/bin/printf "%b" "Host: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n" | /usr/local/nagi
os/shell/sendemail.py -s "$HOSTADDRESS$ is $HOSTSTATE$" -R $CONTACTEMAIL$
        }
  
# 'notify-service-by-email' command definition      
define command{
        command_name    notify-service-by-email
        command_line    /usr/bin/printf "%b" "Service: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\nAdditional Info: $SERVICEOUTPUT$\n\nDate
/Time: $LONGDATETIME$\n" | /usr/local/nagios/shell/sendemail.py -s "$HOSTADDRESS$/$SERVICEDESC$ is $SERVICESTATE$" -R $CONTACTEMAIL$
        }



sendemail脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# --2016.01.04-- v2.0
# 脚本用来替换nagios监控发报警邮件
# sendemail.py
# 方法:
# printf "邮件内容" | sendemail.py -s "邮件主题" -R 收件人1,收件人2
import smtplib,sys,random,getopt
from email.mime.text import MIMEText

def sendemail(host, sender, SSL=True):
    subject = ''
    receivers = []
    host = host
    sender = sender
    copyto = ['10001@qq.com', '10002@qq.com', '10003@qq.com', '10004@qq.com', '10005@qq.com']
    passwd = 'password'
    #参数获取收件人
    try:
        opts, args = getopt.getopt(sys.argv[1:], 's:R:')
        for i in opts:
            if '-s' in i:
                subject = i[1]
            elif '-R' in i:
                receivers.append(i[1])
    except getopt.GetoptError, e:
        print e
    #以下代码段使用的MIMEText函数会生成邮件头格式,方便后边发送邮件时提供一些选项配置(object.sendmail方法)
    body = ''.join(sys.stdin.readlines())
    msg = MIMEText(body)
    msg['subject'] = subject
    msg['from'] = sender
    msg['to'] = ','.join(receivers)
    msg['cc'] = ','.join(copyto)
    receivers = receivers + copyto
    if SSL :
        port = 465
        s = smtplib.SMTP_SSL(host, port)
    else :
        port = 25
        s = smtplib.SMTP(host, port)
    s.login(sender, passwd)
    s.sendmail(sender, receivers, msg.as_string())
def someone():
    backuplist = [('smtp.yourdomain.com', 'yourmail@yourdomain.com'),  ('smtp.yourdomain.cn', 'yourmail@yourdomain.cn')]
    some_one = random.choice(backuplist)
    return some_one
     
def main():
    count = 0
    while count <5 :
        try:
            sendemail('mail.cipnet.cn', 'nagios@cipnet.cn', False)
        except:
            host,sender = someone()
            try:
                sendemail(host,sender)
            except:
                continue
            else:
                break
        else:
            break
            

if __name__ == '__main__':
    main()



  脚本略乱,我是大致分为三部分

第一部分,用于设置发件人收件人主题等变量
第二部分,使用MIMEText函数把邮件内容主题等格式化为邮件头格式
第三部分,登录邮箱,发送邮件代码
   如果不嫌弃,想拿去用的话,可以改下发件人(sender变量)、发件smtp(Host变量)、发件人密码(pass变量)、抄送人(copyto变量,我们公司就固定几个人所以我直接把邮箱写脚本,你也可以写成参数指定)
列出几个遇到问题
1、不明白MIMEText到底是个什么东西,它生成是什么样一个邮件头?
然后我把命令挨个敲了一遍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>> from email.mime.text import MIMEText
>>> body = '123456'
>>> subject = 'test mail'
>>> sender = 'from@qq.com'      
>>> receivers = 'to@qq.com'
>>> copyto = 'cc@qq.com'
>>> msg = MIMEText(body)
>>> msg['subject'] = subject
>>> msg['from'] = sender
>>> msg['to'] = receivers
>>> msg['cc'] = copyto
>>> print msg
From nobody Tue Aug 11 10:54:59 2015
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
subject: test mail
from: from@qq.com
to: to@qq.com
cc: cc@qq.com

123456



就是这样,就是一个纯文本格式,对了,MIMEText函数还可以指定第二个参数为格式,例如html格式,具体可以参考这里:
https://docs.python.org/2/library/email.mime.html#email.mime.text.MIMEText
2、收件人可以收到、抄送人和暗送人怎么都收不到?

这个确实纠结了不少时间,而且关键是收件人收到的邮件下边是有抄送人的!
这让我一度怀疑smtplib模块并不支持抄送的!
后来我查到有一个模糊回答说,你要把cc和bcc加入list!我就觉得肯定可以解决,然后我继续查了下去,果然你只需要以下这行代码就可以!
1
receivers = receivers + copyto



.sendmail方法的第二个参数也就是收件人参数指定的是所有可以收到这封邮件的人,所以我们要把收件人、抄送人、暗送合并到一起
而具体谁是收件人和抄送人已经在MIMEText函数格式化过了,并且会赋给.sendmail的第三个参数
可以参考这里:
https://docs.python.org/2/library/smtplib.html#smtplib.SMTP.sendmail
3、python标准输入readline与readlines区别

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# name: 1.py
import sys
while True:
    line = sys.stdin.readline()
    if not line: break
    sys.stdout.write(line)
------------------------------------------------------------------------------------
[iyunv@xfwy tmp]# printf "1\n2\n3" | ./1.py
1
2
3



1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# name: 2.py
import sys
for i in sys.stdin.readlines():
    sys.stdout.write(i)
-------------------------------------------------------------------------------------
[iyunv@xfwy tmp]# printf "1\n2\n3\n" | ./2.py  
1
2
3



.readline()方法和.readlines()方法区别(两个方法均不属于sys.stdin下的方法)
所以,python标准输入输出问题不讨论。
⑴、readline是以行读取,直到遇到换行符结束。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# name: 1.py
import sys
print sys.stdin.readline()
------------------------------------------------------------------------------------
[iyunv@xfwy tmp]# printf "1" | ./1.py   
1
[iyunv@xfwy tmp]# printf "1\n" | ./1.py
1

[iyunv@xfwy tmp]# printf "1\n2" | ./1.py
1

[iyunv@xfwy tmp]# printf "1\n\n" | ./1.py  
1



⑵、readlines则是读取所有内容,把他们保存为列表

1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# name: 2.py
import sys
print sys.stdin.readlines()
------------------------------------------------------------------------------------
[iyunv@xfwy tmp]# printf "1\n2" | ./2.py   
['1\n', '2']
[iyunv@xfwy tmp]# printf "1\n2\n" | ./2.py
['1\n', '2\n']



4、getopt函数返回了两个表,这两个表分别保存是什么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# -*- coding: utf-8 -*-
# name: test.py
import sys,getopt

opts, args = getopt.getopt(sys.argv[1:], 's:R:', ['help', 'text='])
print opts
print args
------------------------------------------------------------------------------------
[iyunv@xfwy tmp]# ./test.py -s sss -R rrr --help --text abc
[('-s', 'sss'), ('-R', 'rrr'), ('--help', ''), ('--text', 'abc')]
[]
[iyunv@xfwy tmp]# ./test.py -s sss -R rrr --help --text abc other -h
[('-s', 'sss'), ('-R', 'rrr'), ('--help', ''), ('--text', 'abc')]
['other', '-h']  #这样看来第二个表格用来寸未定义的参数



参数怎么写参考这里:
https://docs.python.org/2/library/getopt.html#getopt.getopt




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-161361-1-1.html 上篇帖子: python 并发执行之多线程 下篇帖子: Python格式化时间 python
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表