class Puppet::Util::Instrumentation

Public Class Methods

[](key) click to toggle source
# File lib/puppet/util/instrumentation.rb, line 134
def self.[](key)
  @listeners[key.intern]
end
[]=(key, value) click to toggle source
# File lib/puppet/util/instrumentation.rb, line 138
def self.[]=(key, value)
  @listeners[key.intern] = value
  rehash
end
clear() click to toggle source
# File lib/puppet/util/instrumentation.rb, line 128
def self.clear
  @listeners = {}
  @listeners_of = {}
  @id = 0
end
each_listener(label) { |l| ... } click to toggle source
# File lib/puppet/util/instrumentation.rb, line 72
def self.each_listener(label)
  @listeners_of[label] ||= @listeners.select do |k,l|
    l.listen_to?(label)
  end.each do |l|
    yield l
  end
end
init() click to toggle source
# File lib/puppet/util/instrumentation.rb, line 120
def self.init
  # let's init our probe indirection
  require 'puppet/util/instrumentation/indirection_probe'
  @listeners ||= {}
  @listeners_of ||= {}
  instance_loader(:listener).loadall
end
instrument(label, data = {}) { || ... } click to toggle source

Triggers an instrumentation

Call this method around the instrumentation point

Puppet::Util::Instrumentation.instrument(:my_long_computation) do
  ... a long computation
end

This will send an event to all the listeners of “my_long_computation”. Note: this method uses ruby yield directive to call the instrumented code. It is usually way slower than calling start and stop directly around the instrumented code. For high traffic code path, it is thus advisable to not use this method.

# File lib/puppet/util/instrumentation.rb, line 35
def self.instrument(label, data = {})
  id = self.start(label, data)
  yield
ensure
  self.stop(label, id, data)
end
new_listener(name, options = {}, &block) click to toggle source

Adds a new listener

Usage:

Puppet::Util::Instrumentation.new_listener(:my_instrumentation, pattern) do

  def notify(label, data)
    ... do something for data...
  end
end

It is possible to use a “pattern”. The listener will be notified only if the pattern match the label of the event. The pattern can be a symbol, a string or a regex. If no pattern is provided, then the listener will be called for every events

# File lib/puppet/util/instrumentation.rb, line 94
def self.new_listener(name, options = {}, &block)
  Puppet.debug "new listener called #{name}"
  name = name.intern
  listener = genclass(name, :hash => instance_hash(:listener), :block => block)
  listener.send(:define_method, :name) do
    name
  end
  subscribe(listener.new, options[:label_pattern], options[:event])
end
publish(label, event, data) click to toggle source
# File lib/puppet/util/instrumentation.rb, line 62
def self.publish(label, event, data)
  each_listener(label) do |k,l|
    l.notify(label, event, data)
  end
end
start(label, data) click to toggle source

Triggers a “start” instrumentation event

Important note:

For proper use, the data hash instance used for start should also
be used when calling stop. The idea is to use the current scope
where start is called to retain a reference to 'data' so that it is possible
to send it back to stop.
This way listeners can match start and stop events more easily.
# File lib/puppet/util/instrumentation.rb, line 50
def self.start(label, data)
  data[:started] = Time.now
  publish(label, :start, data)
  data[:id] = next_id
end
stop(label, id, data) click to toggle source

Triggers a “stop” instrumentation event

# File lib/puppet/util/instrumentation.rb, line 57
def self.stop(label, id, data)
  data[:finished] = Time.now
  publish(label, :stop, data)
end
subscribe(listener, label_pattern, event) click to toggle source
# File lib/puppet/util/instrumentation.rb, line 104
def self.subscribe(listener, label_pattern, event)
  raise "Listener #{listener.name} is already subscribed" if @listeners.include?(listener.name)
  Puppet.debug "registering instrumentation listener #{listener.name}"
  @listeners[listener.name] = Listener.new(listener, label_pattern, event)
  listener.subscribed if listener.respond_to?(:subscribed)
  rehash
end
unsubscribe(listener) click to toggle source
# File lib/puppet/util/instrumentation.rb, line 112
def self.unsubscribe(listener)
  Puppet.warning("#{listener.name} hasn't been registered but asked to be unregistered") unless @listeners.include?(listener.name)
  Puppet.info "unregistering instrumentation listener #{listener.name}"
  @listeners.delete(listener.name)
  listener.unsubscribed if listener.respond_to?(:unsubscribed)
  rehash
end