基于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日志记录和子进程输出和错误流相关推荐

  1. pycharm/python报错:Traceback (most recent call last): .....

    python报错:Traceback (most recent call last): - python报错: Traceback (most recent call last):File " ...

  2. python 报错 IndentationError: expected an indented block SyntaxError: invalid character in identifie

    红色方框那里敲击一个空格就好! 输入要在全英情况下! 另外,还要注意括号的事情.括号别出错误! IndentationError: expected an indented block的报错: Syn ...

  3. Python安装库较慢问题,Python报错pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool解决方法

    本文参考:https://blog.csdn.net/sinat_26811377/article/details/99698807 出现问题 在安装第三方库的时候,Python报错pip._vend ...

  4. 解决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 ...

  5. 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报 ...

  6. Python 报错 SyntaxError: invalid syntax 解决方法

    Python 报错 SyntaxError: invalid syntax 解决方法 参考文章: (1)Python 报错 SyntaxError: invalid syntax 解决方法 (2)ht ...

  7. python 报错 AttributeError: type object ‘datetime.datetime‘ has no attribute ‘datetime‘

    python报错:type object 'datetime.datetime' has no attribute 'datetime' 描述:在第一个python程序里还未报错,第二个程序完全复制过 ...

  8. Python报错TypeError: 'str' object is not callable

    原文:http://blog.sina.com.cn/s/blog_71f3890901017rsh.html Python报错TypeError: 'str' object is not calla ...

  9. 电脑安装python为什么显示的是程序丢失-python报错:无法启动此程序,因为计算机中丢失...

    原标题:python报错:无法启动此程序,因为计算机中丢失 python报错:无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-|1-1-0.dll api-ms-win- ...

  10. 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标题没法用英文引号,以后注意别搜引号!!!! ...

最新文章

  1. 将C#编译为javascript
  2. 防止Entity Framework重复插入关联对象
  3. .NET 6 Preview 2 发布
  4. 未来计算机是什么结合的产物,计算机未来发展趋势 (2)
  5. 简化java_JAVA之旅-简化java开发
  6. springboot整合activemq加入会签,自动重发机制,持久化
  7. 关于游戏小说与学习知识的不同
  8. python字典函数_python-字典常用函数
  9. iOS 实现简单的列表预加载
  10. 冒泡排序详解(C++)
  11. 将机器学习、人工智能、数据挖掘融合的Testin 2.0有哪些不同之处
  12. 计算机房等电位接地规范,一个实例全面讲解机房如何做防雷接地?
  13. CTP程序化交易入门系列之五:现手、增仓、开平、对手盘计算
  14. VISIO中如何增加连接点
  15. 空间后方交会编程c语言,单像空间后方交会(python实现)
  16. 信号隔离器直流电流电压变送器 分配转换模块0-10V一进二出4-20mA
  17. 使用FFMPEG将WebM转为MP4或MKV
  18. 【数据结构】哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度
  19. CentOS 之 openssl-devel 安装
  20. 【笑话】公交车上的艳遇

热门文章

  1. C++对象内存布局--③测试多继承中派生类的虚函数在哪一张虚函数表中
  2. Linux网络基本网络配置
  3. 宽带拨号时出现错误列表
  4. 【OS】课设记录总结+进程整理
  5. 前端趋势榜:上周最有意思、又实用的 10 大 Web 项目 - 210922
  6. standford lessons
  7. 【收藏】GeoMesa Spark
  8. 【nginx配置】 proxy_pass反向代理配置中url后面加不加/的说明
  9. python pyyaml模块使用示例:读取yaml文件内容
  10. docker安装influxdb、grafana及展示数据到grafana