Ready set Go!

(Jonas Larson)

I really like to write C programs! I can't help it, I think it's the beauty of the speed and control that gives me such pleasure. But writing code in C can be difficult and slow. But it doesn't stop there, debugging and reading code is even more problematic!

Obviously this is not a new problem, we at RedBridge default to Python for our scripting and programming needs as the 'de facto' standard! And that is not a big surprise, Python excels at one thing in particular: readability!

After you have been writing code for a while, may it be sysadmin-scripts, the latest 'n' greatest web application or "real" programming, you will need to revisit your own or someone else's code. That's when the quality of the code (and programmer) reveals it self...

I remember an ugly hack I did in Perl 10 years ago that I had to revisit to fix a bug for a firm that still used it: boy was it messy!!! And that was my own code, albeit 10 years old... That shows how important readability really is.

It's all about speed!

So if writing code in C I so difficult why do it? Well speed is certainly a big reason. Others might be that you need the low levelness of C in order to get your stuff done.

What if...

You could get both? Both the speed of C (compiled code) and the high levelness, memory management and readability of Python?

Ready! Set! Go!

Well, you can! The Go programming language is exactly that, the speed of C and the readability of Python! Yes, that's right: The speed of C and the readability of Python

Proof in the pudding!

OK, seeing is believing! Let's write a local check for a great monitoring tool called Check MK, it will give us something to compare and is reasonably fast to put together...

Writing a local check is easy, the only thing that matters is that the output is formatted according to the standards! I won't go into the details since this is about Go not Check MK...

Python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python

import sys
import requests

url = 'http://localhost:8000/pages/cloud.html'

cookies = {'pool_cookie': 'h'}

try:
    res = requests.get(url, cookies=cookies)
    if res.status_code < 399:
        time = res.elapsed.seconds + res.elapsed.microseconds/1000
        print "0 URL_%s response_time=%s OK - response code: %s" % (url, time, res.status_code)
    else:
        print "2 URL_%s - CRITICAL - response code: %s reason: %s  " % (url, res.status_code, res.reason)
except Exception as e:
    print "2 URL_%s - CRITICAL - %s " % (url, e)

OK, let's test it...

jonas$ ./foo.py
0 URL_http://www.redbridge.se response_time=243 OK - response code: 200

Sweet, 18 lines of code! That's Python magic for ya!

Let's give go a ... Go?! (sorry, couldn't help it):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import (
    "fmt"
    "net/http"
    "time"
    "os"
    "net/http/cookiejar"
)

func main() {
    var url = "http://www.redbridge.se"
    start := time.Now()
    jar, err := cookiejar.New(nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{Jar: jar}
    resp, err := client.Get(url)

    if err != nil {
        fmt.Printf("2 URL_%s - CRITICAL - Error in connection\n", url)
        os.Exit(2)
    }

    if resp.StatusCode < 399 {
        fmt.Printf("0 URL_%s response_time=%d OK - response code: %s\n", url,time.Since(start)/1000000,resp.Status)
    } else {
        fmt.Printf("2 URL_%s - CRITICAL - response code: \n", url,resp.Status)
    }
}

Not to shabby! Does it work?

jonas$ ./foo
0 URL_http://www.redbridge.se response_time=203 OK - response code: 200 OK

Nice! It works, but more importantly: it's very readable...

So, you have a language that is very readable, high level, memory managed language (kinda like Python) but compiles and has all the benefits of the raw speed that the interpreted languages do not.

Should the Go programming language be a tool in your toolbox?

Speed is relative (ain't it all), most of the times you do not need the speed of compiled languages. But if you do I and the task fits within Go's realm it might be a good choice...

Who knows, you might find it the best thing since sliced bread :-)

If you still need your fix of Python, stay tuned for some Cython magic...