예제 #1
0
파일: config.py 프로젝트: klmitch/tach
    def __init__(self, config, label, items):
        """Initialize a method wrapped with metric collection.

        :param config: The global configuration.
        :param label: The label to use to identify the notifier.
        :param items: A list of key, value pairs giving the
                      configuration for setting up the notifier.
        """

        self.config = config
        self.default = False
        self._driver = None
        self._driver_cache = None
        self.additional = {}

        self.label = label.partition(':')[-1]
        if not self.label:
            # No label makes this the default
            self.default = True

        # Process configuration
        for option, value in items:
            if option == 'driver':
                self._driver = utils.import_class_or_module(value)

            # Other options go into additional
            else:
                self.additional[option] = value

        # Default driver to the print notifier
        if not self._driver:
            self._driver = notifiers.PrintNotifier
예제 #2
0
    def __init__(self, config, label, items):
        """Initialize a method wrapped with metric collection.

        :param config: The global configuration.
        :param label: The label to use to identify the notifier.
        :param items: A list of key, value pairs giving the
                      configuration for setting up the notifier.
        """

        self.config = config
        self.default = False
        self._driver = None
        self._driver_cache = None
        self.additional = {}

        self.label = label.partition(':')[-1]
        if not self.label:
            # No label makes this the default
            self.default = True

        # Process configuration
        for option, value in items:
            if option == 'driver':
                self._driver = utils.import_class_or_module(value)

            # Other options go into additional
            else:
                self.additional[option] = value

        # Default driver to the print notifier
        if not self._driver:
            self._driver = notifiers.PrintNotifier
예제 #3
0
파일: config.py 프로젝트: klmitch/tach
    def metric(self):
        """Return an initialized statistic object."""

        if not self._metric_cache:
            # Select an appropriate statistic
            cls = utils.import_class_or_module(self._metric)
            self._metric_cache = cls(self.additional)

        return self._metric_cache
예제 #4
0
    def __init__(self, config):
        """Initialize the notifier from the configuration."""

        # First, figure out the real notifier
        self.driver_name = config['real_driver']

        # Get the class and instantiate it
        cls = utils.import_class_or_module(self.driver_name)
        self.driver = cls(config)
예제 #5
0
파일: notifiers.py 프로젝트: klmitch/tach
    def __init__(self, config):
        """Initialize the notifier from the configuration."""

        # First, figure out the real notifier
        self.driver_name = config['real_driver']

        # Get the class and instantiate it
        cls = utils.import_class_or_module(self.driver_name)
        self.driver = cls(config)
예제 #6
0
    def metric(self):
        """Return an initialized statistic object."""

        if not self._metric_cache:
            # Select an appropriate statistic
            cls = utils.import_class_or_module(self._metric)
            self._metric_cache = cls(self.additional)

        return self._metric_cache
예제 #7
0
파일: metrics.py 프로젝트: klmitch/tach
    def __init__(self, config):
        """Initialize the metric from the configuration."""

        # First, figure out the real metric
        self.metric_name = config['real_metric']

        # Get the class and instantiate it
        cls = utils.import_class_or_module(self.metric_name)
        self.metric = cls(config)
        self.vtype = self.metric.vtype
예제 #8
0
파일: config.py 프로젝트: klmitch/tach
    def app(self):
        """Return the application transformer."""
        # Don't crash if we don't have an app set
        if not self._app or not self._app_helper:
            return None

        if not self._app_cache:
            app_cls = utils.import_class_or_module(self._app_helper)
            self._app_cache = getattr(app_cls, self._app)

        return self._app_cache
예제 #9
0
    def __init__(self, config):
        """Initialize the metric from the configuration."""
        super(DebugMetric, self).__init__(config)

        # First, figure out the real metric
        self.metric_name = config['real_metric']

        # Get the class and instantiate it
        cls = utils.import_class_or_module(self.metric_name)
        self.metric = cls(config)
        self.vtype = self.metric.vtype
예제 #10
0
    def app(self):
        """Return the application transformer."""

        # Don't crash if we don't have an app set
        if not self._app or not self._app_helper:
            return None

        if not self._app_cache:
            app_cls = utils.import_class_or_module(self._app_helper)
            self._app_cache = getattr(app_cls, self._app)

        return self._app_cache
