2012-05-20 6 views
7

Actualmente estoy trabajando en la versión 1.0.0 del módulo pyftpdlib. Esta nueva versión introducirá algunos cambios incompatibles hacia atrás en que ciertas API ya no aceptarán bytes sino unicode. Mientras estoy en ello, como parte de esta brecha, estaba contemplando la posibilidad de deshacerme de mis funciones de registro, que actualmente usan la declaración de impresión , y usar el módulo de registro en su lugar.Ventajas de registrar frente a impresión() + mejores prácticas de registro

A partir de ahora pyftpdlib delegados de la tala de 3 funciones:

def log(s): 
    """Log messages intended for the end user.""" 
    print s 

def logline(s): 
    """Log commands and responses passing through the command channel.""" 
    print s 

def logerror(s): 
    """Log traceback outputs occurring in case of errors.""" 
    print >> sys.stderr, s 

El usuario dispuesto a personalizar los registros (por ejemplo, escribir en un archivo) se supone que simplemente sobrescribir estas 3 funciones como en:

>>> from pyftpdlib import ftpserver 
>>> 
>>> def log2file(s): 
...  open('ftpd.log', 'a').write(s) 
... 
>>> ftpserver.log = ftpserver.logline = ftpserver.logerror = log2file 

Ahora me pregunto: ¿qué ventajas implicaría deshacerse de este enfoque y utilizar el módulo de registro en su lugar? Desde la perspectiva de un proveedor de módulos, ¿cómo exactamente se supone que debo exponer las funcionalidades de registro en mi módulo? supone que tengo que hacer esto:

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

... y el estado en mi doc que "registrador" es el objetivo que se supone que se utilizará en caso de que el usuario desea personalizar cómo se comportan los registros? ¿Es legítimo para establecer deliberadamente una salida de formato predefinido como en:

FORMAT = '[%(asctime)] %(message)s' 
logging.basicConfig(format=FORMAT) 
logger = logging.getLogger('pyftpdlib') 

...?

¿Puede pensar en un módulo de terceros que pueda tomar indicaciones desde donde la funcionalidad de registro está expuesta y consolidada como parte de la API pública?

Gracias de antemano.

Respuesta

0

Aquí hay un recurso que utilicé para personalizar logger. No cambié mucho, acabo de agregar una declaración if y paso si quiero iniciar sesión en un archivo o solo en la consola.

Verificar this Colorer out. Es realmente bueno para colorear el resultado, por lo que DEBUG se ve diferente de WARN que se ve diferente de INFO.

El módulo de registro incluye una gran cantidad de funcionalidades agradables, como el registro SMTP, el registro de rotación de archivos (para que pueda guardar un par de archivos de registro antiguos, pero no haga cientos cada vez que algo salga mal).

Si alguna vez desea migrar a Python 3, el uso del módulo de registro eliminará la necesidad de cambiar sus instrucciones de impresión.

El registro es increíble dependiendo de lo que esté haciendo, solo lo he utilizado ligeramente antes para ver dónde estoy en un programa (si está ejecutando esta función, coloree de esta manera), pero tiene mucho más poder que una declaración de impresión regular.

0

Puede ver Django (simplemente cree un proyecto de muestra) y vea cómo inicializa el subsistema de registrador.

También hay un contextual logger helper que he escrito hace tiempo: este registrador toma automáticamente el nombre del módulo/clase/función desde el cual se inicializó.Esto es muy útil para los mensajes de depuración donde se puede ver directamente a través de ese módulo escupe los mensajes y cómo va el flujo de llamadas.

3

bibliotecas (servidor ftp o biblioteca de cliente) nunca deben inicializar el sistema de registro. Así que está bien instanciar un objeto logger y apuntar a logging.basicConfig en la documentación (o proporcionar una función a lo largo de las líneas de basicConfig con la salida fancier y dejar que el usuario elija entre su estrategia de configuración de registro, basicConfig simple o biblioteca proporcionado configuración)

marcos (por ejemplo django) o servidores (daemon servidor ftp) deberían inicializar el sistema de registro a una razonable predeterminado y permitir la personalización de la configuración del sistema de registro.

2

Normalmente, las bibliotecas solo deben crear un controlador NullHandler, que es simplemente un controlador de no hacer nada. El usuario final o el desarrollador de la aplicación que usa su biblioteca puede configurar el sistema de registro. Consulte la sección Configuring Logging for a Library en la documentación logging para obtener más información. En particular, consulte la nota que comienza en

Se recomienda encarecidamente que no agregue ningún manipulador que no sea NullHandler a los registradores de su biblioteca.

En su caso, yo simplemente crear un controlador de registro, según la documentación de registro,

import logging 
logging.getLogger('pyftpdlib').addHandler(logging.NullHandler()) 

Editar La aplicación de registro esbozado en la cuestión parece perfectamente razonable. En su documentación, solo mencione logger y discuta o señale a los usuarios los métodos logging.setLevel y logging.setFormatter para personalizar el resultado de su biblioteca. En lugar de usar logging.basicConfig(format=FORMAT), puede considerar usar logging.config.fileConfig para administrar la configuración de su salida y documentar el archivo de configuración en algún lugar de su documentación, apuntando nuevamente al usuario a la documentación del módulo de registro para el formato esperado en este archivo.

+0

¿Eso significa que no se producirá ninguna salida por defecto? En ese caso, no estoy contento con eso. –

+0

Esto no producirá ninguna salida por defecto. Además, 'logging.NullHandler' solo está disponible en Python 2.7 (y> 3.2 creo), lo que puede ser un problema. Si solo usa 'logger = logging.getLogger ('pyftpdlib')' obtendrá mensajes de manera predeterminada y puede simplemente señalar a sus usuarios a la documentación 'logging.setLevel' y' logging.setFormatter' para demostrar cómo configurar la salida mensajes para tu biblioteca. Además, puede usar la configuración de archivo ['logging.config.fileConfig'] (http://docs.python.org/dev/library/logging.config.html#logging.config.fileConfig) para permitir a los usuarios configurar el logger – Chris

+0

Además, para responder a una de sus preguntas originales, los beneficios de usar registros en lugar de imprimir declaraciones se mencionan brevemente en [PEP 282] (http://www.python.org/dev/peps/pep-0282/): * Si un mecanismo de registro único está consagrado en la biblioteca estándar, 1) es más probable que se realice el registro 'bien', y 2) múltiples bibliotecas podrán integrarse en aplicaciones más grandes que se pueden registrar de forma razonablemente coherente. * – Chris