python报错输出到日志_Python日志记录和子进程输出和错误流
基于Adam Rosenfield’s code,你可以
>使用select.select来阻止,直到有要读取的输出
proc.stdout或proc.stderr,
>然后读取并记录该输出
>重复直到完成该过程.
请注意,以下内容写入/tmp/test.log并运行命令ls -laR / tmp.根据您的需求进行更改.
(PS:通常/ tmp包含普通用户无法读取的目录,因此运行ls -laR / tmp会向stdout和stderr生成输出.下面的代码在生成它们时正确地交错这两个流.)
import logging
import subprocess
import shlex
import select
import fcntl
import os
import errno
import contextlib
logger = logging.getLogger(__name__)
def make_async(fd):
'''add the O_NONBLOCK flag to a file descriptor'''
fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
def read_async(fd):
'''read some data from a file descriptor, ignoring EAGAIN errors'''
try:
return fd.read()
except IOError, e:
if e.errno != errno.EAGAIN:
raise e
else:
return ''
def log_fds(fds):
for fd in fds:
out = read_async(fd)
if out:
logger.info(out)
@contextlib.contextmanager
def plain_logger():
root = logging.getLogger()
hdlr = root.handlers[0]
formatter_orig = hdlr.formatter
hdlr.setFormatter(logging.Formatter('%(message)s'))
yield
hdlr.setFormatter(formatter_orig)
def main():
# fmt = '%(name)-12s: %(levelname)-8s %(message)s'
logging.basicConfig(filename = '/tmp/test.log', mode = 'w',
level = logging.DEBUG)
logger.info("Started")
cmdStr = 'ls -laR /tmp'
with plain_logger():
proc = subprocess.Popen(shlex.split(cmdStr),
stdout = subprocess.PIPE, stderr = subprocess.PIPE)
# without `make_async`, `fd.read` in `read_async` blocks.
make_async(proc.stdout)
make_async(proc.stderr)
while True:
# Wait for data to become available
rlist, wlist, xlist = select.select([proc.stdout, proc.stderr], [], [])
log_fds(rlist)
if proc.poll() is not None:
# Corner case: check if more output was created
# between the last call to read_async and now
log_fds([proc.stdout, proc.stderr])
break
logger.info("Done")
if __name__ == '__main__':
main()
编辑:
您可以将stdout和stderr重定向到logfile = open(‘/ tmp / test.log’,’a’).
但是,这样做的一个小难点是,任何写入/tmp/test.log的记录器处理程序都不会知道子进程正在编写什么,因此日志文件可能会出现乱码.
如果在子进程执行其业务时未进行日志记录调用,则唯一的问题是在子进程完成后,记录器处理程序在文件中的位置错误.这可以通过调用来解决
handler.stream.seek(0, 2)
所以处理程序将在文件末尾继续写入.
import logging
import subprocess
import contextlib
import shlex
logger = logging.getLogger(__name__)
@contextlib.contextmanager
def suspended_logger():
root = logging.getLogger()
handler = root.handlers[0]
yield
handler.stream.seek(0, 2)
def main():
logging.basicConfig(filename = '/tmp/test.log', filemode = 'w',
level = logging.DEBUG)
logger.info("Started")
with suspended_logger():
cmdStr = 'test2.py 1>>/tmp/test.log 2>&1'
logfile = open('/tmp/test.log', 'a')
proc = subprocess.Popen(shlex.split(cmdStr),
stdout = logfile,
stderr = logfile)
proc.communicate()
logger.info("Done")
if __name__ == '__main__':
main()
python报错输出到日志_Python日志记录和子进程输出和错误流相关推荐
- pycharm/python报错:Traceback (most recent call last): .....
python报错:Traceback (most recent call last): - python报错: Traceback (most recent call last):File " ...
- python 报错 IndentationError: expected an indented block SyntaxError: invalid character in identifie
红色方框那里敲击一个空格就好! 输入要在全英情况下! 另外,还要注意括号的事情.括号别出错误! IndentationError: expected an indented block的报错: Syn ...
- Python安装库较慢问题,Python报错pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool解决方法
本文参考:https://blog.csdn.net/sinat_26811377/article/details/99698807 出现问题 在安装第三方库的时候,Python报错pip._vend ...
- 解决Python报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 658: illegal multibyte
解决Python报错–UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 658: illegal multibyte ...
- python报错UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xe8 in position 0 解决方案
python报错UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 0 解决方案 参考文章: (1)python报 ...
- Python 报错 SyntaxError: invalid syntax 解决方法
Python 报错 SyntaxError: invalid syntax 解决方法 参考文章: (1)Python 报错 SyntaxError: invalid syntax 解决方法 (2)ht ...
- python 报错 AttributeError: type object ‘datetime.datetime‘ has no attribute ‘datetime‘
python报错:type object 'datetime.datetime' has no attribute 'datetime' 描述:在第一个python程序里还未报错,第二个程序完全复制过 ...
- Python报错TypeError: 'str' object is not callable
原文:http://blog.sina.com.cn/s/blog_71f3890901017rsh.html Python报错TypeError: 'str' object is not calla ...
- 电脑安装python为什么显示的是程序丢失-python报错:无法启动此程序,因为计算机中丢失...
原标题:python报错:无法启动此程序,因为计算机中丢失 python报错:无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-|1-1-0.dll api-ms-win- ...
- python报错:TypeError: cant multiply sequence by non-int of type float(bug)(csdn标题没法用英文引号,以后注意别搜引号)
python报错:TypeError: can't multiply sequence by non-int of type 'float' 注意:csdn标题没法用英文引号,以后注意别搜引号!!!! ...
最新文章
- 将C#编译为javascript
- 防止Entity Framework重复插入关联对象
- .NET 6 Preview 2 发布
- 未来计算机是什么结合的产物,计算机未来发展趋势 (2)
- 简化java_JAVA之旅-简化java开发
- springboot整合activemq加入会签,自动重发机制,持久化
- 关于游戏小说与学习知识的不同
- python字典函数_python-字典常用函数
- iOS 实现简单的列表预加载
- 冒泡排序详解(C++)
- 将机器学习、人工智能、数据挖掘融合的Testin 2.0有哪些不同之处
- 计算机房等电位接地规范,一个实例全面讲解机房如何做防雷接地?
- CTP程序化交易入门系列之五:现手、增仓、开平、对手盘计算
- VISIO中如何增加连接点
- 空间后方交会编程c语言,单像空间后方交会(python实现)
- 信号隔离器直流电流电压变送器 分配转换模块0-10V一进二出4-20mA
- 使用FFMPEG将WebM转为MP4或MKV
- 【数据结构】哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度
- CentOS 之 openssl-devel 安装
- 【笑话】公交车上的艳遇