Project

General

Profile

Anomalie #4573

Le logger ne fonctionne pas par défaut

Added by Emmanuel GARETTE over 7 years ago. Updated over 6 years ago.

Status:
Fermé
Priority:
Normal
Assigned To:
Category:
-
Start date:
12/11/2012
Due date:
% Done:

100%

Spent time:
Distribution:
EOLE 2.4

Description

L'idée est d'utiliser le logger pyeole partout. Le problème c'est que par défaut aucun message n'apparaitra. Il faudra se faire c***r à gérer les loggers dans chacun des scripts utilisant Creole/pyeole (notamment les scripts posttemplate, ...).

Sinon on aura une première fois une erreur :

No handlers could be found for logger "root" 

Puis aucun log (notamment les erreurs) n'apparaitrons.

Pour moi, le comportement par défaut devrait être "ca affiche les informations à la console". Les cas particulières devront être gérés au cas par cas.

Associated revisions

Revision c742f45a (diff)
Added by Daniel Dehennin over 7 years ago

Création automatique d’un logger root lorsque nécessaire

Lorsqu’une bibliothèque créé un logger, l’appelant ne gérant pas de
logger root reçois le message :

'No handlers could be found for logger "XXX"'
  • pyeole/log.py (PyEoleLog): Créé un objet wrapper afin de créér un
    logger root automatiquement au premier logging.

Fixes: #4573 @25m

Revision 4d175bbc (diff)
Added by Daniel Dehennin over 7 years ago

Remplacement de la classe « PyEoleLog » par une fonction « getLogger »

Initialisation d’un root logger basic à l’import du module si
l’utilisateur n’a pas configurer de logging.

Cela permet d’avoir les messages à partir de « warning » par défaut dès
que l’on import « pyeole.log ».

Ce logger basic sera ensuite écrasé par « init_logging » si nécessaire.

  • pyeole/log.py (getLogger): Wrapper autour de « logging.getLogger ».
    (PyEoleLog): on transforme en fonction qui est notée dépréciée.

Ref: #4573 @10m

History

#1 Updated by Daniel Dehennin over 7 years ago

En fait, l’idée est d’utiliser le logger python lorsque cela fait sens.

D’après la documentation python, une lib ne fait pas de print, sauf si c’est un wrapper pour interagir avec l’utilisateur ;-)

De ce que j’ai retenu de la documentation python :

  1. Une lib utilise logging et raise pour communiquer :
    import logging
    log = logging.getLogger(__name__)
    
  2. Les utilisateurs des libs « catch » et log les exceptions lorsqu’ils ne veulent pas planter :
    try:
        libquiraise.fonction()
    except ExceptionACatcher, err:
        log.error("J’ai choppé une exception en plein vol: '%s'" % err)
    
source:pyeole/log.py est là pour faciliter la mise en place d’un logger de base pour les « utilisateurs de libs » qui envoi :
  • sur la sortie standard les log.info ;
  • sur la sortie d’erreur tous les autres niveaux de log ;
  • avec coloration en fonction du niveau les sorties sont des tty.

Ce fabuleux prodige n’est accessible qu’avec deux lignes de codes seulement :

from pyeole.log import init_logging
log = init_logging()

Et pour quelques arguments de plus, nous faisons cadeau de logger dans un fichier et via syslog tout en modifiant le niveau de log :

from pyeole.log import init_logging
log = init_logging(level='debug', filename='/var/log/bidule.log', syslog=True)

Bénéficiez de cette offre exceptionnelle dès maintenant, sur toutes notre gamme 2.4.

Ça va ? J’ai réussi à vous le vendre ?

#2 Updated by Emmanuel GARETTE over 7 years ago

Pour moi, le problème n'est pas l'utilisation de logging (au contraire, ca semble plus propre que le code actuel), mais la configuration du logger par défaut.

Dans le lien donné il est écrit :

A very simple example is:

import logging
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything

If you type these lines into a script and run it, you’ll see:

WARNING:root:Watch out!

Ce comportement me semble tout a fait satisfaisant.

Mais ce n'est pas le cas avec la configuration du logger actuel.

#3 Updated by Daniel Dehennin over 7 years ago

En regardant le code de la lib logging les fonctions logging.error et companie font :

def error(msg, *args, **kwargs):
    """ 
    Log a message with severity 'ERROR' on the root logger.
    """ 
    if len(root.handlers) == 0:
        basicConfig()
    root.error(msg, *args, **kwargs)

Je vais donc ajouter un wrapper à être utilisé comme :

# pyeole/log.py
import logging

class PyEoleLog(object):
    """Delegation to a logger which create a basicConfig if root logger has no handler
   """ 
    def __init__(self, name=None):
        self.log = logging.getLogger(name)

    def __getattr__(self, name):
        if len(logging.getLogger().handlers) == 0:
            logging.basicConfig()
        return getattr(self.__dict__['log'], name)

# In whatever library
from pyeole.log import PyEoleLog

log = PyEoleLog(__name__)

log.warn("Does it works?")

# In whatever script
from pyeole.log import init_logging
from whateverlibrary import whateverfunction

log = init_logging()

whateverfunction()

#4 Updated by Daniel Dehennin over 7 years ago

  • Status changed from Nouveau to Résolu
  • % Done changed from 0 to 100

#5 Updated by Joël Cuissinat almost 7 years ago

  • Assigned To set to Daniel Dehennin
  • Target version set to Eole 2.4-alpha

#6 Updated by Joël Cuissinat over 6 years ago

  • Status changed from Résolu to Fermé

Also available in: Atom PDF