gristlabs_grist-core/sandbox/grist/logger.py

75 lines
1.9 KiB
Python
Raw Normal View History

"""
Logging for code running in the sandbox. The output simply goes to stderr (which gets to the
console of the Node process), but the levels allow some configuration.
We don't use the `logging` module because it assumes more about the `time` module than we have.
Usage:
import logger
log = logger.Logger(__name__, logger.DEBUG) # Or logger.WARN; default is logger.INFO.
log.info("Hello world")
-> produces "[I] [foo.bar] Hello world"
"""
import sys
# Level definitions
DEBUG = 10
INFO = 20
WARN = 30
ERROR = 40
CRITICAL = 50
# Level strings
level_strings = {
DEBUG: 'DEBUG',
INFO: 'INFO',
WARN: 'WARN',
ERROR: 'ERROR',
CRITICAL: 'CRITICAL',
}
def log_stderr(level, name, msg):
sys.stderr.write("[%s] [%s] %s\n" % (level_strings.get(level, '?'), name, msg))
sys.stderr.flush()
_log_handler = log_stderr
def set_handler(log_handler):
"""
Allows overriding the handler for all log messages. The handler should be a function, called as
log_handler(level, name, message).
Returns the handler which was set previously.
"""
global _log_handler # pylint: disable=global-statement
prev = _log_handler
_log_handler = log_handler
return prev
class Logger(object):
"""
The object that actually provides the logging interface, specifically the methods debug, info,
warn, error, and critical. The constructor takes an argument for a name that gets included in
each message, and a minimum level, below which messages get ignored.
"""
def __init__(self, name, min_level=INFO):
self._name = name
self._min_level = min_level
def _log(self, level, msg):
if level >= self._min_level:
_log_handler(level, self._name, msg)
def debug(self, msg):
self._log(DEBUG, msg)
def info(self, msg):
self._log(INFO, msg)
def warn(self, msg):
self._log(WARN, msg)
def error(self, msg):
self._log(ERROR, msg)
def critical(self, msg):
self._log(CRITICAL, msg)