2012-01-12 14 views
5

Voglio fare qualcosa che ho pensato sia semplice.Diversi livelli di registrazione in python

In realtà con il modulo di registrazione pitone, io sono la registrazione interessa tutto sulla linea di comando a livello di data dagli argomenti della riga di comando , e Registra su file ad un livello DEBUG fisso.

Creazione di due registratori diversi con diversi livelli non funziona, ma impostare i livelli di due diversi gestori sia aggiunto alla radice registratore non funziona neanche, in modo che qualsiasi idea su come avrei dovuto farlo davvero? (lettura su altri collegamenti secondo approccio dovrebbe funzionare, così sto facendo qualcos'altro di stupido?)

Questo è il codice che imposta il mio sistema di registrazione in questo momento:

class LoggerSetup(object): 
    """Setup the different logger objects 
    """ 

    def __init__(self): 
     self.root_logger = logging.getLogger() 
     self.shell_hdlr = logging.StreamHandler() 

    #TODO: add another logging handler which stores to a temporary file 
    #which should be cleaned up later 
    def setup_shell_logger(self, log_level): 
     self.root_logger.setLevel(LOG_LEVELS[log_level]) 
     # in this way the root logger is not set but the handlers are set 
     self.shell_hdlr = logging.StreamHandler() 
     self.shell_hdlr.setLevel(LOG_LEVELS[log_level]) 
     self.shell_hdlr.setFormatter(StarFormatter()) 
     #FIXME: add the support for regular expression exclusion too 
     self.root_logger.addHandler(self.shell_hdlr) 

    def setup_log_include(self, log_include): 
     """Set up the filter to include log messages 
     """ 
     if log_include: 
      incl = FilterInclude(log_include) 
      self.shell_hdlr.addFilter(incl) 

    def setup_log_exclude(self, log_exclude): 
     """Set up the filters to exclude log messages 
     """ 
     if log_exclude: 
      excl = FilterExclude(log_exclude) 
      self.shell_hdlr.addFilter(excl) 

    def setup_file_logging(self): 
     """Set up the file logger, which always logs in DEBUG mode 
     even if the top level logger is set to another level 
     """ 
     #XXX: not working, one possible way to make it work is to create 
     #only one log, and different handler/filters to make to handle all 
     #the different outputs 
     file_handler = logging.FileHandler(LOG_FILENAME) 
     # the file logging is always in debug mode 
     file_handler.setLevel(logging.DEBUG) 
     formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s - %(asctime)s') 
     file_handler.setFormatter(formatter) 
     self.root_logger.addHandler(file_handler) 
+0

", ma impostare i livelli di due diversi gestori sia aggiunti al root logger non funziona "? Puoi chiarire, per favore? –

risposta

12

Questo è qualcosa che sto usando con tutte le mie app da linea di comando Python. E 'un po' prolisso, ma si dovrebbe essere in grado di ottenere un logger che accetta un argomento opzionale per creare un logger di console a qualsiasi livello, indipendentemente da ciò che viene connesso al file:

#!/usr/bin/env python 
import logging 
from argparse import ArgumentParser 

COMPANY_LOGGER = 'COMPANY.Python.Logger' 
CONSL_LEVEL_RANGE = range(0, 51) 
LOG_FILE = 'company.log' 
FORMAT_STR = '%(asctime)s %(levelname)s %(message)s' 

parser = ArgumentParser() 
parser.add_argument('-c', '--console-log', metavar='ARG', 
        type=int, choices=range(0, 51), 
        action='store', dest='console_log', 
        default=None, 
        help='Adds a console logger for the level specified in the range 1..50') 

args = parser.parse_args() 

# Create logger 
logger = logging.getLogger(COMPANY_LOGGER) 
logger.setLevel(logging.DEBUG) 
formatter = logging.Formatter(FORMAT_STR) 

# Add FileHandler and only log WARNING and higher 
fh = logging.FileHandler(LOG_FILE) 
fh.name = 'File Logger' 
fh.level = logging.WARNING 
fh.formatter = formatter 
logger.addHandler(fh) 

# Add optional ConsoleHandler 
if args.console_log: 
    ch = logging.StreamHandler() 
    ch.name = 'Console Logger' 
    ch.level = args.console_log 
    ch.formatter = formatter 
    logger.addHandler(ch) 

logger.debug('DEBUG') 
logger.info('INFO') 
logger.warning('WARNING') 
logger.critical('CRITICAL') 

Whenrun dalla riga di comando che abbiamo può vedere le differenze nei livelli registrati.

-c1 equivale a "DEBUG e superiore" (il più verboso), ma company.log è ancora solo la registrazione ATTENZIONE e superiori:

~ zacharyyoung$ ./so.py -c1 
2012-01-12 08:59:50,086 DEBUG DEBUG 
2012-01-12 08:59:50,086 INFO INFO 
2012-01-12 08:59:50,087 WARNING WARNING 
2012-01-12 08:59:50,087 CRITICAL CRITICAL 

~ zacharyyoung$ cat company.log 
2012-01-12 08:59:50,087 WARNING WARNING 
2012-01-12 08:59:50,087 CRITICAL CRITICAL 

-c20 equivale a INFO:

~ zacharyyoung$ ./so.py -c20 
2012-01-12 09:00:09,393 INFO INFO 
2012-01-12 09:00:09,393 WARNING WARNING 
2012-01-12 09:00:09,393 CRITICAL CRITICAL 

~ zacharyyoung$ cat company.log 
2012-01-12 08:59:50,087 WARNING WARNING 
2012-01-12 08:59:50,087 CRITICAL CRITICAL 
2012-01-12 09:00:09,393 WARNING WARNING 
2012-01-12 09:00:09,393 CRITICAL CRITICAL 
+0

+1 Solo un suggerimento: Penso che si possa evitare di definire la funzione 'getConsoleLevel' se si usano le parole chiave' type = int' e 'choices = xrange (51)' del metodo 'parser.add_argument'. Vedi la [fine di questa sezione sul doc] (https://docs.python.org/2/library/argparse.html#type). Ed è possibile impostare un valore predefinito di '21' e ottenere lo stesso livello di default del modulo' logging'. – logc

+0

@logc: grazie per il suggerimento ... Non sono sicuro del motivo per cui non l'ho fatto prima (forse ero preoccupato per il modo in cui è stata stampata la dichiarazione di aiuto), ma posso vedere che funziona altrettanto bene usando solo built-in. Grazie :) –

Problemi correlati