Exemple #1
0
def decorate_handlers():
    """
    A function to apply the StatsTool to handlers given in the config
    
    This function must be called after the apps have been mounted to the
    tree, otherwise there will be no config to alter. However normally
    this module is imported before the engine is setup, so that initialising
    functions can be profiled. Therefore this function is hooked to the
    'start' call on the cherrypy bus with a high priority.
    """

    cherrypy.tools.stats = StatsTool()

    # decorate all handlers supplied in config
    stat_logger.info('Wrapping cherrypy handers for stats gathering.')
    try:
        for root in cfg['handlers'].keys():
            if cfg['handlers'][root]:
                for handler in cfg['handlers'][root].split(','):
                    if str(root) == '/': # Can't have empty key in config file
                        root = ''
                    cherrypy.tree.apps[str(root)].merge({str(handler):{'tools.stats.on':True}})
        for root in cfg['ignored_handlers'].keys():
            if cfg['ignored_handlers'][root]:
                for handler in cfg['ignored_handlers'][root].split(','):
                    cherrypy.tree.apps[str(root)].merge({str(handler):{'tools.stats.on':False}})
    except KeyError:
        stat_logger.warning('Stats configuration incorrect. Could not obtain handlers to wrap.')
    except Exception:
        stat_logger.warning('Failed to wrap cherrypy handler for stats profiling.')
def decorate_function(module_str, func_str):
    """
    Takes the string of a module, i.e. "serv.core.some_module.some_function"
    and acquires the actual function (or method) object. It does this by splitting
    the string, importing the root module, recursively uses getattr to acquire
    the submodules. Finally it replaces the object with an instance of StatWrapper
    which wraps that function.

    If the function in question is wrapped with a decorator, the decorator function's
    closure items are scanned for the raw function. This is also used in generating
    the StatWrapper object so that the original, unwrapped functions name and module
    name can be used on the stat record.

    How the function in the argument is imported will affect when this function must be
    called (or rather where this module is imported). If the function is imported like so:
    "import a.b.c"
    then decorate_function can be called at anytime before a.b.c is called, however if it
    is imported like so:
    "from a.b import c"
    then decorate_function must be called after the import, as the import will overwrite
    our instance. Lastly when doing:
    "import a.b.c as d"
    calling decorate_function on d will not work, only a.b.c will work.
    """

    try:
        # import the root
        __import__(module_str)
        module = sys.modules[module_str]

        path = func_str.split('.')

        attribute = path[0]
        function = getattr(module, attribute)
        # loop through the submodules to get their instances
        for attribute in path[1:]:
            module = function
            function = getattr(function, attribute)

        # at this point we need to test if the function is wrapped
        outer_func, inner_func = get_wrapped(function)

        # replace the function instance with a wrapped one.
        setattr(module, attribute, StatWrapper(outer_func, inner_func))
    except Exception:
        stat_logger.warning(
            'Failed to wrap function {0} for stats profiling'.format('.'.join(
                [module_str, func_str])))
        print traceback.print_exc()
def decorate_function(module_str,func_str):
    """
    Takes the string of a module, i.e. "serv.core.some_module.some_function"
    and acquires the actual function (or method) object. It does this by splitting
    the string, importing the root module, recursively uses getattr to acquire
    the submodules. Finally it replaces the object with an instance of StatWrapper
    which wraps that function.

    If the function in question is wrapped with a decorator, the decorator function's
    closure items are scanned for the raw function. This is also used in generating
    the StatWrapper object so that the original, unwrapped functions name and module
    name can be used on the stat record.

    How the function in the argument is imported will affect when this function must be
    called (or rather where this module is imported). If the function is imported like so:
    "import a.b.c"
    then decorate_function can be called at anytime before a.b.c is called, however if it
    is imported like so:
    "from a.b import c"
    then decorate_function must be called after the import, as the import will overwrite
    our instance. Lastly when doing:
    "import a.b.c as d"
    calling decorate_function on d will not work, only a.b.c will work.
    """

    try:
        # import the root
        __import__(module_str)
        module =  sys.modules[module_str]

        path = func_str.split('.')

        attribute = path[0]
        function = getattr(module, attribute)
        # loop through the submodules to get their instances
        for attribute in path[1:]:
            module = function
            function = getattr(function, attribute)

        # at this point we need to test if the function is wrapped
        outer_func, inner_func = get_wrapped(function)
        
        # replace the function instance with a wrapped one.
        setattr(module, attribute, StatWrapper(outer_func, inner_func))
    except Exception:
        stat_logger.warning('Failed to wrap function {0} for stats profiling'.format('.'.join([module_str,func_str])))
        print traceback.print_exc()