def add_timing(min_duration=3):
    module = import_module('urllib3')
    if not module:
        return

    def gather_args_url(r, m, url, *args, **kwargs):
        return {'type': 'remote',
                'statement': 'urllib3.request.RequestMethods.request_encode_url',
                'parameters': url,
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module.request, 'RequestMethods.request_encode_url',
                        time_trace, gatherer=gather_args_url, min_duration=min_duration)


    def gather_args_body(r, m, url, *args, **kwargs):
        return {'type': 'remote',
                'statement': 'urllib3.request.RequestMethods.request_encode_body',
                'parameters': url,
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module.request, 'RequestMethods.request_encode_body',
                        time_trace, gatherer=gather_args_body, min_duration=min_duration)
예제 #2
0
def add_timing(min_duration=0.1):
    module = import_module('redis')
    if not module:
        return

    def general_factory(slow_call_name):
        def gather_args(self, *args, **kwargs):
            return {
                'type': 'nosql',
                'subtype': 'redispy',
                'count': True,
                'statement': slow_call_name,
                'ignore_in': ignore_set
            }

        return gather_args

    if hasattr(module, 'StrictRedis'):
        for m in to_decorate:
            deco_func_or_method(module,
                                'StrictRedis.%s' % m,
                                time_trace,
                                gatherer=general_factory('%s' % m),
                                min_duration=min_duration)
    else:
        for m in to_decorate:
            deco_func_or_method(module,
                                'Redis.%s' % m,
                                time_trace,
                                gatherer=general_factory('%s' % m),
                                min_duration=min_duration)
def add_timing(min_duration=0.15):
    module = import_module('jinja2')
    if not module:
        return

    from jinja2 import environment

    def gather_template(template, *args, **kwargs):
        try:
            tmpl_name = str(template.name)
        except Exception:
            tmpl_name = ''
        return {
            'type': 'tmpl',
            'subtype': 'jinja2',
            'statement': 'render',
            'parameters': tmpl_name,
            'count': True,
            'ignore_in': ignore_set
        }

    deco_func_or_method(environment,
                        'Template.render',
                        time_trace,
                        gatherer=gather_template,
                        min_duration=min_duration,
                        is_template=True)

    environment.Environment.template_class = environment.Template
    module.Template = environment.Template
def add_timing(min_duration=0.15):
    module = import_module('django')
    if not module:
        return

    from django import template

    def gather_template(self, *args, **kwargs):
        try:
            tmpl_name = str(self.name)
        except Exception:
            tmpl_name = ''
        return {'type': 'tmpl',
                'subtype': 'django',
                'statement': 'render',
                'count': True,
                'parameters': tmpl_name,
                'ignore_in': ignore_set}

    if hasattr(template.Template, 'render'):
        deco_func_or_method(template, 'Template.render', time_trace,
                            gatherer=gather_template, min_duration=min_duration, is_template=True)
    elif hasattr(template.Template, '_render'):
        deco_func_or_method(template, 'Template._render', time_trace,
                            gatherer=gather_template, min_duration=min_duration, is_template=True)
예제 #5
0
def add_timing(min_duration=0.1):
    module = import_module('pymongo')
    if not module:
        return
    logging.warning('mongodb timing is currently experimental')

    from pymongo.collection import Collection

    def general_factory(slow_call_name):
        def gather_args(self, *args, **kwargs):
            return {
                'type': 'nosql',
                'subtype': 'mongo',
                'count': True,
                'statement': slow_call_name,
                'ignore_in': ignore_set
            }

        return gather_args

    for m in to_decorate:
        deco_func_or_method(module.collection,
                            'Collection.%s' % m,
                            time_trace,
                            gatherer=general_factory('%s' % m),
                            min_duration=min_duration)
예제 #6
0
def add_timing(min_duration=3):
    module = import_module('httplib')
    if not module:
        return

    def gather_args_host(c):
        return {
            'type': 'remote',
            'statement': 'httplib.HTTPConnection.connect',
            'parameters': c.host,
            'count': True,
            'ignore_in': ignore_set
        }

    def gather_args_sslhost(c):
        return {
            'type': 'remote',
            'statement': 'httplib.HTTPSConnection.connect',
            'parameters': c.host,
            'count': True,
            'ignore_in': ignore_set
        }

    deco_func_or_method(module,
                        'HTTPConnection.connect',
                        time_trace,
                        gatherer=gather_args_host,
                        min_duration=min_duration)

    deco_func_or_method(module,
                        'HTTPSConnection.connect',
                        time_trace,
                        gatherer=gather_args_sslhost,
                        min_duration=min_duration)
