Example #1
0
 def __init__( self ):
   self._minLevel = 0
   self._showCallingFrame = False
   self._systemName = False
   self._outputList = []
   self._subLoggersDict = {}
   self._logLevels = LogLevels()
   self.__backendOptions = { 'showHeaders' : True, 'showThreads' : False, 'Color' : False }
   self.__preinitialize()
   self.__initialized = False
Example #2
0
 def __init__( self, optionsDictionary ):
   threading.Thread.__init__( self )
   self.__interactive = optionsDictionary[ 'Interactive' ]
   self.__sleep = optionsDictionary[ 'SleepTime' ]
   self._messageQueue = Queue.Queue()
   self._Transactions = []
   self._alive = True
   self._site = optionsDictionary[ 'Site' ]
   self._hostname = Network.getFQDN()
   self._logLevels = LogLevels()
   self._negativeLevel = self._logLevels.getLevelValue( 'ERROR' )
   self._positiveLevel = self._logLevels.getLevelValue( 'ALWAYS' )
   self._maxBundledMessages = 20
   self.setDaemon(1)
   self.start()
Example #3
0
 def __init__( self ):
   self._minLevel = 0
   self._showCallingFrame = False
   self._systemName = False
   self._outputList = []
   self._subLoggersDict = {}
   self._logLevels = LogLevels()
   self.__backendOptions = { 'showHeaders' : True, 'showThreads' : False, 'Color' : False }
   self.__preinitialize()
   self.__initialized = False
Example #4
0
 def __init__( self, optionsDictionary ):
   threading.Thread.__init__( self )
   self.__interactive = optionsDictionary[ 'Interactive' ]
   self.__sleep = optionsDictionary[ 'SleepTime' ]
   self._messageQueue = Queue.Queue()
   self._Transactions = []
   self._alive = True
   self._site = optionsDictionary[ 'Site' ]
   self._hostname = Network.getFQDN()
   self._logLevels = LogLevels()
   self._negativeLevel = self._logLevels.getLevelValue( 'ERROR' )
   self._positiveLevel = self._logLevels.getLevelValue( 'ALWAYS' )
   self._maxBundledMessages = 20
   self.setDaemon(1)
   self.start()
