2013-03-28 11 views
5

Nel mio programma Python Ho il seguente codice:Come specificare in YAML per creare sempre il file di registro nella cartella del progetto usando dictConfig?

def main(): 
    # The file's path 
    path = os.path.dirname(os.path.realpath(__file__)) 
    ... 
    # Config file relative to this file 
    loggingConf = open('{0}/configs/logging.yml'.format(path), 'r') 
    logging.config.dictConfig(yaml.load(loggingConf)) 
    loggingConf.close() 
    logger = logging.getLogger(LOGGER) 
    ... 

e questo è il mio logging.yml file di configurazione:

version: 1 
formatters: 
    default: 
    format: '%(asctime)s %(levelname)s %(name)s %(message)s' 
handlers: 
    console: 
    class: logging.StreamHandler 
    level: DEBUG 
    formatter: default 
    stream: ext://sys.stdout 
    file: 
    class : logging.FileHandler 
    formatter: default 
    filename: bot.log 
loggers: 
    cloaked_chatter: 
    level: DEBUG 
    handlers: [console, file] 
    propagate: no 

è che si crea il problema del file bot.log dove il programma è lanciato. Voglio che venga sempre creato nella cartella del progetto, cioè nella stessa cartella del mio programma Python.

Per un esempio, l'avvio del programma con ./bot.py creerebbe il file di registro nella stessa cartella. Ma lanciandolo con python3 path/bot.py creerebbe il file di log un livello sopra il programma Python nella gerarchia dei file.

Come dovrei scrivere il nome file nel file di configurazione per risolvere questo? O devo scrivere un gestore personalizzato? Se é cosi, come? O questo non è possibile risolvere usando dictConfig?

+1

Ho aggiornato la mia risposta in risposta al tuo commento. –

risposta

5

Esistono diversi modi per ottenere ciò che si desidera. Ad esempio, un modo è quello di fare un initialiser personalizzato per il gestore:

import os 
import yaml 

def logmaker(): 
    path = os.path.dirname(os.path.realpath(__file__)) 
    path = os.path.join(path, 'bot.log') 
    return logging.FileHandler(path) 

def main(): 
    # The file's path 
    path = os.path.dirname(os.path.realpath(__file__)) 

    # Config file relative to this file 
    loggingConf = open('{0}/logging.yml'.format(path), 'r') 
    logging.config.dictConfig(yaml.load(loggingConf)) 
    loggingConf.close() 
    logger = logging.getLogger('cloaked_chatter') 
    logger.debug('Hello, world!') 

if __name__ == '__main__': 
    main() 

Si noti che ho spostato il logging.yml ad essere adiacente allo script. logmaker è l'inizializzatore personalizzato. Specificare nella YAML come segue:

version: 1 
formatters: 
    default: 
    format: '%(asctime)s %(levelname)s %(name)s %(message)s' 
handlers: 
    console: 
    class: logging.StreamHandler 
    level: DEBUG 
    formatter: default 
    stream: ext://sys.stdout 
    file: 
    () : __main__.logmaker 
    formatter: default 
loggers: 
    cloaked_chatter: 
    level: DEBUG 
    handlers: [console, file] 
    propagate: no 

Se si esegue lo script Python, si dovrebbe trovare che il bot.log viene creato adiacente allo script e file YAML. Lo stesso messaggio viene stampato sulla console e bot.log:

2013-04-16 11:08:11,178 DEBUG cloaked_chatter Hello, world! 

N.B. La sceneggiatura potrebbe essere un po 'più ordinata, ma illustra il mio punto.

Aggiornamento: Secondo the documentation, l'uso di () come una chiave nel dizionario indica che il valore è un callable che è essenzialmente un costruttore personalizzato per il gestore.

+1

Nel codice YAML, cosa significa '():' di fronte a '__main __. Logmaker' significa? –

Problemi correlati