From db299a1eade835bbddafddeb60fba686c69fa536 Mon Sep 17 00:00:00 2001 From: calvin Date: Thu, 10 Mar 2005 22:03:40 +0000 Subject: [PATCH] support printing tracebacks git-svn-id: https://linkchecker.svn.sourceforge.net/svnroot/linkchecker/trunk/linkchecker@2394 e7d03fd6-7b0d-0410-9947-9c21f3af8025 --- linkcheck/log.py | 78 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/linkcheck/log.py b/linkcheck/log.py index 99ae963b..5d12a989 100644 --- a/linkcheck/log.py +++ b/linkcheck/log.py @@ -22,60 +22,114 @@ Logging and debug functions. __all__ = ["debug", "info", "warn", "error", "critical", "exception", ] import logging +import traceback +import inspect +import cStringIO as StringIO # memory leak debugging #import gc #gc.enable() #gc.set_debug(gc.DEBUG_LEAK) -def debug (log, msg, *args): + +PRINT_LOCALVARS = False + +def _stack_format (stack): + """ + Format a stack trace to a message. + + @return: formatted stack message + @rtype: string + """ + s = StringIO.StringIO() + traceback.print_stack(stack, file=s) + if PRINT_LOCALVARS: + s.write("Locals by frame, innermost last%s" % os.linesep) + for frame in stack: + s.write(os.linesep) + s.write("Frame %s in %s at line %s%s" % (frame.f_code.co_name, + frame.f_code.co_filename, + frame.f_lineno, + os.linesep)) + for key, value in frame.f_locals.items(): + s.write("\t%20s = " % key) + # be careful not to cause a new error in the error output + try: + s.write(str(value)) + s.write(os.linesep) + except: + s.write("error in str() call%s" % os.linesep) + return s.getvalue() + + +def _log (fun, msg, args, tb=False): + """ + Log a message with given function and an optional traceback. + + @return: None + """ + fun(msg, *args) + if tb: + # note: get rid of last parts of the stack + s = _stack_format(inspect.stack()[2:]) + fun(s) + + +def debug (log, msg, *args, **kwargs): """ Log a debug message. return: None """ - logging.getLogger(log).debug(msg, *args) + _log(logging.getLogger(log).debug, msg, args, tb=kwargs.get("tb")) -def info (log, msg, *args): +def info (log, msg, *args, **kwargs): """ Log an informational message. return: None """ - logging.getLogger(log).info(msg, *args) + _log(logging.getLogger(log).info, msg, args, tb=kwargs.get("tb")) -def warn (log, msg, *args): +def warn (log, msg, *args, **kwargs): """ Log a warning. return: None """ - logging.getLogger(log).warn(msg, *args) + _log(logging.getLogger(log).warn, msg, args, tb=kwargs.get("tb")) -def error (log, msg, *args): +def error (log, msg, *args, **kwargs): """ Log an error. return: None """ - logging.getLogger(log).error(msg, *args) + _log(logging.getLogger(log).error, msg, args, tb=kwargs.get("tb")) -def critical (log, msg, *args): +def critical (log, msg, *args, **kwargs): """ Log a critical error. return: None """ - logging.getLogger(log).critical(msg, *args) + _log(logging.getLogger(log).critical, msg, args, tb=kwargs.get("tb")) -def exception (log, msg, *args): +def exception (log, msg, *args, **kwargs): """ Log an exception. return: None """ - logging.getLogger(log).exception(msg, *args) + _log(logging.getLogger(log).exception, msg, args, tb=kwargs.get("tb")) + + +def is_debug (log): + """ + See if logger is on debug level. + """ + return logging.getLogger(log).isEnabledFor(logging.DEBUG)