tags:

views:

232

answers:

2

Hi.

I'm implementing a RESTful web service in python and would like to add some QOS logging functionality by intercepting function calls and logging their execution time and so on.

Basically i thought of a class from which all other services can inherit, that automatically overrides the default method implementations and wraps them in a logger function. What's the best way to achieve this?

+2  A: 

What if you write a decorator on each functions ? Here is an example on python's wiki.

Do you use any web framework for doing your webservice ? Or are you doing everything by hand ?

dzen
This is the more explicit, non-magical way of doing things.
Mike Graham
It's an example, to understand how it works. An Example by definition is not something magical
dzen
+6  A: 

Something like this? This implictly adds a decorator to your method (you can also make an explicit decorator based on this if you prefer that):

class Foo(object):
    def __getattribute__(self,name):
        attr = object.__getattribute__(self, name)
        if hasattr(attr, '__call__'):
            def newfunc(*args, **kwargs):
                print('before calling %s' %attr.__name__)
                attr(*args, **kwargs)
                print('done calling %s' %attr.__name__)
            return newfunc
        else:
            return attr

when you now try something like:

class Bar(Foo):
    def myFunc(self, data):
        print("myFunc: %s"% data)

bar = Bar()
bar.myFunc(5)

You'll get:

before calling myFunc
myFunc:  5
done calling myFunc
KillianDS
This code is kind of odd in that if `attr` doesn't have a `__call__` attribute (which, incidentally, is slightly different than not being callable), this gives a `NameError` rather than returning the attribute. Also, `attr.__call__(*args, **kwargs)` is usually spelled `attr(*args, **kwargs)`.
Mike Graham
perfect, just what i need. i had done something similar, but in the init method and somehow messed it up but your approach worked like a charm. thanks.
Erik Aigner
@Mike: indeed, if forgot the else clause. I was mixing python2.6 and 3 btw, hence not using callable built-in. In 3, I do not really know a more straightforward way to check this.
KillianDS
@KillianDS, calling it would be more accurate but, if there are side effects, problematic.
Mike Graham