Recently, the need arose for me to monitor a URL so that notifications could be sent out if the site was suddenly unavailable. Later on down the road this will need to evolve into a more proactive system rather than reactive but for now I am just focusing on site down notifications.

To start, I set some minimal requirements for myself.

  • Needs to be easy to write, can't take more than an hour to build
  • Needs to be easy to maintain, problems should be easy to find and fix
  • Needs to be able to send SMS messages in case of outages
  • Needs to be able to run standalone or on a server under cron

When looking at the requirements I had to think about what kind of scripting environment would be best served for the task. I had several options available to me each with pros and cons.

  • bash
    • Pros
      • Runs natively on any *nix based system
    • Cons
      • Extremely verbose
      • Will not run on non *nix based systems
  • Perl
    • Pros
      • I would be able to drudge up ancient knowledge that I had buried deep in the catacombs of my mind
    • Cons
      • I don't have enough time to drudge up my ancient, and dusty, knowledge of Perl
      • I would spend too much time trying to figure out how to do everything in a single line of code
  • Groovy
    • Pros
      • I work with Groovy every day at work
      • I can use Grape to supply dependencies using the @Grab annotation
      • Code tends to be clean and simple
      • Can be run on any system that has Groovy installed
    • Cons
      • Must have Groovy installed
      • It is a little slow to startup

It should be no surprise that I chose to use Groovy for this project. For me, Groovy just fits the bill better in terms of code verbosity and features available.

Building the script was a snap. One of the cool things about shell scripting is that you are able to specify the binary that you want to use to execute your script. So by adding a single line of declaration I was able to create a script that can run as if it was a native executable.

#!/usr/bin/env groovy

After that it's just a matter of writing the code that does the work! Lets start with the dependent libraries.

First I needed to make sure I had the HTTP-Builder library. Grape makes this a snap to get by letting me take advantage of the @Grab annotation. I just place the following towards the top of my script and like magic everything I need is available.

@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.2')

I also need to make sure I have the Apache commons httpclient libraries. I use another @Grab to do this.

@Grab(group='commons-httpclient',module='commons-httpclient',version='3.1')

Grape is actually going out to the maven repositories and downloading the jars I requested and adding them to my classpath. Pretty slick eh?

I'll skip the imports (but you can check out the full source if those kinds of things excite you) and just straight to the guts of the script.

Next, among other things, I wanted to make sure that the script was configurable enough that I could add a list of phone numbers and be able to easily specify the url to monitor. To do that I created a nice little HashMap of key value pairs.

def options = [
        server: "https://google.com/",
        intervalSeconds: 600,
        sid: "",
        authToken: "",
        fromPhone: "",
        toPhone: "",
        smsOnStart: false,
        smsOnStartMessage: "Site monitoring script started at ${new Date().format('H:mm:ss')} on ${new Date().format('yyyy-MM-dd')}"
]

Ok, so options are great, but without some functionality they really mean nothing. Next I define two functions.

Here's the method that sends the SMS.

def sendSMS(def message, def opts){
    if (opts.sid != "" && opts.authToken != "" && message != ""){
        String twilioHost = "api.twilio.com"
        String sid = opts.sid
        String authToken = opts.authToken

        def hc = new HostConfiguration()
        hc.setHost(twilioHost, 443, "https")
        def url = "/2010-04-01/Accounts/$sid/SMS/Messages"

        def client = new HttpClient()
        Credentials defaultcreds = new UsernamePasswordCredentials(sid, authToken)
        client.getState().setCredentials(null, null, defaultcreds)

        opts.toPhone.split(',')?.each { toPhn ->
            PostMethod postMethod = new PostMethod(url)
            postMethod.addParameter("IfMachine","Continue")
            postMethod.addParameter("Method","POST")
            postMethod.addParameter("From",opts.fromPhone)
            postMethod.addParameter("To",toPhn)
            postMethod.addParameter("Body",message)

            client.executeMethod(hc, postMethod)

            postMethod.releaseConnection()
        }
    }
}

