Package warn
[hide private]
[frames] | no frames]

Source Code for Package warn

  1  #coding: iso-8859-1; 
  2  ############################################################################ 
  3  #                                                                          # 
  4  #    This file 'warn/__init__.py'                                          # 
  5  #    is part of 'SPyRO: Simple Python Remote Objects'                      # 
  6  #    Copyright (C) 2004,2005 by Eric Sadit Téllez Avila                    # 
  7  #    Copyright (C) 2006,2007 by Eric Sadit Téllez Avila                    # 
  8  #    Copyright (C) 2008      by Eric Sadit Téllez Avila                    # 
  9  #    sadit@lsc.fie.umich.mx or donsadit@gmail.com                          # 
 10  #                                                                          # 
 11  #    This program is free software; you can redistribute it and#or modify  # 
 12   
 13  #    sadit@lsc.fie.umich.mx or donsadit@gmail.com                          # 
 14  #                                                                          # 
 15  #    This program is free software; you can redistribute it and#or modify  # 
 16   
 17  #    sadit@lsc.fie.umich.mx or donsadit@gmail.com                          # 
 18  #                                                                          # 
 19  #    This program is free software; you can redistribute it and#or modify  # 
 20  #    it under the terms of the GNU General Public License as published by  # 
 21  #    the Free Software Foundation; either version 2 of the License, or     # 
 22  #    (at your option) any later version.                                   # 
 23  #                                                                          # 
 24  #    This program is distributed in the hope that it will be useful,       # 
 25  #    but WITHOUT ANY WARRANTY; without even the implied warranty of        # 
 26  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         # 
 27  #    GNU General Public License for more details.                          # 
 28  #                                                                          # 
 29  #    You should have received a copy of the GNU General Public License     # 
 30  #    along with this program; if not, write to the                         # 
 31  #    Free Software Foundation, Inc.,                                       # 
 32  #    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             # 
 33  ############################################################################ 
 34   
 35   
 36  __all__ = ['debug','log','warn','stack','halt'] 
 37  """ Debug and warning system (just error display). """ 
 38   
 39  # from SPyRO import SPyRO 
 40  import traceback 
 41  import sys 
 42  import time 
 43  import os 
 44   
