Commit abfa4420 authored by Giuseppe Carboni's avatar Giuseppe Carboni Committed by aorlati
Browse files

Fix #222, done a little rework on `IRAPY/customlogging.py` module. (#224)

Added an internal method in the CustomLogger class that recursively replaces the `<` and `>` characters in exception strings with `{` and `}` respectively before logging them.
Also now the `logException` method logs the name of the calling method to the user correctly (before this fix the caller appeared to be `logException` with no further informations).
parent c3054faa
Loading
Loading
Loading
Loading
+33 −33
Original line number Diff line number Diff line
"""
This module is intended to replace the ACS Logging module in our python code. 
This is necessary as our logging events contain a key-value pair of extra data used to distinguish them 
from the ACS system log.
This module is intended to extend the ACS Logging module in our python code.
"""
from Acspy.Common import Log
import logging
import ACSLog


"""
Key-Value pair distinguishing our custom logging.
"""
CUSTOM_ENV = dict(source="custom")
CUSTOM_DATA = dict(data=CUSTOM_ENV)
CUSTOM_EXTRA = dict(extra=CUSTOM_DATA)
import sys
from Acspy.Common import Log
from ACSLog import ACS_LOG_CRITICAL

class CustomLogger(Log.Logger):
    """This class replaces the standard logging functionalities by overloading the log method. 
    Each log event now will have additional custom key-value data pairs.
    """
    This class replaces the standard logging functionalities by overloading the
    `log` method and by defining a new `logException` method.
    """
    def __init__(self, name):
        self.isUserLogger=False
@@ -27,33 +19,41 @@ class CustomLogger(Log.Logger):
        return self._Logger__formatMessage(msg)

    def log(self, level, msg, *args, **kwargs):
        """Add key-value custom data to the LogRecord structure
        """
        #if 'extra' in kwargs:
        #    if 'data' in kwargs['extra']:
        #        kwargs['extra']['data'].update(CUSTOM_ENV)
        #    else:
        #        kwargs['extra'].update(CUSTOM_DATA)
        #else:
        #    kwargs.update(CUSTOM_EXTRA)
        # Replace some characters in order to avoid parsing errors
        msg = msg.replace('[', '{')
        msg = msg.replace(']', '}')
        Log.Logger.log(self, level, msg, *args, **kwargs)
        
    #This is another workaround to match c++ with buggy python behaviour.
    #It results into having a double entry in acs log
    #The LOG_CRITICAL level correspond in the ERROR level...other ACS bug!
    def logException(self, ex):
        """This method is another workaround to match c++ with buggy python
        behaviour. It results into having a double entry in acs log. The
        LOG_CRITICAL level correspond in the ERROR level...other ACS bug!
        """
        ex.errorTrace = self._fix_error_trace(ex.errorTrace)
        if self.isUserLogger:
            self.logError(ex.shortDescription)
        ex.log(self,ACSLog.ACS_LOG_CRITICAL)
            # Get caller name first to log it correctly
            caller = sys._getframe(1).f_code.co_name
            self.log(logging.ERROR, '%s - %s' % (caller, ex.shortDescription))
        ex.log(self, ACS_LOG_CRITICAL)

    def _fix_error_trace(self, trace):
        """In order to avoid XML parsing errors in the CustomLogger component,
        fields errorTrace.file and errorTrace.routine must not have XML key
        characters `<` and `>`, therefore, we replace them with `{` and `}`."""
        trace.file = trace.file.replace('<', '{').replace('>', '}')
        trace.routine = trace.routine.replace('<', '{').replace('>', '}')
        for index in range(len(trace.previousError)):
            previousTrace = trace.previousError[index]
            previousTrace = self._fix_error_trace(previousTrace)
            trace.previousError[index] = previousTrace
        return trace


logging.setLoggerClass(CustomLogger)
logging.root.setLevel(logging.NOTSET)

def getLogger(name=None):
    """Get our custom logger form the system
    """
    """Get our custom logger from the system."""
    return logging.getLogger(str(name))

if __name__ == '__main__':