Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New SENSU handling added to "contacts" #199

Merged
merged 8 commits into from Jan 30, 2015
1 change: 1 addition & 0 deletions lib/god.rb
Expand Up @@ -95,6 +95,7 @@ def load_contact(name)
load_contact(:webhook)
load_contact(:airbrake)
load_contact(:slack)
load_contact(:sensu)

$:.unshift File.join(File.dirname(__FILE__), *%w[.. ext god])

Expand Down
57 changes: 57 additions & 0 deletions lib/god/contacts/sensu.rb
@@ -0,0 +1,57 @@
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Send a notice to a SENSU client socket, port 3030 on 'localhost' only.
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# [mandatory]
# check_name - a unique check name
#
# [optional]
# status_code - status codes used are 0 for OK, 1 for WARNING, 2 for CRITICAL, and 3 or greater to indicate UNKNOWN or CUSTOM.
# handler - default handler
#

CONTACT_DEPS[:sensu] = ['json']
CONTACT_DEPS[:sensu].each do |d|
require d
end

module God
module Contacts

class Sensu < Contact
class << self
attr_accessor :check_name, :status_code, :handler, :host, :port
end

self.status_code = 2
self.handler = 'default'
self.host = 'localhost'
self.port = 3030

def valid?
valid = true
valid &= complain("Attribute 'check_name' must be specified", self) unless arg(:check_name)
valid
end

attr_accessor :check_name, :status_code, :handler, :host, :port

def sensu_client_socket(msg)
u = UDPSocket.new
u.send(msg + "\n", 0, arg(:host).nil? ? self.host : arg(:host), arg(:port).nil? ? self.port : arg(:port))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll want to close the UDPSocket once you're done using it to prevent leaking sockets.

end

def notify(message, time, priority, category, host)
data = {
:category => category,
:message => message,
:priority => priority,
:host => host,
:time => time,
}
parcel = { 'name' => eval("\"" + arg(:check_name) + "\""), 'status' => arg(:status_code).nil? ? self.status_code : arg(:status_code), 'output' => data.to_json, 'handler' => arg(:handler).empty? ? self.handler : arg(:handler) }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry but I didn't notice this eval before. Can you give me more details as to why this is needed? I'm pretty worried about having evals floating around. Is there a way we could do this without an eval?

sensu_client_socket parcel.to_json
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the message is sent, update self.info = with a status like this in lib/god/contacts/hipchat.rb

end
end
end
end

12 changes: 12 additions & 0 deletions test/test_sensu.rb
@@ -0,0 +1,12 @@
#!/usr/bin/env ruby
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The #! line shouldn't be necessary.

require File.dirname(__FILE__) + '/helper'

class TestSensu < Test::Unit::TestCase
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using minitest for this project, so you'll need to change Test::Unit::TestCase to Minitest::Test.

def test_sensu_notify
sensu = God::Contacts::Sensu.new
sensu.check_name = "TestSensuContact"

sensu.notify("Test", Time.now, "Test", "Test", "")
assert_equal "sent sensu #{sensu.check_name} notification with status code #{sensu.status_code}", "sent sensu #{sensu.check_name} notification with status code #{sensu.status_code}"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of this assert_equal, you can use a mock before calling sensu.notify() to ensure that the right thing is sent to UDPSocket:

    UDPSocket.any_instance.expects(:send)
    sensu.notify("Test", Time.now, "Test", "Test", "")

end
end