double-z
4/6/2012 - 8:00 AM

Real-time Chef events, a la http://www.devco.net/archives/2011/07/03/real_time_puppet_events_and_network_wide_callbacks.php

# mcollective plugin: agent/chef_reporter.rb
#
# Produces a logfile like:
# 2011-08-29T14:32:58+01:00 service[nrpe] ran enable (resource updated?: false)
# 2011-08-29T14:32:58+01:00 remote_directory[/usr/lib/nagios/plugins] ran create (resource updated?: true)
# 2011-08-29T14:32:58+01:00 template[/etc/nagios/nrpe.cfg] ran create (resource updated?: false)

module MCollective
  module Agent
    class Chef_reporter<RPC::Agent
      def log_action_action
        dir = "/var/tmp/mcollective-chef"
        FileUtils.mkdir_p(dir) unless File.directory?(dir)
        File.open("#{dir}/#{request.sender}", 'a') do |f|
          f.write("%s %s ran %s (resource updated?: %s)\n" %
                  [ DateTime.now.to_s,
                    request[:msg][:resource],
                    request[:msg][:action],
                    request[:msg][:updated?],
                  ])
        end
        nil
      end
    end
  end
end
# cookbooks/chef_notifier/libraries/chef_notifier.rb
#
# This monkeypatches Chef::Runner to report the result of run_action calls via MCollective

require 'mcollective'

class MRPC
  include MCollective::RPC
  def report_action(resource, action)
    options =  MCollective::Util.default_options
    mc = rpcclient("chef_reporter", {:options => options})
    reqid = mc.log_action(
                          :msg => {
                            :resource => "#{resource}",
                            :action   => "#{action}",
                            :updated? => "#{resource.updated_by_last_action?}",
                          },
                          :process_results => false)
    Chef::Log.debug "Sent status to MCollective with reqid #{reqid}"
    mc.disconnect                      
  end
end

class Chef
  class Runner
    alias_method :run_action_original, :run_action
    def run_action(resource, action)
      Chef::Log.debug "Wrapping run_action on #{resource} with MRPC.report_action"
      run_action_original(resource, action)
      MRPC.new.report_action(resource, action)
    end
  end
end