Salome HOME
the legend is now collapsible
[tools/sat.git] / src / logger.py
index e2d2d1ee897880cf4400f941cd7905a92fa06dab..0b31fba8de827abe438003f6dfdd8b73451ae070 100644 (file)
@@ -15,6 +15,8 @@
 #  You should have received a copy of the GNU Lesser General Public
 #  License along with this library; if not, write to the Free Software
 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+'''In this file are implemented the classes and method relative to the logging
+'''
 
 import sys
 import os
@@ -30,7 +32,7 @@ logCommandFileExpression = "^[0-9]{8}_+[0-9]{6}_+.*\.xml$"
 class Logger(object):
     '''Class to handle log mechanism.
     '''
-    def __init__(self, config, silent_sysstd=False):
+    def __init__(self, config, silent_sysstd=False, all_in_terminal=False):
         '''Initialization
         
         :param config pyconf.Config: The global configuration.
@@ -43,19 +45,26 @@ class Logger(object):
         
         # Construct xml log file location for sat prints.
         logFileName = config.VARS.datehour + "_" + config.VARS.command + ".xml"
-        logFilePath = os.path.join(config.SITE.log.logDir, logFileName)
+        logFilePath = os.path.join(config.SITE.log.log_dir, logFileName)
         # Construct txt file location in order to log 
         # the external commands calls (cmake, make, git clone, etc...)
         txtFileName = config.VARS.datehour + "_" + config.VARS.command + ".txt"
-        txtFilePath = os.path.join(config.SITE.log.logDir, "OUT", txtFileName)
+        txtFilePath = os.path.join(config.SITE.log.log_dir, "OUT", txtFileName)
         
         src.ensure_path_exists(os.path.dirname(logFilePath))
         src.ensure_path_exists(os.path.dirname(txtFilePath))
         
+        # The path of the log files (one for sat traces, and the other for 
+        # the system commands traces)
         self.logFileName = logFileName
         self.logFilePath = logFilePath
         self.txtFileName = txtFileName
         self.txtFilePath = txtFilePath
+        
+        # The list of all log files corresponding to the current command and
+        # the commands called by the current command
+        self.l_logFiles = [logFilePath, txtFilePath]
+        
         # Initialize xml instance and put first fields 
         # like beginTime, user, command, etc... 
         self.xmlFile = xmlManager.XmlLogFile(logFilePath, "SATcommand", 
@@ -63,6 +72,10 @@ class Logger(object):
         self.put_initial_xml_fields()
         # Initialize the txt file for reading
         self.logTxtFile = open(str(self.txtFilePath), 'w')
+        # If the option all_in_terminal was called, all the system commands
+        # are redirected to the terminal
+        if all_in_terminal:
+            self.logTxtFile = sys.__stdout__
         
     def put_initial_xml_fields(self):
         '''Method called at class initialization : Put all fields 
@@ -94,8 +107,34 @@ class Logger(object):
                         attrib={"application" : self.config.VARS.application})
         # The initialization of the trace node
         self.xmlFile.add_simple_node("Log",text="")
+        # The system commands logs
         self.xmlFile.add_simple_node("OutLog",
                                     text=os.path.join("OUT", self.txtFileName))
