debug.py

Go to the documentation of this file.
00001 #! /usr/bin/python
00002 # ----------------------------------------------------------------------------
00003 #
00004 # -*- coding: iso-8859-1 -*-
00005 #
00006 # debug.py
00007 # 
00008 # Logging module
00009 #
00010 # TODO: make everything object oriented and add support for more levels of
00011 # filtering
00012 #
00013 # Needs python > 2.0. Might work with 1.5.X and above
00014 
00015 __version__="1.0"
00016 __date__="2006"
00017 __author__="Radu Stoica"
00018 
00019 # ----------------------------------------------------------------------------
00020 
00021 import sys, string, os
00022 
00023 #global _DEBUG, _VERBOSE, _ERROR
00024 _DEBUG   = 0
00025 _VERBOSE = 1
00026 _ERROR   = 1
00027 
00028 __private = 'test'
00029 
00030 __err = sys.stderr
00031 __out = sys.stdout
00032 __dbg = sys.stdout
00033 
00034 def resetErrorStream():
00035     __err = sys.stderr
00036 
00037 def resetOutputStream():
00038     __out = sys.stdout
00039 
00040 def resetDebugStream():
00041     __dbg = sys.stdout
00042 
00043 def setErrorStream(fileDescriptor):
00044     if not hasattr(fileDescriptor, 'write'):
00045         raise AttributeError("File descriptor %s has no write method"
00046                              %fileDescriptor)
00047     global __err
00048     __err = fileDescriptor
00049 
00050 def setOutputStream(fileDescriptor):
00051     if not hasattr(fileDescriptor, 'write'):
00052         raise AttributeError("File descriptor %s has no write method"
00053                              %fileDescriptor)
00054     global __out
00055     __out = fileDescriptor
00056 
00057 def setDebugStream(fileDescriptor):
00058     if not hasattr(fileDescriptor, 'write'):
00059         raise AttributeError("File descriptor %s has no write method"
00060                              %fileDescriptor)
00061     global __dbg
00062     __dbg = fileDescriptor
00063 
00064 def setSyslog(name=None, facility=None):
00065     import syslog
00066     class SysLogger:
00067         def __init__(self, level=syslog.LOG_UUCP):
00068             self.level = level
00069             
00070         def write(self, msg):
00071             if msg == '\n': return
00072             syslog.syslog(self.level, msg)
00073 
00074         def flush(self):
00075             pass
00076     
00077     if facility is None : facility = syslog.LOG_UUCP
00078     syslog.openlog(name, 0, facility)
00079     setOutputStream(SysLogger(syslog.LOG_INFO))
00080     setErrorStream (SysLogger(syslog.LOG_ERR))
00081     setDebugStream (SysLogger(syslog.LOG_DEBUG))
00082     
00083 
00084 def setDebug(value):
00085     global _DEBUG
00086     _DEBUG = value
00087 
00088 ##
00089 #     
00090 #     Returns a string containing informations about the function that called it
00091 #     at a desired level.
00092 #     level = how many level up should the tracing of this function start.
00093 #     
00094 #     @param level How many level up should the tracing of this function start.
00095 #     @param just: The string will be left justified with the provided input
00096 #     @return a string containing informations about the function that called it
00097 #     at the desired stack level.
00098 #     
00099 def getCallerID(level, just=20):
00100     linePrintStart = ""
00101     linePrintEnd = ""    
00102     try:
00103         raise FakeException("")
00104     except:
00105         func = sys.exc_info()[2].tb_frame
00106     while level >= 0:
00107         func = func.f_back
00108         level -= 1
00109     obj = func.f_locals.get("self", None)
00110     functionName = func.f_code.co_name
00111     if obj:
00112         callStr = "%-8s::%-8s %s%3d%s"\
00113                    %(obj.__class__.__name__,
00114                     func.f_code.co_name,
00115                     linePrintStart,
00116                     func.f_lineno,
00117                     linePrintEnd)
00118     else:
00119         callStr = "%-18s %s%3d%s"\
00120                   %(func.f_code.co_name, linePrintStart, 
00121                     func.f_lineno, linePrintEnd)
00122     return callStr.ljust(just)
00123 
00124 
00125 def LAST_EXCEPTION():
00126     return str(sys.exc_info()[0]) + " :" + str (sys.exc_info()[1])
00127 
00128 ##
00129 # Prints messages adding the caller class name and the line of where the call was invoked.
00130 #     Behaviour can be changed (on/off) by modifying the _VERBOSE global var.
00131 #     
00132 def SAY2(*args):
00133     if _VERBOSE:
00134         msg = "%s: %s" %(getCallerID(2), string.join(map(str, args)))
00135         print >> __out, msg
00136         __out.flush()
00137 
00138 ##
00139 # Prints messages adding the caller class name and the line of where the call was invoked.
00140 #     Behaviour can be changed (on/off) by modifying the _ERROR global var.
00141 #     
00142 def ERROR2(*args):
00143     if _ERROR:
00144         msg="ERROR: in " + getCallerID(2) + ": " + string.join(map(str, args))
00145         print >> __err, msg
00146         __err.flush()
00147 
00148 ##
00149 # Prints messages adding the caller class name and the line of where the call was invoked.
00150 #     Behaviour can be changed (on/off) by modifying the _DEBUG global var.
00151 #     
00152 def DEBUG2(*args):
00153     if _DEBUG:
00154         msg="DEBUG: in " + getCallerID(2) + ": " + string.join(map(str,args))
00155         print >> __dbg, msg
00156         __dbg.flush()
00157 
00158 ##
00159 # Prints messages adding the caller class name and the line of where the call was invoked.
00160 #     Behaviour can be changed (on/off) by modifying the _VERBOSE global var.
00161 #     
00162 def SAY(*args):
00163     if _VERBOSE:
00164         msg = "%s: %s" %(getCallerID(1), string.join(map(str, args)))
00165         print >> __out, msg
00166         __out.flush()
00167 
00168 ##
00169 # Prints messages adding the caller class name and the line of where the call was invoked.
00170 #     Behaviour can be changed (on/off) by modifying the _ERROR global var.
00171 #     
00172 def ERROR(*args):
00173     if _ERROR:
00174         msg="ERROR: in " + getCallerID(1) + ": " + string.join(map(str, args))
00175         print >> __err, msg
00176         __err.flush()
00177 
00178 ##
00179 # Prints messages adding the caller class name and the line of where the call was invoked.
00180 #     Behaviour can be changed (on/off) by modifying the _DEBUG global var.
00181 #     
00182 def DEBUG(*args):
00183     if _DEBUG:
00184         msg="DEBUG: in " + getCallerID(1) + ": " + string.join(map(str,args))
00185         print >> __dbg, msg
00186         __dbg.flush()
00187 
00188 ##
00189 # Sets the debugging location based on the command line arguments given.
00190 #     Argument: 
00191 #         -f (foreground)    -> all logging informations goes to stdout/stderr
00192 #         -l (log) <logfile> -> prints to <logfile>
00193 #         -s (syslog)        -> prints to syslog using the UUCP facility
00194 #     
00195 def parseCommandLine():
00196     if '-l' in sys.argv[1:]:
00197         try:
00198             f = open(sys.argv[sys.argv.index('-l')+1], 'a+')
00199         except:
00200             raise RuntimeError("Could not open log file")
00201         setErrorStream(f)
00202         setOutputStream(f)
00203         setDebugStream(f)
00204         sys.argv.pop(sys.argv.index('-l')+1)
00205         sys.argv.remove('-l')
00206     elif '-f' in sys.argv[1:]:
00207         sys.argv.remove('-f')
00208     elif '-s' in sys.argv[1:]:
00209         setSyslog(sys.argv[0])
00210         sys.argv.remove('-s')
00211     else:
00212         setSyslog(sys.argv[0])
00213 
00214 def commandLineUsage():
00215    
00216    print """Output options:
00217         -f           -> stdout/stderr (foreground mode)
00218         -l <logfile> -> prints to <logfile>
00219         -s           -> syslog using the UUCP facility
00220     """
00221 
00222 # ---------------------------------------------------------------------------
00223 if __name__=='__main__':
00224     _DEBUG = 1
00225     SAY("This is a normal output message")
00226     ERROR("This is an error message")
00227     DEBUG("This is a debug message")
00228     print "Sending the same messages through syslog"
00229     setSyslog("Test debugging")
00230     SAY("This is a normal output message")
00231     ERROR("This is an error message")
00232     DEBUG("This is a debug message")
00233 
00234 

Generated on 5 Feb 2014 for PyDIM by  doxygen 1.4.7