And here's the method that checks the status of the url.

def doPing(def opts) {
    if (opts.server != ""){
        try {
            new HTTPBuilder( opts.server ).get( path:'' ) { response ->
                def msg = ""
                if (response.statusLine.statusCode == 200){
                    msg = "${new Date()} :: UP!"
                    println msg
                } else {
                    msg = "${new Date()} :: There might be a production problem! -> ${response.statusLine.statusCode}"
                    println msg
                    sendSMS(msg,opts)
                }
            }
        } catch( e ){
            println "${new Date()}"
            e.printStackTrace()
            sendSMS("There was an error when connecting to the production server, it might be down.",opts)
        }

        if (opts.intervalSeconds > 0){
            def then = new Date()
            then.seconds += opts.intervalSeconds
            println "Checking again at ${then}"
            while (new Date() <= then){
                // do nothing
            }

            doPing( opts )
        }
    }
}

Since these are both method declarations and they won't just call themselves we need to do one last thing, call the doPing method.

if (options.smsOnStart){
    sendSMS(options.smsOnStartMessage,options)
}

doPing( options )

That's the whole script! If you are interested in looking at or using the script Github's going to be the best place to do that. With comments and code the whole thing come to a mere 106 lines of code! Not bad for something that monitors a URL and then sends an SMS when there is a problem.

I know I glossed over how the methods actually work but I felt they were pretty self explanatory. Feel free to ask questions in the comments if you would like further explanation.

Thanks for reading!

August 23, 2012 Comments: 1  ::  Tags: groovy , monitor , notifications , script , server , sms , tools , twilio , url

KaiNexus, the company where I am the Principal Architect, has just released our latest "Explainer" video. The new video includes 3 use cases and a bunch of screen grabs from the actual software. This video is quite exciting as I think it really shows what kinds of problems our software solves. Check it out!

July 24, 2012 Comments: 0  ::  Tags: explainer , improvement , kainexus , kaizen , lean , process improvement , video

SmugMug Grails Plugin Update

A few weeks ago I mentioned that I was building a Grails plugin that aimed to wrap the SmugMug API. As of today, I am about 80% done with the coding and will be giving it a through test phase and creating docs soon. Once done, it will be available through the normal Grails plugin channels and be completely open source.

The Way Out

Sometimes it is so easy to ignore the things around us that we see on a daily basis. The subject of this photo was no exception. This is a walkway at the office complex where I work 5 days a week and I never once thought to bring my camera and shoot it. A few days ago I decided to change that. Here are the results.

Taken at an office park in Dallas, TX

July 05, 2012 Comments: 0  ::  Tags: everyday things , grails , hdr , industrial , plugin , smugmug

Living in a Hospital

I've spent the last five days pretty much living at UT Southwestern Medical Center. My step daughter has been unable to eat more than a few bites of food without throwing up for about three months. After many tests and even a surgery to remove her gall bladder, doctors finally admitted her to the hospital for observation and even more tests. As a result, my wife and I have spent nearly the whole time living I the hospital room with her. I ask, for those comfortable with it, for prayers for her health and that the doctors would be able find the problem and come up with a solution.

The Hallway

There is a really interesting hallway at UT Southwestern Medical Center that just screamed "spooky" at me. I wanted to grab my camera and shoot some of the interesting angles and lines but I was a bit worried about offending patients and staff by walking around the hotel with camera and tripod in hand. As an alternative, I used my iPhone and captured the following video. I processed it a little bit in iMovie.

June 26, 2012 Comments: 0  ::  Tags: hallway , hospital , imovie , iphone , spooky

Brackets

I saw a post on Google+ where someone posted a collage with the brackets used to make up one of their HDRs. I thought this was pretty cool and decided to do one of my own using Diptic for Mac. What do ya' think?

Stone, Steel and Glass Brackets

Stone, Steel and Glass