+        # The initialization of the node where 
+        # to put the links to the other sat commands that can be called by any
+        # command 
+        self.xmlFile.add_simple_node("Links")
+
+    def add_link(self,
+                 log_file_name,
+                 command_name,
+                 command_res,
+                 full_launched_command):
+        '''Add a link to another log file.
+        
+        :param log_file_name str: The file name of the link.
+        :param command_name str: The name of the command linked.
+        :param command_res str: The result of the command linked. "0" or "1"
+        :parma full_launched_command str: The full lanch command 
+                                          ("sat command ...")
+        '''
+        xmlLinks = self.xmlFile.xmlroot.find("Links")
+        src.xmlManager.add_simple_node(xmlLinks,
+                                       "link", 
+                                       text = log_file_name,
+                                       attrib = {"command" : command_name,
+                                                 "passed" : command_res,
+                                           "launchedCommand" : full_launched_command})
 
     def write(self, message, level=None, screenOnly=False):
         '''the function used in the commands 
@@ -112,7 +151,7 @@ class Logger(object):
                                           printcolors.cleancolor(message))
 
         # get user or option output level
-        current_output_level = self.config.USER.output_level
+        current_output_verbose_level = self.config.USER.output_verbose_level
         if not ('isatty' in dir(sys.stdout) and sys.stdout.isatty()):
             # clean the message color if the terminal is redirected by user
             # ex: sat compile appli > log.txt
@@ -120,10 +159,10 @@ class Logger(object):
         
         # Print message regarding the output level value
         if level:
-            if level <= current_output_level and not self.silentSysStd:
+            if level <= current_output_verbose_level and not self.silentSysStd:
                 sys.stdout.write(message)
         else:
-            if self.default_level <= current_output_level and not self.silentSysStd:
+            if self.default_level <= current_output_verbose_level and not self.silentSysStd:
                 sys.stdout.write(message)
 
     def error(self, message):
@@ -145,6 +184,7 @@ class Logger(object):
         '''Flush terminal
         '''
         sys.stdout.flush()
+        self.logTxtFile.flush()
         
     def end_write(self, attribute):
         '''Method called just after command end : Put all fields 
@@ -166,7 +206,7 @@ class Logger(object):
         seconds = total_time - hours*3600 - minutes*60
         # Add the fields corresponding to the end time
         # and the total time of command
-        endtime = dt.strftime('%d/%Y/%m %Hh%Mm%Ss')
+        endtime = dt.strftime('%Y/%m/%d %Hh%Mm%Ss')
         self.xmlFile.append_node_attrib("Site", attrib={"endTime" : endtime})
         self.xmlFile.append_node_attrib("Site", 
                 attrib={"TotalTime" : "%ih%im%is" % (hours, minutes, seconds)})
@@ -177,6 +217,17 @@ class Logger(object):
         # Call the method to write the xml file on the hard drive
         self.xmlFile.write_tree(stylesheet = "command.xsl")
         
+        # Dump the config in a pyconf file in the log directory
+        logDir = self.config.SITE.log.log_dir
+        dumpedPyconfFileName = (self.config.VARS.datehour 
+                                + "_" 
+                                + self.config.VARS.command 
+                                + ".pyconf")
+        dumpedPyconfFilePath = os.path.join(logDir, 'OUT', dumpedPyconfFileName)
+        f = open(dumpedPyconfFilePath, 'w')
+        self.config.__save__(f)
+        f.close()
+        
 
 def date_to_datetime(date):
     '''Little method that gets year, mon, day, hour , 
@@ -227,7 +278,13 @@ def show_command_log(logFilePath, cmd, application, notShownCommands):
         return False, None
  
     # Get the application of the log file
-    logFileXml = src.xmlManager.readXmlFile(logFilePath)
+    try:
+        logFileXml = src.xmlManager.ReadXmlFile(logFilePath)
+    except Exception as e:
+        msg = _("WARNING: the log file %s cannot be read:" % logFilePath)
+        sys.stdout.write(printcolors.printcWarning("%s\n%s\n" % (msg, e)))
+        return False, None
+
     if 'application' in logFileXml.xmlroot.keys():
         appliLog = logFileXml.xmlroot.get('application')
         # if it corresponds, then the log has to be shown
@@ -261,10 +318,12 @@ def list_log_file(dirPath, expression):
             date_hour_cmd = fileName.split('_')
             date_not_formated = date_hour_cmd[0]
             date = "%s/%s/%s" % (date_not_formated[6:8], 
-                                 date_not_formated[4:6], date_not_formated[0:4] )
+                                 date_not_formated[4:6], 
+                                 date_not_formated[0:4])
             hour_not_formated = date_hour_cmd[1]
             hour = "%s:%s:%s" % (hour_not_formated[0:2], 
-                                 hour_not_formated[2:4], hour_not_formated[4:6])
+                                 hour_not_formated[2:4], 
+                                 hour_not_formated[4:6])
             cmd = date_hour_cmd[2][:-len('.xml')]
             lRes.append((os.path.join(dirPath, fileName), 
                          date_not_formated, date, hour_not_formated, hour, cmd))