Tuesday, January 8, 2013

Pretty Capistrano output

I recently started tinkering around with capistrano to automate a few things like doing checks and generally make my life easier in terms of managing a bunch of linux machines. While capistrano is really cool, it's output is all over the place and I find that very irritating. Maybe it's just me but I don't like non-aligned repeating Strings. Take this output for example:

 ** [out :: borked.swisstech.net] puppetd (pid  14395) is running...
 ** [out :: carmine.swisstech.net] puppetd (pid  14433) is running...
 ** [out :: mandelbrot.swisstech.net] puppetd (pid  2835) is running...
 ** [out :: magi.swisstech.net] puppetd (pid  28830) is running...
 ** [out :: enchilada.swisstech.net] puppetd (pid  4455) is running...
 ** [out :: titan.swisstech.net] puppetd (pid  30098) is running...
 ** [out :: kronos.swisstech.net] puppetd (pid  27332) is running...
 ** [out :: serenity.swisstech.net] puppetd (pid  11072) is running...
 ** [out :: ackbar.swisstech.net] puppetd (pid  17522) is running...
 ** [out :: r2d2.swisstech.net] puppetd (pid  15535) is running...
 ** [out :: seraph.swisstech.net] puppetd (pid  24193) is running...
 ** [out :: box.swisstech.net] puppetd (pid  23061) is running...
 ** [out :: fermi.swisstech.net] puppetd (pid  8380) is running...
 ** [out :: gossamer.swisstech.net] puppetd (pid  28875) is running...
 ** [out :: marvin.swisstech.net] puppetd (pid  17977) is running...

The above is one of the easier to read examples. There are many more that are much worse to read than that (but too big to paste into the blog here).

So when looking for a solution I came across a blog entry called Streaming Capistrano that described how to tail from logfiles. Of course I had to try this and the completely unformatted output became apparent again.

So what to do? I already had half of the solution in front of me thanks to the post linked above. It didn't put the hostname in front of each line, only the first of a bunch so we need to iterate over the lines in the data variable. Plus to align everything we need to calculate the longest hostname in use and fill shorter hostnames with spaces before we print the data itself. Luckily, Ruby Strings have some pretty cool helper methods like ljust, rjust, center and many more so this couldn't be easier to solve.

A little bit of tinkering later I made that thing into a function and thus reusable in my entire capfile. So instead of 'run' I now call 'arun' (aligned-run) and that's it!

So here's the same output but neatly aligned. Much easier to read, isn't it?

 ** [out :: borked.swisstech.net    ] puppetd (pid  14395) is running...
 ** [out :: carmine.swisstech.net   ] puppetd (pid  14433) is running...
 ** [out :: mandelbrot.swisstech.net] puppetd (pid  2835) is running...
 ** [out :: magi.swisstech.net      ] puppetd (pid  28830) is running...
 ** [out :: titan.swisstech.net     ] puppetd (pid  30098) is running...
 ** [out :: enchilada.swisstech.net ] puppetd (pid  4455) is running...
 ** [out :: kronos.swisstech.net    ] puppetd (pid  27332) is running...
 ** [out :: serenity.swisstech.net  ] puppetd (pid  11072) is running...
 ** [out :: ackbar.swisstech.net    ] puppetd (pid  17522) is running...
 ** [out :: r2d2.swisstech.net      ] puppetd (pid  15535) is running...
 ** [out :: seraph.swisstech.net    ] puppetd (pid  24193) is running...
 ** [out :: box.swisstech.net       ] puppetd (pid  23061) is running...
 ** [out :: fermi.swisstech.net     ] puppetd (pid  8380) is running...
 ** [out :: gossamer.swisstech.net  ] puppetd (pid  28875) is running...
 ** [out :: marvin.swisstech.net    ] puppetd (pid  17977) is running...

Now I'm really not a ruby hacker. This works for me but if the more experienced rubyist sees anything wrong with the above code please let me know.

I think there are two potential problems with this code:

  • As far as I can tell, it may happen that the first few lines aren't aligned because I don't analyse the length of the hostnames upfront but do this on the go. But I think I can live with that.
  • The statement length = [length, host.length].max creates a list in the background which may be a bit too much overhead for many hosts and lots of data going trough this function but so far no problems.

Why isn't that the format of capistrano anyways? The output is so much easier to read!

Hostnames for the anonymized examples above were generated using computernamer.com

No comments:

Post a Comment