Projet

Général

Profil

Anomalie #4573

Le logger ne fonctionne pas par défaut

Ajouté par Emmanuel GARETTE il y a plus de 11 ans. Mis à jour il y a plus de 10 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Catégorie:
-
Début:
11/12/2012
Echéance:
% réalisé:

100%

Temps passé:
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.

Révisions associées

Révision c742f45a (diff)
Ajouté par Daniel Dehennin il y a plus de 11 ans

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

Révision 4d175bbc (diff)
Ajouté par Daniel Dehennin il y a plus de 11 ans

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

Historique

#1 Mis à jour par Daniel Dehennin il y a plus de 11 ans

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 Mis à jour par Emmanuel GARETTE il y a plus de 11 ans

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 Mis à jour par Daniel Dehennin il y a plus de 11 ans

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 Mis à jour par Daniel Dehennin il y a plus de 11 ans

  • Statut changé de Nouveau à Résolu
  • % réalisé changé de 0 à 100

#5 Mis à jour par Joël Cuissinat il y a plus de 10 ans

  • Assigné à mis à Daniel Dehennin
  • Version cible mis à Eole 2.4-alpha

#6 Mis à jour par Joël Cuissinat il y a plus de 10 ans

  • Statut changé de Résolu à Fermé

Formats disponibles : Atom PDF