1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2008-2023 EDF R&D
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
24 Ce module permet de mettre en place un logging utilisable partout dans
25 l'application, par défaut à la console, et si nécessaire dans un fichier.
27 Il doit être appelé en premier dans Aidsm (mais pas directement dans les
28 applications utilisateurs), en l'important et en instanciant un objet :
29 import ExtendedLogging ; ExtendedLogging.ExtendedLogging()
31 Par défaut, seuls les messages du niveau WARNING ou au-delà sont disponibles
32 (donc les simples messages d'info ne sont pas disponibles), ce que l'on peut
33 changer à l'instanciation avec le mot-clé "level" :
34 import ExtendedLogging ; ExtendedLogging.ExtendedLogging(level=20)
36 On peut éventuellement demander à l'objet de sortir aussi les messages dans
37 un fichier (noms par défaut : AdaoOutputLogfile.log, niveau NOTSET) :
38 import ExtendedLogging ; ExtendedLogging.ExtendedLogging().setLogfile()
40 Si on veut changer le nom du fichier ou le niveau global de message, il faut
41 récupérer l'instance et appliquer les méthodes :
42 import ExtendedLogging
43 log = ExtendedLogging.ExtendedLogging()
45 log.setLevel(logging.DEBUG)
46 log.setLogfile(filename="toto.log", filemode="a", level=logging.WARNING)
47 et on change éventuellement le niveau avec :
48 log.setLogfileLevel(logging.INFO)
50 Ensuite, n'importe où dans les applications, il suffit d'utiliser le module
51 "logging" (avec un petit "l") :
53 log = logging.getLogger(NAME) # Avec rien (recommandé) ou un nom NAME
59 ou encore plus simplement :
63 Dans une application, à n'importe quel endroit et autant de fois qu'on veut,
64 on peut changer le niveau global de message en utilisant par exemple :
66 log = logging.getLogger(NAME) # Avec rien (recommandé) ou un nom NAME
67 log.setLevel(logging.DEBUG)
69 On rappelle les niveaux (attributs de "logging") et leur ordre :
70 NOTSET=0 < DEBUG=10 < INFO=20 < WARNING=30 < ERROR=40 < CRITICAL=50
72 __author__ = "Jean-Philippe ARGAUD"
80 from daCore import PlatformInfo
82 LOGFILE = os.path.join(os.path.abspath(os.curdir),"AdaoOutputLogfile.log")
84 # ==============================================================================
85 class ExtendedLogging(object):
87 Logger général pour disposer conjointement de la sortie standard et de la
90 __slots__ = ("__logfile")
92 def __init__(self, level=logging.WARNING):
94 Initialise un logging à la console pour TOUS les niveaux de messages.
96 if sys.version_info.major <= 3 and sys.version_info.minor < 8:
97 if logging.getLogger().hasHandlers():
98 while logging.getLogger().hasHandlers():
99 logging.getLogger().removeHandler( logging.getLogger().handlers[-1] )
100 __sys_stdout = logging.StreamHandler(sys.stdout)
101 __sys_stdout.setFormatter(logging.Formatter('%(levelname)-8s %(message)s'))
102 logging.getLogger().addHandler(__sys_stdout)
105 format = '%(levelname)-8s %(message)s',
109 else: # Actif lorsque Python > 3.7
111 format = '%(levelname)-8s %(message)s',
116 self.__logfile = None
118 # Initialise l'affichage de logging
119 # ---------------------------------
120 p = PlatformInfo.PlatformInfo()
122 logging.info( "--------------------------------------------------" )
123 logging.info( p.getName()+" version "+p.getVersion() )
124 logging.info( "--------------------------------------------------" )
125 logging.info( "Library availability:" )
126 logging.info( "- Python.......: True" )
127 logging.info( "- Numpy........: "+str(PlatformInfo.has_numpy) )
128 logging.info( "- Scipy........: "+str(PlatformInfo.has_scipy) )
129 logging.info( "- Matplotlib...: "+str(PlatformInfo.has_matplotlib) )
130 logging.info( "- Gnuplot......: "+str(PlatformInfo.has_gnuplot) )
131 logging.info( "- Sphinx.......: "+str(PlatformInfo.has_sphinx) )
132 logging.info( "- Nlopt........: "+str(PlatformInfo.has_nlopt) )
133 logging.info( "Library versions:" )
134 logging.info( "- Python.......: "+p.getPythonVersion() )
135 logging.info( "- Numpy........: "+p.getNumpyVersion() )
136 logging.info( "- Scipy........: "+p.getScipyVersion() )
137 logging.info( "- Matplotlib...: "+p.getMatplotlibVersion() )
138 logging.info( "- Gnuplot......: "+p.getGnuplotVersion() )
139 logging.info( "- Sphinx.......: "+p.getSphinxVersion() )
140 logging.info( "- Nlopt........: "+p.getNloptVersion() )
143 def setLogfile(self, filename=LOGFILE, filemode="w", level=logging.NOTSET):
145 Permet de disposer des messages dans un fichier EN PLUS de la console.
147 if self.__logfile is not None:
148 # Supprime le précédent mode de stockage fichier s'il existait
149 logging.getLogger().removeHandler(self.__logfile)
150 self.__logfile = logging.FileHandler(filename, filemode)
151 self.__logfile.setLevel(level)
152 self.__logfile.setFormatter(
153 logging.Formatter('%(asctime)s %(levelname)-8s %(message)s',
154 '%d %b %Y %H:%M:%S'))
155 logging.getLogger().addHandler(self.__logfile)
157 def setLogfileLevel(self, level=logging.NOTSET ):
159 Permet de changer le niveau des messages stockés en fichier. Il ne sera
160 pris en compte que s'il est supérieur au niveau global.
162 self.__logfile.setLevel(level)
166 Renvoie le niveau de logging sous forme texte
168 return logging.getLevelName( logging.getLogger().getEffectiveLevel() )
170 # ==============================================================================
173 def wrapper(*args, **kwargs):
174 start = time.clock() # time.time()
175 result = f(*args, **kwargs)
176 end = time.clock() # time.time()
177 msg = 'TIMER Durée elapsed de la fonction utilisateur "{}": {:.3f}s'
178 logging.debug(msg.format(f.__name__, end-start))
182 # ==============================================================================
183 if __name__ == "__main__":
184 print('\n AUTODIAGNOSTIC\n')