45 -class FileWriter:
46 - def __init__(self, name, outfile=None):
47 self.name = name 48 if outfile: 49 self.file = outfile 50 else: 51 self.file = file(name,'a+b',0)
52
53 - def write(self, string):
54 self.file.write(string)
55
56 -class SyslogWriter:
57 - def __init__(self, name):
58 self.name = name
59
60 - def write(self, string):
61 syslog.openlog(self.name) 62 syslog.syslog(syslog.LOG_ERR, string) 63 syslog.closelog()
64 65 66 # In output_handlers is stored every special handler to manage the output 67 # the handlers must support write and _write methods, both of them must 68 # receive a string as argument. 69 70 output = {}
71 -def logger_simple(logname, string):
72 """ A simple output to the logname log """ 73 try: 74 Warn.output[logname].write(string) 75 except KeyError: 76 sys.stderr.write(string)
77
78 -def logger_create_by_function(logid, logsplitter, openfun=None):
79 """ Creates a logger function (a closure) 80 With |logid| name (to the set the output filename) and a function that choose the 81 a tuple of log names to be used by call (|logsplitter|). The output files will be opened 82 using the function |openfun|(logid, logname) and must return a file like object 83 (only write method is needed) 84 if |openfun| is None every file is opened in append and binary mode and 85 output filenames are ${main-log-directory}/log.${logid}.${logname} 86 Where ${main-log-directory} can be set with the function set_main_log_directory 87 ${logid} It the logid gived to this function 88 ${logname} It's the returned value of the logsplitter function 89 90 ------------------------ 91 For example: 92 logger = logger_create_by_function("by-date", lambda x,y: (time.strftime("%y-%m"),)) 93 logger = logger_create_by_function("spyro-user", lambda x,y: (spyro.getrequest()['auth'][0],)) # Using the SPyRO's Module 94 logger = logger_create_by_function("spyro-obj", lambda x,y: (spyro.getrequest()['objname'],))# Using the SPyRO's Module 95 logger = logger_create_by_function("log-ip", lambda x,y: (shttp.http.getrequest()['HTTP_REMOTE_ADDR'],)) # Using the SPyRO's shttp Module 96 set_main_log_function(logger) 97 98 The exact prototype of |logsplitter| 99 iterableobject logsplitter(str logid, str logname) 100 101 Note: The opened files are never closed, if you need to close them, use the 102 dictionary warn.Warn.outputs 103 104 key: logname (not logid), value: output file 105 106 ------------------------------ 107 If logsplitter raises an exception (like KeyError for unknown logs or a failed log name resolution) 108 the default log is used (logger_simple) 109 """ 110 if openfun is None: 111 def xopenfun(_logid, _logname): 112 xfilename = os.path.join(_MAIN_LOG_DIRECTORY,"log.%s.%s"%(_logid,_logname)) 113 return file(xfilename, "ab", 0)
114 openfun = xopenfun 115 def _thelogger(_logname, string): 116 try: 117 lognamelist = logsplitter(logid, _logname) 118 for logname in lognamelist: 119 try: 120 outfile = Warn.output[logname] 121 except KeyError: 122 outfile = Warn.output[logname] = openfun(logid, logname) 123 outfile.write(string) 124 except Exception: 125 logger_simple(_logname, string) 126 return _thelogger 127 128 _MAIN_LOG_FUNCTION = logger_simple 129 _MAIN_LOG_DIRECTORY = "." # In the same directory of the application 130
131 -def set_main_log_directory(dirname):
132 """ The main log directory. For default loggers """ 133 global _MAIN_LOG_DIRECTORY 134 _MAIN_LOG_DIRECTORY = dirname
135
136 -def set_main_log_function(logger):
137 """ Initialices the global logger, this is the core of the warn module 138 And it can be used to perform fancy splitted logs, like log by session, 139 user, module, spyro objects, by network address, by time, by day, etc. 140 141 |logger| The function logger. It can be any object that can be called. 142 The prototype must be: 143 144 void logger(logname, logdata) 145 146 Where logname is the name of the log 147 logdata is the data to be logged 148 """ 149 global _MAIN_LOG_FUNCTION 150 _MAIN_LOG_FUNCTION = logger
151
152 -class Warn:
153 LOG_SYSLOG = 1 154 LOG_FILE = 2 155 LOG_STDERR = 3 156 output = output
157 - def __init__(self, name, outfile=None, filename=None, logtype=None):
158 """ Creates a Warn object. Warn objects provide useful 159 tools to show errors and warnings. 160 |name| The name of the warn object 161 |outfile| An output object in case that you have a default output. 162 If None, a file will be created 163 |logtype| If it must use syslog. If none it uses output to file. 164 Possible values are: Warn.LOG_FILE, Warn.LOG_SYSLOG, Warn.LOG_STDERR 165 Default: LOG_STDERR 166 If LOG_FILE is specified the constructor needs any of the 167 following keyword arguments: 168 filename='filename-to-output' or outfile=fileobject 169 170 NOTE: If output already has a handler, this handler is used overriding 171 any of the opening instructions. In order to override, you need 172 to modify the handler (using warn.output) directly 173 """ 174 self.name = name 175 if logtype is None: logtype = Warn.LOG_STDERR 176 #### To avoid an overload of a previously defined handler 177 if Warn.output.has_key(name): return 178 if logtype == Warn.LOG_STDERR: 179 Warn.output[name] = sys.stderr 180 elif logtype == Warn.LOG_SYSLOG: 181 Warn.output[name] = SyslogWriter(name) 182 elif logtype == Warn.LOG_FILE: 183 if not outfile: 184 if not filename: 185 raise "You must specify a filename if you want a LOG_FILE Warn object" 186 outfile = open(filename,'a+b',0) 187 Warn.output[name] = outfile 188 else: 189 raise Exception("Invalid type of Warn")
190
191 - def write(self, string):
192 """ Output for loggin, append the current time, the name of the log, and the pid """ 193 self._write("%s %s: %s"%(time.ctime(time.time()), self.name, string))
194
195 - def _write(self, string):
196 """ Direct write to the output """ 197 _MAIN_LOG_FUNCTION(self.name, string)
198
199 - def debug(self, *args):
200 """ Shows the args on the stderr """ 201 self.write("DEBUG: " + "".join(map(str,args)) + "\n")
202
203 - def log(self, *args):
204 """ Shows the args on a log """ 205 self.write("LOG: " + "".join(map(str,args)) + "\n")
206
207 - def warn(self,*args):
208 """ Shows |args| as warning, and print the last exception catched """ 209 exc=sys.exc_info() 210 self.write("".join(("WARNING: ", "".join(map(str,args)), "\n", str(exc[1])))) 211 traceback.print_tb(exc[2],file=self)
212
213 - def stack(self,*args):
214 """ Shows |args| as warning, and print the stack of current caller """ 215 self.write("STACK: " + "".join(map(str,args)) + "\n") 216 traceback.print_stack(file=self)
217
218 - def halt(self,*args):
219 """ Displays |args|, print the last_exception and exits with code 127""" 220 exc=sys.exc_info() 221 self.write("".join(("HALT: ", "".join(map(str,args)), "\n", str(exc[1])))) 222 traceback.print_tb(exc[2],file=self)
223 224 try: 225 _name = "PID " + str(os.getpid()) 226 except AttributeError: 227 _name = sys.argv[0] 228 _w = Warn(_name,outfile=sys.stderr) 229 debug = _w.debug 230 log = _w.log 231 warn = _w.warn 232 stack = _w.stack 233 halt = _w.halt 234 write = _w.write 235 _write = _w._write 236