如何将python列表数据处理成MIME的邮件功能。下面是查找" sshd
"在系统上进行处理并根据应用的条件,如果它运行超过30分钟,然后通过电子邮件报告。
我正在使用" cStringIO
"用于重定向目的的模块因此数据可以保存在data_stream
变量上,我可以将其调用到邮件发送功能中。因此,当我运行脚本时,它正确地在控制台上运行,但是它发送到不同部分的电子邮件,我在脚本代码后很快引用了下面的示例..
问题摘要:
如下面的测试示例,当我运行脚本时,它在命令控制台上运行正常,但是当它通过电子邮件处理时,它会发送这4个不同的电子邮件备注..
#!/usr/bin/python
from subprocess import Popen, PIPE
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import subprocess
import socket
import sys
import cStringIO
import re
mylist = list()
hst_name = (socket.gethostname())
def checK_ps():
ps = subprocess.Popen(['ps', '-eo' 'pid,user,args,etime='], stdout=subprocess.PIPE)
output = ps.communicate()[0]
for line in output.splitlines():
result = re.search(".*[\/\s]+(sshd:)\s+", line)
if result:
time_items = re.split('-|:',(line.split(' ')[-1]))
time_len = len(time_items)
mystdout = sys.stdout
data_stream = cStringIO.StringIO()
sys.stdout = data_stream
if time_len == 4:
print "Alert sshd: is running longer on the host",hst_name,time_items[0],"days:" # "-->",line.strip()
elif time_len == 3:
print "Alert sshd: is running longer on the host",hst_name,time_items[-3],"hours:" # "-->",line.strip()
elif time_len == 2 and int(time_items[-2]) >= 30:
print "Alert sshd: is running longer on the host",hst_name,time_items[-2],"minutes:" #, "-->",line.strip()
sys.stdout = mystdout
variable_data = data_stream.getvalue()
xxx = variable_data + line.strip() + "\n\n"
mylist.append(xxx)
mailp = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
msg = MIMEMultipart('alternative')
msg['To'] = "karn@example.com"
msg['Subject'] = "Daily PS Check Report"
msg['From'] = "systemHealth@example.com"
msg1 = MIMEText(xxx, 'text')
msg.attach(msg1)
mailp.communicate(msg.as_string())
print "".join([str(x) for x in mylist] )
checK_ps()
示例:脚本的测试运行:
主要问题是以下所有"警报"正在进入4个不同的电子邮件,这些电子邮件应该是同一个系统中的所有进程。
$ ./testps.py 警报sshd:在主机root-karn 01小时运行更长时间: 4536 root sshd:karn [priv] 01:03:21
Alert sshd: is running longer on the host root-karn 01 hours:
4621 karn sshd: karn@pts/1 01:03:11
Alert sshd: is running longer on the host root-karn 20 hours:
20124 root sshd: niraj [priv] 20:16:06
Alert sshd: is running longer on the host root-karn 20 hours:
20130 niraj sshd: niraj@pts/2 20:16:05
现在,我已尝试附加列表并对其进行处理,但上面看起来相同,我很想知道它如何处理成单个电子邮件。
要求: 在单个服务器运行时从单个服务器获取单个电子邮件并捕获该过程。
欣赏任何组织和建议。
答案 0 :(得分:0)
您必须将脚本拆分为不同的部分,每个部分都有专门的任务。
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import subprocess
import socket
import re
def _read_ps()
with subprocess.Popen(['ps', '-eo' 'pid,user,args,etime='], stdout=subprocess.PIPE) as ps:
messages = list()
for line in output.splitlines():
if re.search(".*[\/\s]+(sshd:)\s+", line):
time_items = re.split('-|:',(line.split(' ')[-1]))
time_len = len(time_items)
message = ""
if time_len in (3, 4,) or (time_len == 2 & int(time_items[0] >= 30)):
message = "Alert sshd: is running longer on the host %s %s days:" % hst_name,time_items[0]
messages.append("".join(message, line.strip, '\n\n'))
return messages
lst[-3]
如果len(lst) == 3
与lst[0]
相同,那么该部分可以简化
您重定向sys.stdout
以打印邮件,但使用print >> buffer, message
比使用现在的方式更容易,甚至该方法也不像字符串格式化那么简单你用它的目的
上一个方法的结果是要发送的消息列表。如果有任何消息,此方法会将其编译为一封电子邮件。我不熟悉在Python上编译电子邮件,所以这可能需要一些工作。
def _construct_message(messages):
if not messages: # no messages to send
return None
msg = MIMEMultipart('alternative')
msg['To'] = "karn@example.com"
msg['Subject'] = "Daily PS Check Report"
msg['From'] = "systemHealth@example.com"
for message in messages:
msg.attach(MIMEText(message, 'text')
return msg
您可以使用以下内容替换最后3行代替for循环:
return msg.attach(MIMEText'\n'.join(messages), 'text')
但我对电子邮件不太熟悉
编译完电子邮件后,您需要发送
def _send_mail(mail_message):
with Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=subprocess.PIPE) as mailp:
mailp.communicate(mail_message.as_string())
def check_ps():
messages = _read_ps()
mail_message = _construct_message(messages)
if mail_message:
_send_mail(mail_message)
将工作分成小部分的优点是,您可以更轻松地调试和测试每个单独的方法
Popen
可以使用with
语句用作上下文管理器。这样,即使出现问题,连接也会正确关闭
答案 1 :(得分:0)
感谢大家在帖子上灌输您的想法和观点,如果有的话,我以不同的方式工作并获得我的解决方案!
from subprocess import Popen, PIPE
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import subprocess
import socket
import sys
import os
import re
hst_name = (socket.gethostname())
def checK_ps():
ps = subprocess.Popen(['ps', '-eo' 'pid,user,args,etime='], stdout=subprocess.PIPE)
output = ps.communicate()[0]
for line in output.splitlines():
#if len(re.findall('\\b'+line+'\\b', "rm", flags=re.IGNORECASE))>0:
result = re.search(".*[\/\s]+(rm)\s+", line)
#result = re.search(".*[\/|\s]+(rm)\s+", line)
if result:
time_items = re.split('-|:',(line.split(' ')[-1]))
time_len = len(time_items)
print_stdout = sys.stdout
print_output = open('/tmp/ps_msg', 'a')
sys.stdout = print_output
if time_len == 4:
print "Alert rm is running longer on the host",hst_name,time_items[0],"days:" + "\n" + line.strip()
print ""
#elif time_len == 3:
elif time_len == 3 and int(time_items[-3]) >= 02:
print "Alert rm is running longer on the host",hst_name,time_items[-3],"hours:" + "\n" + line.strip()
print ""
elif time_len == 2 and int(time_items[-2]) >= 05:
print "Alert rm is running longer on the host",hst_name,time_items[-2],"minutes:" + "\n" + line.strip()
print ""
sys.stdout = print_stdout
print_output.close()
checK_ps()
############ Process capturing part done above #################
############ File comparison & sendmail part starts here ########
def ps_Mail():
filename = "/tmp/ps_msg"
f = file(filename)
if os.path.exists(filename) and os.path.getsize(filename) > 0:
mailp = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
msg = MIMEMultipart('alternative')
msg['To'] = "karn@example.com"
msg['Subject'] = "Uhh!! Unsafe rm process Seen"
msg['From'] = "psCheck@example.com"
msg1 = MIMEText(f.read(), 'text')
msg.attach(msg1)
mailp.communicate(msg.as_string())
ps_Mail()
########### Clean the file after Sending an E-mail ############
os.unlink("/tmp/ps_msg")