예제 #11
0
파일: config.py 프로젝트: klmitch/tach
    def __init__(self, config, label, items, **kwargs):
        """Initialize a method wrapped with metric collection.

        :param config: The global configuration; needed for the
                       notifier.
        :param label: The label to use when reporting the collected
                      statistic.
        :param items: A list of key, value pairs giving the
                      configuration for setting up the method wrapper.
        """

        self.config = config
        self.label = label
        self._app_cache = None
        self._metric_cache = None
        self._app_helper = kwargs.get('app_helper')

        # Other important configuration values
        required = set(['module', 'method', 'metric'])
        attrs = set(['notifier', 'app']) | required
        for attr in attrs:
            setattr(self, '_' + attr, None)
        self.additional = {}

        # Process configuration
        for option, value in items:
            if option in attrs:
                setattr(self, '_' + option, value)
                required.discard(option)
            else:
                self.additional[option] = value

            # Add app to required if necessary
            if option == 'app' and not self._app_helper:
                required.add('app_helper')

        # Make sure we got the essential configuration
        if required:
            raise Exception("Missing configuration options for %s: %s" %
                            (label, ', '.join(required)))

        # Grab the method we're operating on
        method_cls = utils.import_class_or_module(self._module)
        if inspect.ismodule(method_cls):
            method = raw_method = getattr(method_cls, self._method)
            kind = 'function'
        else:
            method, raw_method, kind = _get_method(method_cls, self._method)
        self._method_cache = method

        # We need to wrap the replacement if its a static or class
        # method
        if kind == 'static method':
            meth_wrap = staticmethod
        elif kind == 'class method':
            meth_wrap = classmethod
        else:
            meth_wrap = lambda f: f

        # Wrap the method to perform statistics collection
        @functools.wraps(method)
        def wrapper(*args, **kwargs):
            # Deal with class method calling conventions
            if kind == 'class method':
                args = args[1:]

            # Handle app translation
            label = None
            if self._app:
                args, kwargs, label = self.app(*args, **kwargs)

            # Run the method, bracketing with statistics collection
            # and notification
            value = self.metric.start()
            result = method(*args, **kwargs)
            self.notifier(self.metric(value), self.metric.vtype,
                          label or self.label)

            return result
        # Save some introspecting data
        wrapper.tach_descriptor = self
        wrapper.tach_function = method

        # Save what we need
        self._method_cls = method_cls
        self._method_wrapper = meth_wrap(wrapper)
        self._method_orig = raw_method

        setattr(self._method_cls, self._method, self._method_wrapper)
예제 #12
0
    def __init__(self, config, label, items, **kwargs):
        """Initialize a method wrapped with metric collection.

        :param config: The global configuration; needed for the
                       notifier.
        :param label: The label to use when reporting the collected
                      statistic.
        :param items: A list of key, value pairs giving the
                      configuration for setting up the method wrapper.
        """

        self.config = config
        self.label = label
        self._app_cache = None
        self._post_app_cache = None
        self._metric_cache = None
        self._app_helper = kwargs.get('app_helper')

        # Other important configuration values
        required = set(['module', 'method', 'metric'])
        attrs = set(['notifier', 'app', 'post_app']) | required

        # if there's a global helper set, we don't require a local one
        if not self._app_helper:
            attrs.add('app_helper')

        for attr in attrs:
            setattr(self, '_' + attr, None)
        self.additional = {}

        # Process configuration
        for option, value in items:
            if option in attrs:
                setattr(self, '_' + option, value)
                required.discard(option)
            else:
                self.additional[option] = value

            # Add app to required if necessary
            if option == 'app' and not self._app_helper:
                required.add('app_helper')

        # Make sure we got the essential configuration
        if required:
            raise Exception("Missing configuration options for %s: %s" %
                            (label, ', '.join(required)))

        # Grab the method we're operating on
        method_cls = utils.import_class_or_module(self._module)
        if inspect.ismodule(method_cls):
            that_method = raw_method = getattr(method_cls, self._method)
            kind = 'function'
        else:
            that_method, raw_method, kind = _get_method(
                method_cls, self._method)
        self._method_cache = that_method

        # We need to wrap the replacement if it's a static or class
        # method
        if kind == 'static method':
            meth_wrap = staticmethod
        elif kind == 'class method':
            meth_wrap = classmethod
        else:
            meth_wrap = lambda f: f

        # Wrap the method to perform statistics collection
        @functools.wraps(that_method)
        def wrapper(*args, **kwargs):
            # Deal with class method calling conventions
            if kind == 'class method':
                args = args[1:]

            # Handle app translation
            label = None
            if self._app:
                args, kwargs, label = self.app(*args, **kwargs)

            # Run the method, bracketing with statistics collection
            # and notification
            if self.metric.bump_transaction_id:
                self.notifier.bump_transaction_id()
            value = self.metric.start()
            result = that_method(*args, **kwargs)

            if self._post_app:
                result, label = self.post_app(result, *args, **kwargs)

            self.notifier(self.metric(value), self.metric.vtype, label
                          or self.label)

            return result

        # Save some introspecting data
        wrapper.tach_descriptor = self
        wrapper.tach_function = that_method

        # Save what we need
        self._method_cls = method_cls
        self._method_wrapper = meth_wrap(wrapper)
        self._method_orig = raw_method

        setattr(self._method_cls, self._method, self._method_wrapper)