def add_timing(min_duration=3):
    module = import_module("urllib")
    if not module:
        return

    def gather_args_open(opener, url, *args, **kwargs):
        return {
            "type": "remote",
            "statement": "urllib.URLopener.open",
            "parameters": url,
            "count": True,
            "ignore_in": ignore_set,
        }

    deco_func_or_method(module, "URLopener.open", time_trace, gatherer=gather_args_open, min_duration=min_duration)

    def gather_args_urlretrieve(url, *args, **kwargs):
        return {
            "type": "remote",
            "statement": "urllib.urlretrieve",
            "parameters": url,
            "count": True,
            "ignore_in": ignore_set,
        }

    deco_func_or_method(module, "urlretrieve", time_trace, gatherer=gather_args_urlretrieve, min_duration=min_duration)
예제 #8
0
def add_timing(min_duration=3):
    module = import_module('urllib3')
    if not module:
        return

    def gather_args_url(r, m, url, *args, **kwargs):
        return {
            'type': 'remote',
            'statement': 'urllib3.request.RequestMethods.request_encode_url',
            'parameters': url,
            'count': True,
            'ignore_in': ignore_set
        }

    deco_func_or_method(module.request,
                        'RequestMethods.request_encode_url',
                        time_trace,
                        gatherer=gather_args_url,
                        min_duration=min_duration)

    def gather_args_body(r, m, url, *args, **kwargs):
        return {
            'type': 'remote',
            'statement': 'urllib3.request.RequestMethods.request_encode_body',
            'parameters': url,
            'count': True,
            'ignore_in': ignore_set
        }

    deco_func_or_method(module.request,
                        'RequestMethods.request_encode_body',
                        time_trace,
                        gatherer=gather_args_body,
                        min_duration=min_duration)
예제 #9
0
def add_timing(min_duration=0.15):
    module = import_module('django')
    if not module:
        return

    from django import template

    def gather_template(self, *args, **kwargs):
        try:
            tmpl_name = str(self.name)
        except Exception:
            tmpl_name = ''
        return {
            'type': 'tmpl',
            'subtype': 'django',
            'statement': 'render',
            'count': True,
            'parameters': tmpl_name,
            'ignore_in': ignore_set
        }

    if hasattr(template.Template, 'render'):
        deco_func_or_method(template,
                            'Template.render',
                            time_trace,
                            gatherer=gather_template,
                            min_duration=min_duration,
                            is_template=True)
    elif hasattr(template.Template, '_render'):
        deco_func_or_method(template,
                            'Template._render',
                            time_trace,
                            gatherer=gather_template,
                            min_duration=min_duration,
                            is_template=True)
예제 #10
0
def add_timing(min_duration=3):
    module = import_module('requests')
    if not module:
        return

    def gather_args_url(method, url, *args, **kwargs):
        return {'type': 'remote', 'statement': 'requests.request',
                'parameters': url,
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module, 'api.request', time_trace,
                        gatherer=gather_args_url, min_duration=min_duration)
def add_timing(min_duration=0.15):
    module = import_module('chameleon')
    if not module:
        return

    def gather_template(template, *args, **kwargs):
        return {'type': 'tmpl',
                'subtype': 'chameleon',
                'statement': 'render',
                'parameters': '',
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module.template, 'Template.render', time_trace,
                        gatherer=gather_template, min_duration=min_duration, is_template=True)