Example #5
0
class Logger( object ):

  defaultLogLevel = 'NOTICE'

  def __init__( self ):
    self._minLevel = 0
    self._showCallingFrame = False
    self._systemName = False
    self._outputList = []
    self._subLoggersDict = {}
    self._logLevels = LogLevels()
    self.__backendOptions = { 'showHeaders' : True, 'showThreads' : False, 'Color' : False }
    self.__preinitialize()
    self.__initialized = False

  def initialized( self ):
    return self.__initialized

  def showHeaders( self, yesno = True ):
    self.__backendOptions[ 'showHeaders' ] = yesno

  def showThreadIDs( self, yesno = True ):
    self.__backendOptions[ 'showThreads' ] = yesno

  def registerBackends( self, desiredBackends ):
    self._backendsDict = {}
    for backend in desiredBackends:
      backend = backend.lower()
      if not backend in gBackendIndex:
        self.warn( "Unexistant method for showing messages",
                   "Unexistant %s logging method" % backend )
      else:
        self._backendsDict[ backend ] = gBackendIndex[ backend ]( self.__backendOptions )

  def __preinitialize ( self ):
    """ This sets some defaults
    """
    self._systemName = "Framework"
    self.registerBackends( [ 'stdout' ] )
    self._minLevel = self._logLevels.getLevelValue( "NOTICE" )
    # HACK to take into account dev levels before the command line if fully parsed
    debLevs = 0
    for arg in sys.argv:
      if arg.find( "-d" ) == 0:
        debLevs += arg.count( "d" )
    if debLevs == 1:
      self.setLevel( "VERBOSE" )
    elif debLevs == 2:
      self.setLevel( "VERBOSE" )
      self.showHeaders( True )
    elif debLevs >= 3:
      self.setLevel( "DEBUG" )
      self.showHeaders( True )
      self.showThreadIDs()

  def initialize( self, systemName, cfgPath ):
    if self.__initialized:
      return
    self.__initialized = True

    from DIRAC.ConfigurationSystem.Client.Config import gConfig
    from os import getpid

    # self.__printDebug( "The configuration path is %s" % cfgPath )
    # Get the options for the different output backends
    retDict = gConfig.getOptionsDict( "%s/BackendsOptions" % cfgPath )

    # self.__printDebug( retDict )
    if not retDict[ 'OK' ]:
      cfgBackOptsDict = { 'FileName': 'Dirac-log_%s.log' % getpid(), 'Interactive': True, 'SleepTime': 150 }
    else:
      cfgBackOptsDict = retDict[ 'Value' ]

    self.__backendOptions.update( cfgBackOptsDict )

    if 'FileName' not in self.__backendOptions:
      self.__backendOptions[ 'FileName' ] = 'Dirac-log_%s.log' % getpid()

    sleepTime = 150
    try:
      sleepTime = int ( self.__backendOptions[ 'SleepTime' ] )
    except:
      pass
    self.__backendOptions[ 'SleepTime' ] = sleepTime

    self.__backendOptions[ 'Interactive' ] = gConfig.getValue( "%s/BackendsOptions/Interactive" % cfgPath, True )

    self.__backendOptions[ 'Site' ] = DIRAC.siteName()

    self.__backendOptions[ 'Color' ] = gConfig.getValue( "%s/LogColor" % cfgPath, False )

    # Configure outputs
    desiredBackends = gConfig.getValue( "%s/LogBackends" % cfgPath, 'stdout' )
    self.registerBackends( List.fromChar( desiredBackends ) )
    # Configure verbosity
    defaultLevel = Logger.defaultLogLevel
    if "Scripts" in cfgPath:
      defaultLevel = gConfig.getValue( '/Systems/Scripts/LogLevel', Logger.defaultLogLevel )
    self.setLevel( gConfig.getValue( "%s/LogLevel" % cfgPath, defaultLevel ) )
    # Configure framing
    self._showCallingFrame = gConfig.getValue( "%s/LogShowLine" % cfgPath, self._showCallingFrame )
    # Get system name
    self._systemName = str( systemName )

    if not self.__backendOptions['Interactive']:
      ExitCallback.registerExitCallback( self.flushAllMessages )

  def setLevel( self, levelName ):
    levelName = levelName.upper()
    if levelName in self._logLevels.getLevels():
      self._minLevel = abs( self._logLevels.getLevelValue( levelName ) )
      return True
    return False

  def getLevel( self ):
    return self._logLevels.getLevel( self._minLevel )

  def shown( self, levelName ):
    levelName = levelName.upper()
    if levelName in self._logLevels.getLevels():
      return self._logLevels.getLevelValue( levelName ) <= levelName
    return False

  def getName( self ):
    return self._systemName

  def always( self, sMsg, sVarMsg = '' ):
    return self._sendMessage( self._logLevels.always,
                              sMsg,
                              sVarMsg )

  def notice( self, sMsg, sVarMsg = '' ):
    return self._sendMessage( self._logLevels.notice,
                              sMsg,
                              sVarMsg )

  def info( self, sMsg, sVarMsg = '' ):
    return self._sendMessage( self._logLevels.info,
                              sMsg,
                              sVarMsg )

  def verbose( self, sMsg, sVarMsg = '' ):
    return self._sendMessage( self._logLevels.verbose,
                              sMsg,
                              sVarMsg )

  def debug( self, sMsg, sVarMsg = '' ):
    # In case of S_ERROR structure make full string representation
    if self.__testLevel( self._logLevels.debug ):
      if isReturnStructure( sMsg ):
        sMsg = reprReturnErrorStructure( sMsg, full = True )
      if isReturnStructure( sVarMsg ):
        sVarMsg = reprReturnErrorStructure( sVarMsg, full = True )
      return self._sendMessage( self._logLevels.debug,
                                sMsg,
                                sVarMsg )

  def warn( self, sMsg, sVarMsg = '' ):
    return self._sendMessage( self._logLevels.warn,
                              sMsg,
                              sVarMsg )

  def error( self, sMsg, sVarMsg = '' ):
    return self._sendMessage( self._logLevels.error,
                              sMsg,
                              sVarMsg )

  def exception( self, sMsg = "", sVarMsg = '', lException = False, lExcInfo = False ):
    if self.__testLevel( self._logLevels.exception ):
      if sVarMsg:
        sVarMsg += "\n%s" % self.__getExceptionString( lException, lExcInfo )
      else:
        sVarMsg = "\n%s" % self.__getExceptionString( lException, lExcInfo )
      return self._sendMessage( self._logLevels.exception,
                                sMsg,
                                sVarMsg )

  def fatal( self, sMsg, sVarMsg = '' ):
    return self._sendMessage( self._logLevels.fatal,
                              sMsg,
                              sVarMsg )

  def showStack( self ):
    return self._sendMessage( self._logLevels.debug, '', '' )

  def _sendMessage( self, level, msgText, variableText ):
    if self.__testLevel( level ):
      messageObject = Message( self._systemName,
                               level,
                               Time.dateTime(),
                               msgText,
                               variableText,
                               self.__discoverCallingFrame() )
      self._processMessage( messageObject )
    return True

  def processMessage( self, messageObject ):
    if self.__testLevel( messageObject.getLevel() ):
      if not messageObject.getName():
        messageObject.setName( self._systemName )
      self._processMessage( messageObject )
    return True

  def __testLevel( self, sLevel ):
    return abs( self._logLevels.getLevelValue( sLevel ) ) >= self._minLevel

  def _processMessage( self, messageObject ):
    for backend in self._backendsDict:
      self._backendsDict[ backend ].doMessage( messageObject )

  def __getExceptionString( self, lException = False, lExcInfo = False ):
    """
    Return a formated string with exception and traceback information
    If lExcInfo is present: full traceback
    Elif lException is present: only last call traceback
    Else: no traceback
    """
    if lExcInfo:
      if isinstance( lExcInfo, bool ):
        lExcInfo = sys.exc_info()
      # Get full traceback
      stack = "".join( traceback.format_tb( lExcInfo[2] ) )
    elif lException:
      # This is useless but makes pylint happy
      if not lException:
        lException = Exception()
      lExcInfo = sys.exc_info()
      try:
        args = lException.args
      except:
        return "Passed exception to the logger is not a valid Exception: %s" % str( lException )
      exceptType = lException.__class__.__name__
      value = ','.join( [str( arg ) for arg in args] )
      # Only print out last part of the traceback
      stack = traceback.format_tb( lExcInfo[2] )[-1]
    else:
      lExcInfo = sys.exc_info()
      stack = ""
    exceptType = lExcInfo[0].__name__
    value = lExcInfo[1]

    return "== EXCEPTION == %s\n%s\n%s: %s\n===============" % ( exceptType, stack, exceptType, value )


  def __discoverCallingFrame( self ):
    if self.__testLevel( self._logLevels.debug ) and self._showCallingFrame:
      oActualFrame = inspect.currentframe()
      lOuterFrames = inspect.getouterframes( oActualFrame )
      lCallingFrame = lOuterFrames[2]
      return "%s:%s" % ( lCallingFrame[1].replace( sys.path[0], "" )[1:], lCallingFrame[2] )
    else:
      return ""

  def __getExtendedExceptionString( self, lException = None ):
    """
    Print the usual traceback information, followed by a listing of all the
    local variables in each frame.
    """
    if lException:
      tb = lException[2]
    else:
      tb = sys.exc_info()[2]
    if not tb:
      return
    while 1:
      if not tb.tb_next:
        break
      tb = tb.tb_next
    stack = []
    f = tb.tb_frame
    while f:
      stack.append( f )
      f = f.f_back
    stack.reverse()
    # traceback.print_exc()
    sExtendedException = "Locals by frame, innermost last\n"
    for frame in stack:
      sExtendedException += "\n"
      sExtendedException += "Frame %s in %s at line %s\n" % ( frame.f_code.co_name,
                                                              frame.f_code.co_filename,
                                                              frame.f_lineno )
      for key, value in frame.f_locals.iteritems():
        # We have to be careful not to cause a new error in our error
        # printer! Calling str() on an unknown object could cause an
        # error we don't want.
        try:
          sExtendedException += "\t%20s = %s\n" % ( key, value )
        except:
          sExtendedException += "\t%20s = <ERROR WHILE PRINTING VALUE>\n" % key
    return sExtendedException

  def __getStackString( self ):
    """ This function returns the stack as a string to be printed via
     a debug message, the upper 3 levels are skipped since they correspond
     to gLogger.showStack,  self.__getStackString, traceback.print_stack
    """
    stack_list = traceback.extract_stack()
    return ''.join( traceback.format_list( stack_list[:-2] ) )

  def flushAllMessages( self, exitCode = 0 ):
    for backend in self._backendsDict:
      self._backendsDict[ backend ].flush()

  def getSubLogger( self, subName, child = True ):
    from DIRAC.FrameworkSystem.private.logging.SubSystemLogger import SubSystemLogger
    if not subName in self._subLoggersDict.keys():
      self._subLoggersDict[ subName ] = SubSystemLogger( subName, self, child )
    return self._subLoggersDict[ subName ]

  def __printDebug( self, debugString ):
    """ This function is implemented to debug problems with initialization
     of the logger. We have to use it because the Logger is obviously unusable
     during its initialization.
    """
    if DEBUG:
      print debugString
