如何将输出重定向数据处理到电子邮件中,使其附加到列表中



如何将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() + "nn"
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:在主机根卡恩上运行时间更长 01 小时: 4536根固态混合硬盘: 卡恩 [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

现在,我尝试附加列表并处理它,但它在上面看起来相同,我很想知道如何将它处理成一封电子邮件。

要求: 在单个服务器运行时有来自单个服务器的电子邮件并捕获进程。

感谢任何历史和建议。

您必须将脚本拆分为不同的部分,每个部分都有一个专用任务。

进口

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, 'nn'))
return messages

lst[-3]如果len(lst) == 3lst[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语句用作上下文管理器。这样,即使在此过程中出现问题,您也可以正确关闭连接

感谢所有关注帖子的人灌输您的想法和观点(如果有的话),我以不同的方式工作并得到了我的解决方案!

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")

相关内容

最新更新