def add_timing(min_duration=0.1):
    module = import_module('pylibmc')
    if not module:
        return

    class TimerWrapper(object):

        def __init__(self, instance, module_name):
            # assign to superclass or face the infinite recursion consequences
            object.__setattr__(self, '_e_module_name', module_name)
            object.__setattr__(self, '_e_object', instance)

        def __setattr__(self, name, value):
            return setattr(self._e_object, name, value)

        def __getattr__(self, name):
            return getattr(self._e_object, name)

        def __iter__(self):
            return iter(self._e_object)

        def __call__(self, *args, **kwargs):
            return self._e_object(*args, **kwargs)

    class Wrapper(object):

        _e_attached_wrapper = True

        def __init__(self, conn_callable, module_name):
            # assign to superclass or face the infinite recursion consequences
            object.__setattr__(self, '_e_module_name', module_name)
            object.__setattr__(self, '_e_object', conn_callable)

        def __setattr__(self, name, value):
            return setattr(self._e_object, name, value)

        def __getattr__(self, name):
            return getattr(self._e_object, name)

        def __call__(self, *args, **kwargs):
            return TimerWrapper(_e_trace(general_factory, min_duration,
                                         self._e_object, *args, **kwargs),
                                self._e_module_name)


    module.Client = Wrapper(module.Client, 'pylibmc')
def add_timing(min_duration=0.1):
    module = import_module('memcache')
    if not module:
        return

    def general_factory(slow_call_name):
        def gather_args(self, *args, **kwargs):
            return {'type': 'nosql', 'subtype': 'memcache-py',
                    'count': True,
                    'statement': slow_call_name,
                    'ignore_in': ignore_set}

        return gather_args

    for m in to_decorate:
        deco_func_or_method(module, 'Client.%s' % m, time_trace,
                        gatherer=general_factory('%s' % m), min_duration=min_duration)
예제 #14
0
def add_timing(min_duration=0.1):
    module = import_module('memcache')
    if not module:
        return

    def general_factory(slow_call_name):
        def gather_args(self, *args, **kwargs):
            return {'type': 'nosql', 'subtype': 'memcache-py',
                    'count': True,
                    'statement': slow_call_name,
                    'ignore_in': ignore_set}

        return gather_args

    for m in to_decorate:
        deco_func_or_method(module, 'Client.%s' % m, time_trace,
                            gatherer=general_factory('%s' % m), min_duration=min_duration)
def add_timing(min_duration=3):
    module = import_module('urllib2')
    if not module:
        return

    def gather_args_open(opener, url, *args, **kwargs):
        if not isinstance(url, basestring):
            g_url = url.get_full_url()
        else:
            g_url = url

        return {'type': 'remote', 'statement': 'urllib2.OpenerDirector.open',
                'parameters': g_url,
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module, 'OpenerDirector.open', time_trace,
                        gatherer=gather_args_open, min_duration=min_duration)
def add_timing(min_duration=0.1):
    module = import_module('pysolr')
    if not module:
        return

    def general_factory(slow_call_name):
        def gather_args(solr, *args, **kwargs):
            return {'type': 'nosql', 'subtype': 'solr',
                    'statement': slow_call_name,
                    'count': True,
                    'ignore_in': ignore_set}

        return gather_args

    def gather_args_search(solr, q, *args, **kwargs):
        return {'type': 'nosql', 'subtype': 'solr', 'statement': q,
                'count': True,
                'ignore_in': ignore_set}

    def gather_args_more_like_this(solr, q, *args, **kwargs):
        return {'type': 'nosql', 'subtype': 'solr', 'statement': q,
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module, 'Solr.search', time_trace,
                        gatherer=gather_args_search, min_duration=min_duration)

    deco_func_or_method(module, 'Solr.add', time_trace,
                        gatherer=general_factory('Solr.add'), min_duration=min_duration)

    deco_func_or_method(module, 'Solr.commit', time_trace,
                        gatherer=general_factory('Solr.commit'), min_duration=min_duration)

    deco_func_or_method(module, 'Solr.delete', time_trace,
                        gatherer=general_factory('Solr.delete'), min_duration=min_duration)

    deco_func_or_method(module, 'Solr.extract', time_trace,
                        gatherer=general_factory('Solr.extract'), min_duration=min_duration)

    deco_func_or_method(module, 'Solr.more_like_this', time_trace,
                        gatherer=gather_args_more_like_this, min_duration=min_duration)

    deco_func_or_method(module, 'Solr.suggest_terms', time_trace,
                        gatherer=general_factory('Solr.commit'), min_duration=min_duration)
