smart logging and the "inspect" module ...

D

Darran Edmundson

I was playing around with the inspect module the other day
trying to write a quick and dirty "smart" logger. By this I mean
that writing a message to the global log would also yield some
info about the calling scope. If you look at my function "test"
below, I'd ideally like log messages:

foo.py:test, "message 1"
foo.py:Foo.__init__, "message 2"
foo.py:Foo.bar, "message 3"

For the life of me I can't figure out how to get this info without
resorting to ridiculous things like parsing the source code (available
via inspect.stack.

Any help would be much appreciated - my unit tests are failing
on this at the moment ;-)

Cheers,
Darran.

#------------ foo.py ---------------------------------

import inspect

class Log:

def __init__(self):
pass

def write(self, msg):
print
"------------------------------------------------------------"
print msg
print
"------------------------------------------------------------"
cframe, cmodule, cline, cfunction, csrc, tmp = inspect.stack()[1]
print inspect.stack()

# I want to determine if cfunction is a regular function or a
class method.
# If the latter, what is the name of the class?

del cframe


def test():

log = Log()
log.write('message 1)

class Foo:
def __init__(self):
log.write('message 2')

def bar(self):
log.write('message 3')

f = Foo()
f.bar()


test()

#--------------------- end of foo.py --------------
 
G

George Sakkis

Darran Edmundson said:
I was playing around with the inspect module the other day
trying to write a quick and dirty "smart" logger. By this I mean
that writing a message to the global log would also yield some
info about the calling scope. If you look at my function "test"
below, I'd ideally like log messages:

foo.py:test, "message 1"
foo.py:Foo.__init__, "message 2"
foo.py:Foo.bar, "message 3"

For the life of me I can't figure out how to get this info without
resorting to ridiculous things like parsing the source code (available
via inspect.stack.

Any help would be much appreciated - my unit tests are failing
on this at the moment ;-)

Cheers,
Darran.

Unfortunately introspection gives access to frame and code objects, but
not to the callable objects (functions, methods, builtins); I think the
reason is that code objects can be shared for different callables.
Also, even the function name and the line number are misleading if
there is an alias (e.g. baz = bar). By the way, here's an alternative
that doesn't use inspect.

import sys

class Log:
def write(self,message):
frame = sys._getframe(1)
code = frame.f_code
print "%s:%d:%s, %s" % (code.co_filename, frame.f_lineno,
code.co_name, message)


There's a logging module in the standard library btw; make sure you
check it out before going on and extending the quick and dirty logger.

Regards,
George
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top