Metric configuration and plugin architecture

37 views
Skip to first unread message

Benjamin Fleischer

unread,
Jul 17, 2013, 10:25:35 AM7/17/13
to metr...@googlegroups.com
Hey all-

We're moving forward on MetricFu modularity, and separating concerns.  One major feature on that path is making each metric self-contained.  Each metric needs to know how to configure itself.  In order to make plugins possible, MetricFu should know about configured plugins.

I have a work-in-progress PR right now that is a first step in that direction. https://github.com/metricfu/metric_fu/pull/91  Each metric has a class that subclasses MetricFu::Metric. MetricFu::Metric has an inherited hook that collects all its subclasses, which means it knows about all configured metrics.

Right now, it knows its name, its run options, whether it has a graph, and some limited information about when it can be enabled.  I'm following in how Pry has for each plugin an 'activated' and 'enabled' attribute.  Enabled plugins are used by Pry.  Activated means that their libraries have been required.  So, a library can be activated, but not enabled.

# Encapsulates the configuration options for each metric
module MetricFu
  class Metric

    attr_accessor :enabled

    def initialize
      self.enabled = false
    end

    def enable
      self.enabled = true
    end

    # @return metric name [Symbol]
    def metric_name
      not_implemented
    end

    # @return metric run options [Hash]
    def run_options
      not_implemented
    end

    # @return metric_options [Hash]
    def has_graph?
      not_implemented
    end

    @metrics = []
    # @return all subclassed metrics [Array<MetricFu::Metric>]
    def self.metrics
      @metrics
    end

    def self.get_metric(metric_name)
      metrics.find{|metric|metric.metric_name.to_s == metric_name.to_s}
    end

    def self.inherited(subclass)
      @metrics << subclass.new
    end

    private

    def not_implemented
      raise "Required method #{caller[0]} not implemented in #{__FILE__}"
    end
  end
end

I think the following are all the things the metric should know about itself

* metric_name
* run_options
* graph_options for bluff and gchart
* its templates for html, yaml, etc output
* whether it is activated
* whether it is enabled. There is an 'enable' method that encapsulates logic that prevents enabled such as something like
    def enable
      if MetricFu.configuration.mri?
        super
      else
        MetricFu.configuration.mf_debug("Cane is only available in MRI. It requires ripper")
      end
    end
* -> it should know about its environment so it can make decisions based on it. We'll have an environment class that knows the ruby engine(cruby,jruby etc), the ruby version, if there's ripper support, if there's a rails project, cruise control?, etc
* Its hotspots configuration, how it identifies and weights problems
* Error handling?


Thoughts?

-Benjamin

Robin Curry

unread,
Jul 17, 2013, 2:46:44 PM7/17/13
to metr...@googlegroups.com, benj...@benjaminfleischer.com
I like this Benjamin. It will be *really* nice to be able to configure and plugin metrics. Huge wins! The only thing here I'm not sure about is the metric knowing about templating/graphing stuff. 

What about taking more of a statsd type approach - each metric just provides its bucket(s) of stats and doesn't need to know about how to create a graph or format the data? Looking at the various graph classes, it seems like for the most part they are all similar - provide the data or sets of data and the associated labels to the graphing library. What if the metric provided those things instead, and let the various formatters decide how to display/graph?

Benjamin Fleischer

unread,
Jul 17, 2013, 3:02:26 PM7/17/13
to metr...@googlegroups.com
On Wed, Jul 17, 2013 at 1:46 PM, Robin Curry <robin...@gmail.com> wrote:
The only thing here I'm not sure about is the metric knowing about templating/graphing stuff. 

Looking at the various graph classes, it seems like for the most part they are all similar - provide the data or sets of data and the associated labels to the graphing library. What if the metric provided those things instead, and let the various formatters decide how to display/graph?

Yes, that's what I'd like, as well.  Unfortunately, there are some configurations that are graph-specific, so, in the meantime, I'd like each MetricFu::Metric to be able to answer questions other parts of MetricFu ask it. 

What are your run_options? What are your data? What are your graph_options? How do you weight your problem/data for hotspots? Are you enabled? Are you activated? What are your templates? But have sane fallbacks if a MetricFu::Metric subclass isn't specially configured for some of these. 

I don't want it to have to tell MetricFu anything. The same for almost every part of the configuration class: metrics, environment stuff, graph stuff, io stuff.  Right now, too much of the library knows too much about how Configuration works.

-Benjamin

Dan Mayer

unread,
Jul 27, 2013, 11:49:49 AM7/27/13
to metric_fu
Nice this looks like a big step forward in terms of making things more configurable. I really like the approach you are taking from Pry. 

As you build plugins I would try to think about how to have a common error reporting structure. So that when errors occur with a given metric they can send that back to metric_fu in a way it can not generate graphs etc, but in the output list that metric along with any error information the metric can provide. 

Dan

--
You received this message because you are subscribed to the Google Groups "metric_fu" group.
To unsubscribe from this group and stop receiving emails from it, send an email to metric_fu+...@googlegroups.com.
To post to this group, send email to metr...@googlegroups.com.
Visit this group at http://groups.google.com/group/metric_fu.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages