Domanda

Potresti aiutarmi a risolvere il seguente problema di incompatibilità tra Python 2.5 e 2.6?

logger.conf:

[loggers]
keys=root,aLogger,bLogger

[handlers]
keys=consoleHandler

[formatters]
keys=

[logger_root]
level=NOTSET
handlers=consoleHandler

[logger_aLogger]
level=DEBUG
handlers=consoleHandler
propagate=0
qualname=a

[logger_bLogger]
level=INFO
handlers=consoleHandler
propagate=0
qualname=b

[handler_consoleHandler]
class=StreamHandler
args=(sys.stderr,)

module_one.py:

import logging
import logging.config

logging.config.fileConfig('logger.conf')
a_log = logging.getLogger('a.submod')
b_log = logging.getLogger('b.submod')

def function_one():
    b_log.info("function_one() called.")

module_two.py:

import logging
import logging.config

logging.config.fileConfig('logger.conf')
a_log = logging.getLogger('a.submod')
b_log = logging.getLogger('b.submod')

def function_two():
    a_log.info("function_two() called.")

logger.py:

from module_one import function_one
from module_two import function_two

function_one()
function_two()

Output della chiamata logger.py sotto Ubuntu 9.04:

$ python2.5 logger.py
$

$ python2.6 logger.py
function_one() called.
function_two() called.
$
È stato utile?

Soluzione

Questo è un bug che è stato corretto tra 2.5 e 2.6. La funzione fileConfig () è progettata per una configurazione unica e quindi non deve essere chiamata più di una volta, tuttavia si sceglie di organizzarla. Il comportamento previsto di fileConfig è disabilitare tutti i logger che non sono esplicitamente menzionati nella configurazione e lasciare abilitati i logger menzionati e i loro figli; il bug stava causando la disabilitazione dei bambini quando non avrebbero dovuto esserlo. La configurazione del logger di esempio menziona i logger 'a' e 'b'; dopo aver chiamato getLogger ('a.submod') viene creato un logger figlio. La seconda chiamata fileConfig lo disabilita erroneamente in Python 2.5 - in Python 2.6 il logger non è disabilitato in quanto figlio di un logger menzionato esplicitamente nella configurazione.

Altri suggerimenti

Non capisco le ragioni di questo comportamento, ma come hai ben detto in 2.6, funziona in modo diverso. Possiamo supporre che si tratti di un bug che interessa 2.5

Come soluzione alternativa suggerisco quanto segue:

extra_module.py:

import logging
import logging.config

logging.config.fileConfig('logger.conf')
a_log = logging.getLogger('a.submod')
b_log = logging.getLogger('b.submod')

module_one.py:

from extra_module import a_log

def function_one():
    a_log.info("function_one() called.")

module_two.py:

from extra_module import b_log

def function_two():
    b_log.info("function_two() called.")

usando questo schema sono stato in grado di eseguire logger.py su python2.5.4 con lo stesso comportamento di 2.6

Interessante ... Ho giocato un po 'nella console e sembra che la seconda chiamata a logging.config.fileConfig stia facendo confusione. Non sono sicuro del perché questo sia ... Ecco una trascrizione che mostra il problema:

lorien$ python2.5
Python 2.5.1 (r251:54863, Feb  6 2009, 19:02:12) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> import logging.config
>>> logging.config.fileConfig('logger.conf')
>>> alog = logging.getLogger('a.submod')
>>> alog.info('foo')
foo
>>> import logging
>>> import logging.config
>>> alog.info('foo')
foo
>>> logging.config.fileConfig('logger.conf')
>>> alog.info('foo')
>>> alog = logging.getLogger('a.submod')
>>> alog.info('foo')
>>> 
>>> blog = logging.getLogger('b.submod')
>>> blog.info('foo')
foo
>>>

Non appena chiamo logging.config.fileConfig la seconda volta, la mia istanza del logger interrompe la registrazione. Afferrare una nuova istanza di registrazione non aiuta poiché è lo stesso oggetto. Se aspetto fino a dopo aver configurato entrambe le volte per recuperare le istanze del logger, allora le cose funzionano - ecco perché l'istanza blog funziona.

Il mio suggerimento è di ritardare l'acquisizione delle istanze del logger fino a quando non si entra nelle funzioni. Se sposti le chiamate in logging.getLogger () in function_one e function_two , allora tutto funziona bene.

Sono stato in grado di risolvere questo problema modificando i nomi dei logger in questo modo, in entrambi i file:

logging.config.fileConfig('logger.conf')
a_log = logging.getLogger('a')
b_log = logging.getLogger('b')

Non sono sicuro dell'errore esatto, ma il modulo di registrazione v2.5 sembra avere problemi a trovare i nomi passati a getLogger () con i nomi nel file di configurazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top