2017-05-17 7 views
0

Ich benutze Python, um einen Dienst zu schreiben, der aus einer Nachrichtenwarteschlange liest. Für jede Nachricht wird ein Prozess ausgeführt, und nach Abschluss wird eine weitere Nachricht aus der Warteschlange abgerufen. Ich verwende das Logging-Paket, um Informationen, Warnungen und Fehler zu protokollieren. Wenn der Prozess aus irgendeinem Grund fehlschlägt, fängt der Prozess den Fehler ab und sendet eine E-Mail mit dem Traceback. Ich möchte, dass die E-Mail auch die Protokolle enthält, wenn die Anwendung mit der Verarbeitung der Nachricht begonnen hat. Um es klar zu sagen - ich möchte trotzdem, dass die Anwendung sofort loggt. Wenn die Anwendung jedoch fehlschlägt und die Ausnahme erfolgreich abfängt, möchte ich, dass die Protokolle ebenfalls in der E-Mail gesendet werden.Python Logging Dump bei Fehler

Mein erster Gedanke war, eine Liste zu verwenden, die nur Zeichenfolgen log wie so retten würde:

while True: 
    # Grab the message here 
    log_list = [] 
    try: 
    log_msg = "Some log message here" 
    log_list.append(log_msg) 
    ... 
    except: 
    # send email here using log_list 

Dies würde mein Problem Art lösen, außer ich die anderen Informationen sehen möchten, dass die Python-Logging-Paket fügt um Nachrichten wie einen Zeitstempel zu protokollieren. Mir ist klar, dass ich das nur manuell tun und es zu meinem log_list-Objekt hinzufügen könnte. Was würde Ich mag zu tun ist:

import logging 
logger = logging.getLogger() 
while True: 
    logger.reset() 
    # Grab the message here 
    try: 
    logger.info("Some log message here") 
    ... 
    except: 
    # send email here using something like logger.dump() 

Also ... meine Frage - Gibt es eine andere Art und Weise darüber, in welcher geht ich vermeiden kann eine Liste mit meinen Logs zu speichern und andere Anmeldung info speichern wie der Zeitstempel, die Protokollierungsstufe usw.?

+0

Sinn macht. Ich würde immer noch wollen, dass es sofort protokolliert. Ich möchte nur die Protokolle für die E-Mail bündeln, die bei einem Fehler ebenfalls gesendet wird. – archeezee

+2

Dies klingt wie ein Job für einen zusätzlichen benutzerdefinierten Logging-Handler, der dem Logger hinzugefügt wurde. – chepner

+0

Ich würde einen benutzerdefinierten Protokollhandler mit einem Ringpuffer (mit 'deque') hinzufügen, der sich die letzten mehreren protokollierten Nachrichten merkt und diese Zeilen extrahiert und sendet. – 9000

Antwort

0

I endete mit riscnotcisc Vorschlag, aber ich die logging.Logger Klasse erweitert

from logging import Logger 
import logging 
import datetime 

class CustomLogger(Logger): 
    def __init__(self, process_name): 
     self.process_name = process_name 
     super(CustomLogger, self).__init__(process_name) 
     self.log_list = [] 

     ch = logging.StreamHandler() 
     ch.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) 
     self.handlers.append(ch) 

    def info(self, message, *args, **kwargs): 
     self.log_list.append('{} - {} - INFO - {}'.format(datetime.datetime.now(), self.process_name, message)) 
     super(CustomLogger, self).info(message, *args, **kwargs) 

    def debug(self, message, *args, **kwargs): 
     self.log_list.append('{} - {} - DEBUG - {}'.format(datetime.datetime.now(), self.process_name, message)) 
     super(CustomLogger, self).debug(message, *args, **kwargs) 

    def warning(self, message, *args, **kwargs): 
     self.log_list.append('{} - {} - WARNING - {}'.format(datetime.datetime.now(), self.process_name, message)) 
     super(CustomLogger, self).warning(message, *args, **kwargs) 

    def dump(self): 
     return '\n'.join(self.log_list) 

    def reset(self): 
     self.log_list = [] 
0

Versuchen Sie nur eine benutzerdefinierte Protokollklasse? Etwas wie:

import time 

class Log: 
    msgs = [] 
    def __init__(self): 
     pass 

    def addLog(self,msg): 
     self.msgs.append("LOG AT "+str(time.time())+":\n"+msg) 

    def dumpLog(self): 
     s = "" 
     for each in self.msgs: 
      s+= each+"\n------------------------\n" 
     return s 

bin ich mit dem Logging-Modul nicht vertraut und es sieht über kompliziert für die meisten Anwendungsfälle.

+0

Danke! Ich habe tatsächlich bereits eine erweiterte Klasse für das Logger-Modul erstellt. Also werde ich wahrscheinlich ein bisschen Funktionalität hinzufügen. – archeezee