Package dogtail :: Module logging
[hide private]
[frames] | no frames]

Source Code for Module dogtail.logging

  1  # -*- coding: utf-8 -*- 
  2  """ 
  3  Logging facilities 
  4   
  5  Authors: Ed Rousseau <rousseau@redhat.com>, Zack Cerza <zcerza@redhat.com, David Malcolm <dmalcolm@redhat.com> 
  6  """ 
  7   
  8  __author__ = """Ed Rousseau <rousseau@redhat.com>, 
  9  Zack Cerza <zcerza@redhat.com, 
 10  David Malcolm <dmalcolm@redhat.com> 
 11  """ 
 12  import os 
 13  import sys 
 14  import time 
 15  from config import config 
 16  import codecs 
 17   
 18  # Timestamp class for file logs 
 19   
 20   
21 -class TimeStamp(object):
22 23 """ 24 Generates timestamps tempfiles and log entries 25 """ 26
27 - def __init__(self):
28 self.now = "0" 29 self.timetup = time.localtime()
30
31 - def zeroPad(self, int, width=2):
32 """ 33 Pads an integer 'int' with zeroes, up to width 'width'. 34 35 Returns a string. 36 37 It will not truncate. If you call zeroPad(100, 2), '100' will be returned. 38 """ 39 if int < 10 ** width: 40 return ("0" * (width - len(str(int)))) + str(int) 41 else: 42 return str(int)
43 44 # file stamper
45 - def fileStamp(self, filename, addTime=True):
46 """ 47 Generates a filename stamp in the format of filename_YYYYMMDD-hhmmss. 48 A format of filename_YYYYMMDD can be used instead by specifying addTime = False. 49 """ 50 self.now = filename.strip() + "_" 51 self.timetup = time.localtime() 52 53 # Should produce rel-eng style filestamps 54 # format it all pretty by chopping the tuple 55 fieldCount = 3 56 if addTime: 57 fieldCount = fieldCount + 3 58 for i in range(fieldCount): 59 if i == 3: 60 self.now = self.now + '-' 61 self.now = self.now + self.zeroPad(self.timetup[i]) 62 return self.now
63 64 # Log entry stamper
65 - def entryStamp(self):
66 """ 67 Generates a logfile entry stamp of YYYY.MM.DD HH:MM:SS 68 """ 69 self.timetup = time.localtime() 70 71 # This will return a log entry formatted string in YYYY.MM.DD HH:MM:SS 72 for i in range(6): 73 # put in the year 74 if i == 0: 75 self.now = str(self.timetup[i]) 76 # Format Month and Day 77 elif i == 1 or i == 2: 78 self.now = self.now + "." + self.zeroPad(self.timetup[i]) 79 else: 80 # make the " " between Day and Hour and put in the hour 81 if i == 3: 82 self.now = self.now + " " + self.zeroPad(self.timetup[i]) 83 # Otherwise Use the ":" divider 84 else: 85 self.now = self.now + ":" + self.zeroPad(self.timetup[i]) 86 return self.now
87 88
89 -class Logger(object):
90 91 """ 92 Writes entries to standard out. 93 """ 94 stamper = TimeStamp() 95
96 - def __init__(self, logName, file=False, stdOut=True):
97 """ 98 name: the name of the log 99 file: The file object to log to. 100 stdOut: Whether to log to standard out. 101 """ 102 self.logName = logName 103 self.stdOut = stdOut 104 self.file = file # Handle to the logfile 105 if not self.file: 106 return 107 108 scriptName = config.scriptName 109 if not scriptName: 110 scriptName = 'log' 111 self.fileName = scriptName 112 113 # check to see if we can write to the logDir 114 if os.path.isdir(config.logDir): 115 self.findUniqueName() 116 else: 117 # If path doesn't exist, raise an exception 118 raise IOError( 119 "Log path %s does not exist or is not a directory" % config.logDir)
120
121 - def findUniqueName(self):
122 # generate a logfile name and check if it already exists 123 self.fileName = config.logDir + self.stamper.fileStamp(self.fileName) \ 124 + '_' + self.logName 125 i = 0 126 while os.path.exists(self.fileName): 127 # Append the pathname 128 if i == 0: 129 self.fileName = self.fileName + "." + str(i) 130 else: 131 logsplit = self.fileName.split(".") 132 logsplit[-1] = str(i) 133 self.fileName = ".".join(logsplit) 134 i += 1
135
136 - def createFile(self):
137 # Try to create the file and write the header info 138 print("Creating logfile at %s ..." % self.fileName) 139 self.file = codecs.open(self.fileName, mode='wb', encoding= 140 'utf-8') 141 self.file.write("##### " + os.path.basename(self.fileName) + '\n') 142 self.file.flush()
143
144 - def log(self, message, newline=True, force=False):
145 """ 146 Hook used for logging messages. Might eventually be a virtual 147 function, but nice and simple for now. 148 149 If force is True, log to a file irrespective of config.logDebugToFile. 150 """ 151 try: 152 message = message.decode('utf-8', 'replace') 153 except UnicodeEncodeError: 154 pass 155 156 157 # Try to open and write the result to the log file. 158 if isinstance(self.file, bool) and (force or config.logDebugToFile): 159 self.createFile() 160 161 if force or config.logDebugToFile: 162 if newline: 163 self.file.write(message + '\n') 164 else: 165 self.file.write(message + ' ') 166 self.file.flush() 167 168 if self.stdOut and config.logDebugToStdOut: 169 if newline: 170 print(message) 171 else: 172 print(message)
173 174
175 -class ResultsLogger(Logger):
176 177 """ 178 Writes entries into the Dogtail log 179 """ 180
181 - def __init__(self, stdOut=True):
182 Logger.__init__(self, 'results', file=True, stdOut=stdOut)
183 184 # Writes the result of a test case comparison to the log
185 - def log(self, entry):
186 """ 187 Writes the log entry. Requires a 1 {key: value} pair dict for an argument or else it will throw an exception. 188 """ 189 # We require a 1 key: value dict 190 # Strip all leading and trailing witespace from entry dict and convert 191 # to string for writing 192 193 if len(entry) == 1: 194 key = entry.keys() 195 value = entry.values() 196 key = key[0] 197 value = value[0] 198 entry = str(key) + ": " + str(value) 199 else: 200 raise ValueError(entry) 201 print( 202 "Method argument requires a 1 {key: value} dict. Supplied argument not one {key: value}") 203 204 Logger.log(self, self.stamper.entryStamp() + " " + entry, 205 force=True)
206 207 debugLogger = Logger('debug', config.logDebugToFile) 208 209 import traceback 210 211
212 -def exceptionHook(exc, value, tb): # pragma: no cover
213 tbStringList = traceback.format_exception(exc, value, tb) 214 tbString = ''.join(tbStringList) 215 debugLogger.log(tbString) 216 sys.exc_clear() 217 218 sys.excepthook = exceptionHook 219