问题描述
我正在尝试使长时间运行的工作自动化,并且我希望能够将所有控制台输出上传到另一个日志,例如CloudWatch Logs。在大多数情况下,这可以通过制作和使用自定义函数来代替打印来完成。但是MachineLearning中有一些功能,例如Model.summary()或进度条,它们可以在训练时自行输出到stdout。
我可以通过内部控制台日志在最后获得所有控制台输出。但是我需要的是实时上载stdout,无论谁调用。这样一来,通过查看Cloudwatch上的日志即可查看进度,而不必登录计算机并查看内部控制台日志。
基本上我需要的是:
From: call_to_stdout -> Console(and probably other stuff)
To: call_to_stdout -> uploadLog() -> Console(and probably other stuff)
我需要的伪代码
class stdout_Passthru:
def __init__(self,in_old_stdout):
self.old_stdout = in_old_stdout
def write(self,msg):
self.old_stdout.write(msg)
uploadLogToCloudwatch(msg)
def uploadLogToCloudwatch(msg):
# Botocore stuff to upload to Cloudwatch
myPassthru = stdout_Passthru(sys.stdout)
sys.stdout = myPassthru
我已经尝试使用谷歌搜索,但是我得到的最好的是stringIO的东西,我可以在其中捕获stdout,但是直到调用的函数结束并且可以再次插入代码后,我才能对其进行任何处理。我想每次使用stdout时都运行我的上传日志代码。
这甚至可能吗? 请,谢谢。
编辑:有人建议将重定向/输出到文件。问题在于,随着事物的输出,流/文件只写入/写入文件。我需要调用对stdout的每次调用都起作用的函数,这不是流。如果stdout每次刷新时都输出,那么进行函数调用也将很好。
解决方法
我解决了我的问题。某种隐藏在其他答案中。 此解决方案的最初问题是,在Jupyter Notebook中对其进行测试时,sys.stdout = myClass(sys.stdout)会导致Jupyter……等待吗?不确定,但是它永远不会完成对段落的处理。
但是当我将其放入python文件并与python test.py一起运行时,它可以完美运行,并且符合预期。
从某种意义上讲,这使我可以通过打印调用进行传递,而每次打印调用都执行自己的功能。
def addLog(message):
# my boto function to upload Cloudwatch logs
class sendToLog:
def __init__(self,stream):
self.stream = stream
def write(self,o):
self.stream.write(o)
addLog(o)
self.stream.flush()
def writelines(self,o):
self.stream.writelines(o)
addLog(o)
self.stream.flush()
def __getattr__(self,attr):
return getattr(self.stream,attr)
sys.stdout = sendToLog(sys.stdout)