2015-01-27 18 views
5

Dzienniki, które tworzę w Pythonie, mają być tymczasowo przechowywane jako pliki, które z kolei będą przetwarzane w bazę danych dziennika. Przyjmują one format oznaczony rurami, aby określić sposób przetwarzania dzienników, ale metoda logging.exception() łamie mój standard, dodając jedną zbyt dużą liczbę pól i zbyt wiele nowych linii.Jak mogę formatować stosy wyjątków w dziennikach Pythona?

import logging 
logging.basicConfig(filename='output.txt', 
        format='%(asctime)s|%(levelname)s|%(message)s|', 
        datefmt='%m/%d/%Y %I:%M:%S %p', 
        level=logging.DEBUG) 
logging.info('Sample message') 

try: 
    x = 1/0 
except ZeroDivisionError as e: 
    logging.exception('ZeroDivisionError: {0}'.format(e)) 

# output.txt 
01/27/2015 02:09:01 PM|INFO|Sample message| 
01/27/2015 02:09:01 PM|ERROR|ZeroDivisionError: integer division or modulo by zero| 
Traceback (most recent call last): 
    File "C:\Users\matr06586\Desktop\ETLstage\Python\blahblah.py", line 90, in <module> 
    x = 1/0 
ZeroDivisionError: integer division or modulo by zero 

Jak najlepiej mogę obsługiwać lub formatu tracebacks ze spacjami i znakami nowej linii? Te komunikaty są częścią i paczkami w logging.exception(), ale dziwne jest ominięcie tej funkcji, gdy próbuję udokumentować wystąpienia wyjątków. Jak mogę nagrać moje tracebacki i sformatować je również? Czy informacje o śledzeniu powinny być ignorowane?

Dziękuję za poświęcony czas!

+0

Czy pytasz, co powinieneś zrobić lub jak to zrobić? Sposób formatowania komunikatów o błędach w pliku dziennika należy do Ciebie. Jak * ty * chcesz, żeby wyglądały? – BrenBarn

+0

Dzięki za wyczyszczenie tego. Najlepiej byłoby, gdybym umieścił tracebacki jako inny atrybut rozdzielany odgałęzieniami w tym samym wierszu, co reszta zalogowanego komunikatu. – twoxmachine

Odpowiedz

5

Można zdefiniować własne Formatter którego metody mogą zastąpić informacji wyjątków Format dokładnie tak, jak chcesz. Tutaj jest uproszczone (ale działa) przykład:

import logging 

class OneLineExceptionFormatter(logging.Formatter): 
    def formatException(self, exc_info): 
     result = super(OneLineExceptionFormatter, self).formatException(exc_info) 
     return repr(result) # or format into one line however you want to 

    def format(self, record): 
     s = super(OneLineExceptionFormatter, self).format(record) 
     if record.exc_text: 
      s = s.replace('\n', '') + '|' 
     return s 

fh = logging.FileHandler('output.txt', 'w') 
f = OneLineExceptionFormatter('%(asctime)s|%(levelname)s|%(message)s|', '%m/%d/%Y %I:%M:%S %p') 
fh.setFormatter(f) 
root = logging.getLogger() 
root.setLevel(logging.DEBUG) 
root.addHandler(fh) 
logging.info('Sample message') 

try: 
    x = 1/0 
except ZeroDivisionError as e: 
    logging.exception('ZeroDivisionError: {0}'.format(e)) 

To daje tylko dwie linie:

01/28/2015 07:28:27 AM|INFO|Sample message| 
01/28/2015 07:28:27 AM|ERROR|ZeroDivisionError: integer division or modulo by zero|'Traceback (most recent call last):\n File "logtest2.py", line 23, in <module>\n x = 1/0\nZeroDivisionError: integer division or modulo by zero'| 

Oczywiście, można zbudować na tym przykładzie dokładnie to, co chcesz, na przykład za pośrednictwem modułu traceback.

0

Należy zdefiniować własną funkcję, która używa traceback.extract_tb formatować traceback do składni chcesz, a potem zwrócić go lub zapisać go do pliku:

traceback.extract_tb(traceback[, limit]) 

zwróci listę maksymalnie ograniczyć „pre- przetworzone wpisy śledzenia stosu wyodrębnione z traceback obiektu traceback. Jest to przydatne do alternatywnego formatowania śladów stosu. Jeśli pominięto ograniczenie lub Brak, wszystkie pozycje zostaną wyodrębnione. "Wstępnie przetworzony" wpis śledzenia stosu to 4-tka (nazwa pliku, numer linii, nazwa funkcji, tekst) reprezentująca informacje, które są zwykle drukowane dla śledzenia stosu. Tekst jest ciągiem z usuniętymi początkowymi i końcowymi białymi znakami; jeśli źródło nie jest dostępne, jest to None.

https://docs.python.org/2/library/traceback.html