Коли я пишу демон пітона, я виловлю всі винятки і кидаю потім у файл журналу. Я не тільки використовую для налагодження, але і у виробництві теж. У мене є невеликий сценарій, який я запускаю щоранку, шукаючи щось неприємне в журналах.
Це також допомагає підтримувати демон, звичайно.
Деякі зразки коду (я видаляю не цікаві частини):
import logging
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(levelname)s %(message)s',
filename=LOG_FILE,
filemode='w')
logging.info("Sincrod inicializado")
if not DEBUG:
daemonize()
while True:
try:
actua()
except:
logging.error(sys.exc_info())
if (datetime.datetime.now().hour > NOITE_EMPEZA\
and datetime.datetime.now().hour < NOITE_REMATA):
time.sleep(INTERVALO_NOITE)
else:
time.sleep(INTERVALO_DIA)
Де actua () - це справжній демон (він також пише в журнал). Зауважте, що у мене також є змінна DEBUG у файлі налаштувань, коли це правда, я не розщеплюю демона, щоб він виконувався на консолі.
Демони
Демони - це еквівалент unix сервісам Windows. Це процеси, які працюють у фоновому режимі, незалежно від інших процесів. Це означає, що їх батько, як правило, інітій, і що вони відсторонені від будь-яких. Оскільки вони незалежні, то немає наперед визначеного місця для розміщення їх результатів.
Існує багато бібліотек і фрагментів python для створення демона, у наведеному вище прикладі я використовую власну функцію, яка поєднує деякі ідеї версій Steinar Knutsens та Jeff Kunces. Це максимально просто, зауважте, що я роздвоююсь двічі .
def daemonize():
"""Forks this process creating a daemon and killing the original one"""
if (not os.fork()):
# get our own session and fixup std[in,out,err]
os.setsid()
sys.stdin.close()
sys.stdout = NullDevice()
sys.stderr = NullDevice()
if (not os.fork()):
# hang around till adopted by init
ppid = os.getppid()
while (ppid != 1):
time.sleep(0.5)
ppid = os.getppid()
else:
# time for child to die
os._exit(0)
else:
# wait for child to die and then bail
os.wait()
sys.exit()