Quando escrevo um daemon python, pego todas as exceções e as lanço no arquivo de log. Eu não apenas uso para depuração, mas também na produção. Eu tenho um pequeno script que eu executo todas as manhãs que procura algo perturbador nos logs.
Também ajuda a manter o daemon em execução, é claro.
Algum código de exemplo (removo as partes não interessantes):
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)
Onde actua () é o daemon real (ele também grava no log). Observe que eu também tenho uma variável DEBUG em um arquivo de configurações, quando é True, não bifurco o daemon para que ele seja executado no console.
Daemons
Daemons são o equivalente unix aos serviços do Windows. São processos executados em segundo plano, independentes de outros processos. Isso significa que seu pai geralmente é init e que eles são desapegados de qualquer tipo. Como eles são independentes, não há lugar predefinido para colocar sua saída.
Existem muitas bibliotecas e trechos de python para criar um daemon. No exemplo acima, eu uso minha própria função, que combina algumas idéias das versões Steinar Knutsens e Jeff Kunces. É o mais simples possível, observe que eu bifurco duas vezes .
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()