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-2025, 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 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( 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( 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())