[Python] Python logging

Daniele Varrazzo piro a develer.com
Sab 8 Dic 2007 17:43:51 CET


dialtone a divmod.com ha scritto:
> On 2 Dec, 10:27 pm, piro a develer.com wrote:
>> Non ho mai sentito niente del genere. Il modulo logging non ha bug 
>> aperti.
>> Vedi se ti d� indicazioni maggiori. Lo sai che il nostro Splendido 
>> Presidente
>> a volte � un po' duro nei suoi giudizi :)
> 
> Lo sono ma sempre con una ragione :).
>> Per quanto ne so io, il modulo � sicuro. Nella parte di sorgenti che 
>> ho letto,
>> mi sembra che le zone critiche siano protette da lock. Non l'ho 
>> sottoposto a
>> chiss� che analisi, ma logging � un modulo molto usato da tantissime 
>> persone,
>> tanto che di logger alternativi non ne � spuntato quasi nessuno. Direi 
>> che, se
>> non altro, ad essere thread-safe ci prova :)
> 
> Non hai guardato troppo bene diciamo :). Anche se il problema e` piu` 
> generalizzato del semplice modulo logging (che comunque ha problemi di 
> suo).
> 
> In realta` il problema principale e` che nessun fd in python e` threadsafe.
> E` un baco noto e non credo lo sistemeranno, tutti gli fd acquisiscono e 
> rilasciano lock nel momento sbagliato.

Ok, allora il buon Giovanni avrà problemi con qualunque cosa multi-thread, non 
solo col modulo di logging. Direi che può stare "tranquillo" :)

Il problema che indichi è interessante: hai un riferimento?

> Inoltre ti ricordo sempre questo:
> 
> import logging, threading
> 
> class C(object):
>   def __init__(self):
>       print threading.currentThread()
>   def __del__(self):
>       print threading.currentThread()
>       logging.warn('deleted %r' % self)
> 
> if __name__ == '__main__':
>   c = C()

L'output dello script è:

     <_MainThread(MainThread, started)>
     <_DummyThread(Dummy-1, started daemon)>
     Exception exceptions.AttributeError: "'NoneType' object has no
     attribute 'warn'" in <bound method C.__del__ of <__main__.C object
     at 0xb7bfe5ac>> ignored

Mi sembra più un problema di interazione tra thread e distruttori che tra 
logger e thread, visto che il secondo print stampa "<_DummyThread(Dummy-1, 
started daemon)>".

In particolare, mi sembra che il distruttore di c viene chiamato quando 
l'interprete è già in fase di cancellazione: se aggiungi un "del c" come 
ultima istruzione dello script l'errore (intendo il "DummyThread") non si 
presenta (perché il distruttore viene invocato quando l'interprete ha ancora 
tutte le rotelle a posto):

     <_MainThread(MainThread, started)>
     <_MainThread(MainThread, started)>
     WARNING:root:deleted <__main__.C object at 0xb7c7eeac>

Inoltre il problema è nella funzione di modulo "logger.warn()", non nei logger 
in sé. Questo ad esempio funziona, ed è un caso più verosimile di uso dei logger:

     import logging, threading

     logging.basicConfig()
     logger = logging.getLogger()

     class C(object):
     def __init__(self):
         print threading.currentThread()
     def __del__(self):
         print threading.currentThread()
         # "logger", non "logging"
         logger.warn('deleted %r' % self)

     if __name__ == '__main__':
         c = C()

L'output in questo caso è:

     <_MainThread(MainThread, started)>
     <_DummyThread(Dummy-1, started daemon)>
     WARNING:root:deleted <__main__.C object at 0xb7c54ecc>

dove il logger ha funzionato bene anche se l'interprete principale è stato già 
distrutto.

A mio giudizio questi piccoli glitch non giustificano la riscrittura di un 
sistema di logging da zero per la propria applicazione. Tu conosci alternative 
già cotte, esenti da problemi e adeguatamente flessibili?

Conosci altri problemi che ti fanno dire che il moduo logging "comunque ha 
problemi di suo"?

A presto!

-- 
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com


More information about the Python mailing list