如何仅在实际发生错误时将 python 错误 (stderr) 保存到日志文件?
How to save python Errors (stderr) to a log file ONLY in case errors actually happen?
我有一个每分钟运行一次的 python 脚本。为了调试,我想创建带有 errors/exceptions 的文本文件以防它们出现。如果没有错误,我不需要任何日志文件。
编辑:我无法将所有代码包装在 try/except 循环中,因此 this 无济于事。
首先,我将 stderr
保存到 .txt 中:
sys.stderr = open('ERRORS_%s.txt' % (infile), 'a')
with open("%s_Error_Messages.txt" % (MSKSN), "a") as myfile:
myfile.close()
其次,我尝试删除任何 raise SystemExit
位置之前的空 "%s_Error_Messages.txt" % (MSKSN)
文件,因为没有出现错误(否则,不会到达 raise SystemExit
位置)。
if os.path.getsize('ERRORS_%s.txt' % (infile)) == 0:
os.remove('ERRORS_%s.txt' % (infile))
我得到的是WindowsError: [Error 32] The process cannot access the file because it is being used by another process
。我认为这是因为只要脚本运行,stderr
总是被 python.exe 使用。
第一步,我也尝试过:
if sys.stderr != 0:
sys.stderr = open('ERRORS_%s.txt' % (infile), 'a')
这不起作用,因为 sys.stderr 永远不会为 0。
如何将 sys.stderr 写入 .txt 仅在实际错误的情况下?
除非你担心大量的错误数据,否则你可以直接将stderr重定向到一个stringIO对象,然后根据内容写出(或不写)
import StringIO
import sys
sys.stderr = StringIO.StringIO()
# do stuff
if sys.stderr.getvalue():
with open ("path/to/log.txt") as output:
output.write(sys.stderr.getvalue())
对于上下文管理器来说,这是一个很好的案例,它将设置替换标准错误,运行 您的代码,然后在完成后将标准错误重置回 sys.__stderr__
。
如果您无法在尝试中包装代码,您也可以尝试使用 sys.excepthook
设置此功能
由于接受的答案根本不起作用,这里是解决方案:
你说你不想要 try-except 机制,所以你可以使用 sys.excepthook
它在发生“未处理”异常时调用,并打印出给定的回溯和异常到 sys.stderr
.每当你 运行 你的脚本,如果异常引发你的程序终止(因为你没有捕获它)但是你可以在你的文件中记录错误。
import sys
def myexcepthook(e_type, e_value, e_tb, org_excepthook=sys.excepthook):
with open('errors.txt', 'a') as error_file:
sys.stderr = error_file
sys.stderr.write(f'--------------- Exception --------------\n')
# Now this logs into our 'sys.stderr' which is 'error_file'.
org_excepthook(e_type, e_value, e_tb)
sys.stderr.write('\n')
sys.excepthook = myexcepthook
# This terminates the program here
1 / 0
print("You can see this only if an exception doesn't occur")
注意 :我可以直接写入文件,但我选择重定向让原始 sys.excepthook
记录它的相当回溯。如果您对 traceback
模块感到满意,您可以那样处理它。
这是运行ning 3次后的输出:
--------------- Exception --------------
Traceback (most recent call last):
File "....", line 17, in <module>
1 / 0
ZeroDivisionError: division by zero
--------------- Exception --------------
Traceback (most recent call last):
File "....", line 17, in <module>
1 / 0
ZeroDivisionError: division by zero
--------------- Exception --------------
Traceback (most recent call last):
File "....", line 17, in <module>
1 / 0
ZeroDivisionError: division by zero
我有一个每分钟运行一次的 python 脚本。为了调试,我想创建带有 errors/exceptions 的文本文件以防它们出现。如果没有错误,我不需要任何日志文件。
编辑:我无法将所有代码包装在 try/except 循环中,因此 this 无济于事。
首先,我将 stderr
保存到 .txt 中:
sys.stderr = open('ERRORS_%s.txt' % (infile), 'a')
with open("%s_Error_Messages.txt" % (MSKSN), "a") as myfile:
myfile.close()
其次,我尝试删除任何 raise SystemExit
位置之前的空 "%s_Error_Messages.txt" % (MSKSN)
文件,因为没有出现错误(否则,不会到达 raise SystemExit
位置)。
if os.path.getsize('ERRORS_%s.txt' % (infile)) == 0:
os.remove('ERRORS_%s.txt' % (infile))
我得到的是WindowsError: [Error 32] The process cannot access the file because it is being used by another process
。我认为这是因为只要脚本运行,stderr
总是被 python.exe 使用。
第一步,我也尝试过:
if sys.stderr != 0:
sys.stderr = open('ERRORS_%s.txt' % (infile), 'a')
这不起作用,因为 sys.stderr 永远不会为 0。
如何将 sys.stderr 写入 .txt 仅在实际错误的情况下?
除非你担心大量的错误数据,否则你可以直接将stderr重定向到一个stringIO对象,然后根据内容写出(或不写)
import StringIO
import sys
sys.stderr = StringIO.StringIO()
# do stuff
if sys.stderr.getvalue():
with open ("path/to/log.txt") as output:
output.write(sys.stderr.getvalue())
对于上下文管理器来说,这是一个很好的案例,它将设置替换标准错误,运行 您的代码,然后在完成后将标准错误重置回 sys.__stderr__
。
如果您无法在尝试中包装代码,您也可以尝试使用 sys.excepthook
设置此功能由于接受的答案根本不起作用,这里是解决方案:
你说你不想要 try-except 机制,所以你可以使用 sys.excepthook
它在发生“未处理”异常时调用,并打印出给定的回溯和异常到 sys.stderr
.每当你 运行 你的脚本,如果异常引发你的程序终止(因为你没有捕获它)但是你可以在你的文件中记录错误。
import sys
def myexcepthook(e_type, e_value, e_tb, org_excepthook=sys.excepthook):
with open('errors.txt', 'a') as error_file:
sys.stderr = error_file
sys.stderr.write(f'--------------- Exception --------------\n')
# Now this logs into our 'sys.stderr' which is 'error_file'.
org_excepthook(e_type, e_value, e_tb)
sys.stderr.write('\n')
sys.excepthook = myexcepthook
# This terminates the program here
1 / 0
print("You can see this only if an exception doesn't occur")
注意 :我可以直接写入文件,但我选择重定向让原始 sys.excepthook
记录它的相当回溯。如果您对 traceback
模块感到满意,您可以那样处理它。
这是运行ning 3次后的输出:
--------------- Exception --------------
Traceback (most recent call last):
File "....", line 17, in <module>
1 / 0
ZeroDivisionError: division by zero
--------------- Exception --------------
Traceback (most recent call last):
File "....", line 17, in <module>
1 / 0
ZeroDivisionError: division by zero
--------------- Exception --------------
Traceback (most recent call last):
File "....", line 17, in <module>
1 / 0
ZeroDivisionError: division by zero