1   
  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   
 19   
 20   
 22   
 23      """ 
 24      Generates timestamps tempfiles and log entries 
 25      """ 
 26   
 28          self.now = "0" 
 29          self.timetup = time.localtime() 
  30   
 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       
 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           
 54           
 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       
 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           
 72          for i in range(6): 
 73               
 74              if i == 0: 
 75                  self.now = str(self.timetup[i]) 
 76               
 77              elif i == 1 or i == 2: 
 78                  self.now = self.now + "." + self.zeroPad(self.timetup[i]) 
 79              else: 
 80                   
 81                  if i == 3: 
 82                      self.now = self.now + " " + self.zeroPad(self.timetup[i]) 
 83                   
 84                  else: 
 85                      self.now = self.now + ":" + self.zeroPad(self.timetup[i]) 
 86          return self.now 
   87   
 88   
 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   
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           
114          if os.path.isdir(config.logDir): 
115              self.findUniqueName() 
116          else: 
117               
118              raise IOError( 
119                  "Log path %s does not exist or is not a directory" % config.logDir) 
 120   
122           
123          self.fileName = config.logDir + self.stamper.fileStamp(self.fileName) \ 
124              + '_' + self.logName 
125          i = 0 
126          while os.path.exists(self.fileName): 
127               
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   
137           
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           
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   
176   
177      """ 
178      Writes entries into the Dogtail log 
179      """ 
180   
183   
184       
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           
190           
191       
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   
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