Source code for gavo.user.logui

"""
An observer doing logging of warnings, infos, errors, etc.

No synchronization takes place; it's probably not worth sweating this.
"""

#c Copyright 2008-2023, the GAVO project <gavo@ari.uni-heidelberg.de>
#c
#c This program is free software, covered by the GNU GPL.  See the
#c COPYING file in the source distribution.


import logging
import os
import sys
import traceback

from gavo import base
from gavo import utils
from gavo.base import ObserverBase, listensTo
from gavo.protocols.gavolog import getLoggingHandler


[docs]def stringify(s): if isinstance(s, bytes): return s.decode("utf-8", "ignore") # logging gives us a headache when there's non-ascii in here; # pending further investigation, hack around it: return s.encode("ascii", "replace").decode("ascii")
[docs]def addRequestURI(msg): """adds info on the request URI to msg if we seem to handle a request. (which, technically, we determine by trying to steal a request variable from upstack). """ try: req = utils.stealVar("request") if req: msg = "While handling %s:\n%s"%( req.uri.decode("ascii"), msg) except: # don't fail if we can't add the request URI for some reason; # people will notice anyway. pass return msg
[docs]class LoggingUI(ObserverBase): logLineFormat = "%(asctime)s [%(levelname)s %(process)s] %(message)s" def __init__(self, eh, errorName="dcErrors", infoName="dcInfos"): ObserverBase.__init__(self, eh) errH = getLoggingHandler( os.path.join(base.getConfig("logDir"), errorName), "errors") errH.setFormatter( logging.Formatter(self.logLineFormat)) self.errorLogger = logging.getLogger("dcErrors") self.errorLogger.addHandler(errH) self.errorLogger.propagate = False infoH = getLoggingHandler( os.path.join(base.getConfig("logDir"), infoName), "infos", backupCount=1) infoH.setFormatter(logging.Formatter(self.logLineFormat)) self.infoLogger = logging.getLogger("dcInfos") self.infoLogger.propagate = False self.infoLogger.addHandler(infoH) self.infoLogger.setLevel(logging.DEBUG)
[docs] @listensTo("ExceptionMutation") def logOldException(self, res): if base.DEBUG: excInfo, newExc = res self.infoLogger.info("Swallowed the exception below, re-raising %s"% repr(newExc), exc_info=excInfo)
[docs] @listensTo("Info") def logInfo(self, message): self.infoLogger.info( addRequestURI( stringify(message)))
[docs] @listensTo("Warning") def logWarning(self, message): self.infoLogger.warning( addRequestURI( stringify(message)))
[docs] @listensTo("Error") def logError(self, message): self.errorLogger.error( addRequestURI( utils.safe_str(message)), exc_info=False) if sys.exc_info()!=(None, None, None): self.infoLogger.info("Traceback (le) of the exception just logged:\n%s"% traceback.format_exc())