예제 #17
0
def add_timing(min_duration=0.1):
    module = import_module('pylibmc')
    if not module:
        return

    class TimerWrapper(object):
        def __init__(self, instance, module_name):
            # assign to superclass or face the infinite recursion consequences
            object.__setattr__(self, '_e_module_name', module_name)
            object.__setattr__(self, '_e_object', instance)

        def __setattr__(self, name, value):
            return setattr(self._e_object, name, value)

        def __getattr__(self, name):
            return getattr(self._e_object, name)

        def __iter__(self):
            return iter(self._e_object)

        def __call__(self, *args, **kwargs):
            return self._e_object(*args, **kwargs)

    class Wrapper(object):

        _e_attached_wrapper = True

        def __init__(self, conn_callable, module_name):
            # assign to superclass or face the infinite recursion consequences
            object.__setattr__(self, '_e_module_name', module_name)
            object.__setattr__(self, '_e_object', conn_callable)

        def __setattr__(self, name, value):
            return setattr(self._e_object, name, value)

        def __getattr__(self, name):
            return getattr(self._e_object, name)

        def __call__(self, *args, **kwargs):
            return TimerWrapper(
                _e_trace(general_factory, min_duration, self._e_object, *args,
                         **kwargs), self._e_module_name)

    module.Client = Wrapper(module.Client, 'pylibmc')
