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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    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 émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    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 Expert
    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
    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 confirmé
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    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 confirmé
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    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 émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    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 éprouvé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    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 confirmé
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    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 !

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