Salome HOME
add xsl stylesheet
[tools/sat.git] / src / logger.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2012  CEA/DEN
4 #
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.
9 #
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.
14 #
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
18
19 import sys
20 import os
21 import datetime
22
23 import src
24 from . import printcolors
25 from . import xmlManager
26
27 class Logger(object):
28     '''Class that handle log mechanism
29     '''
30     def __init__(self, config, silent_sysstd=False):
31         '''Initialization
32         
33         :param config pyconf.Config: The global configuration.
34         :param silent_sysstd boolean: if True, do not write anything in terminal.
35         '''
36         self.config = config
37         self.default_level = 3
38         self.silentSysStd = silent_sysstd
39         
40         # Construct log file location. There are two cases. With an application an without any application.
41         logFileName = config.VARS.datehour + "_" + config.VARS.command + ".xml"
42         if 'APPLICATION' in config:
43             logFilePath = os.path.join(config.APPLICATION.out_dir, 'LOGS', logFileName)
44         else:
45             logFilePath = os.path.join(config.VARS.personalDir, 'LOGS', logFileName)
46         src.ensure_path_exists(os.path.dirname(logFilePath))
47         
48         self.logFileName = logFileName
49         self.logFilePath = logFilePath   
50         
51         self.xmlFile = xmlManager.xmlLogFile(logFilePath, config.VARS.command)
52         self.putInitialXMLFields()
53         
54     def putInitialXMLFields(self):
55         self.xmlFile.add_simple_node("field", text=self.config.VARS.command , attrib={"name" : "command"})
56         self.xmlFile.add_simple_node("field", text=self.config.INTERNAL.sat_version , attrib={"name" : "satversion"})
57         self.xmlFile.add_simple_node("field", text=self.config.VARS.hostname , attrib={"name" : "hostname"})
58         self.xmlFile.add_simple_node("field", text=self.config.VARS.dist , attrib={"name" : "OS"})
59         self.xmlFile.add_simple_node("field", text=self.config.VARS.user , attrib={"name" : "user"})
60         self.xmlFile.add_simple_node("field", text=self.config.VARS.datehour , attrib={"name" : "beginTime"})
61         self.xmlFile.add_simple_node("traces",text="")
62
63     def write(self, message, level=None, screenOnly=False):
64         '''the function used in the commands that will print in the terminal and the log file.
65         
66         :param message str: The message to print.
67         :param level int: The output level corresponding to the message 0 < level < 6.
68         :param screenOnly boolean: if True, do not write in log file.
69         '''
70         # do not write message starting with \r to log file
71         if not message.startswith("\r") and not screenOnly:
72             self.xmlFile.append_node("traces", printcolors.cleancolor(message))
73
74         # get user or option output level
75         current_output_level = self.config.USER.output_level
76         if not ('isatty' in dir(sys.stdout) and sys.stdout.isatty()):
77             # clean the message color if the terminal is redirected by user
78             # ex: sat compile appli > log.txt
79             message = printcolors.cleancolor(message)
80         
81         # Print message regarding the output level value
82         if level:
83             if level <= current_output_level and not self.silentSysStd:
84                 sys.stdout.write(message)
85         else:
86             if self.default_level <= current_output_level and not self.silentSysStd:
87                 sys.stdout.write(message)
88
89     def error(self, message):
90         '''Print an error.
91         
92         :param message str: The message to print.
93         '''
94         # Print in the log file
95         self.xmlFile.append_node("traces", _('ERROR:') + message)
96
97         # Print in the terminal and clean colors if the terminal is redirected by user
98         if not ('isatty' in dir(sys.stderr) and sys.stderr.isatty()):
99             sys.stderr.write(printcolors.printcError(_('ERROR:') + message))
100         else:
101             sys.stderr.write(_('ERROR:') + message)
102
103     def flush(self):
104         '''Flush terminal
105         '''
106         sys.stdout.flush()
107         
108     def endWrite(self):
109         dt = datetime.datetime.now()
110         endtime = dt.strftime('%Y%m%d_%H%M%S')
111         t0 = date_to_datetime(self.config.VARS.datehour)
112         tf = dt
113         delta = tf - t0
114         total_time = delta.total_seconds()
115         hours = int(total_time / 3600)
116         minutes = int((total_time - hours*3600) / 60)
117         seconds = total_time - hours*3600 - minutes*60
118         self.xmlFile.add_simple_node("field", text=endtime , attrib={"name" : "endTime"})
119         self.xmlFile.add_simple_node("field", text="%ih%im%is" % (hours, minutes, seconds) , attrib={"name" : "Total Time"})
120         self.xmlFile.write_tree(stylesheet = "command.xsl")
121
122 def date_to_datetime(date):
123     Y = int(date[:4])
124     m = int(date[4:6])
125     dd = int(date[6:8])
126     H = int(date[9:11])
127     M = int(date[11:13])
128     S = int(date[13:15])
129     return datetime.datetime(Y, m, dd, H, M, S)