def add_timing(min_duration=0.15):
    module = import_module('jinja2')
    if not module:
        return

    from jinja2 import environment

    def gather_template(template, *args, **kwargs):
        return {'type': 'tmpl',
                'subtype': 'jinja2',
                'statement': 'render',
                'parameters': '',
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(environment, 'Template.render', time_trace,
                        gatherer=gather_template, min_duration=min_duration, is_template=True)

    environment.Environment.template_class = environment.Template
    module.Template = environment.Template
def add_timing(min_duration=0.1):
    module = import_module('pymongo')
    if not module:
        return
    logging.warning('mongodb timing is currently experimental')

    from pymongo.collection import Collection

    def general_factory(slow_call_name):
        def gather_args(self, *args, **kwargs):
            return {'type': 'nosql', 'subtype': 'mongo',
                    'count': True,
                    'statement': slow_call_name,
                    'ignore_in': ignore_set}

        return gather_args

    for m in to_decorate:
        deco_func_or_method(module.collection, 'Collection.%s' % m, time_trace,
                            gatherer=general_factory('%s' % m), min_duration=min_duration)
예제 #20
0
def add_timing(min_duration=0.15):
    module = import_module('chameleon')
    if not module:
        return

    def gather_template(template, *args, **kwargs):
        return {
            'type': 'tmpl',
            'subtype': 'chameleon',
            'statement': 'render',
            'parameters': '',
            'count': True,
            'ignore_in': ignore_set
        }

    deco_func_or_method(module.template,
                        'Template.render',
                        time_trace,
                        gatherer=gather_template,
                        min_duration=min_duration,
                        is_template=True)
def add_timing(min_duration=0.15):
    module = import_module('mako')
    if not module:
        return

    from mako import template

    def gather_template(template, *args, **kwargs):
        return {'type': 'tmpl',
                'subtype': 'mako',
                'statement': 'render',
                'parameters': '',
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(template, 'Template.render', time_trace,
                        gatherer=gather_template, min_duration=min_duration, is_template=True)
    deco_func_or_method(template, 'Template.render_unicode', time_trace,
                        gatherer=gather_template, min_duration=min_duration, is_template=True)
    deco_func_or_method(template, 'Template.render_context', time_trace,
                        gatherer=gather_template, min_duration=min_duration, is_template=True)
def add_timing(min_duration=0.15):
    module = import_module('mako')
    if not module:
        return

    from mako import template

    def gather_template(template, *args, **kwargs):
        return {'type': 'tmpl',
                'subtype': 'mako',
                'statement': 'render',
                'parameters': '',
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(template, 'Template.render', time_trace,
                        gatherer=gather_template, min_duration=min_duration, is_template=True)
    deco_func_or_method(template, 'Template.render_unicode', time_trace,
                        gatherer=gather_template, min_duration=min_duration, is_template=True)
    deco_func_or_method(template, 'Template.render_context', time_trace,
                        gatherer=gather_template, min_duration=min_duration, is_template=True)
def add_timing(min_duration=0.15):
    module = import_module("mako")
    if not module:
        return

    from mako import template

    def gather_template(self, *args, **kwargs):
        try:
            tmpl_name = str(self.filename or self.module_id)
        except Exception:
            tmpl_name = ""
        return {
            "type": "tmpl",
            "subtype": "mako",
            "statement": "render",
            "parameters": tmpl_name,
            "count": True,
            "ignore_in": ignore_set,
        }

    deco_func_or_method(
        template, "Template.render", time_trace, gatherer=gather_template, min_duration=min_duration, is_template=True
    )
    deco_func_or_method(
        template,
        "Template.render_unicode",
        time_trace,
        gatherer=gather_template,
        min_duration=min_duration,
        is_template=True,
    )
    deco_func_or_method(
        template,
        "Template.render_context",
        time_trace,
        gatherer=gather_template,
        min_duration=min_duration,
        is_template=True,
    )
def add_timing(min_duration=3):
    module = import_module('urllib')
    if not module:
        return

    def gather_args_open(opener, url, *args, **kwargs):
        return {'type': 'remote', 'statement': 'urllib.URLopener.open',
                'parameters': url,
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module, 'URLopener.open', time_trace,
                        gatherer=gather_args_open, min_duration=min_duration)

    def gather_args_urlretrieve(url, *args, **kwargs):
        return {'type': 'remote', 'statement': 'urllib.urlretrieve',
                'parameters': url,
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module, 'urlretrieve', time_trace,
                        gatherer=gather_args_urlretrieve, min_duration=min_duration)
def add_timing(min_duration=0.1):
    module = import_module('redis')
    if not module:
        return

    def general_factory(slow_call_name):
        def gather_args(self, *args, **kwargs):
            return {'type': 'nosql', 'subtype': 'redispy',
                    'count': True,
                    'statement': slow_call_name,
                    'ignore_in': ignore_set}

        return gather_args

    if hasattr(module, 'StrictRedis'):
        for m in to_decorate:
            deco_func_or_method(module, 'StrictRedis.%s' % m, time_trace,
                                gatherer=general_factory('%s' % m), min_duration=min_duration)
    else:
        for m in to_decorate:
            deco_func_or_method(module, 'Redis.%s' % m, time_trace,
                                gatherer=general_factory('%s' % m), min_duration=min_duration)
def add_timing(min_duration=3):
    module = import_module('urllib')
    if not module:
        return

    def gather_args_open(opener, url, *args, **kwargs):
        return {'type': 'remote', 'statement': 'urllib.URLopener.open',
                'parameters': url,
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module, 'URLopener.open', time_trace,
                        gatherer=gather_args_open, min_duration=min_duration)

    def gather_args_urlretrieve(url, *args, **kwargs):
        return {'type': 'remote', 'statement': 'urllib.urlretrieve',
                'parameters': url,
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module, 'urlretrieve', time_trace,
                        gatherer=gather_args_urlretrieve, min_duration=min_duration
    )
def add_timing(min_duration=3):
    module = import_module('httplib')
    if not module:
        return

    def gather_args_host(c):
        return {'type': 'remote',
                'statement': 'httplib.HTTPConnection.connect',
                'parameters': c.host,
                'count': True,
                'ignore_in': ignore_set}

    def gather_args_sslhost(c):
        return {'type': 'remote',
                'statement': 'httplib.HTTPSConnection.connect',
                'parameters': c.host,
                'count': True,
                'ignore_in': ignore_set}

    deco_func_or_method(module, 'HTTPConnection.connect', time_trace,
                        gatherer=gather_args_host, min_duration=min_duration)

    deco_func_or_method(module, 'HTTPSConnection.connect', time_trace,
                        gatherer=gather_args_sslhost, min_duration=min_duration)
예제 #28
0
def add_timing(min_duration=3):
    module = import_module('urllib2')
    if not module:
        return

    def gather_args_open(opener, url, *args, **kwargs):
        if not isinstance(url, basestring):
            g_url = url.get_full_url()
        else:
            g_url = url

        return {
            'type': 'remote',
            'statement': 'urllib2.OpenerDirector.open',
            'parameters': g_url,
            'count': True,
            'ignore_in': ignore_set
        }

    deco_func_or_method(module,
                        'OpenerDirector.open',
                        time_trace,
                        gatherer=gather_args_open,
                        min_duration=min_duration)
def add_timing(min_duration=0.1):
    module = import_module('pysolr')
    if not module:
        return

    def general_factory(slow_call_name):
        def gather_args(solr, *args, **kwargs):
            return {
                'type': 'nosql',
                'subtype': 'solr',
                'statement': slow_call_name,
                'count': True,
                'ignore_in': ignore_set
            }

        return gather_args

    def gather_args_search(solr, q, *args, **kwargs):
        return {
            'type': 'nosql',
            'subtype': 'solr',
            'statement': q,
            'count': True,
            'ignore_in': ignore_set
        }

    def gather_args_more_like_this(solr, q, *args, **kwargs):
        return {
            'type': 'nosql',
            'subtype': 'solr',
            'statement': q,
            'count': True,
            'ignore_in': ignore_set
        }

    deco_func_or_method(module,
                        'Solr.search',
                        time_trace,
                        gatherer=gather_args_search,
                        min_duration=min_duration)

    deco_func_or_method(module,
                        'Solr.add',
                        time_trace,
                        gatherer=general_factory('Solr.add'),
                        min_duration=min_duration)

    deco_func_or_method(module,
                        'Solr.commit',
                        time_trace,
                        gatherer=general_factory('Solr.commit'),
                        min_duration=min_duration)

    deco_func_or_method(module,
                        'Solr.delete',
                        time_trace,
                        gatherer=general_factory('Solr.delete'),
                        min_duration=min_duration)

    deco_func_or_method(module,
                        'Solr.extract',
                        time_trace,
                        gatherer=general_factory('Solr.extract'),
                        min_duration=min_duration)

    deco_func_or_method(module,
                        'Solr.more_like_this',
                        time_trace,
                        gatherer=gather_args_more_like_this,
                        min_duration=min_duration)

    deco_func_or_method(module,
                        'Solr.suggest_terms',
                        time_trace,
                        gatherer=general_factory('Solr.commit'),
                        min_duration=min_duration)
예제 #30
0
def add_timing(module_name, min_duration=0.1):
    module = import_module(module_name)
    if not module:
        return

    class CursorWrapper(object):
        def __init__(self, instance, module_name):
            object.__setattr__(self, '_e_db_module_name', module_name)
            object.__setattr__(self, '_e_db_fetch',
                               general_factory('fetch', module_name))
            object.__setattr__(self, '_e_db_fetchmany',
                               general_factory('fetchmany', module_name))
            object.__setattr__(self, '_e_db_fetchall',
                               general_factory('fetchall', module_name))
            object.__setattr__(self, '_e_db_nextset',
                               general_factory('nextset', module_name))
            object.__setattr__(self, '_e_db_next',
                               general_factory('next', module_name))
            object.__setattr__(self, '_e_db_query',
                               gather_query_factory(module_name))
            object.__setattr__(self, '_e_object', instance)

        #        def callproc(self, *args, **kwargs):
        #            return _e_trace(self._e_db_query, min_duration,
        #                            self._e_object.callproc, *args, **kwargs)

        def execute(self, *args, **kwargs):
            return _e_trace(self._e_db_query, min_duration,
                            self._e_object.execute, *args, **kwargs)

        def executemany(self, *args, **kwargs):
            return _e_trace(self._e_db_query, min_duration,
                            self._e_object.executemany, *args, **kwargs)

        def fetch(self, *args, **kwargs):
            return _e_trace(self._e_db_fetch, min_duration,
                            self._e_object.fetch, *args, **kwargs)

        def fetchmany(self, *args, **kwargs):
            return _e_trace(self._e_db_fetchmany, min_duration,
                            self._e_object.fetchmany, *args, **kwargs)

        def fetchall(self, *args, **kwargs):
            return _e_trace(self._e_db_fetchall, min_duration,
                            self._e_object.fetchall, *args, **kwargs)

        def nextset(self, *args, **kwargs):
            return _e_trace(self._e_db_nextset, min_duration,
                            self._e_object.nextset, *args, **kwargs)

        def next(self, *args, **kwargs):
            return _e_trace(self._e_db_next, min_duration, self._e_object.next,
                            *args, **kwargs)

        def __setattr__(self, name, value):
            return setattr(self._e_object, name, value)

        def __getattr__(self, name):
            return getattr(self._e_object, name)

        def __iter__(self):
            return iter(self._e_object)

        def __call__(self, *args, **kwargs):
            return self._e_object(*args, **kwargs)

        def __enter__(self):
            self._e_object.__enter__()
            return self

        def __exit__(self, exc_type, exc_value, traceback):
            return self._e_object.__exit__(exc_type, exc_value, traceback)

    class TimerWrapper(object):
        def __init__(self, instance, module_name):
            # assign to superclass or face the infinite recursion consequences
            object.__setattr__(self, '_e_db_module_name', module_name)
            object.__setattr__(self, '_e_db_commit',
                               general_factory('COMMIT', module_name))
            object.__setattr__(self, '_e_db_rollback',
                               general_factory('ROLLBACK', module_name))
            object.__setattr__(self, '_e_object', instance)

        def cursor(self, *args, **kwargs):
            result = CursorWrapper(self._e_object.cursor(*args, **kwargs),
                                   self._e_db_module_name)
            return result

        def commit(self, *args, **kwargs):
            return _e_trace(self._e_db_commit, min_duration,
                            self._e_object.commit, *args, **kwargs)

        def rollback(self, *args, **kwargs):
            return _e_trace(self._e_db_rollback, min_duration,
                            self._e_object.rollback, *args, **kwargs)

        def __setattr__(self, name, value):
            return setattr(self._e_object, name, value)

        def __getattr__(self, name):
            return getattr(self._e_object, name)

        def __iter__(self):
            return iter(self._e_object)

        def __call__(self, *args, **kwargs):
            return self._e_object(*args, **kwargs)

    class Wrapper(object):

        _e_attached_wrapper = True

        def __init__(self, conn_callable, module_name):
            # assign to superclass or face the infinite recursion consequences
            object.__setattr__(self, '_e_module_name', module_name)
            object.__setattr__(self, '_e_object', conn_callable)
            object.__setattr__(self, '_e_db_connect',
                               general_factory('CONNECT', module_name))

        def __setattr__(self, name, value):
            return setattr(self._e_object, name, value)

        def __getattr__(self, name):
            return getattr(self._e_object, name)

        def __call__(self, *args, **kwargs):
            return TimerWrapper(
                _e_trace(self._e_db_connect, min_duration / 2.0,
                         self._e_object, *args, **kwargs), self._e_module_name)

    if module_name == 'psycopg2':
        # psycopg2 does a weird type check when someone does
        # psycopg2.extensions.register_type
        # we need to go around this issue by monkey patching it
        import psycopg2.extensions

        org_register_type = psycopg2.extensions.register_type

        def new_register_type(obj, scope=None):
            attached_scope = getattr(scope, '_e_object', scope)
            if attached_scope:
                return org_register_type(obj, attached_scope)
            return org_register_type(obj)

        psycopg2.extensions.register_type = new_register_type
    if module_name == 'sqlite3':
        if hasattr(module.dbapi2.connect, '_e_attached_wrapper'):
            return
        module.dbapi2.connect = Wrapper(module.dbapi2.connect, module_name)
        module.connect = Wrapper(module.connect, module_name)
    elif module_name == 'pg8000':
        if hasattr(module.DBAPI.connect, '_e_attached_wrapper'):
            return
        module.DBAPI.connect = Wrapper(module.DBAPI.connect, module_name)
    else:
        if hasattr(module.connect, '_e_attached_wrapper'):
            return
        module.connect = Wrapper(module.connect, module_name)
def add_timing(module_name, min_duration=0.1):
    module = import_module(module_name)
    if not module:
        return

    class CursorWrapper(object):
        def __init__(self, instance, module_name):
            object.__setattr__(self, '_e_db_module_name', module_name)
            object.__setattr__(self, '_e_db_fetch',
                               general_factory('fetch', module_name))
            object.__setattr__(self, '_e_db_fetchmany',
                               general_factory('fetchmany', module_name))
            object.__setattr__(self, '_e_db_fetchall',
                               general_factory('fetchall', module_name))
            object.__setattr__(self, '_e_db_nextset',
                               general_factory('nextset', module_name))
            object.__setattr__(self, '_e_db_next',
                               general_factory('next', module_name))
            object.__setattr__(self, '_e_db_query',
                               gather_query_factory(module_name))
            object.__setattr__(self, '_e_object', instance)

        #        def callproc(self, *args, **kwargs):
        #            return _e_trace(self._e_db_query, min_duration,
        #                            self._e_object.callproc, *args, **kwargs)

        def execute(self, *args, **kwargs):
            return _e_trace(self._e_db_query, min_duration,
                            self._e_object.execute, *args, **kwargs)

        def executemany(self, *args, **kwargs):
            return _e_trace(self._e_db_query, min_duration,
                            self._e_object.executemany, *args, **kwargs)

        def fetch(self, *args, **kwargs):
            return _e_trace(self._e_db_fetch, min_duration,
                            self._e_object.fetch, *args, **kwargs)

        def fetchmany(self, *args, **kwargs):
            return _e_trace(self._e_db_fetchmany, min_duration,
                            self._e_object.fetchmany, *args, **kwargs)

        def fetchall(self, *args, **kwargs):
            return _e_trace(self._e_db_fetchall, min_duration,
                            self._e_object.fetchall, *args, **kwargs)

        def nextset(self, *args, **kwargs):
            return _e_trace(self._e_db_nextset, min_duration,
                            self._e_object.nextset, *args, **kwargs)

        def next(self, *args, **kwargs):
            return _e_trace(self._e_db_next, min_duration,
                            self._e_object.next, *args, **kwargs)

        def __setattr__(self, name, value):
            return setattr(self._e_object, name, value)

        def __getattr__(self, name):
            return getattr(self._e_object, name)

        def __iter__(self):
            return iter(self._e_object)

        def __call__(self, *args, **kwargs):
            return self._e_object(*args, **kwargs)

    class TimerWrapper(object):

        def __init__(self, instance, module_name):
            # assign to superclass or face the infinite recursion consequences
            object.__setattr__(self, '_e_db_module_name', module_name)
            object.__setattr__(self, '_e_db_commit',
                               general_factory('COMMIT', module_name))
            object.__setattr__(self, '_e_db_rollback',
                               general_factory('ROLLBACK', module_name))
            object.__setattr__(self, '_e_object', instance)

        def cursor(self, *args, **kwargs):
            result = CursorWrapper(self._e_object.cursor(*args, **kwargs),
                                   self._e_db_module_name)
            return result

        def commit(self, *args, **kwargs):
            return _e_trace(self._e_db_commit, min_duration,
                            self._e_object.commit, *args, **kwargs)

        def rollback(self, *args, **kwargs):
            return _e_trace(self._e_db_rollback, min_duration,
                            self._e_object.rollback, *args, **kwargs)

        def __setattr__(self, name, value):
            return setattr(self._e_object, name, value)

        def __getattr__(self, name):
            return getattr(self._e_object, name)

        def __iter__(self):
            return iter(self._e_object)

        def __call__(self, *args, **kwargs):
            return self._e_object(*args, **kwargs)

    class Wrapper(object):

        _e_attached_wrapper = True

        def __init__(self, conn_callable, module_name):
            # assign to superclass or face the infinite recursion consequences
            object.__setattr__(self, '_e_module_name', module_name)
            object.__setattr__(self, '_e_object', conn_callable)
            object.__setattr__(self, '_e_db_connect',
                               general_factory('CONNECT', module_name))

        def __setattr__(self, name, value):
            return setattr(self._e_object, name, value)

        def __getattr__(self, name):
            return getattr(self._e_object, name)

        def __call__(self, *args, **kwargs):
            return TimerWrapper(_e_trace(self._e_db_connect, min_duration/2.0,
                                         self._e_object, *args, **kwargs),
                                self._e_module_name)

    if module_name == 'psycopg2':
        # psycopg2 does a weird type check when someone does
        # psycopg2.extensions.register_type
        # we need to go around this issue by monkey patching it
        import psycopg2.extensions

        org_register_type = psycopg2.extensions.register_type

        def new_register_type(obj, scope=None):
            attached_scope = getattr(scope, '_e_object', scope)
            if attached_scope:
                return org_register_type(obj, attached_scope)
            return org_register_type(obj)

        psycopg2.extensions.register_type = new_register_type
    if module_name == 'sqlite3':
        if hasattr(module.dbapi2.connect, '_e_attached_wrapper'):
            return
        module.dbapi2.connect = Wrapper(module.dbapi2.connect, module_name)
        module.connect = Wrapper(module.connect, module_name)
    elif module_name == 'pg8000':
        if hasattr(module.DBAPI.connect, '_e_attached_wrapper'):
            return
        module.DBAPI.connect = Wrapper(module.DBAPI.connect, module_name)
    else:
        if hasattr(module.connect, '_e_attached_wrapper'):
            return
        module.connect = Wrapper(module.connect, module_name)