Text is nice, graphs are pretty
Over the last few weeks I have been writing more and more metric gathering tasks to identify how the systems we use are being used and what is valuable about them. All of this wonderful metric information at the moment is text based and mailed out, but text representation works fine for things that are tangible, such as the cost or number of users, but what if you wan to know how many users are online at 8 am or 10 am or 1 pm? Well this is where something pretty comes into the mix.
As part of the metrics gathering I have been looking at various graph drawing tools and there are quite a few out there, some although technically brilliant are ugly, some or pretty but limited. Over a longer term it will probably make sense to use some javascript library to draw the graphs, but I wanted something now and we had a graphite server which was being used for some more generic stuff but I hadn’t done anything with it.
Get some data in
Graphite is pretty cool, you just send some very basic information to it and it tracks it, it can then take care of the display of the information and certain functions like the average or max of a metric. All of the graphs are drawn on the flu so you can change the time frame, add extra plots and all this good stuff. Initially I was put off by Graphite because it looks messy but I decided that now was a good time to learn.
The first challenge I had was putting some data into it, because it just takes a text string you can update it using net cat if you really wanted, but I decided to g for a pure ruby implementation.
# # Graphite DAO # require 'socket' class GraphiteDAO def initialize (server, port) @server = server @port = port end def put_graphite(metric_name, metric_value, date = Time.now.to_i) string = metric_name.to_s + " " + metric_value.to_s + " " + date.to_s #puts "string = #{string}" write(string) end private def write(data) socket = TCPSocket.open(@server, @port) socket.puts "#{data}" socket.close end end
This is very functional and there is no error checking but its enough to get it working, as you can see I just take the metric name i.e. the path in graphite and the value, you can optionally pass in the date if you wish, but it made more sense to just use “now” as the date in most cases.
The metric name is a path in graphie, so the metric name I pass in may be “prod.application.concurrent_users” this allows for the data to be structured logically within graphite and is easier to recall later.
Getting something out
By far the most useful thing I learnt about graphite is changing the line mode to be connected, it turns the tiny line spec that I can’t see into a connected line… so now graphs are visible. In short graphite lets you select any number of metrics to graph onto one graph, and the default view is sort of a graph builder. This typically works fine if you only have 1 metric or you are comparing the same metric from three sources, however if the range between the lowest metric and the highest is too far, you just end up with a straight line for each, this is not a graphite issue but a general issue with graphs.
Now for the really useful stuff, you can use graphite to render specific graphs for you by calling a specific url to render your graphs, so once you know what the path is to the metric you can do all sorts of stuff.
for example…
Because it is just a matter of adding options of multiple targets it is easy to use, and the documentation is okay (and Here)
The other element that is really useful is drawing graphs that don’t exist for example
http://my-graphite-server/render?graphType=pie&target=alpha:111&target=beta:222&target=gamma:333
The rendering engine is good and I like it, so considering this whole thing only took 25 mins to work out it was well worth the effort in doing so, a quick return for not much effort