2011-09-08 2 views
5

Ho uno script python che gira su Ubuntu e processa il contenuto di un database MySQL. Voglio essere informato quando lo script viene eseguito in un exception non gestito o quando è stata completata l'elaborazione.Come notificarmi quando uno script python si imbatte in un errore o si ferma semplicemente?

Qual è il modo appropriato per farlo accadere?

ho pensato di mandare me una e-mail dall'interno di pitone con il metodo illustrato in this SO-Answer, ma per essere in grado di farlo devo hardcode mia logindata - che io non sono confortevoli, con (lo script viene eseguito su un server pubblico all'interno della società).

Qualche suggerimento per ignorarlo o per farlo accadere usando un modo più appropriato?

+0

Questi dati di accesso sono autenticati con il server SMTP o MySQL o entrambi? – arunkumar

+0

Con il server SMTP. Voglio usare il mio account GMail per quello. – Aufwind

risposta

1

In genere non è necessario fornire i dati di accesso quando si invia un'e-mail tramite SMTP. Se fossi in te, sperimenterei il codice fornito nella risposta a cui ti sei collegato e provalo con il server SMTP della tua azienda.

+0

Potresti spiegare cosa intendi per * Tu ... non è necessario fornire i dati di accesso quando si invia un'email via SMTP. ... *? – Aufwind

+0

@Aufwind: Tutto quello che sto dicendo è che se stai inviando un'email a 'abc @ xyz.com', e connettiti al server SMTP di' xyz.com' (cioè quello elencato nel record MX), nella maggior parte dei casi accetterà la tua e-mail senza che tu debba fornire dettagli di accesso. – NPE

1

Ecco un gestore di eccezioni che ho scritto e che usa l'e-mail l'eccezione quando lo script muore. Set con sys.excepthook = ExceptHook:

import os 
import sys 
import traceback 
import re 
import smtplib 
import getpass 

def ExceptHook(etype, value, tb): 
    """Formats traceback and exception data and emails the error to me: &^&^@&^&^&.com. 

    Arguments: 
    etype -- Exception class type 
    value -- Exception string value 
    tb -- Traceback string data 
    """ 

    excType = re.sub('(<(type|class \')|\'exceptions.|\'>|__main__.)', '', str(etype)).strip() 
    Email = {'TO':"*****@*****.com", 'FROM':getpass.getuser() + '@blizzard.com', 'SUBJECT':'** Exception **', 'BODY':'%s: %s\n\n' % (excType, etype.__doc__)} 

    for line in traceback.extract_tb(tb): 
     Email['BODY'] += '\tFile: "%s"\n\t\t%s %s: %s\n' % (line[0], line[2], line[1], line[3]) 
    while 1: 
     if not tb.tb_next: break 
     tb = tb.tb_next 
    stack = [] 
    f = tb.tb_frame 
    while f: 
     stack.append(f) 
     f = f.f_back 
    stack.reverse() 
    Email['BODY'] += '\nLocals by frame, innermost last:' 
    for frame in stack: 
     Email['BODY'] += '\nFrame %s in %s at line %s' % (frame.f_code.co_name, frame.f_code.co_filename, frame.f_lineno) 
     for key, val in frame.f_locals.items(): 
      Email['BODY'] += '\n\t%20s = ' % key 
      try: 
       Email['BODY'] += str(val) 
      except: 
       Email['BODY'] += '<ERROR WHILE PRINTING VALUE>' 
    thisHost = socket.gethostname() 
    thisIP = socket.gethostbyname(thisHost) 
    gmTime = time.gmtime() 
    logName = 'SomeTool_v%s_%s_%s_%s.%s.%s_%s.%s.%s.log' % (__version__, thisHost, thisIP, gmTime.tm_mon, gmTime.tm_mday, gmTime.tm_year, gmTime.tm_hour, gmTime.tm_min, gmTime.tm_sec) 
    if not os.path.exists(LOGS_DIR): 
     try: 
      os.mkdir(LOGS_DIR) 
     except: 
      baseLogDir = os.path.join(NET_DIR, "logs") 
      if not os.path.exists(baseLogDir): 
       try: 
        os.mkdir(baseLogDir) 
       except: 
        pass 
       else: 
        open(os.path.join(baseLogDir, logName), 'w').write(Email['BODY']) 
     else: 
      open(os.path.join(LOGS_DIR, logName), 'w').write(Email['BODY']) 
    Email['ALL'] = 'From: %s\nTo: %s\nSubject: %s\n\n%s' % (Email['FROM'], Email['TO'], Email['SUBJECT'], Email['BODY']) 
    server = smtplib.SMTP(MY_SMTP) 
    server.sendmail(Email['FROM'], Email['TO'], Email['ALL']) 
    server.quit() 

if __name__ == '__main__': 
    sys.excepthook = ExceptHook 
    try: 
     1/0 
    except: 
     sys.exit() 
0

Se stai usando questo con cron, vorrei suggerire a guardare il valore di ritorno dello script al di fuori di pitone in bash. Ad esempio, se lo script solleva un'eccezione, si otterrà un valore di ritorno di 1:

$ python test.py 
Traceback (most recent call last): 
    File "test.py", line 7, in <module> 
    raise ValueError("test") 
ValueError: test 
$ echo $? 
1 

Mentre un'uscita pulita restituisce 0:

$ python test.py 
$ echo $? 
0 

Per monitorare il cron, è possibile scrivere il ritorno valore su un file da qualche parte. Quindi, utilizzare monit per notificare quando il file contiene un valore diverso da 0 o when the timestamp is older than how often your cron is supposed to run.

0

Quella macchina ha installato sendmail, vorrei semplicemente usare sendmail per inviare e-mail invece di parlare direttamente con il server smtp, ad es. provare questo

echo -e "To: [email protected]\nSubject: Testx\nTest\n" | sudo sendmail -bm -t -v 

Mostrerà sendmail in azione in modalità dettagliata e se funziona si può semplicemente utilizzare sendmail per inviare e-mail per esempio

ps = Popen(["/usr/lib/sendmail"]+list(your_recipents), \ 
       stdin=PIPE) 
    ps.stdin.write('you msg') 
    ps.stdin.flush() 
    ps.stdin.close() 
0

Alcune delle vostre opzioni sono -

Se si ha accesso ad una macchina/server sulla rete aziendale, dove è possibile configurare un server SMTP semplice come un mail relay. È quindi possibile configurare i dettagli di accesso per GMail in modo un po 'più sicuro, a seconda di chi ha accesso alla macchina. Potrebbe persino essere eseguito come una semplice VM su un altro server. Una VM a cui solo tu hai accesso. Quindi usa questo server per inviare posta dal tuo script python.

Se non si ha accesso a un server sulla rete aziendale, è possibile cercare server SMTP che non richiedono l'autenticazione.

Oppure un'altra opzione è creare un utente GMail solo per l'invio di e-mail e utilizzando le sue credenziali.

0

È possibile utilizzare l'API di GMail. Non ha bisogno della tua password all'interno dello script. This answer potrebbe aiutare.