Ведение журнала Python завершается неудачно при обнаружении сообщения об открытом дескрипторе файла - PullRequest
2 голосов
/ 11 июля 2011

У меня есть следующий код Python для создания снимка lvm на компьютере с Linux.

#!/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, что должно затем запустить строку logging.debug в операторе if. Однако этого не происходит, и вместо этого я получил следующий вывод из сценария:

> /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
>

Который, как вы можете видеть, пропускает сообщение lvm logging.debug (оно должно появляться между двумя сообщениями регистрации тестов, которые я создал).

Почему это происходит и как я могу это исправить?

1 Ответ

3 голосов
/ 11 июля 2011

Вы не вызываете «пропущенное» logging.debug, поскольку lvmCreateSnapshot возвращает ноль и, следовательно, ваше условие if никогда не выполняется.Попробуйте

if lvm_create_snapshot:
    logging.debug('Error creating lvm snapshot of %s/%s, exited with status %s', lvm_vg, lvm_name, lvm_create_snapshot)
else:
    logging.debug('created lvm snapshot of %s/%s, lvm_vg, lvm_name)

, чтобы при успешном вызове subprocess находилось else, а в противном случае - условие if, или

if not lvm_create_snapshot:
    logging.debug('...debugging text...')

только для вывода отладочной информации.сообщение, если subprocess возвращает ошибку.

РЕДАКТИРОВАТЬ:

Я только что посмотрел документацию для subprocess.check_call(), см. http://docs.python.org/library/subprocess.html,, в которой говорится, что subprocess.check_call возвращает нольесли вызов подпроцесса был успешным и в противном случае возникает исключение CalledProcessError.Поэтому вы должны поймать это исключение с помощью обычного блока try / исключением.Должно быть что-то похожее на следующее:

try:
    lvmCreateSnapshot(lvm_vg, lvm_name, lvm_snapshot_size)
    logging.debug('created lvm snapshot of %s/%s', lvm_vg, lvm_name)
except CalledProcessError as e:
    logging.debug('Error creating lvm snapshot of {0}/{1}. Return code was {2}'.format(lvm_vg,
        lvm_name, e.returncode))
    raise

Последний рейз предназначен для печати трассировки.Конечно, вы можете использовать что-то вроде return 1.

...