2012-02-23 8 views
11

Tengo un archivo de configuración de registro de Python con un manejador de archivos del siguiente formulario.Ruta de archivo dinámica y nombre de archivo para FileHandler en el archivo de configuración del registrador en python

[handler_filelog] 
class: FileHandler 
args = ('/var/tmp/log/client.log','a') 

En cambio, lo necesito en el siguiente formulario (ruta generada dinámicamente).

[handler_filelog] 
class: FileHandler 
args = ('/var/tmp/log_<unique_string>/client.log','a') 

Se pueden estar ejecutando varias instancias del programa y, por lo tanto, se deben usar rutas y archivos de registro no conflictivos. El registrador una vez configurado no necesita cambiarse hasta el final de la ejecución del programa.

¿Hay alguna manera de manejar esto usando el enfoque del archivo de configuración? No estoy interesado en recurrir a la creación de los registradores/controladores/formateadores por mi cuenta ya que mi archivo de configuración de registro tiene muchos de estos y el enfoque basado en archivos de configuración es mucho más agradable.

(Actualización: Estoy usando Python 2.4)

+0

¿Ha intentado extender la clase FileHandler? – Phani

+0

Sí. Como se comenta a continuación, funciona si instancia el manejador yo mismo. Para hacer lo mismo a través del archivo de configuración, no he descubierto cómo hacer que la definición de mi clase sea visible para el módulo de registro. – Gns

+0

Actualicé mi respuesta. –

Respuesta

6

Esto hace lo que necesita. Primero debe extender la clase FileHandler. Colocar esto en un archivo, por ejemplo myHandler.py en el directorio del archivo de configuración:

import logging 
import random 
import os 
class myFileHandler(logging.FileHandler): 
    def __init__(self,path,fileName,mode): 
     r = random.randint(1,100000) 
     path = path+"/log_"+str(r) 
     os.mkdir(path) 
     super(myFileHandler,self).__init__(path+"/"+fileName,mode) 

Y luego en el archivo de configuración, puede utilizar esta FileHandler encargo como éste

class: myHandler.myFileHandler 
args = ('/var/tmp','client.log','a') 

probé éste en mi máquina

+0

Con la extensión de FileHandler, pude obtener el comportamiento creando mi propio controlador y agregando al registrador. Pero no pude hacer que esto funcione a través del archivo de configuración. El "randomFileHandler" no está definido en el punto donde el módulo de registro está usando config ini. Estoy comprobando si hay una manera fácil de hacer visible la definición de clase o si termino yendo por el camino de los propios manejadores. – Gns

+0

Intenté hacer visible la definición definiendo _logging. = _, pero me encuentro con el problema de _AttributeError: la instancia de MyFileHandler no tiene atributo 'level'_ -> posiblemente http://bugs.python.org/issue8165. Todavía estoy comprobando si es mi uso incorrecto o un error conocido del módulo de registro. – Gns

+0

Soy nuevo en Python inheritance. Entonces, estaba haciendo algo terrible con la subclase inicialmente. Parece que funciona ahora ... – Phani

6

Si está usando Python 2.7 o 3.2, puede usar dictionary-based configuration, que le permite especificar callables arbitrarios para devolver manejadores - podría, por ej. usa el proceso PID para construir el nombre del archivo.

Actualización: Si está utilizando 2.4, puede utilizar el paquete logutils, que debe trabajar con Python 2.4 (aparte de la clase LoggerAdapter, que requiere 2.5 o posterior). El paquete logutils contiene la funcionalidad de configuración basada en el diccionario.

+0

Estoy usando python 2.4. Gracias por la pista, si las alternativas no son lo suficientemente simples, probablemente eliminaré el archivo de configuración e implementaré una configuración basada en el diccionario. A partir de ahora, este camino aún no es deseable. – Gns

+0

Gracias por la actualización que apunta a logutils. Esta es una pista útil. Esto aborda la pregunta, pero escogí la otra porque es más adecuada para mis necesidades (no introduce una nueva dependencia de la biblioteca). – Gns

+0

Esta respuesta debería obtener más votos. Perdón por el op que tiene que usar Python2.4 pero logging.config.dictConfig es el estándar actual donde se puede manipular fácilmente la configuración. –

0

"CallbackFilter" se puede utilizar para implementar el archivo de ruta de archivo dinámico & para el archivo de configuración del registrador en python. Se puede definir como write_dynamic_log a continuación:

def write_dynamic_log(record): 
    now = datetime.datetime.now().strftime("%Y%m%d%H%M%S") 
    dynamic_log_name = '/var/log/test_%s.log' %now 
    log_file = open(dynamic_log_name, "w") 
    log_file.write(record.msg) 
    log_file.close(); 
    return True 

A continuación, en el archivo de configuración, puede utilizar este filtro de la siguiente manera:

[handler_filelog] 
class: FileHandler 
formatter: brief 
level : INFO 
filters: [write_dynamic_log] 
filename: static.log 

El INFO o por encima de registro de salida será a static.log y también para dynamic_log.

Lo probé en mi proyecto django, en el que escribí config en mi settings.py. Funciona bien. LOGGING will es como:

LOGGING = { 
    'version': 1, 
    'disable_existing_loggers': False, 
    'formatters': { 
     'verbose': { 
      'format': '[%(levelname)s] %(asctime)s - %(pathname)s:%(lineno)d\n%(message)s' 
     }, 
     'debug': { 
      'format': '[%(levelname)s] %(asctime)s - %(pathname)s:%(lineno)d\n\033[34m%(message)s\033[0m' 
     }, 
     'error': { 
      'format': 'Component: %(module)s\nErrorCode: %(funcName)s\nReason: %(funcName)s\nDetail: [%(message)s]' 
     }, 
    }, 
    'filters': { 
     'write_error_logs': { 
      '()': 'django.utils.log.CallbackFilter', 
      'callback': write_error_log, 
     } 
    }, 
    'handlers': { 
     'console': { 
      'class': 'logging.StreamHandler', 
      'formatter': 'verbose', 
     }, 
     'debug': { 
      'class': 'logging.StreamHandler', 
      'formatter': 'debug', 
     }, 
     'error': { 
      'level': 'ERROR', 
      'class': 'logging.FileHandler', 
      'filename': '/var/log/SmartStorageApp.err', 
      'formatter': 'error', 
      'filters': ['write_error_logs'], 
     }, 
    }, 
    'loggers': { 
     'django': { 
      'handlers': ['debug' if DEBUG else 'console', 'error'], 
      'level': 'INFO', 
      'propagate': True, 
     }, 
    } 
} 
Cuestiones relacionadas