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