As a modern system we need St. Ruby (Ragios) to be able to tweet alerts to system admins and web masters when a test fails.
To do this, first we need to create and register an App on Twitter. This is the App that Ragios will use to tweet the alerts. So we create and register a twitter app from here: http://twitter.com/apps/new. After we register the App, Twitter will give us a consumer_key and a consumer_secret. We will need this later.
Next we need to create a new twitter account for the Ragios system. This is the Twitter account that will tweet the alerts. To receive the tweets the system admin should follow this account. Of course this account should be set to private on twitter.
After we create the account, we need to grant our twitter app access to it. Lets write a script to do that.
We need the oauth ruby gem.
sudo gem install oauth
This ruby script will do the trick;
twitter_auth.rb
#!/usr/bin/ruby require 'rubygems' require 'oauth' consumer = OAuth::Consumer.new( 'consumer key', 'consumer secret', {:site => 'http://twitter.com'} ) request_token = consumer.get_request_token puts "Twitter App Authorize URL \n" + request_token.authorize_url puts "Enter PIN:" pin = STDIN.readline.chomp access_token = request_token.get_access_token(:oauth_verifier => pin) puts "access token: " + access_token.token puts "access secret: " + access_token.secret
We use the ‘consumer_key’ and ‘consumer secret’ Twitter generated for our app. We need this to create a request_token which gives us an authorization URL. This is the URL which we use to ALLOW or DENY, the Twitter App access to the twitter account that will tweet the alerts.
The script will display the authorization URL for our App. Open this URL on a browser and click ALLOW to grant access. Twitter will give you a PIN number. Enter that PIN number on the prompt. This PIN number is our oauth_verifier which is used to generate the access_token.
The access_token and access_secret is all we need to gain read and write access to the twitter account. So we don’t need a twitter username and password to access the account. Thats the fun in using oauth. We need to save the access_token and access_secret somewhere to use later for tweeting.
This script from BeefyApps Blog, Simple Ruby OAuth with Twitter and this great post OAuth Explained and What It Is Good For, saved me a lot of trouble.
Now lets write a simple ruby script that tweets.
We need the twitter ruby gem;
sudo gem install twitter
Sample script 1:
For twitter gem v1.0 and above
tweet.rb
#!/usr/bin/ruby require 'rubygems' require 'twitter' Twitter.configure do |config| config.consumer_key = 'Consumer Key' config.consumer_secret = 'Consumer secret' config.oauth_token = 'access token' config.oauth_token_secret = 'access secret' end Twitter.update("first tweet, this is a test")
We use the same ‘Consumer Key’ and ‘Consumer secret’ that Twitter generated for our App. We also use the ‘access token’ and ‘access secret’ we generated in the twitter_auth.rb script. The last line of the tweet.rb script will tweet the test message.
Sample script 2;
For twitter gem pre v1.0
[Edit March 13,2011] The code below only works with twitter gem below version 1.0. It doesn’t work with twitter gem version 1.0+ Thanks to @pablochacin for pointing this out in the comments. Note: Ragios uses twitter gem v0.9.12.
tweet1.rb
#!/usr/bin/ruby require 'rubygems' require 'twitter' oauth = Twitter::OAuth.new('Consumer Key', 'Consumer secret') oauth.authorize_from_access('access token', 'access secret') client = Twitter::Base.new(oauth) client.update('first tweet, this is a test')
Now lets add Tweet Alerts to our Ragios System
First, we need to create a new Class that knows how to tweet. This class will hide the dirty details of tweeting from the rest of the system.
#this class hides the messy details of tweeting from rest of the system class Tweet def initialize oauth = Twitter::OAuth.new('Consumer Key', 'Consumer secret') oauth.authorize_from_access('access token', 'access secret') @client = Twitter::Base.new(oauth) end def tweet message @client.update(message) end end
Note: I have changed the Naming convention for Ragios to use CamelCase for Class names and more_like_this for method names. Thanks to great tips here “Little Known Ways to Ruby Mastery by Jamie van Dyke”
Next we need to add a tweet_alert method to the SystemMonitor Class.
The tweet_alert method
def tweet_alert Tweet.new.tweet @test_description + " FAILED! " + @describe_test_result + " = " + @test_result + " Created on: " + Time.now.to_s end
The tweet_alert method is invoked by the failed method. The system admin can choose to use tweet alerts or email alerts by editing the failed method.
#defines the action to take when a test fails #- May send email, SMS or tweet to the system admin #- May also take action to fix the issue like restart a process/service def failed tweet_alert #email_alert end
In the above sample, the System will send out a tweet when a test fails.
New SystemMonitor Class with the tweet_alert method
#base class that defines the behavior of all system monitors class SystemMonitor # a short description of the test performed by this system monitor attr_reader :test_description #hostname of the system being monitored attr_reader :hostname #ip address of the system being monitored attr_reader :address #email address of admin to contact when a test fails attr_reader :contact #results of a test attr_reader :test_result #describes the test result, this gives technical details on the test_result #This gives the sysadmin info on the technical details of the test results attr_reader :describe_test_result def initialize end #defines the tests to run on a system def test_command end #defines the action to take when a test fails #- May send email, SMS or tweet to the system admin #- May also take action to fix the issue like restart a process/service def failed tweet_alert #email_alert end def tweet_alert Tweet.new.tweet @test_description + " FAILED! " + @describe_test_result + " = " + @test_result + " Created on: "+ Time.now.to_s end def email_alert puts 'sending mail alert...' Pony.mail :to => @contact, :from => 'Ragios', :subject => @test_description + " FAILED", :body => @test_description + " FAILED \n\n" + @describe_test_result + " = " + @test_result + "\n\n Created on: " + Time.now.to_s end end
Now lets test the system with a sample test, that monitors my website and alerts me (by posting a tweet) when the site is down.
This is the sample test. (The code is explained in more detail here)
#defines how services will be monitored class Service < SystemMonitor def initialize super end end #monitors a webpage to check if the site is loading #PASSED if it gets a HTTP 200 Response status code from the website class TestWebpageForHttp200 < Service attr_reader :test_url def initialize @contact = "obi@mail.com" @describe_test_result = "HTTP Request to " + @test_url super end #returns true when http request to test_url returns a 200 OK Response def test_command response = Net::HTTP.get_response(URI.parse(test_url)) @test_result = response.code if response.code != "200" return FALSE else return TRUE end end end class TestMySite < TestWebpageForHttp200 def initialize @test_description = "My Website Test" @test_url = "http://www.whisperservers.com/blog/" super end end
When this test fails the system will tweet a message like this;
My Website Test FAILED! HTTP Request to http://www.whisperservers.com/blog/ = 500 Created on: Wed Sep 22 13:55:21 -0400 2010
So we are now all set with Tweet Alerts for St. Ruby.
Source for Ragios:http://github.com/obi-a/Ragios.