2013-06-11 16 views
16

Chcę napisać klasę Python, która korzysta z logowania w języku Python. Ta klasa Pythona będzie odpowiedzialna za stworzenie pliku o podanej nazwie w funkcji init.Logowanie do wielu plików dziennika z różnych klas w Pythonie

Chcę utworzyć obiekt powyższej klasy w dwóch lub więcej klasach i oczekiwać wygenerowania dwóch lub plików.

Próbowałem pisać tę klasę, ale nie mogę utworzyć wielu plików.

Czy każdy może mnie poprowadzić w jaki sposób mogę to zrobić?

Utworzono następujące klasy:

class Logger: 
def __init__(self, log_filename = "test.log"): 
    if not os.path.exists("LogFiles"): 
     os.makedirs("LogFiles") 
    self.Logger = logging.getLogger("main") 
    logging.basicConfig(level=logging.DEBUG, 
         format='%(asctime)s : %(message)s', 
         filename= log_filename, 
         filemode='w')   # change filemode to 'w' to overwrite file on each run 

    consoleHandler = logging.StreamHandler() 
    consoleHandler.setLevel(logging.DEBUG) 
    formatter = logging.Formatter('%(asctime)s - %(message)s') 
    consoleHandler.setFormatter(formatter) 
    logging.getLogger('').addHandler(consoleHandler)  # Add to the root logger 
    self.Logger.info("Starting new logging sessions") 


def writeToFile(self, line): 
    if self.Logger.propagate == True: 
     self.Logger.debug(line) 

def closeFile(self): 

    if self.Logger.propagate == True: 
     self.Logger.propagate = False 
+1

[Logowanie do wielu miejsc docelowych] (http://docs.python.org/2/howto/logging-cookbook.html#logging-to-multiple-dracinations) – jfs

+0

@JFSebastian Wierzę, że nie całkiem robi to, co chce ; wysyła dane wyjściowe z jednego rejestratora do dwóch lokalizacji. Korzysta także z bardzo magicznego rejestrowania nadrzędnego. OP chce wysyłać dane wyjściowe do dwóch różnych lokalizacji z niezależnymi rejestratorami. – jpmc26

Odpowiedz

44

brzmi jak wewnętrzne z klasy powinny prawdopodobnie mają Logger i że będziemy chcieli dodać FileHandler do Logger. Możesz rozważyć użycie metody fabrycznej, która tworzy Logger s i dodaje program obsługi zamiast implementowania własnej klasy. Może być konieczne utworzenie katalogów przechowujących pliki dziennika. Aby uzyskać porady dotyczące tworzenia katalogów, patrz: this answer.

Edit:

Nie sądzę, trzeba napisać własną Logger klasę. Moduł Pythona logging ma wszystkie potrzebne elementy. Prawdopodobnie potrzebujesz tylko metody fabrycznej. Kluczem do realizacji jest utworzenie dwóch oddzielnych, całkowicie niezależnych obiektów rejestrowania. Robisz to z logging.getLogger i za każdym razem, gdy przekażesz mu inną nazwę, otrzymasz inny rejestrator. Możesz użyć czegokolwiek, co chcesz, do nazwy loggera. Na pewno chcesz pozostać z dala od basicConfig, co robisz. Został zaprojektowany z myślą o prostych rzeczach dla osób, które po prostu nie chcą robić nic specjalnego.

Myślę, że to demonstruje funkcjonalność, której szukasz. Kluczem jest utworzenie dwóch różnych rejestratorów z różnymi programami obsługi. Następnie użyj ich osobno. Pamiętaj, że moje drugie połączenie z numerem logging.getLogger nie tworzy nowego rejestratora; dostaje ten, który ustawiliśmy początkowo w setup_logger.

log_test.py:

from __future__ import absolute_import 

import logging 

def setup_logger(logger_name, log_file, level=logging.INFO): 
    l = logging.getLogger(logger_name) 
    formatter = logging.Formatter('%(asctime)s : %(message)s') 
    fileHandler = logging.FileHandler(log_file, mode='w') 
    fileHandler.setFormatter(formatter) 
    streamHandler = logging.StreamHandler() 
    streamHandler.setFormatter(formatter) 

    l.setLevel(level) 
    l.addHandler(fileHandler) 
    l.addHandler(streamHandler)  

def main(): 
    setup_logger('log1', r'C:\temp\log1.log') 
    setup_logger('log2', r'C:\temp\log2.log') 
    log1 = logging.getLogger('log1') 
    log2 = logging.getLogger('log2') 

    log1.info('Info for log 1!') 
    log2.info('Info for log 2!') 
    log1.error('Oh, no! Something went wrong!') 

if '__main__' == __name__: 
    main() 

run Próbka:

C:\temp>C:\Python\27\python.exe logtest.py 
2013-06-12 02:00:13,832 : Info for log 1! 
2013-06-12 02:00:13,832 : Info for log 2! 
2013-06-12 02:00:13,832 : Oh, no! Something went wrong! 

log1.log:

2013-06-12 02:00:13,832 : Info for log 1! 
2013-06-12 02:00:13,832 : Oh, no! Something went wrong! 

log2.log:

2013-06-12 02:00:13,832 : Info for log 2! 
+0

Jestem nowy w module logowania i widzę, że nawet jeśli podaję inną nazwę pliku w basicConfig, utworzono tylko jeden plik. Pozwól mi powiedzieć jaki jest mój problem Załóżmy, że istnieje klasa A, klasa B i plik C. C ma główną funkcję, w której tworzę obiekt klasy A i B. Dzienniki klasy A powinny przejść do pliku A.log, a dziennik klasy B powinien przejdź do pliku B.log. Nie chcę, żeby jakikolwiek log A pojawiał się B.log lub viceversa. Więc mogę utworzyć wspólną klasę rejestratora i użyć tej klasy zarówno w A i B.Dowolny przykład z psuedocode pomogłby –

+0

dodać klasę generyczną, którą chcę utworzyć. Czy możesz mi powiedzieć, co robię źle? –

+0

+1. 'setup_logger()' może być lepszą nazwą (getLogger() tworzy rejestratory jeśli to konieczne). Możesz chcieć, aby 'l.propagate = False' nie przekazywał wiadomości do rejestratorów przodków. Nazwa rejestratora prawdopodobnie powinna pochodzić od nazwy klasy (okres w nazwie rejestratora jest szczególny, tzn. W jaki sposób tworzona jest hierarchia loggera, tzn. Należy unikać '.' w nazwie, chyba że jest to wyraźnie pożądane (można [użyć' logging_tree' do wizualizacji ] (https://pypi.python.org/pypi/logging_tree))). – jfs

Powiązane problemy