Example #6
0
class Logger(object):

    defaultLogLevel = 'NOTICE'

    def __init__(self):
        self._minLevel = 0
        self._showCallingFrame = False
        self._systemName = False
        self._outputList = []
        self._subLoggersDict = {}
        self._logLevels = LogLevels()
        self.__backendOptions = {
            'showHeaders': True,
            'showThreads': False,
            'Color': False
        }
        self.__preinitialize()
        self.__initialized = False

    def initialized(self):
        return self.__initialized

    def showHeaders(self, yesno=True):
        self.__backendOptions['showHeaders'] = yesno

    def showThreadIDs(self, yesno=True):
        self.__backendOptions['showThreads'] = yesno

    def registerBackends(self, desiredBackends):
        self._backendsDict = {}
        for backend in desiredBackends:
            backend = backend.lower()
            if not backend in gBackendIndex:
                self.warn("Unexistant method for showing messages",
                          "Unexistant %s logging method" % backend)
            else:
                self._backendsDict[backend] = gBackendIndex[backend](
                    self.__backendOptions)

    def __preinitialize(self):
        """ This sets some defaults
    """
        self._systemName = "Framework"
        self.registerBackends(['stdout'])
        self._minLevel = self._logLevels.getLevelValue("NOTICE")
        # HACK to take into account dev levels before the command line if fully parsed
        debLevs = 0
        for arg in sys.argv:
            if arg.find("-d") == 0:
                debLevs += arg.count("d")
        if debLevs == 1:
            self.setLevel("VERBOSE")
        elif debLevs == 2:
            self.setLevel("VERBOSE")
            self.showHeaders(True)
        elif debLevs >= 3:
            self.setLevel("DEBUG")
            self.showHeaders(True)
            self.showThreadIDs()

    def initialize(self, systemName, cfgPath):
        if self.__initialized:
            return
        self.__initialized = True

        from DIRAC.ConfigurationSystem.Client.Config import gConfig
        from os import getpid

        # self.__printDebug( "The configuration path is %s" % cfgPath )
        # Get the options for the different output backends
        retDict = gConfig.getOptionsDict("%s/BackendsOptions" % cfgPath)

        # self.__printDebug( retDict )
        if not retDict['OK']:
            cfgBackOptsDict = {
                'FileName': 'Dirac-log_%s.log' % getpid(),
                'Interactive': True,
                'SleepTime': 150
            }
        else:
            cfgBackOptsDict = retDict['Value']

        self.__backendOptions.update(cfgBackOptsDict)

        if 'FileName' not in self.__backendOptions:
            self.__backendOptions['FileName'] = 'Dirac-log_%s.log' % getpid()

        sleepTime = 150
        try:
            sleepTime = int(self.__backendOptions['SleepTime'])
        except:
            pass
        self.__backendOptions['SleepTime'] = sleepTime

        self.__backendOptions['Interactive'] = gConfig.getValue(
            "%s/BackendsOptions/Interactive" % cfgPath, True)

        self.__backendOptions['Site'] = DIRAC.siteName()

        self.__backendOptions['Color'] = gConfig.getValue(
            "%s/LogColor" % cfgPath, False)

        # Configure outputs
        desiredBackends = gConfig.getValue("%s/LogBackends" % cfgPath,
                                           'stdout')
        self.registerBackends(List.fromChar(desiredBackends))
        # Configure verbosity
        defaultLevel = Logger.defaultLogLevel
        if "Scripts" in cfgPath:
            defaultLevel = gConfig.getValue('/Systems/Scripts/LogLevel',
                                            Logger.defaultLogLevel)
        self.setLevel(gConfig.getValue("%s/LogLevel" % cfgPath, defaultLevel))
        # Configure framing
        self._showCallingFrame = gConfig.getValue("%s/LogShowLine" % cfgPath,
                                                  self._showCallingFrame)
        # Get system name
        self._systemName = str(systemName)

        if not self.__backendOptions['Interactive']:
            ExitCallback.registerExitCallback(self.flushAllMessages)

    def setLevel(self, levelName):
        levelName = levelName.upper()
        if levelName in self._logLevels.getLevels():
            self._minLevel = abs(self._logLevels.getLevelValue(levelName))
            return True
        return False

    def getLevel(self):
        return self._logLevels.getLevel(self._minLevel)

    def shown(self, levelName):
        levelName = levelName.upper()
        if levelName in self._logLevels.getLevels():
            return self._logLevels.getLevelValue(levelName) <= levelName
        return False

    def getName(self):
        return self._systemName

    def always(self, sMsg, sVarMsg=''):
        messageObject = Message(self._systemName, self._logLevels.always,
                                Time.dateTime(), sMsg, sVarMsg,
                                self.__discoverCallingFrame())
        return self.processMessage(messageObject)

    def notice(self, sMsg, sVarMsg=''):
        messageObject = Message(self._systemName, self._logLevels.notice,
                                Time.dateTime(), sMsg, sVarMsg,
                                self.__discoverCallingFrame())
        return self.processMessage(messageObject)

    def info(self, sMsg, sVarMsg=''):
        messageObject = Message(self._systemName, self._logLevels.info,
                                Time.dateTime(), sMsg, sVarMsg,
                                self.__discoverCallingFrame())
        return self.processMessage(messageObject)

    def verbose(self, sMsg, sVarMsg=''):
        messageObject = Message(self._systemName, self._logLevels.verbose,
                                Time.dateTime(), sMsg, sVarMsg,
                                self.__discoverCallingFrame())
        return self.processMessage(messageObject)

    def debug(self, sMsg, sVarMsg=''):
        # In case of S_ERROR structure make full string representation
        if isReturnStructure(sMsg):
            sMsg = reprReturnErrorStructure(sMsg, full=True)
        if isReturnStructure(sVarMsg):
            sVarMsg = reprReturnErrorStructure(sVarMsg, full=True)
        messageObject = Message(self._systemName, self._logLevels.debug,
                                Time.dateTime(), sMsg, sVarMsg,
                                self.__discoverCallingFrame())
        return self.processMessage(messageObject)

    def warn(self, sMsg, sVarMsg=''):
        messageObject = Message(self._systemName, self._logLevels.warn,
                                Time.dateTime(), sMsg, sVarMsg,
                                self.__discoverCallingFrame())
        return self.processMessage(messageObject)

    def error(self, sMsg, sVarMsg=''):
        messageObject = Message(self._systemName, self._logLevels.error,
                                Time.dateTime(), sMsg, sVarMsg,
                                self.__discoverCallingFrame())
        return self.processMessage(messageObject)

    def exception(self, sMsg="", sVarMsg='', lException=False, lExcInfo=False):
        if sVarMsg:
            sVarMsg += "\n%s" % self.__getExceptionString(lException, lExcInfo)
        else:
            sVarMsg = "\n%s" % self.__getExceptionString(lException, lExcInfo)

        messageObject = Message(self._systemName, self._logLevels.exception,
                                Time.dateTime(), sMsg, sVarMsg,
                                self.__discoverCallingFrame())
        return self.processMessage(messageObject)

    def fatal(self, sMsg, sVarMsg=''):
        messageObject = Message(self._systemName, self._logLevels.fatal,
                                Time.dateTime(), sMsg, sVarMsg,
                                self.__discoverCallingFrame())
        return self.processMessage(messageObject)

    def showStack(self):
        messageObject = Message(self._systemName, self._logLevels.debug,
                                Time.dateTime(), "", self.__getStackString(),
                                self.__discoverCallingFrame())
        self.processMessage(messageObject)

    def processMessage(self, messageObject):
        if self.__testLevel(messageObject.getLevel()):
            if not messageObject.getName():
                messageObject.setName(self._systemName)
            self._processMessage(messageObject)
        return True

    # S_OK()

    def __testLevel(self, sLevel):
        return abs(self._logLevels.getLevelValue(sLevel)) >= self._minLevel

    def _processMessage(self, messageObject):
        for backend in self._backendsDict:
            self._backendsDict[backend].doMessage(messageObject)

    def __getExceptionString(self, lException=False, lExcInfo=False):
        """
    Return a formated string with exception and traceback information
    If lExcInfo is present: full traceback
    Elif lException is present: only last call traceback
    Else: no traceback
    """
        if lExcInfo:
            lException = False
        if lException:
            # This is useless but makes pylint happy
            if not lException:
                lException = Exception()
            lExcInfo = sys.exc_info()
            try:
                args = lException.args
            except:
                return "Passed exception to the logger is not a valid Exception: %s" % str(
                    lException)
            exceptType = lException.__class__.__name__
            value = ','.join([str(arg) for arg in args])
            # Only print out last part of the traceback
            stack = traceback.format_tb(lExcInfo[2])[-1]
        else:
            if lExcInfo:
                if isinstance(lExcInfo, bool):
                    lExcInfo = sys.exc_info()
                # Get full traceback
                stack = "".join(traceback.format_tb(lExcInfo[2]))
            else:
                lExcInfo = sys.exc_info()
                stack = ""
            exceptType = lExcInfo[0].__name__
            value = lExcInfo[1]

        return "== EXCEPTION == %s\n%s\n%s: %s\n===============" % (
            exceptType, stack, exceptType, value)

    def __discoverCallingFrame(self):
        if self.__testLevel(self._logLevels.debug) and self._showCallingFrame:
            oActualFrame = inspect.currentframe()
            lOuterFrames = inspect.getouterframes(oActualFrame)
            lCallingFrame = lOuterFrames[2]
            return "%s:%s" % (lCallingFrame[1].replace(
                sys.path[0], "")[1:], lCallingFrame[2])
        else:
            return ""

    def __getExtendedExceptionString(self, lException=None):
        """
    Print the usual traceback information, followed by a listing of all the
    local variables in each frame.
    """
        if lException:
            tb = lException[2]
        else:
            tb = sys.exc_info()[2]
        if not tb:
            return
        while 1:
            if not tb.tb_next:
                break
            tb = tb.tb_next
        stack = []
        f = tb.tb_frame
        while f:
            stack.append(f)
            f = f.f_back
        stack.reverse()
        # traceback.print_exc()
        sExtendedException = "Locals by frame, innermost last\n"
        for frame in stack:
            sExtendedException += "\n"
            sExtendedException += "Frame %s in %s at line %s\n" % (
                frame.f_code.co_name, frame.f_code.co_filename, frame.f_lineno)
            for key, value in frame.f_locals.iteritems():
                # We have to be careful not to cause a new error in our error
                # printer! Calling str() on an unknown object could cause an
                # error we don't want.
                try:
                    sExtendedException += "\t%20s = %s\n" % (key, value)
                except:
                    sExtendedException += "\t%20s = <ERROR WHILE PRINTING VALUE>\n" % key
        return sExtendedException

    def __getStackString(self):
        """ This function returns the stack as a string to be printed via
     a debug message, the upper 3 levels are skipped since they correspond
     to gLogger.showStack,  self.__getStackString, traceback.print_stack
    """
        stack_list = traceback.extract_stack()
        return ''.join(traceback.format_list(stack_list[:-2]))

    def flushAllMessages(self, exitCode=0):
        for backend in self._backendsDict:
            self._backendsDict[backend].flush()

    def getSubLogger(self, subName, child=True):
        from DIRAC.FrameworkSystem.private.logging.SubSystemLogger import SubSystemLogger
        if not subName in self._subLoggersDict.keys():
            self._subLoggersDict[subName] = SubSystemLogger(
                subName, self, child)
        return self._subLoggersDict[subName]

    def __printDebug(self, debugString):
        """ This function is implemented to debug problems with initialization
     of the logger. We have to use it because the Logger is obviously unusable
     during its initialization.
    """
        if DEBUG:
            print debugString