This is the finished product of the image above. It was taken in downtown Fort Worth on my last photowalk research day. I was fascinated by the combination of glass, metal and concrete and the lines they formed. Normally, this is filled with flowing water but I got there just shortly after they turned everything off. I really dig the way everything looks even without the water.

June 20, 2012 Comments: 0  ::  Tags: concrete , diptic , fort worth , glass , hdr , steel , stone , texas

Here is another shot I snapped while exploring Fort Worth and gathering info for my fall photowalk. This is on the side of Bass Performance Hall. The building and the angel are carved out of Texas limestone, which was quarried near Austin. You can read more about these amazing sculptures on Google Books.

One of the carved angels on the side of Bass Performance Hall

June 19, 2012 Comments: 0  ::  Tags: angel , bass hall , carving , fort worth , hdr , stone , texas

The SteveGood.org Repository Visualized

A while back I found a really interesting utility for visualizing the activity of a Git repository. Here's a cool little video of the repo for this site as visualized by Gource. Enjoy

What Big Teeth You Have

I have been experimenting with a number of different photography techniques, one of those is the invisible black backdrop. Using this technique, I decided to follow my chihuahua around and generally annoy him with my flash. The result was a yawn captured at just the right moment. Isn't he just so vicious?

June 18, 2012 Comments: 0  ::  Tags: black and white , chihuahua , git , gource , invisible black backdrop , nikon d7000

Father's Day

To all the father's out there, including my own, happy Father's Day! Kids, if you know what's good for you you'll wait on dad hand and foot! No, really.

Sundance Court

I grabbed this shot while doing research for a future photowalk around Fort Worth. It was a little bit of a surprise for me since I found this on a street that was more of an alley. It is located behind Risky's BBQ at Sundance Square.

This little gem is located right behind Risky's BBQ

June 17, 2012 Comments: 0  ::  Tags: father's day , fort worth , nikon d7000 , star wars , sundance square , texas

Grunge + Portraits = Hours of Fun

I started messing around with some techniques to add a feeling of grunge to a couple of the portraits in my library (nothing worth sharing yet) and found that I can't get enough. I found a pretty good, if not fast, tutorial (below) on the basics of applying grunge to a photo. One thing to note, I don't have one of the plugins this video uses but I was able to get the same effect by creating a new layer and desaurating it completely and messing around with the levels, curves and exposure. It's not as easy as the plugin filters but it costs way less.

The Milk Silo

I stopped on my way home from the office about a week ago and took a few shots of a park that I pass everyday. It is amazing how many power lines and other modern things there are in almost every frame I want to capture. This was one of those rare shots where I was able to avoid the power lines and hide the pesky water towers and street lights. All-in-all, I like the final result.

June 16, 2012 Comments: 0  ::  Tags: grunge , hdr , milk , nikon D7000 , no powerlines

Explore Fort Worth

Over the next few weekends I'll be in or around downtown Fort Worth doing research for a photowalk. If you would like to join me be sure to follow me on Twitter or circle me on Google+ to get the details of where I will be and when I will be there.

The first exploration will be June 15th 16th, 2012 at 5pm and I will be starting at the little park between Bluff St and Belknap (across from the court house) and working my way towards Sunset Square. If you are planning to come make sure to bring water and hydrate ahead of time, nobody needs to be getting dehydrated in the Texas heat. Comment below with questions or to let me know you will be joining me (that way I don't just take off and leave you behind). Also, street parking is generally free on the weekends after 6 or 7 but space is limited so you may want to be there early to find a parking spot. Also, if anyone joins me, we can head over to the Flying Saucer afterwards for drinks and german food.

UPDATE: I originally posted the wrong date. The correct date should have been June 16th (Saturday)

Some Kind of Date

While the Fort Worth Water Gardens were awesome for me to visit not all people share my enthusiasm. Perhaps the next date will be better. Smile!

They are clearly having the time of their lives.  Or not.

June 15, 2012 Comments: 0  ::  Tags: date , fort worth , fort worth water gardens , hdr , nikon D7000 , people , texas , water