日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python报错输出到日志_Python日志记录和子进程输出和错误流

發布時間:2024/10/14 python 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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日志记录和子进程输出和错误流的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。