Example #7
0
class RemoteBackend(BaseBackend, threading.Thread):
    def __init__(self, optionsDictionary):
        BaseBackend.__init__(self, optionsDictionary)
        threading.Thread.__init__(self)
        self.__interactive = optionsDictionary['Interactive']
        self.__sleep = optionsDictionary['SleepTime']
        self._messageQueue = Queue.Queue()
        self._Transactions = []
        self._alive = True
        self._site = optionsDictionary['Site']
        self._hostname = Network.getFQDN()
        self._logLevels = LogLevels()
        self._negativeLevel = self._logLevels.getLevelValue('ERROR')
        self._positiveLevel = self._logLevels.getLevelValue('ALWAYS')
        self._maxBundledMessages = 20
        self.setDaemon(1)
        self.start()

    def doMessage(self, messageObject):
        self._messageQueue.put(messageObject)

    def run(self):
        import time
        while self._alive:
            self._bundleMessages()
            time.sleep(self.__sleep)

    def _bundleMessages(self):
        while not self._messageQueue.empty():
            bundle = []
            while ( len( bundle ) < self._maxBundledMessages ) and \
                      ( not self._messageQueue.empty() ):
                message = self._messageQueue.get()
                if self._testLevel(message.getLevel()):
                    bundle.append(message.toTuple())

            if len(bundle):
                self._sendMessageToServer(bundle)

        if len(self._Transactions):
            self._sendMessageToServer()

    def _sendMessageToServer(self, messageBundle=None):
        from DIRAC.Core.DISET.RPCClient import RPCClient
        if messageBundle:
            self._Transactions.append(messageBundle)
        TransactionsLength = len(self._Transactions)
        if TransactionsLength > 100:
            del self._Transactions[:TransactionsLength - 100]
            TransactionsLength = 100

        try:
            oSock = RPCClient("Framework/SystemLogging")
        except Exception, v:
            return False

        while TransactionsLength:
            result = oSock.addMessages(self._Transactions[0], self._site,
                                       self._hostname)
            if result['OK']:
                TransactionsLength = TransactionsLength - 1
                self._Transactions.pop(0)
            else:
                return False
        return True
