Skip to content

Instantly share code, notes, and snippets.

@jhmartin
Forked from steveberryman/hipchat-extension.rb
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhmartin/c43d63bb2e3780c651de to your computer and use it in GitHub Desktop.
Save jhmartin/c43d63bb2e3780c651de to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'rubygems' if RUBY_VERSION < '1.9.0'
require 'sensu-handler'
require 'hipchat'
require 'timeout'
require 'oj'
module Sensu::Extension
class Hipchat < Handler # Sub-class the appropriate extension type
def filter_disabled
bail 'alert disabled' if @event['check']['alert'] == false
end
def filter
# filter_disabled
filter_repeated
# filter_silenced
# filter_dependencies
end
def filter_repeated
defaults = {
'occurrences' => 1,
'interval' => 30,
'refresh' => 1800
}
if @settings['sensu_plugin'].is_a?(Hash)
defaults.merge!(@settings['sensu_plugin'])
end
occurrences = (@event['check']['occurrences'] || defaults['occurrences']).to_i
interval = (@event['check']['interval'] || defaults['interval']).to_i
if @event['occurrences'] < occurrences
@event['check']['status'] = 5
end
if @event['occurrences'] > occurrences && @event['action'] == 'create'
number = refresh.fdiv(interval).to_i
unless number == 0 || @event['occurrences'] % number == 0
@event['check']['status'] = 5
end
end
end
def filter_silenced
stashes = [
['client', '/silence/' + @event['client']['name']],
['check', '/silence/' + @event['client']['name'] + '/' + @event['check']['name']],
['check', '/silence/all/' + @event['check']['name']]
]
stashes.each do |(scope, path)|
begin
timeout(2) do
if stash_exists?(path)
bail scope + ' alerts silenced'
end
end
rescue Timeout::Error
puts 'timed out while attempting to query the sensu api for a stash'
end
end
end
def filter_dependencies
if @event['check'].key?('dependencies')
if @event['check']['dependencies'].is_a?(Array)
@event['check']['dependencies'].each do |dependency|
begin
timeout(2) do
check, client = dependency.split('/').reverse
if event_exists?(client || @event['client']['name'], check)
bail 'check dependency event exists'
end
end
rescue Timeout::Error
puts 'timed out while attempting to query the sensu api for an event'
end
end
end
end
end
def event_name
@event['client']['name'] + '/' + @event['check']['name']
end
def initialize
@event = nil
end
# The post_init hook is called after the main event loop has started
# At this time EventMachine is available for interaction.
def post_init
end
# Must at a minimum define type and name. These are used by
# Sensu during extension initialization.
def definition
{
:type => 'extension', # Always.
:name => 'hipchat', # Usually just class name lower case.
}
end
# Simple accessor for the extension's name. You could put a different
# value here that is slightly more descriptive, or you could simply
# refer to the definition name.
def name
definition[:name]
end
# A simple, brief description of the extension's function.
def description
'Hipchat extension. Because otherwise the sensu server will forking die.'
end
def send_hipchat(room, from, message, color, _notify)
apiversion = @settings['hipchat']['apiversion'] || 'v1'
apikey = @settings['hipchat']['apikey']
hipchatmsg = HipChat::Client.new(apikey, :api_version => apiversion)
begin
timeout(3) do
hipchatmsg[room].send(from, "#{message}.", :color => color, :notify => false)
# hipchatmsg[room].send(from, "#{message}.", :color => @event['check']['status'] == 1 ? 'yellow' : 'red', :notify
end
rescue Timeout::Error
"Timed out while attempting to message #{room} [#{message}]"
end
end
# run() is passed a copy of the event_data hash
# for more information, see links below.
def run(event_data)
@event = Oj.load(event_data)
filter
resolved = true if @event['action'].eql?('resolve')
if resolved or [1, 2, 3].include?(@event['check']['status'])
room = @event['check']['hipchat_room'] || @settings['hipchat']['room']
from = @event['check']['hipchat_from'] || @settings['hipchat']['from'] || 'Sensu'
client = @event['client']
client_name = @event['source'] || client['name']
check = @event['check']
check_name = check['name']
state = check['status']
output = check['notification'] || check['output']
status_msg = resolved ? '[RESOLVED]' : '[PROBLEM]'
if state == 0
state_msg = 'OK'
color = 'green'
notify = true
elsif state == 1
state_msg = 'WARNING'
color = 'yellow'
notify = true
elsif state == 2
state_msg = 'CRITICAL'
color = 'red'
notify = true
else
state_msg = 'UNKNOWN'
color = 'gray'
notify = false
end
# If the playbook attribute exists and is a URL, "[<a href='url'>playbook</a>]" will be output.
# To control the link name, set the playbook value to the HTML output you would like.
if check['playbook']
begin
uri = URI.parse(check['playbook'])
if %w( http https ).include?(uri.scheme)
playbook = "[<a href='#{@event['check']['playbook']}'>Playbook</a>]"
else
playbook = "[Playbook: #{@event['check']['playbook']}]"
end
rescue
playbook = "[Playbook: #{@event['check']['playbook']}]"
end
end
occurrences = @event['occurrences']
message = "#{status_msg} #{client_name}/#{check_name}:#{occurrences} - #{state_msg}: #{output} #{playbook}"
operation = proc {
send_hipchat(room, from, message, color, notify)
}
callback = proc do|result|
"Hipchat message: #{result}"
end
EM.defer(operation, callback)
yield 'Sent an event to Hipchat', 0
end
end
# Called when Sensu begins to shutdown.
def stop
yield
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment