2010-07-28 5 views
10

Tengo un paquete que tiene varios componentes que se beneficiarían enormemente del uso del registro y la salida de información útil.Manera eficiente de configurar el registro en un módulo de paquete

Lo que no quiero hacer es 'setup' registrador apropiado para cada archivo individual con alguna parte a lo largo de estas líneas:

import logging 
logging.basicConfig(level=DEBUG) 
my_function = logging.getLogger("my_function") 
my_class = logging.getLogger("my_class") 

He probado un par de enfoques, uno de ellos es la adición de la plancha de caldera código en una clase dentro de un módulo de servicios públicos y tratar de hacer algo como esto:

from util import setlogging 
set_logging() 

Pero incluso la solución anterior no se ve limpio para mí y que podría causar problemas debido a setLogger no tiene un método __call__. Lo que sí me gustó fue que mi clase "set_logging" leería un archivo de configuración y tendría algunos valores predeterminados para que no importara qué nivel o qué tipo de formato de registro quería que lo configurara correctamente.

¿Hay alguna forma de inicializar el registro adecuado en mi paquete? ¿Tal vez en el archivo __init__.py?

Y sólo para ser lo más detallado posible, esto es lo que setlogging (ahora una función, no una clase) que parece:

def setlogging(config=None): 
    if config == None: 
     config = config_options() # sets default values 
    levels = { 
     'debug': DEBUG, 
     'info': INFO 
     } 

    level = levels.get(config['log_level']) 
    log_format = config['log_format'] 
    datefmt = config['log_datefmt'] 

    basicConfig(
     level = level, 
     format = log_format, 
     datefmt = datefmt) 

Respuesta

11

Si desea todo el código en los diferentes módulos de su paquete a utilizar el mismo objeto registrador, sólo tiene que (hacer que el maderero disponibles - véase más adelante - y) llamar

mylogger.warning("Attenzione!") 

o similares, en lugar de logging.warning & c. Por lo tanto, el problema se reduce a hacer un objeto mylogger para todo el paquete y hacerlo disponible en todos los módulos del paquete. (Alternativamente, podría utilizar registradores con nombres que comiencen con el nombre del paquete seguido de un punto, pero si bien eso forma parte de la funcionalidad del paquete logging, personalmente nunca he encontrado que sea una forma natural de operar).

lo tanto, su función util.setlogging simplemente podría ser seguido por, digamos,

mylogger = logging.getLogger(package_name) 

y cada módulo que las importaciones util puede simplemente usar

util.mylogger.warning('Watch out!') 

y similares. Este me parece ser el enfoque más simple, siempre que se aplique el concepto de que todo el código en el paquete debe iniciar sesión de la misma manera.

+0

¿No tendría que llamar a setlogging() para poder acceder a 'mylogger'? Aunque intento eso, todavía obtengo un AttributeError esperado ya que el objeto 'function' no tiene el atributo 'mylogger'. Tal vez no entiendo por completo ... – alfredodeza

+0

@alfredo, necesita ser llamado solo una vez (del '' __init__. Py' del paquete sería el lugar más simple de usar para este propósito, ya que usted sabe que siempre se ejecuta antes que cualquier código en cualquier módulo del paquete) y por supuesto puede agregar a ese registrador un manejador, con su formateador configurado como lo desee, como en el código de ejemplo dado en http://docs.python.org/library/logging.html?highlight=logging#configuring-logging. –

+0

Gracias Alex, ¡eso realmente ayudó! Te compraré una cerveza el próximo año en PyCon :) – alfredodeza

1

La manera apropiada para un módulo de usar el registro es

import logging 
logger = logging.getLogger('my_module_name') 

y

logger.debug('help!') 

se convierte en un no-op hasta que alguien llama a logging.basicConfig() (o una variante).

Cuestiones relacionadas