Example #8
0
class Logger:

    defaultLogLevel = "NOTICE"

    def __init__(self):
        self._minLevel = 0
        self._showCallingFrame = False
        self._systemName = False
        self._outputList = []
        self._subLoggersDict = {}
        self._logLevels = LogLevels()
        self.__backendOptions = {"showHeaders": True, "showThreads": False}
        self.__preinitialize()
        self.__initialized = False

    def initialized(self):
        return self.__initialized

    def showHeaders(self, yesno=True):
        self.__backendOptions["showHeaders"] = yesno

    def showThreadIDs(self, yesno=True):
        self.__backendOptions["showThreads"] = yesno

    def registerBackends(self, desiredBackends):
        self._backendsDict = {}
        for backend in desiredBackends:
            backend = backend.lower()
            if not backend in gBackendIndex:
                self.warn("Unexistant method for showing messages", "Unexistant %s logging method" % backend)
            else:
                self._backendsDict[backend] = gBackendIndex[backend](self.__backendOptions)

    def __preinitialize(self):
        self._systemName = "Framework"
        self.registerBackends(["stdout"])
        self._minLevel = self._logLevels.getLevelValue("NOTICE")
        # HACK to take into account dev levels before the command line if fully parsed
        debLevs = 0
        for arg in sys.argv:
            if arg.find("-d") == 0:
                debLevs += arg.count("d")
        if debLevs == 1:
            self.setLevel("VERBOSE")
        elif debLevs == 2:
            self.setLevel("VERBOSE")
            self.showHeaders(True)
        elif debLevs >= 3:
            self.setLevel("DEBUG")
            self.showHeaders(True)
            self.showThreadIDs()

    def initialize(self, systemName, cfgPath):
        if self.__initialized:
            return
        self.__initialized = True

        from DIRAC.ConfigurationSystem.Client.Config import gConfig
        from os import getpid

        # self.__printDebug( "The configuration path is %s" % cfgPath )
        # Get the options for the different output backends
        retDict = gConfig.getOptionsDict("%s/BackendsOptions" % cfgPath)

        # self.__printDebug( retDict )
        if not retDict["OK"]:
            cfgBackOptsDict = {"FileName": "Dirac-log_%s.log" % getpid(), "Interactive": True, "SleepTime": 150}
        else:
            cfgBackOptsDict = retDict["Value"]

        self.__backendOptions.update(cfgBackOptsDict)

        if not self.__backendOptions.has_key("Filename"):
            self.__backendOptions["FileName"] = "Dirac-log_%s.log" % getpid()

        sleepTime = 150
        try:
            sleepTime = int(self.__backendOptions["SleepTime"])
        except:
            pass
        self.__backendOptions["SleepTime"] = sleepTime

        self.__backendOptions["Interactive"] = gConfig.getValue("%s/BackendsOptions/Interactive" % cfgPath, True)

        self.__backendOptions["Site"] = DIRAC.siteName()

        # Configure outputs
        desiredBackends = gConfig.getValue("%s/LogBackends" % cfgPath, "stdout")
        self.registerBackends(List.fromChar(desiredBackends))
        # Configure verbosity
        defaultLevel = Logger.defaultLogLevel
        if "Scripts" in cfgPath:
            defaultLevel = gConfig.getValue("/Systems/Scripts/LogLevel", Logger.defaultLogLevel)
        self.setLevel(gConfig.getValue("%s/LogLevel" % cfgPath, defaultLevel))
        # Configure framing
        self._showCallingFrame = gConfig.getValue("%s/LogShowLine" % cfgPath, self._showCallingFrame)
        # Get system name
        self._systemName = str(systemName)

        if not self.__backendOptions["Interactive"]:
            ExitCallback.registerExitCallback(self.flushAllMessages)

    def setLevel(self, levelName):
        levelName = levelName.upper()
        if levelName.upper() in self._logLevels.getLevels():
            self._minLevel = abs(self._logLevels.getLevelValue(levelName))
            return True
        return False

    def getName(self):
        return self._systemName

    def always(self, sMsg, sVarMsg=""):
        messageObject = Message(
            self._systemName, self._logLevels.always, Time.dateTime(), sMsg, sVarMsg, self.__discoverCallingFrame()
        )
        return self.processMessage(messageObject)

    def notice(self, sMsg, sVarMsg=""):
        messageObject = Message(
            self._systemName, self._logLevels.notice, Time.dateTime(), sMsg, sVarMsg, self.__discoverCallingFrame()
        )
        return self.processMessage(messageObject)

    def info(self, sMsg, sVarMsg=""):
        messageObject = Message(
            self._systemName, self._logLevels.info, Time.dateTime(), sMsg, sVarMsg, self.__discoverCallingFrame()
        )
        return self.processMessage(messageObject)

    def verbose(self, sMsg, sVarMsg=""):
        messageObject = Message(
            self._systemName, self._logLevels.verbose, Time.dateTime(), sMsg, sVarMsg, self.__discoverCallingFrame()
        )
        return self.processMessage(messageObject)

    def debug(self, sMsg, sVarMsg=""):
        messageObject = Message(
            self._systemName, self._logLevels.debug, Time.dateTime(), sMsg, sVarMsg, self.__discoverCallingFrame()
        )
        return self.processMessage(messageObject)

    def warn(self, sMsg, sVarMsg=""):
        messageObject = Message(
            self._systemName, self._logLevels.warn, Time.dateTime(), sMsg, sVarMsg, self.__discoverCallingFrame()
        )
        return self.processMessage(messageObject)

    def error(self, sMsg, sVarMsg=""):
        messageObject = Message(
            self._systemName, self._logLevels.error, Time.dateTime(), sMsg, sVarMsg, self.__discoverCallingFrame()
        )
        return self.processMessage(messageObject)

    def exception(self, sMsg="", sVarMsg="", lException=False, lExcInfo=False):
        if sVarMsg:
            sVarMsg += "\n%s" % self.__getExceptionString(lException, lExcInfo)
        else:
            sVarMsg = "\n%s" % self.__getExceptionString(lException, lExcInfo)
        messageObject = Message(
            self._systemName, self._logLevels.exception, Time.dateTime(), sMsg, sVarMsg, self.__discoverCallingFrame()
        )
        return self.processMessage(messageObject)

    def fatal(self, sMsg, sVarMsg=""):
        messageObject = Message(
            self._systemName, self._logLevels.fatal, Time.dateTime(), sMsg, sVarMsg, self.__discoverCallingFrame()
        )
        return self.processMessage(messageObject)

    def showStack(self):
        messageObject = Message(
            self._systemName,
            self._logLevels.debug,
            Time.dateTime(),
            "",
            self.__getStackString(),
            self.__discoverCallingFrame(),
        )
        self.processMessage(messageObject)

    def processMessage(self, messageObject):
        if self.__testLevel(messageObject.getLevel()):
            if not messageObject.getName():
                messageObject.setName(self._systemName)
            self._processMessage(messageObject)
        return True

    # S_OK()

    def __testLevel(self, sLevel):
        return abs(self._logLevels.getLevelValue(sLevel)) >= self._minLevel

    def _processMessage(self, messageObject):
        for backend in self._backendsDict:
            self._backendsDict[backend].doMessage(messageObject)

    def __getExceptionString(self, lException=False, lExcInfo=False):
        if lException:
            try:
                args = lException.args
            except:
                return "Passed exception to the logger is not a valid Exception: %s" % str(lException)
            if len(args) == 0:
                type = "Unknown exception type"
                value = "Unknown exception"
                stack = ""
            elif len(args) == 1:
                type = "Unknown exception type"
                value = args[0]
                stack = ""
            elif len(args) == 2:
                type = args[0]
                value = args[1]
                stack = ""
            else:
                type = args[0]
                value = args[1]
                stack = "\n".join(args[2])
        else:
            if not lExcInfo:
                lExcInfo = sys.exc_info()
            type, value = (lExcInfo[0], lExcInfo[1])
            stack = "\n".join(traceback.format_tb(lExcInfo[2]))
        return "== EXCEPTION ==\n%s:%s\n%s===============" % (type, value, stack)

    def __discoverCallingFrame(self):
        if self.__testLevel(self._logLevels.debug) and self._showCallingFrame:
            oActualFrame = inspect.currentframe()
            lOuterFrames = inspect.getouterframes(oActualFrame)
            lCallingFrame = lOuterFrames[2]
            return "%s:%s" % (lCallingFrame[1].replace(sys.path[0], "")[1:], lCallingFrame[2])
        else:
            return ""

    def __getExtendedExceptionString(self, lException=None):
        """
    Print the usual traceback information, followed by a listing of all the
    local variables in each frame.
    """
        if lException:
            tb = lException[2]
        else:
            tb = sys.exc_info()[2]
        if not tb:
            return
        while 1:
            if not tb.tb_next:
                break
            tb = tb.tb_next
        stack = []
        f = tb.tb_frame
        while f:
            stack.append(f)
            f = f.f_back
        stack.reverse()
        # traceback.print_exc()
        sExtendedException = "Locals by frame, innermost last\n"
        for frame in stack:
            sExtendedException += "\n"
            sExtendedException += "Frame %s in %s at line %s\n" % (
                frame.f_code.co_name,
                frame.f_code.co_filename,
                frame.f_lineno,
            )
            for key, value in frame.f_locals.items():
                # We have to be careful not to cause a new error in our error
                # printer! Calling str() on an unknown object could cause an
                # error we don't want.
                try:
                    sExtendedException += "\t%20s = %s\n" % (key, value)
                except:
                    sExtendedException += "\t%20s = <ERROR WHILE PRINTING VALUE>\n" % key
        return sExtendedException

    def __getStackString(self):
        """ This function returns the stack as a string to be printed via
     a debug message, the upper 3 levels are skipped since they correspond
     to gLogger.showStack,  self.__getStackString, traceback.print_stack
    """
        stack_list = traceback.extract_stack()
        return "".join(traceback.format_list(stack_list[:-2]))

    def flushAllMessages(self, exitCode):
        for backend in self._backendsDict:
            self._backendsDict[backend].flush()

    def getSubLogger(self, subName, child=True):
        from DIRAC.FrameworkSystem.private.logging.SubSystemLogger import SubSystemLogger

        if not subName in self._subLoggersDict.keys():
            self._subLoggersDict[subName] = SubSystemLogger(subName, self, child)
        return self._subLoggersDict[subName]

    def __printDebug(self, debugString):
        """ This function is implemented to debug problems with initialization 
     of the logger. We have to use it because the Logger is obviously unusable 
     during its initialization.
    """
        if DEBUG:
            print debugString
