Python3 解决日志解析器的 TypeError
Python3 to resolve TypeError for a log parser
我正在使用 python3 日志解析器来过滤日志并将电子邮件作为 HTML 附件发送到 Outlook,虽然这在 python2 上工作正常但是 python3 我收到警报了。
如有任何帮助,我们将不胜感激。
Python 日志文件解析(pyParser.py)
#!/usr/bin/python3
import sys
import re
from subprocess import Popen, PIPE
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg_body = ''
node_name = ''
mailstr = """<html><head></head><body>
<table border=1>
<tr>
<th bgcolor=fe9a2e>Hostname</th>
<th bgcolor=fe9a2e>Service</th>
</tr>
"""
fh=open(sys.argv[1],"r")
for line in fh:
pat_match_next=re.search("^\s*\"stdout.*", line)
if pat_match_next:
continue
pat_match=re.search("^.*\"?Service Status:\s+(.*)(\s+\S+)\"?.*$", line)
if pat_match:
msg_body = pat_match.group(1)
node_name = pat_match.group(2)
mailstr += """<TR><TD bgcolor=fe9a2e>""" + node_name + """</TD>\n"""
mailstr += """<TR><TD><TD>""" + msg_body + node_name + """</TD></TD></TR>\n"""
mailstr += """</body></html>"""
mailp = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
msg = MIMEMultipart('alternative')
msg['To'] = ""
msg['Cc'] = ""
msg['Subject'] = "HealthCheck Report"
msg['From'] = ""
msg1 = MIMEText(mailstr, 'html')
msg.attach(msg1)
mailp.communicate(msg.as_string())
日志文件(healthCheck_log):
HostName: fsxdb01.example.com
Service Status: NTP is not Running on the host fsxdb01.example.com
Service Status: NSCD is not Running on the host fsxdb01.example.com
Service Status: Sendmail is Running on the host fsxdb01.example.com
Service Status: Automount is Running on the host fsxdb01.example.com
Service Status: Filesystem For root (/) is not normal and 47% used on the host fsxdb01.example.com
Service Status: Filesystem For Var (/var) is not normal and 68% used on the host fsxdb01.example.com
Service Status: Filesystem For tmp (/tmp) is normal on the host fsxdb01.example.com
当我运行针对日志文件执行上述脚本时,我收到如下警报。
$ ./pyParser.py healthCheck_log
Traceback (most recent call last):
File "./pyParser.py", line 40, in <module>
mailp.communicate(msg.as_string())
File "/usr/lib64/python3.6/subprocess.py", line 848, in communicate
self._stdin_write(input)
File "/usr/lib64/python3.6/subprocess.py", line 801, in _stdin_write
self.stdin.write(input)
TypeError: a bytes-like object is required, not 'str'
No recipient addresses found in header
另一个问题不是关于 运行,而是关于邮件格式,例如主机名和消息对齐到同一行并创建一个空白单元格。
应该是:
来自the docs for subprocess(多处提到):
If encoding or errors are specified, or text (also known as
universal_newlines) is true, the file objects stdin, stdout and stderr
will be opened in text mode using the encoding and errors specified in
the call or the defaults for io.TextIOWrapper.
...
If text mode is not used, stdin, stdout and stderr will be opened as
binary streams. No encoding or line ending conversion is performed.
所以在python3中尝试
mailp.communicate(msg.as_bytes())
至于html:
mailstr += """<TD>""" + msg_body + node_name + """</TD></TR>\n"""
当然,最好使用 f-strings [甚至像 jinja2
这样的模板引擎],而不是连接
我正在使用 python3 日志解析器来过滤日志并将电子邮件作为 HTML 附件发送到 Outlook,虽然这在 python2 上工作正常但是 python3 我收到警报了。
如有任何帮助,我们将不胜感激。
Python 日志文件解析(pyParser.py)
#!/usr/bin/python3
import sys
import re
from subprocess import Popen, PIPE
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg_body = ''
node_name = ''
mailstr = """<html><head></head><body>
<table border=1>
<tr>
<th bgcolor=fe9a2e>Hostname</th>
<th bgcolor=fe9a2e>Service</th>
</tr>
"""
fh=open(sys.argv[1],"r")
for line in fh:
pat_match_next=re.search("^\s*\"stdout.*", line)
if pat_match_next:
continue
pat_match=re.search("^.*\"?Service Status:\s+(.*)(\s+\S+)\"?.*$", line)
if pat_match:
msg_body = pat_match.group(1)
node_name = pat_match.group(2)
mailstr += """<TR><TD bgcolor=fe9a2e>""" + node_name + """</TD>\n"""
mailstr += """<TR><TD><TD>""" + msg_body + node_name + """</TD></TD></TR>\n"""
mailstr += """</body></html>"""
mailp = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
msg = MIMEMultipart('alternative')
msg['To'] = ""
msg['Cc'] = ""
msg['Subject'] = "HealthCheck Report"
msg['From'] = ""
msg1 = MIMEText(mailstr, 'html')
msg.attach(msg1)
mailp.communicate(msg.as_string())
日志文件(healthCheck_log):
HostName: fsxdb01.example.com
Service Status: NTP is not Running on the host fsxdb01.example.com
Service Status: NSCD is not Running on the host fsxdb01.example.com
Service Status: Sendmail is Running on the host fsxdb01.example.com
Service Status: Automount is Running on the host fsxdb01.example.com
Service Status: Filesystem For root (/) is not normal and 47% used on the host fsxdb01.example.com
Service Status: Filesystem For Var (/var) is not normal and 68% used on the host fsxdb01.example.com
Service Status: Filesystem For tmp (/tmp) is normal on the host fsxdb01.example.com
当我运行针对日志文件执行上述脚本时,我收到如下警报。
$ ./pyParser.py healthCheck_log
Traceback (most recent call last):
File "./pyParser.py", line 40, in <module>
mailp.communicate(msg.as_string())
File "/usr/lib64/python3.6/subprocess.py", line 848, in communicate
self._stdin_write(input)
File "/usr/lib64/python3.6/subprocess.py", line 801, in _stdin_write
self.stdin.write(input)
TypeError: a bytes-like object is required, not 'str'
No recipient addresses found in header
另一个问题不是关于 运行,而是关于邮件格式,例如主机名和消息对齐到同一行并创建一个空白单元格。
应该是:
来自the docs for subprocess(多处提到):
If encoding or errors are specified, or text (also known as universal_newlines) is true, the file objects stdin, stdout and stderr will be opened in text mode using the encoding and errors specified in the call or the defaults for io.TextIOWrapper.
...
If text mode is not used, stdin, stdout and stderr will be opened as binary streams. No encoding or line ending conversion is performed.
所以在python3中尝试
mailp.communicate(msg.as_bytes())
至于html:
mailstr += """<TD>""" + msg_body + node_name + """</TD></TR>\n"""
当然,最好使用 f-strings [甚至像 jinja2
这样的模板引擎],而不是连接