587
|
1 |
#============================================================================
|
|
2 |
#Name : logger.py
|
|
3 |
#Part of : Helium
|
|
4 |
|
|
5 |
#Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
6 |
#All rights reserved.
|
|
7 |
#This component and the accompanying materials are made available
|
|
8 |
#under the terms of the License "Eclipse Public License v1.0"
|
|
9 |
#which accompanies this distribution, and is available
|
|
10 |
#at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
11 |
#
|
|
12 |
#Initial Contributors:
|
|
13 |
#Nokia Corporation - initial contribution.
|
|
14 |
#
|
|
15 |
#Contributors:
|
|
16 |
#
|
|
17 |
#Description:
|
|
18 |
#===============================================================================
|
|
19 |
|
588
|
20 |
""" Port to python of the ISIS::Logger3 perl module
|
|
21 |
|
|
22 |
1.0.0 (13/12/2006)
|
|
23 |
- First version of the module.
|
|
24 |
"""
|
587
|
25 |
|
628
|
26 |
# pylint: disable=E1101,E1103
|
587
|
27 |
|
|
28 |
import codecs
|
|
29 |
import xml.dom.minidom
|
|
30 |
import datetime
|
|
31 |
import traceback
|
|
32 |
|
|
33 |
class _CustomizePrint(object):
|
588
|
34 |
""" This is an Internal helper call. """
|
587
|
35 |
|
|
36 |
def __init__(self, logger, name):
|
588
|
37 |
"""Initialise the instance content
|
|
38 |
@param logger a Logger instance
|
|
39 |
@param name method name (e.g. Print, Error), could be any strings"""
|
587
|
40 |
self.__logger = logger
|
|
41 |
self.__name = name
|
|
42 |
|
|
43 |
def __call__(self, *args):
|
588
|
44 |
"""Make this object callable. Call _print from the logger instance.
|
|
45 |
@params *args a list of arguments"""
|
628
|
46 |
# pylint: disable=W0212
|
588
|
47 |
self.__logger._print(self.__name, args)
|
|
48 |
|
|
49 |
|
587
|
50 |
class Logger(object):
|
|
51 |
""" Logger class used to create xml logging in python """
|
|
52 |
def __init__(self):
|
588
|
53 |
"""Constructor of the Logger."""
|
587
|
54 |
self.__step = 1
|
|
55 |
self.__doc = xml.dom.minidom.Document()
|
588
|
56 |
self.__lognode = self.__doc.createElementNS("", "__log")
|
587
|
57 |
self.__header = self.__doc.createElementNS("", "__header")
|
|
58 |
self.__footer = self.__doc.createElementNS("", "__footer")
|
|
59 |
self.__summary = self.__doc.createElementNS("", "__summary")
|
|
60 |
self.__lognode.appendChild(self.__header)
|
|
61 |
self.__lognode.appendChild(self.__summary)
|
588
|
62 |
self.__lognode.appendChild(self.__footer)
|
587
|
63 |
self.__lognode.setAttributeNS("", "date", "%s" % datetime.datetime.now().ctime())
|
|
64 |
self.__footer.setAttributeNS("", "title", "")
|
|
65 |
self.__footer.setAttributeNS("", "subtitle", "")
|
|
66 |
self.__doc.appendChild(self.__lognode)
|
|
67 |
self.__build = self.__doc.createElementNS("", "build")
|
|
68 |
self.__lognode.appendChild(self.__build)
|
|
69 |
self.__current_node = self.__build
|
|
70 |
self.__stack = []
|
|
71 |
self.__verbose = True
|
|
72 |
#<__log date="Wed Dec 6 03:07:25 2006">
|
|
73 |
|
|
74 |
def SetInterface(self, url):
|
588
|
75 |
"""Set the url of interface to use."""
|
587
|
76 |
self.__lognode.setAttributeNS("", "interface", url)
|
|
77 |
|
|
78 |
def SetVerbose(self, v):
|
588
|
79 |
"""Enable/Disable shell output
|
|
80 |
@param v boolean to set the logger output"""
|
587
|
81 |
self.__verbose = v
|
|
82 |
|
588
|
83 |
def SetTitle(self, title):
|
|
84 |
"""Set the title of the document
|
|
85 |
@param title the title to set"""
|
587
|
86 |
self.__header.setAttributeNS("", "title", title)
|
|
87 |
|
588
|
88 |
def SetSubTitle(self, title):
|
|
89 |
"""Set the subtitle of the document
|
|
90 |
@param subtitle the subtitle to set"""
|
587
|
91 |
self.__header.setAttributeNS("", "subtitle", title)
|
|
92 |
|
|
93 |
def SetSummaryTitle(self, title):
|
588
|
94 |
"""Set the sumamry title
|
|
95 |
@param title the title to set"""
|
587
|
96 |
self.__summary.setAttributeNS("", "title", title)
|
|
97 |
|
|
98 |
def AddSummaryElement(self, tag, value):
|
588
|
99 |
"""Creates a summary couple.
|
|
100 |
@param tag the description
|
|
101 |
@param value the value"""
|
|
102 |
elem = self.__doc.createElementNS("", "__elmt")
|
|
103 |
elem.setAttributeNS("", "tag", tag)
|
|
104 |
elem.setAttributeNS("", "val", value)
|
|
105 |
self.__summary.appendChild(elem)
|
587
|
106 |
|
|
107 |
|
|
108 |
def OpenMainContent(self, title=""):
|
588
|
109 |
"""Open a MainContent section.
|
|
110 |
@param title title of the MainContent section"""
|
587
|
111 |
self.__stack.append(self.__current_node)
|
588
|
112 |
node = self.__doc.createElementNS("", "task")
|
|
113 |
node.setAttributeNS("", "name", title)
|
|
114 |
node.setAttributeNS("", "type", "maincontent")
|
|
115 |
node.setAttributeNS("", "time", datetime.datetime.now().ctime())
|
|
116 |
self.__current_node.appendChild(node)
|
|
117 |
self.__current_node = node
|
587
|
118 |
if self.__verbose:
|
|
119 |
print ("---------------------------------------------------------------------")
|
|
120 |
print (" %s" % title)
|
|
121 |
print ("---------------------------------------------------------------------")
|
|
122 |
|
|
123 |
|
|
124 |
def CloseMainContent(self):
|
588
|
125 |
""" Close the current main content section.
|
|
126 |
Make sure you have closed other Event/Section first"""
|
587
|
127 |
if self.__current_node.nodeName != "task" and not (self.__current_node.attributes.has_key('type') and self.__current_node.attributes['type']=="maincontent"):
|
|
128 |
raise Exception("not closing a 'maincontent' typed node")
|
|
129 |
self.__current_node = self.__stack.pop()
|
|
130 |
|
|
131 |
|
|
132 |
def OpenEvent(self, title=""):
|
588
|
133 |
"""Create an Event section (can be opened/closed)
|
|
134 |
@param title title of the MainContent section"""
|
587
|
135 |
self.__stack.append(self.__current_node)
|
588
|
136 |
node = self.__doc.createElementNS("", "task")
|
|
137 |
node.setAttributeNS("", "name", title)
|
|
138 |
node.setAttributeNS("", "type", "event")
|
|
139 |
node.setAttributeNS("", "time", datetime.datetime.now().ctime())
|
|
140 |
self.__current_node.appendChild(node)
|
|
141 |
self.__current_node = node
|
587
|
142 |
if self.__verbose:
|
|
143 |
print ("---------------------------------------------------------------------")
|
|
144 |
print (" + %s" % title)
|
|
145 |
|
628
|
146 |
def SetCustomOutputer(self, type_, classname, config = None):
|
588
|
147 |
"""set custom out puter"""
|
|
148 |
node = self.__doc.createElementNS("", "__customoutputer")
|
628
|
149 |
node.setAttributeNS("", "type", type_)
|
588
|
150 |
node.setAttributeNS("", "module", classname)
|
587
|
151 |
if config != None:
|
588
|
152 |
node.appendChild(config)
|
|
153 |
self.__lognode.appendChild(node)
|
587
|
154 |
|
|
155 |
def CloseEvent(self):
|
588
|
156 |
"""# Close the current Event
|
|
157 |
Make sure you have closed other Event/Section first"""
|
587
|
158 |
if self.__current_node.nodeName != "task" and (self.__current_node.attributes.has_key('type') and self.__current_node.attributes['type']=="event"):
|
|
159 |
raise Exception("not closing a 'event' typed node")
|
|
160 |
self.__current_node = self.__stack.pop()
|
|
161 |
|
|
162 |
def __getattribute__(self, attr):
|
588
|
163 |
"""__getattribute__ has been overrided to enable dynamic messaging.
|
|
164 |
@param attr the name of the method (or attribute...)"""
|
587
|
165 |
try:
|
|
166 |
return object.__getattribute__(self, attr)
|
|
167 |
except AttributeError:
|
|
168 |
return _CustomizePrint(self, attr)
|
588
|
169 |
|
587
|
170 |
def _print(self, kind, *args):
|
588
|
171 |
"""Generic method that handle the print in the XML document
|
|
172 |
@param kind type of output
|
|
173 |
@param *args a list of arguments (must be strings)"""
|
628
|
174 |
output = u"".join([u"%s" % x for x in list(*args)])
|
587
|
175 |
nodetype = kind.lower()
|
|
176 |
msgtype = ""
|
|
177 |
if nodetype != "print" and nodetype != "info" and nodetype != "debug":
|
|
178 |
msgtype = "%s:" % nodetype.upper()
|
|
179 |
if self.__verbose:
|
|
180 |
print "%s %s" % (msgtype, output.encode('utf-8'))
|
588
|
181 |
|
|
182 |
node = self.__doc.createElementNS("", "message")
|
|
183 |
node.setAttributeNS("", "priority", nodetype)
|
587
|
184 |
#n.setAttributeNS("", "time", datetime.datetime.now().ctime())
|
588
|
185 |
node.appendChild(self.__doc.createCDATASection(output))
|
|
186 |
self.__current_node.appendChild(node)
|
587
|
187 |
# nodetype = kind.lower()
|
|
188 |
# if kind.lower() != "print" and kind.lower() != "printraw":
|
|
189 |
# nodename = kind.lower()
|
|
190 |
#
|
|
191 |
# if nodename=="__print" and self.__current_node.lastChild!=None and self.__current_node.lastChild.nodeName == nodename:
|
|
192 |
# self.__current_node.lastChild.appendChild(self.__doc.createTextNode("".join(*args).decode('iso-8859-1')))
|
|
193 |
# else:
|
|
194 |
# n = self.__doc.createElementNS("", nodename)
|
|
195 |
# n.setAttributeNS("", "step", "%d" % self.__step)
|
|
196 |
# self.__step += 1
|
|
197 |
# n.setAttributeNS("", "time", datetime.datetime.now().ctime())
|
|
198 |
# text_content = "".join(map(lambda x: str(x), list(*args))).decode('iso-8859-1')
|
|
199 |
# n.appendChild(self.__doc.createTextNode(text_content))
|
|
200 |
# self.__current_node.appendChild(n)
|
|
201 |
|
|
202 |
|
|
203 |
def SetFooterTitle(self, title):
|
588
|
204 |
"""set footer title"""
|
587
|
205 |
self.__footer.attributes['title'] = title
|
|
206 |
|
|
207 |
def SetFooterSubTitle(self, subtitle):
|
588
|
208 |
"""set footer sub title"""
|
587
|
209 |
self.__footer.attributes['subtitle'] = subtitle
|
|
210 |
|
|
211 |
def Die(self, title, subtitle, exception):
|
588
|
212 |
"""Die - kill it off?"""
|
587
|
213 |
self.SetFooterTitle(title)
|
|
214 |
self.SetFooterSubTitle("%s\nException raised: %s\n%s" % (subtitle, exception, traceback.format_exc()))
|
|
215 |
|
588
|
216 |
def WriteToFile(self, filename):
|
|
217 |
"""Write the DOM tree into a file.
|
|
218 |
@param filename the file to write in."""
|
587
|
219 |
file_object = open(filename, "w")
|
|
220 |
file_object.write(codecs.BOM_UTF8)
|
|
221 |
file_object.write(self.__doc.toprettyxml(encoding = "utf-8"))
|
|
222 |
file_object.close()
|
|
223 |
|
|
224 |
|
|
225 |
##
|
|
226 |
# Write the DOM tree into a file.
|
|
227 |
# @param filename the file to write in.
|
588
|
228 |
def __str__(self):
|
587
|
229 |
return self.__doc.toprettyxml(encoding="utf-8")
|