Lorsque j'écris un démon python, j'attrape toutes les exceptions et les jette ensuite dans le fichier journal. Je l'utilise non seulement pour le débogage, mais aussi en production. J'ai un petit script que je lance tous les matins et qui cherche quelque chose de bouleversant dans les journaux.
Cela aide également à maintenir le démon en marche, bien sûr.
Quelques exemples de code (je supprime les parties non intéressantes):
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)
Où actua () est le véritable démon (il écrit aussi pour se connecter). Notez que j'ai également une variable DEBUG dans un fichier de paramètres, quand c'est vrai, je ne bifurque pas le démon donc il s'exécute sur la console.
Démons
Les démons sont l'équivalent unix des services Windows. Ce sont des processus qui s'exécutent en arrière-plan indépendamment des autres processus. Cela signifie que leur père est généralement init et qu'ils sont détachés de tout tty. Comme ils sont indépendants, il n'y a pas de place prédéfinie pour mettre leur sortie.
Il existe de nombreuses bibliothèques et extraits de code Python pour créer un démon, dans l'exemple ci-dessus, j'utilise ma propre fonction, qui combine certaines idées des versions de Steinar Knutsens et Jeff Kunces. C'est aussi simple que possible, notez que je bifurque deux fois .
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()