首页 / 日志 / Python日志记录和子进程输出和错误流
Python日志记录和子进程输出和错误流
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python日志记录和子进程输出和错误流,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3466字,纯文字阅读大概需要5分钟。
内容图文
![Python日志记录和子进程输出和错误流](/upload/InfoBanner/zyjiaocheng/954/3d6a7dcd40bb4cc5a113f37e3dd9586e.jpg)
我想开始一个python进程并将子进程错误消息记录到父脚本的日志记录对象.理想情况下,我希望将日志流统一到一个文件中.我能以某种方式访问??日志记录类的输出流吗?我所知道的一个解决方案是使用proc日志进行日志记录.如下面的答案所述,我可以从proc.stdin和stderr读取,但我有重复的日志标头.我想知道是否有办法将日志记录类下面的文件描述符直接传递给子进程?
logging.basicConfig(filename="test.log",level=logging.DEBUG)
logging.info("Started")
procLog = open(os.path.expanduser("subproc.log"), 'w')
proc = subprocess.Popen(cmdStr, shell=True, stderr=procLog, stdout=procLog)
proc.wait()
procLog.flush()
解决方法:
基于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日志记录和子进程输出和错误流所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。