IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Module logging : reinitialiser de force


Sujet :

Python

  1. #1
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut Module logging : reinitialiser de force
    Bonjour

    J'ai un mega souci avec le module logging.

    J'ai crée une classe et dans sa fonction __init__, j'y ai importé le module logging.

    Mon programme demarre en appelant la fonction start() de cette classe.

    MAIS

    Lorsque je reinstancie ma classe et rappelle cette fonction start() (en lui passant de nouveaux parametres (pour faire tourner mon programme en boucle)), logging me pose des soucis.

    Les variables de ma classe semblent etre reparties a 0, mais pas logging !!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class MaClasse():
     
        def __init__(self):
     
            # Logging
            import logging as logging
            self.logging = logging
     
            # Variables globales de portee classe
            self.machin = "truc"
     
        def start(parametre):
     
            # Demarrage
            self.debogage_initialise(parametre)
     
        def debogage initialise(parametre)
     
                    self.logging.basicConfig(filename = parametre,\
                                             level=self.logging.DEBUG,\
                                             format='%(asctime)s : %(levelname)s : %(message)s',\
                                             filemode = "w")           
     
     
     
     
     
    if __name__ == '__main__':
     
        while i < 7
            maclasse= Maclasse()
            maclasse.start("nomFichierLog" + str(i))
            maclasse = none
            i += 1
    Mon code cree bien le fichierlog0 fichierlog1 fichierlog2 fichierlog3 ...
    Mais n'ecris rien dedans , et complete que le fichierlog0

    De plus au deuxieme passage, dans le module logging\__init__ ,
    il ne rentre pas dans la premiere condition de la fonction basicConfig

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    def basicConfig(**kwargs):
        """
        Do basic configuration for the logging system.
     
        This function does nothing if the root logger already has handlers
        configured. It is a convenience method intended for use by simple scripts
        to do one-shot configuration of the logging package.
     
        The default behaviour is to create a StreamHandler which writes to
        sys.stderr, set a formatter using the BASIC_FORMAT format string, and
        add the handler to the root logger.
     
        A number of optional keyword arguments may be specified, which can alter
        the default behaviour.
     
        filename  Specifies that a FileHandler be created, using the specified
                  filename, rather than a StreamHandler.
        filemode  Specifies the mode to open the file, if filename is specified
                  (if filemode is unspecified, it defaults to 'a').
        format    Use the specified format string for the handler.
        datefmt   Use the specified date/time format.
        level     Set the root logger level to the specified level.
        stream    Use the specified stream to initialize the StreamHandler. Note
                  that this argument is incompatible with 'filename' - if both
                  are present, 'stream' is ignored.
     
        Note that you could specify a stream created using open(filename, mode)
        rather than passing the filename and mode in. However, it should be
        remembered that StreamHandler does not close its stream (since it may be
        using sys.stdout or sys.stderr), whereas FileHandler closes its stream
        when the handler is closed.
        """
        if len(root.handlers) == 0:
    Pour moi, au deuxieme passage, root.handlers != 0

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    Bonsoir,

    Je vois déjà quelques problèmes avec ton script:

    - pourquoi vouloir un self.logging qui référence le module directement ?
    - la méthode start n'a pas self comme premier argument, je ne pense pas que le bout de code que tu donnes soit celui qui tourne réellement sinon tu aurais eu une erreur
    - ce n'est pas none mais None (python est sensible à la casse)
    - il n'y a rien dans tes fichiers car... tu n'écris rien

    Ensuite, je ne vois pas trop ce que tu veux faire mais je peux te proposer cette piste:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    import logging
     
    class MaClasse():
        def __init__(self):
            self.machin = "truc"
     
        def start(self,parametre):
            self.debogage_initialise(parametre)
            self.log.debug(self.machin)
     
        def debogage_initialise(self,parametre)
                    self.log = logging.basicConfig(filename = parametre,\
                                             level=logging.DEBUG,\
                                             format='%(asctime)s : %(levelname)s : %(message)s',\
                                             filemode = "w")
     
    if __name__ == '__main__':
     
        while i < 7
            maclasse= Maclasse()
            maclasse.start("nomFichierLog" + str(i))
            maclasse = None
            i += 1

  3. #3
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Pour expliquer le comportement observé: seul le premier import d'un module va initialiser le module. Python garde une liste des modules chargés (dans sys.modules) et si un import référence un module déjà chargé, il utilise la version déjà chargée plutôt que de recharger le module.

    Pour forcer un nouveau chargement du module, il faut utiliser reload. Mais je déconseille fortement son usage dans un script; cette fonction est plutôt destinée à un usage interactif de l'interpréteur. Par exemple, lorsqu'on a modifié le code d'un module et qu'on souhaite le recharger sans relancer l'interpréteur.

    Je ne sais pas non plus ce que tu cherches à faire, ulysse, mais je doute qu'un chargement répété du module logging soit nécessaire.

  4. #4
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par kango Voir le message
    - pourquoi vouloir un self.logging qui référence le module directement ?
    Au début j'importais le module directement dans le script, puis je pensais qu'en faisant un import dans une classe, sa portée serait de portée classe
    Citation Envoyé par kango Voir le message
    - la méthode start() n'a pas self comme premier argument, je ne pense pas que le bout de code que tu donnes soit celui qui tourne réellement sinon tu aurais eu une erreur
    - ce n'est pas none mais None (python est sensible à la casse)
    - il n'y a rien dans tes fichiers car... tu n'écris rien
    Bien vu je n'ai pas fait de copier/coller

    Citation Envoyé par dividee Voir le message
    Pour expliquer le comportement observé: seul le premier import d'un module va initialiser le module. Python garde une liste des modules chargés (dans sys.modules) et si un import référence un module déjà chargé, il utilise la version déjà chargée plutôt que de recharger le module.Pour forcer un nouveau chargement du module, il faut utiliser reload.
    Je suis désespéré, donc j'essaie quand même pour voir
    Citation Envoyé par kango Voir le message
    Ensuite, je ne vois pas trop ce que tu veux faire
    Juste faire tourner cette classe en boucle, et qu'a chaque fois il me remplisse un nouveau fichier log (en fonction de paramètre). Qu'il arrête de me compléter systématiquement QUE le premier fichier log...


  5. #5
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    Merci pour la fonction reload

    C'est quasi impecc !

    Je dis "quasi impecc" car a la fin du programme, mon programme me sort maintenant des erreurs que je n'ai jamais rencontré jusque la !
    Mais c'est pas gênant puisque cela n'apparait qu'à la fin quand mon programme a fini de faire ce que je lui ai demandé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    if __name__ == '__main__':
     
        maclasse = MaClasse()
        maclasse.start("log.txt")
        reload(logging)
        maclasse = MaClasse()
        maclasse.start("log2.txt")
     
    >>> INFO : #           version 0.5.2          #
    INFO : #**********************************#
    Error in atexit._run_exitfuncs:
    Traceback (most recent call last):
      File "c:\Python25\lib\atexit.py", line 24, in _run_exitfuncs
        func(*targs, **kargs)
      File "c:\Python25\lib\logging\__init__.py", line 1355, in shutdown
        h.close()
      File "c:\Python25\lib\logging\__init__.py", line 785, in close
        StreamHandler.close(self)
    TypeError: unbound method close() must be called with StreamHandler instance as first argument (got FileHandler instance instead)
    Error in sys.exitfunc:
    Traceback (most recent call last):
      File "c:\Python25\lib\atexit.py", line 24, in _run_exitfuncs
        func(*targs, **kargs)
      File "c:\Python25\lib\logging\__init__.py", line 1355, in shutdown
        h.close()
      File "c:\Python25\lib\logging\__init__.py", line 785, in close

  6. #6
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    bonjour,

    au risque de te décevoir, et comme l'a dit dividee, ce n'est pas une bonne chose d'utiliser reload. je fais du python depuis quelques années et je n'en ai jamais eu besoin bien que parfois j'ai été amené à l'utiliser par ce que quelque chose m'échappait, par méconnaissance du langage donc.

    on peut presque toujours le remplacer par une approche différente. là, cela te donne l'illusion que tu as résolu ton problème et cela risque de te donner l'habitude de répéter cette approche dans d'autres situations tout en passant à côté des mécanismes usuels

    comme tu es en phase d'apprentissage, je te conseille de prendre une approche différente.

    quand on fait un import en début de script, la portée du module c'est le script (et donc par voie de conséquence la classe également).

    enfin, as tu essayé le code que je te fournis ? si oui, en quoi ne répond il pas à ce que tu cherches ?

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Points : 102
    Points
    102
    Par défaut
    J'ai un peu utilisé dernièrement le module logging. Son fonctionnement est un peu compliqué du a son coté modulaire. Et pour ce que tu veux faire, à savoir "avoir plusieurs logger qui ciblent plusieurs fichiers", l'utilisation simple de basicConfig n'est pas possible.

    Quand tu fais logging.basicConfig() cela enregistre un objet logger dans logging.root. L'intérêt c'est que n'importe quelle autre module que tu utilises va pouvoir utiliser la configuration que tu as décrite une unique fois lors de l'appel à logging.basicConfig() et enregistrer ses propres message sans avoir a redefinir les paramètres du système de message.

    La raison pour laquelle cela "marche" en faisant un reload, c'est que tu reset la variable logging.root du module. Mais ca n'est clairement pas comme ca qu'il faut l'utiliser.

    Pour avoir tes N instances de classe logger qui vont écrire dans chacun des fichiers que tu veux utiliser, il faut que tu definisses toi-même les N objet logger.

    Pour cela, la doc te donne un exemple complet.
    Code http://docs.python.org/library/logging.html#configuring-logging : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    import logging
     
    # create logger
    logger = logging.getLogger("simple_example")
    logger.setLevel(logging.DEBUG)
    # create console handler and set level to debug
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    # create formatter
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    # add formatter to ch
    ch.setFormatter(formatter)
    # add ch to logger
    logger.addHandler(ch)
     
    # "application" code
    logger.debug("debug message")
    logger.info("info message")
    logger.warn("warn message")
    logger.error("error message")
    logger.critical("critical message")

    Dans ton cas, il faut changer le StreamHandler par un FileHandler et hop, le tour est joué, tu as défini un logger vers un fichier.
    Il me semble que tu n'a pas besoin de mettre un formatter, il va en utiliser un par défaut, comme lors de l'utilisation de basicConfig.
    Il ne te reste plus qu'à répéter l'opération pour les N fichiers.

    C'est un poil plus compliqué que ce que tu voulais faire, mais tu fais une utilisation peu orthodoxe d'un système de logging.

    PS: Si tu veux juste écrire dans les N fichiers a la fois, tu peux utiliser basicConfig en ajoutant d'autre FileStream à l'objet logger créé.
    PPS: Si tu veux que chaque niveau de criticité soit redirigé dans un fichier différant, il me semble que tu peux aussi le faire simplement sur un logger unique et en définissant les règles de dispatch vers l'un ou l'autre de tes FileStream.

  8. #8
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par kango Voir le message
    enfin, as tu essayé le code que je te fournis ? si oui, en quoi ne répond il pas à ce que tu cherches ?
    C'est ce que je faisais dans mon script, mais a chaque itération de boucle, a chaque nouveau BasicConfig(), le module logging se sert de son ancien fichier !

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Points : 102
    Points
    102
    Par défaut
    @kango:
    Ton code ne peut pas marcher car logging.basicConfig() ne retourne pas de logger. Mais l'idée c'est bien d'enregistrer un logger par fichier de sortie voulu.

  10. #10
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    Je vous ai relu avec attention.

    Mais j'ai un problème ... disons ... de méthode !

    Mon script est conçu pour tourner 24h24 et m'écrire des log.
    Aucun de ces fichiers log ne portera jamais le même nom puisque je rajoute au nom de fichier un "timestamp"

    Est ce bien raisonnable de créer des nouveaux logger a chaque fois ?

    Je suis en train de faire des essais pour détruire l'ancien "logger" avant de creer un nouveau. Parce je ne veux pas de poussée de RAM.

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Points : 102
    Points
    102
    Par défaut
    Si tu veux une écriture de fichier par TimeStamp, je te conseil alors l'utilisation d'un TimedRotatingFileHandler qui devrait avoir la fonctionnalité que tu souhaites.

  12. #12
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    Merci shadowsam,
    mais je ne peux pas me permettre de me servir de cette fonction.

    Il faudrait que je réécrive une grosse partie de mon code, alors qu'il fonctionne impecc

    Mon seul souci c'est qu'il fait pas loin de 900 lignes, alors que s'il avait été écrit par quelqu'un de moins débutant, il n'en ferait probablement que la moitié, peut être moins !

    Impossible a poster ici, et franchement je ne vois personne que ca pourrait intéresser. A moins que ces personnes ne soient friand de webscraping.

    M'enfin, ca m'a pas empêché de mettre en place un programme automatique qui me ramène toutes les pages d'un site, quelque soit le site ( sans notion d'authentification, phpssid cookies et autres ), en fonction de filtres pour chacun des sites visés ( définit dans un fichier externe )

  13. #13
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    Citation Envoyé par shadowsam Voir le message
    @kango:
    Ton code ne peut pas marcher car logging.basicConfig() ne retourne pas de logger. Mais l'idée c'est bien d'enregistrer un logger par fichier de sortie voulu.
    ah voui exact, me suis enmêlé les pinceaux avec logging.handlers.RotatingFileHandler qui lui retourne le handler. disouli.

  14. #14
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    Heu j'aurais une dernière question si vous êtes toujours ok.

    En attendant de pouvoir faire mieux, je fais un reload.
    C'est pas la meilleure solution , mais je garde sous le coude la solution que shadowsam m'a proposé de coder.

    MAIS

    en faisant reload (en attendant ) est ce la libère bien la RAM ?
    Est ce que l'ancien référencement du module logging a bien été nettoyé par le ramasse-miette ?

    Je demande ca parce que la je viens d'avoir une sacrée surprise.
    J'ai lancé mon script sous un shell linux, et "top" m'indique que ma RAM augmente de 300 kilo environ toutes les 2/3 secondes.

    Mais cette occupation RAM ne decroit jamais, or elle devrait decroitre a chaque fois que la classe est réinitialisé, puisque je n'ai pas de variables globales au module ( a part les modules re os logging ...).

    C'est un peu gênant , d'après mes calculs , a ce rythme la, j'en ai pour 3 ou 4 heures ... Après ben je sais pas, il explose ???

    M'enfin ...

  15. #15
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    En faisant un reload, le compteur de référence de l'ancien module est décrémenté, mais s'il reste des références vers des objets du module créés à son chargement précédent, ceux-ci restent en mémoire.

    par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> import logging
    >>> a = logging.Logger(None)
    >>> reload(logging)
    >>> b = logging.Logger(None)
    >>> a.__class__ == b.__class__
    False
    >>> a.__class__
    <class logging.Logger at 0x00D86F60>
    >>> b.__class__
    <class logging.Logger at 0x00D8E3F0>
    Cela indique bien que la classe Logger est présente deux fois en mémoire.

  16. #16
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    J'arrive pas a me faire à l'idée que l'on puisse pas effacer toute trace d'un module avant de l'importer a nouveau.

    Puisque reload laisse des traces des modules, existe t-til une fonction qui fasse une réinitialisation de force ? Ou un référencement de variable, de force ?

    Une commande ou un bloc qui ferait un peu ca :
    import logging
    ...
    logging = None
    import logging


  17. #17
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Pourquoi ne pas simplement supprimer le handler du root logger avant d'appeler à nouveau basicConfig ? Je n'ai pas testé mais essaie ceci à la place de faire un reload:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    root = logging.getLogger()
    for hdlr in root.handlers:
        root.removeHandler(hdlr)
    # ensuite on doit pouvoir rappeler basicConfig

  18. #18
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Le module logging est un "singleton" dont les variables sont globales au module et non à une classe - comme dans le cas des Singletons Java - .
    Une fois initialisé, il ne peut être arrêté que par logging.shutdown pour faire un flush des messages dans les fichiers avant l'exit.

    => s'il ne sait pas s'arrêter pour être redémarré ensuite, vous pouvez essayer de 'bricoler' mais c'est peut être du temps perdu, car:

    Une fois initialisé (au démarrage du programme), les différents modules peuvent récupérer un logger spécifique ou en créer un propre à eux via l'appel à
    logging.getLogger(dotted_name)

    Si comme dans votre cas vous avez une classe Toto qui a besoin d'associer le même logger à chaque instance crée, il vous suffit de faire:
    logging.getLogger('toto')
    sans avoir a reconfigurer le "logging"
    Ceci dit une fois initialisé, vous disposez toujours du root logger...

    Démo réalisé en 3 cut&paste à partir de ceux de la doc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
     
    def init_logging():
        import logging                         # récupére le singleton et on l'initialise
        # create root logger
        logger = logging.getLogger('')
        logger.setLevel(logging.DEBUG)
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        # create formatter
        formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
        # add formatter to ch
        ch.setFormatter(formatter)
        # add ch to logger
        logger.addHandler(ch)
        # create console handler and set level to debug
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        # create formatter
        formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
        # add formatter to ch
        ch.setFormatter(formatter)
     
        # ici on cree le logger pour 'Toto'
        logger = logging.getLogger('Toto')
        logger.setLevel(logging.DEBUG)  #<--- initialisation
     
     
    def test():                                        # test est n'importe quoi
        import logging
        loga = logging.getLogger('Toto')        # elle récupère "son" logger
     
        # "application" code
        loga.debug("debug message")
     
        logb = logging.getLogger('Toto')        # un autre
        assert loga is logb                           # qui est le même!!!
        logb.debug("debug message")           # et qui marche...
        logging.info("debug message")
     
    init_logging()
    test()
    Une implication intéressante de ce design est que vous vous rendez compte que la fonction 'test' utilise le module logging tel qu'il aura été configuré 'par ailleurs'. Par exemple avec le NullHandler... ce qui vous permet de faire du code qui loggue sans logger.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  19. #19
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut Merci
    Je vous remercie pour vos réponses

    Je suis en train de ré-écrire mon module énorme, en essayant de refondre ma partie débogage sur une base plus saine.

    Juste entre nous, les développeurs n'auraient jamais du proposer une fonction BasicConfig()

    Si j'ai des soucis majeurs, et s'ils correspondent au titre du post, je poserait ma question à la suite.

    A ++ la communauté

  20. #20
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    Sur vos conseils, je me suis dépatouillé et je n'ai plus de fuites mémoires...
    Enfin je pense ...
    Voici mon code dans sa dernière version pour python 3.1.2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    import re, logging, sys
    class toto():
     
        def DEFINE_DEBOGAGE(self):
     
            self.debogage = logging.getLogger()
            for hdlr in self.debogage.handlers:
                self.debogage.removeHandler(hdlr)
            for hdlr in self.debogage.handlers:
                self.debogage.removeHandler(hdlr)
            logging.basicConfig(level=logging.DEBUG,
                                format = '%(levelname)s --- fonction %(funcName)s --- ligne %(lineno)d\n%(message)s\n',
                                filename = self.fichier_log,
                                filemode = 'w')
            console = logging.StreamHandler()
            console.setLevel(logging.DEBUG)
            formatter = logging.Formatter('%(levelname)s --- fonction %(funcName)s --- ligne %(lineno)d\n%(message)s\n')
            console.setFormatter(formatter)
            logging.getLogger().addHandler(console)
            self.debogage = logging.getLogger()
     
            self.debogage.info(
            "Démarrage du programme ...\n")
            self.debogage.debug(
            "Initialisation du debogage\n")
            self.debogage.info(
            "##########################################################################\n"\
            "#                                                                        #\n"\
            "#           B I E  N V E N U E        D A N S         T O T O            #\n"\
            "#                                                                        #\n"\
            "##########################################################################\n"\
            "                                                                          \n"\
            " Version : " + __version__ + "\n"\
            " Auteur  : " + __author__ + "\n"\
            " Date    : " + __date__ + "\n")
    Mais franchement, je comprend pas grand chose à cette classe.
    Est-ce que vous connaissez un MEGA tuto sur le module logging pour python.
    Parce-que je suis désespéré de ne trouver que des infos en anglais.
    Alors des infos et des url en francais je suis preneur à 1000 %

Discussions similaires

  1. module logging.config, erreur sous mac
    Par souki22 dans le forum Général Python
    Réponses: 1
    Dernier message: 28/11/2014, 13h24
  2. module logging: personaliser le logger d'un module externe
    Par .:Spip:. dans le forum Général Python
    Réponses: 2
    Dernier message: 25/11/2012, 10h57
  3. le module Logging et relativeCreated
    Par rosty38 dans le forum Général Python
    Réponses: 3
    Dernier message: 15/10/2010, 15h46
  4. Rediriger les erreurs en utilisant le module logging
    Par kazh75 dans le forum Général Python
    Réponses: 5
    Dernier message: 12/02/2009, 09h59
  5. Module logging, classe SMTPHandler
    Par kazh75 dans le forum Réseau/Web
    Réponses: 1
    Dernier message: 07/04/2007, 20h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo