遇到打开文件描述符消息时 Python 日志记录失败
我有以下 Python 代码来在 Linux 计算机上创建 lvm 快照。
#!/usr/bin/env python3.1
import subprocess
import logging
logging.basicConfig(filename='/var/log/lvsnap.log', filemode='w', level=logging.DEBUG)
lvm_vg = 'vg00-crunchbang'
lvm_name = 'root'
lvm_snapshot_size = '100'
def lvmCreateSnapshot(lvm_vg, lvm_name, lvm_snapshot_size):
return subprocess.check_call(['lvcreate', '-s', '-l', '+' + lvm_snapshot_size + '%FREE', '-n', lvm_name + '-snapshot', lvm_vg + '/' + lvm_name])
logging.debug('logging is working before lvm snapshot')
''' create lvm snapshot '''
lvm_create_snapshot = lvmCreateSnapshot(lvm_vg, lvm_name, lvm_snapshot_size)
if lvm_create_snapshot:
logging.debug('create lvm snapshot of %s/%s exited with status %s', lvm_vg, lvm_name, lvm_create_snapshot)
logging.debug('logging is working after lvm snapshot')
lvmCreateSnapshot 运行正常并以 0 退出,然后应该运行 if 语句中的logging.debug 行。 然而,这并没有发生,而是我从脚本收到了以下输出:
> /tmp/lvmsnap.py
File descriptor 3 (/var/log/lvsnap.log) leaked on lvcreate invocation. Parent PID 7860: python3.1
Logical volume "root-snapshot" created
>
日志的输出是:
> cat /var/log/lvsnap.log
DEBUG:root:logging is working before lvm snapshot
DEBUG:root:logging is working after lvm snapshot
>
正如您所看到的,其中缺少 lvmlogging.debug 消息(它应该出现在我创建的 2 条测试日志记录消息之间) 。
为什么会发生这种情况以及如何解决它?
I have the following Python code to create an lvm snapshot on a Linux machine.
#!/usr/bin/env python3.1
import subprocess
import logging
logging.basicConfig(filename='/var/log/lvsnap.log', filemode='w', level=logging.DEBUG)
lvm_vg = 'vg00-crunchbang'
lvm_name = 'root'
lvm_snapshot_size = '100'
def lvmCreateSnapshot(lvm_vg, lvm_name, lvm_snapshot_size):
return subprocess.check_call(['lvcreate', '-s', '-l', '+' + lvm_snapshot_size + '%FREE', '-n', lvm_name + '-snapshot', lvm_vg + '/' + lvm_name])
logging.debug('logging is working before lvm snapshot')
''' create lvm snapshot '''
lvm_create_snapshot = lvmCreateSnapshot(lvm_vg, lvm_name, lvm_snapshot_size)
if lvm_create_snapshot:
logging.debug('create lvm snapshot of %s/%s exited with status %s', lvm_vg, lvm_name, lvm_create_snapshot)
logging.debug('logging is working after lvm snapshot')
lvmCreateSnapshot runs fine and exits with 0 which should then run the logging.debug line in the if statement.
However this does not happen and instead I received the following output from the script:
> /tmp/lvmsnap.py
File descriptor 3 (/var/log/lvsnap.log) leaked on lvcreate invocation. Parent PID 7860: python3.1
Logical volume "root-snapshot" created
>
The output of the log is:
> cat /var/log/lvsnap.log
DEBUG:root:logging is working before lvm snapshot
DEBUG:root:logging is working after lvm snapshot
>
Which, as you can see has the lvm logging.debug message missing (it should appear between the 2 test logging messages I created).
Why is this happening and how can I fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您没有调用“缺失”的
logging.debug
,因为lvmCreateSnapshot
返回零,因此永远不会满足您的if
条件。尝试在成功调用
subprocess
时执行else
并执行if
条件,或者仅在以下情况下输出调试消息: code>subprocess 返回错误。
编辑:
我刚刚查看了
subprocess.check_call()
的文档,请参阅 http://docs.python.org/library/subprocess.html,其中指出如果子进程调用成功,则subprocess.check_call
返回零,并引发CalledProcessError< /代码> 异常 否则。因此,您必须使用通常的 try/ except 块捕获此异常。像下面这样的东西就足够了:
最后的加注是为了打印回溯。您当然可以使用诸如
return 1
之类的东西来代替。You are not invoking the "missing"
logging.debug
sincelvmCreateSnapshot
returns zero and yourif
condition is therefore never met. Tryso that the
else
is exectuded on a successfulsubprocess
call and theif
condition is otherwise exectuded, orto only output a debugging message if
subprocess
returns an error.EDIT:
I have just looked at the documentation for
subprocess.check_call()
, see http://docs.python.org/library/subprocess.html, which states thatsubprocess.check_call
returns zero if the subprocess call was successful and raises aCalledProcessError
exception otherwise. Therefore you have to catch this exception with the usual try/except block. Something like the following should suffice:The final raise is there to print the traceback. You could of course use something like
return 1
instead.