On 25/02/11 20:46, Luke Kanies wrote:
> On Feb 25, 2011, at 11:24 AM, Brice Figureau wrote:
> 
>> On 25/02/11 18:29, Markus Roberts wrote:
>>> 
>>> There's also a 3rd thing I didn't started working on: allow the
>>> code to set probes dynamically (instead of statistically adding
>>> them by modifying puppet code). I don't know if ruby versatility
>>> can allow this, but I'd love to be able to instance_eval { ...
>>> add probes around a method ... } to a given live puppet
>>> instance/class fully dynamically (that would be completely
>>> crazy).
>>> 
>>> 
>>> This is in fact fairly easy to do, though you're right that it's 
>>> completely crazy.  :)
>>> 
>>> Suppose we have an array x and we want to do something with it's
>>> length (negate it here, but presumably we'd be doing something
>>> more useful like recording it or something):
>>> 
>>> irb(main)> x = [1,2,3] => [1,2,3] irb(main)> unless x.respond_to?
>>> :brice_wrapped_length irb(main)>   class <<x irb(main)>     alias
>>> brice_wrapped_length length irb(main)>     def length irb(main)>
>>> -brice_wrapped_length irb(main)>     end irb(main)>   end 
>>> irb(main)> end => nil irb(main)> x.length => -3 irb(main)> x <<
>>> :foo => [1, 2, 3, :foo] irb(main)> x.length => -4
>>> 
>>> Note that this only affects the one object; other arrays aren't
>>> touched:
>>> 
>>> irb(main)> y = [:a,:b] [:a,:b] irb(main)> y.length 2
>>> 
>>> The unless part is important to prevent instrumenting the same
>>> object twice, which will cause it to hang (and eventually stack
>>> overflow).  To remove the instrumentation, just reverse
>>> everything (if instead of unless, alias the other way, and then
>>> remove brice_wrapped_length).
>> 
>> Thanks for the example. This is quite interesting and opens the
>> door to a lot of strange things :)
>> 
>> I was thinking about allowing the user to describe probes by
>> specifying a puppet class and a method through an indirection to
>> control probes (like in "Puppet::Indirector::Indirection.find"),
>> then I'd do something (completely untested):
>> 
>> method = "find" klass_name = "Puppet::Indirector::Indirection" 
>> require klass_name.split('::').map { |n| n.downcase }.join('/')
>> 
>> klass = klass_name.split('::').inject(Puppet) { |p,c|
>> p.const_get(c) } klass.class_eval do alias "instr_#{method}"
>> method define_method(method, *args) do # here call to
>> instrumentation send("instr_#{method}", args) ensure # here wrap up
>> instrumentation end end
>> 
>> Then I hope, somewhere else, someone calling
>> Puppet::Something.find (provided Something uses the indirector of
>> course), then it would call my programmatic redifinition of
>> "find"...
>> 
>> This will be a funny week-end if that proves to work :)
> 
> I think this basic model is sound, and is roughly what I'd do.
> 
> You could also have a builtin system to allow classes to specify
> which methods should normally be probed.  E.g., create a module that
> essentially does this:
> 
> module Probable
>   PROBABLE_CLASSES = []
> 
>   class Probe
>     def initialize(method, klass, type)
>     ...
>     end
>     def enable
>       ...do the alias method switcheroo here
>     end
>   end
>   def define_probe(name, type = :time)
>     @probes << probe.new(name, self.class, type)
>     PROBABLE_CLASSES << self.class
>   end
> 
>   def self.enable_probes
>     PROBABLE_CLASSES.each do |klass|
>       klass.probes.each { |probe| probe.enable }
>     end
>   end
> end

OK, I see.
I was planning to insert some of the probe manually (one of the best
target is the indirection various verbs) and allow any other to be
dynamically set, but your scheme seems better.

> Obviously not really a great design per se, but as a general idea, it
> would allow any class to define what were most likely to be the
> appropriate probes, so that turning probes on for the system should
> result in the best data.  I like the idea of being able to manually
> enable probes through your command-line interface ideas, too, but I
> think the system should ship with a bunch of these out of the box.

The system currently designed is dual-fold: on one side you can enable
probes, and on the other side there are probe listeners (which are
loadable plugins). Those listeners can also be enabled on-demand and can
be targeted to some 'events' (events are fired by the probes when they
are reached).
I hope to have the time to finish the patch this week-end :)
-- 
Brice Figureau
My Blog: http://www.masterzen.fr/

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to