Quando eu escrevo um daemon python, eu pego todas as exceções e as lanço no arquivo de log. Eu não uso apenas para depuração, mas também na produção. Eu tenho um pequeno script que eu corro todas as manhãs que procura algo perturbador nos logs.
Também ajuda a manter o daemon em execução, é claro.
Algum exemplo de código (eu 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 (escreve também para logar). Note que eu também tenho uma variável DEBUG em um arquivo de configurações, quando é True, eu 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 o pai deles é geralmente init e que eles estão separados de qualquer tty. Como são independentes, não há lugar predefinido para colocar a saída.
Existem muitas bibliotecas e snippets python para fazer um daemon, no exemplo acima eu uso minha própria função, que combina algumas idéias das versões de Steinar Knutsens e Jeff Kunces. É o mais simples possível, note que eu garfo 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()