Example #9
0
class RemoteBackend( BaseBackend, threading.Thread ):

  def __init__( self, optionsDictionary ):
    BaseBackend.__init__(self, optionsDictionary)
    threading.Thread.__init__( self )
    self.__interactive = optionsDictionary[ 'Interactive' ]
    self.__sleep = optionsDictionary[ 'SleepTime' ]
    self._messageQueue = Queue.Queue()
    self._Transactions = []
    self._alive = True
    self._site = optionsDictionary[ 'Site' ]
    self._hostname = Network.getFQDN()
    self._logLevels = LogLevels()
    self._negativeLevel = self._logLevels.getLevelValue( 'ERROR' )
    self._positiveLevel = self._logLevels.getLevelValue( 'ALWAYS' )
    self._maxBundledMessages = 20
    self.setDaemon(1)
    self.start()

  def doMessage( self, messageObject ):
    self._messageQueue.put( messageObject )

  def run( self ):
    import time
    while self._alive:
      self._bundleMessages()
      time.sleep( self.__sleep )

  def _bundleMessages( self ):
    while not self._messageQueue.empty():
      bundle = []
      while ( len( bundle ) < self._maxBundledMessages ) and \
                ( not self._messageQueue.empty() ):
        message = self._messageQueue.get()
        if self._testLevel( message.getLevel() ):
          bundle.append( message.toTuple() )

      if len( bundle ):
        self._sendMessageToServer( bundle )

    if len( self._Transactions ):
      self._sendMessageToServer()

  def _sendMessageToServer( self, messageBundle=None ):
    from DIRAC.Core.DISET.RPCClient import RPCClient
    if messageBundle:
      self._Transactions.append( messageBundle )
    TransactionsLength = len( self._Transactions )
    if TransactionsLength > 100:
      del self._Transactions[:TransactionsLength-100]
      TransactionsLength = 100

    try:
      oSock = RPCClient( "Framework/SystemLogging" )
    except Exception,v:
      return False

    while TransactionsLength:
      result = oSock.addMessages( self._Transactions[0],
                                  self._site, self._hostname )
      if result['OK']:
        TransactionsLength = TransactionsLength - 1
        self._Transactions.pop(0) 
      else:
        return False
    return True