|
"""Fix missing-API problems in logging module (circa Python 2.3) |
|
|
|
Adds constants to the log objects. |
|
Adds getException(err) to log objects to retrieve |
|
formatted exception or err if traceback not available. |
|
""" |
|
import traceback, logging |
|
from OpenGL._configflags import ERROR_LOGGING, FULL_LOGGING |
|
getLog = logging.getLogger |
|
|
|
def getException(error): |
|
"""Get formatted traceback from exception""" |
|
try: |
|
return traceback.format_exc( limit=10 ) |
|
except Exception as err: |
|
return str( error ) |
|
|
|
logging.Logger.getException = staticmethod( getException ) |
|
logging.Logger.err = logging.Logger.error |
|
logging.Logger.DEBUG = logging.DEBUG |
|
logging.Logger.WARN = logging.WARN |
|
logging.Logger.INFO = logging.INFO |
|
logging.Logger.ERR = logging.Logger.ERROR = logging.ERROR |
|
|
|
if FULL_LOGGING: |
|
getLog( 'OpenGL.calltrace' ).setLevel( logging.INFO ) |
|
|
|
class _LoggedFunction( object ): |
|
"""Proxy that overrides __call__ to log arguments""" |
|
def __init__( self, base, log ): |
|
self.__dict__[''] = base |
|
self.__dict__['log'] = log |
|
def __setattr__( self, key, value ): |
|
if key != '': |
|
setattr( self.__dict__[''], key, value ) |
|
else: |
|
self.__dict__[''] = value |
|
def __getattr__( self, key ): |
|
if key == '': |
|
return self.__dict__[''] |
|
else: |
|
return getattr( self.__dict__[''], key ) |
|
class _FullLoggedFunction( _LoggedFunction ): |
|
"""Fully-logged function wrapper (logs all call params to OpenGL.calltrace)""" |
|
_callTrace = getLog( 'OpenGL.calltrace' ) |
|
def __call__( self, *args, **named ): |
|
argRepr = [] |
|
function = getattr( self, '' ) |
|
for arg in args: |
|
argRepr.append( repr(arg) ) |
|
for key,value in named.items(): |
|
argRepr.append( '%s = %s'%( key,repr(value)) ) |
|
argRepr = ",".join( argRepr ) |
|
self._callTrace.info( '%s( %s )', function.__name__, argRepr ) |
|
try: |
|
return function( *args, **named ) |
|
except Exception as err: |
|
self.log.warning( |
|
"""Failure on %s: %s""", function.__name__, self.log.getException( err ) |
|
) |
|
raise |
|
class _ErrorLoggedFunction ( _LoggedFunction ): |
|
"""On-error-logged function wrapper""" |
|
def __call__( self, *args, **named ): |
|
function = getattr( self, '' ) |
|
try: |
|
return function( *args, **named ) |
|
except Exception as err: |
|
self.log.warning( |
|
"""Failure on %s: %s""", function.__name__, self.log.getException( err ) |
|
) |
|
raise |
|
|
|
|
|
def logOnFail( function, log ): |
|
"""Produce possible log-wrapped version of function |
|
|
|
function -- callable object to be wrapped |
|
log -- the log to which to log information |
|
|
|
Uses ERROR_LOGGING and FULL_LOGGING |
|
to determine whether/how to wrap the function. |
|
""" |
|
if ERROR_LOGGING or FULL_LOGGING: |
|
if FULL_LOGGING: |
|
loggedFunction = _FullLoggedFunction( function, log ) |
|
else: |
|
loggedFunction = _ErrorLoggedFunction( function, log ) |
|
return loggedFunction |
|
else: |
|
return function |
|
|