1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
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, or (at your option) any later version.
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
22 #=============================================================================
23 # Author : Guillaume Boulant (CSSI)
24 # Rewritten by Renaud Barate (EDF R&D)
26 # Copyright : EDF 2001-2009
28 #=============================================================================
30 ## \defgroup logger logger
33 # This module defines a class which provides logging facility in Salome.
37 This module defines a class which provides logging facility in Salome:
43 from salome.kernel.deprecation import deprecated
44 from salome.kernel import termcolor
45 import salome.kernel.logconfig
47 ## This class formats and displays log messages in Salome environment. It
48 # inherits \b logging.Logger class defined in \b logging module from Python
49 # library, so all methods from \b logging.Logger can be used here.
50 # The format of the traces is:
51 # LEVEL[keyword] : Message
53 # ,where \em LEVEL is the level of the message (\em DEBUG, \em INFO, etc.),
54 # \em keyword is the name of the logger, and \em Message is the message to log.
56 # When creating a new Logger object, the parameter \em keyword defines the
57 # name of the logger, \em level defines the logging level (default is
58 # \b logging.DEBUG if KERNEL module is configured with --enable-debug option
59 # or \b logging.WARNING otherwise), and \em color defines the color
60 # of the log messages for this logger (log messages will appear in color
61 # only when displayed on color - capable ASCII terminals). See module
62 # \ref termcolor "salome.kernel.termcolor" for the color constants.
64 # By default, log messages will be displayed only on standard output. They
65 # can also be recorded in a file (see method setLogFile()). For now,
66 # the CORBA-based logging facility can not be used through this class.
68 # A source filename \em sourceFileName can be defined. If this argument is
69 # specified, then the \em keyword is modified to the basename of the
74 # from salome.kernel.logger import Logger
75 # log = Logger("Test")
76 # log.debug("Debug message")
77 # log.info("Information message")
78 # log.warning("Warning message")
79 # log.error("Error message")
80 # log.critical("Fatal error message")
83 class Logger(logging.Logger):
85 This class formats and displays log messages in Salome environment. It
86 inherits :class:`Logger<logging.Logger>` class defined in :mod:`logging`
87 module from Python library, so all methods from :class:`logging.Logger`
88 can be used here. The format of the traces is:
90 LEVEL [keyword] : Message
92 where `LEVEL` is the level of the message (`DEBUG`, `INFO`, etc.),
93 `keyword` is the name of the logger, and `Message` is the message to log.
95 When creating a new Logger object, the parameter `keyword` defines the
96 name of the logger, `level` defines the logging level (default is
97 :const:`logging.DEBUG` if KERNEL module is configured with --enable-debug
98 option or :const:`logging.WARNING` otherwise), and `color` defines the color
99 of the log messages for this logger (log messages will appear in color
100 only when displayed on color-capable ASCII terminals). See module
101 :mod:`salome.kernel.termcolor` for the color constants.
103 By default, log messages will be displayed only on standard output. They
104 can also be recorded in a file (see method :meth:`setLogFile`). For now,
105 the CORBA-based logging facility can not be used through this class.
107 A source filename `sourceFileName` can be defined. If this argument is
108 specified, then the `keyword` is modified to the basename of the `sourceFileName`
112 from salome.kernel.logger import Logger
114 log.debug("Debug message")
115 log.info("Information message")
116 log.warning("Warning message")
117 log.error("Error message")
118 log.critical("Fatal error message")
122 def __init__(self, keyword = "KEY", level = salome.kernel.logconfig.loggingLevel,
123 color = None, sourceFileName=None):
125 if sourceFileName is not None:
126 keyword = os.path.basename(sourceFileName).split('.')[0]
127 logging.Logger.__init__(self, keyword, level)
128 self._baseFormatString = "%(levelname)-8s [%(name)s] : %(message)s"
129 self._baseFormatter = logging.Formatter(self._baseFormatString)
130 if hasattr(sys.stdout, "flush"):
131 self._stdoutStream = sys.stdout
133 self._stdoutStream = _UnFlushableLogStream(sys.stdout)
134 self._stdoutHandler = logging.StreamHandler(self._stdoutStream)
135 self._stdoutHandler.setLevel(logging.DEBUG)
137 self.addHandler(self._stdoutHandler)
138 self._fileHandler = None
140 ## Log all messages, including DEBUG level messages (equivalent to
141 # setLevel(logging.DEBUG)).
144 Log all messages, including DEBUG level messages (equivalent to
145 ``setLevel(logging.DEBUG)``).
147 self.setLevel(logging.DEBUG)
149 ## Define a log file to record the log messages (in addition to the
151 def setLogFile(self, logFilename):
153 Define a log file to record the log messages (in addition to the
157 self._fileHandler = logging.FileHandler(logFilename, 'w')
158 self._fileHandler.setLevel(logging.DEBUG)
159 self._fileHandler.setFormatter(self._baseFormatter)
160 self.addHandler(self._fileHandler)
162 ## Set the color of log messages on color-capable terminals. If \em color
163 # is \b None, the default color will be used.
164 def setColor(self, color):
166 Set the color of log messages on color-capable terminals. If `color`
167 is :const:`None`, the default color will be used.
169 if color is None or not termcolor.canDisplayColor(self._stdoutStream):
170 stdoutFormatter = self._baseFormatter
173 (termcolor.getControlSequence(color),
174 self._baseFormatString,
175 termcolor.getControlSequence(termcolor.DEFAULT)))
176 stdoutFormatter = logging.Formatter(format)
177 self._stdoutHandler.setFormatter(stdoutFormatter)
179 ## Close the log file.
180 def closeLogFile(self):
181 """Close the log file."""
182 if self._fileHandler is not None:
183 self.removeHandler(self._fileHandler)
184 self._fileHandler.close()
185 self._fileHandler = None
187 ## Hide DEBUG level messages (equivalent to setLevel(logging.INFO)).
190 Hide DEBUG level messages (equivalent to ``setLevel(logging.INFO)``).
192 self.setLevel(logging.INFO)
194 @deprecated("Deprecated since version 5.1.5. Please replace with "
195 "Logger.critical(message)")
197 ## Log a message with CRITICAL level. This method only exists for
198 # backward compatibility and is equivalent to \b critical(message).
199 def fatal(self, message):
201 Log a message with CRITICAL level. This method only exists for
202 backward compatibility and is equivalent to ``critical(message)``.
204 self.critical(message)
206 ## This utility class allows to log messages to a stream with no \b flush
207 # method. This is useful to send log messages to \b PyOut objects.
209 class _UnFlushableLogStream:
211 This utility class allows to log messages to a stream with no `flush`
212 method. This is useful to send log messages to `PyOut` objects.
215 def __init__(self, stream):
216 self._stream = stream
218 def write(self, msg):
219 self._stream.write(msg)
224 ## This class extends Logger class and adds exception information
225 # when DEBUG messages are recorded. It exists mainly for backward
226 # compatibility, as the same thing can be done by calling
227 # <em> Logger.debug(message, exc_info = True) </em>.
229 class ExtLogger(Logger):
231 This class extends :class:`Logger` class and adds exception information
232 when DEBUG messages are recorded. It exists mainly for backward
233 compatibility, as the same thing can be done by calling
234 ``Logger.debug(message, exc_info = True)``.
237 @deprecated("Class ExtLogger is deprecated since version 5.1.5. See "
238 "documentation for replacement.")
239 def __init__(self, keyword = "KEY",
240 level = salome.kernel.logconfig.loggingLevel,
241 color = None, sourceFileName=None):
242 Logger.__init__(self, keyword, level, color, sourceFileName)
244 ## Log a DEBUG message with exception information (equivalent to
245 # <em> Logger.debug(message, exc_info = True) </em>).
246 def debug( self, message ):
248 Log a DEBUG message with exception information (equivalent to
249 ``Logger.debug(message, exc_info = True)``).
251 Logger.debug(self, message, exc_info = True)
253 ## Test function for logger module
256 """Test function for logger module"""
260 log.info("Information message")
261 log.debug("Debug message")
262 log.fatal("Fatal error message")
266 log.info("This message displays data = " + str(data))
269 data["KERNEL"] = "V1"
271 log.info("This message displays data = " + str(data))
273 # Test with a non-string parameter
276 # Test with a default instance
278 log.info("Default logger")
280 # Test showDebug method
281 log.setLogFile("test.log")
282 log.debug("Debug trace")
284 log.debug("This trace should NOT be displayed")
286 log.debug("This trace should be displayed")
288 log.info("After closing the log file")
291 # Main function only used to test the module
292 if __name__ == "__main__":