2009-05-18 24 views
24

Estoy usando el registro (registro de importación) para registrar mensajes.logging con filtros

Dentro de 1 único módulo, estoy registrando mensajes en el nivel de depuración (my_logger.debug ('msg'));

Algunos de estos mensajes de depuración provienen de function_a() y otros de function_b(); Me gustaría poder habilitar/deshabilitar el registro en función de si provienen de a o de b;

Supongo que tengo que usar el mecanismo de filtrado de Logging.

¿Puede alguien mostrarme cómo debería instrumentarse el siguiente código para hacer lo que quiero? Gracias.

import logging 
logger= logging.getLogger("module_name") 

def function_a(...): 
    logger.debug("a message") 

def function_b(...): 
    logger.debug("another message") 

if __name__ == "__main__": 
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) 

    #don't want function_a()'s noise -> .... 
    #somehow filter-out function_a's logging 
    function_a() 

    #don't want function_b()'s noise -> .... 
    #somehow filter-out function_b's logging 
    function_b() 

Si escalé este sencillo ejemplo para más módulos y más funcs por módulo, estaría preocupado por un montón de madereros;

¿Puedo mantenerlo en 1 registrador por módulo? Tenga en cuenta que los mensajes de registro están "estructurados", es decir, si la (s) función (es) iniciar sesión están realizando algún trabajo de análisis, todos ellos contienen un prefijo logger.debug ("análisis: xxx") - ¿puedo de alguna manera con solo cerrar una línea? -off de todos los mensajes "de análisis" (independientemente del módulo/función que emita el mensaje?)

Respuesta

36

Sólo implementar una subclase de logging.Filter: http://docs.python.org/library/logging.html#filter-objects. Tendrá un método, filter(record), que examina el registro de registro y devuelve True para registrarlo o False para descartarlo. Luego puede instalar el filtro en Logger o Handler llamando al método addFilter(filter).

Ejemplo:

class NoParsingFilter(logging.Filter): 
    def filter(self, record): 
     return not record.getMessage().startswith('parsing') 

logger.addFilter(NoParsingFilter()) 

O algo así, de todos modos.

+6

Tuve que agregar el filtro al controlador. –

15

No utilice global. Es un accidente esperando a suceder.

Puede dar a sus registradores cualquier "." - nombres separados que sean significativos para usted.

Puede controlarlos como una jerarquía. Si tiene registradores llamados a.b.c y a.b.d, puede verificar el nivel de registro para a.b y modificar ambos registradores.

Puede tener cualquier cantidad de registradores, no son caros.

El patrón de diseño más común es un registrador por módulo. Consulte Naming Python loggers

Haga esto.

import logging 

logger= logging.getLogger("module_name") 
logger_a = logger.getLogger("module_name.function_a") 
logger_b = logger.getLogger("module_name.function_b") 

def function_a(...): 
    logger_a.debug("a message") 

def functio_b(...): 
    logger_b.debug("another message") 

if __name__ == "__main__": 
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) 
    logger_a.setLevel(logging.DEBUG) 
    logger_b.setLevel(logging.WARN) 

    ... etc ... 
+1

agradece a S.Lott por su respuesta; esto funcionaría; sin embargo, si amplié mi simple ejemplo a más módulos y más funciones por módulo, me preocuparía la existencia de muchos registradores; ¿Puedo mantenerlo en 1 logger por módulo? tenga en cuenta que los mensajes de registro están "estructurados", es decir, si la (s) función (es) iniciar sesión están haciendo algún trabajo de análisis, todos ellos contienen un prefijo logger.debug ("análisis: ...") - ¿puedo de alguna manera con una sola línea? simplemente apague todos los mensajes de "análisis sintáctico" (independientemente del módulo/función que emita el mensaje?) –