Re: logging: local functions ==> loss of lineno



Hellmut Weber wrote:

Hi Peter and Jean-Michel,
thanks for all your hints and pieces of code.

It took me a while to play around with what I got from you (and some
study of Vinay's module documentation.

Now I have come up with a more complete solution I'm quite satisfied
with. And I would be very glad to receive your comments on my code
indicating what I could do better, given that I'm still at the very
beginning with python.

Here is my module and a corresponding test program:

# --- color change strings for terminal output ---
#
pc_yell = '\033[01;93m'
pc_purp = '\033[01;33m'
pc_gren = '\033[01;92m'

Hw lng wld psts + prgrms b wr it nt 4 z art of clvr + ez 2 mmrz
abbreviations ;)

# --- Class for all logging functionality ---
#
class locLogg():
_logger = None


def debug_log(self, msg, *args, **kwargs):
def warn_log(self, msg, *args, **kwargs):
def error_log(self, msg, *args, **kwargs):

It should be easy to factor out most the code in your xxx_log() methods into
a common helper.

def fatal_log(self, msg, *args, **kwargs):
previousFrame = inspect.currentframe().f_back
locLogg._logger.fatal(str(level_color['fatal'])+msg+pc_norm + \
' ' + argskw_2_string(*args, **kwargs),
extra={'custom_lineno':previousFrame.f_lineno,
'custom_filename': previousFrame.f_code.co_filename })

I think the formatting belongs into another layer. That's the purpose of the
logging.Formatter class. You could enhance it along those lines:

class Formatter(logging.Formatter):
markers = {
logging.INFO: ("<info>", "</info>"),
logging.WARN: ("<warn>", "</warn>"),
}
def format(self, record):
message = logging.Formatter.format(self, record)
try:
prefix, suffix = self.markers[record.levelno]
except KeyError:
pass
else:
message = prefix + message + suffix
return message

My general impression is that you are fighting the logging library's
structure rather than trying to use it as effectively as possible.

foo.info_log('another bar info', 1,2,3, a=11, b=22, c=44)

You could achieve something similar with a standard logger by passing your
extra information through the extra parameter, e. g:

def extra(*args, **kw):
return dict(argskw=(args, kw))
foo.info("another...", extra=extra(1, 2, 3, a=11, b=22))

Peter
.