Hi, I’m Josh Symonds

I blog about Ruby on Rails, coding, and servers

Awesome Banners With Consul and Monit

Reading time 5 minutes

I love Hashicorp’s Consul and I use it extensively in my infrastructures. I also love Monit and I use the two to keep up-to-date on the services running on my servers and remain confident that they’ll stay up. Though both products have server dashboards (Atlas and mmonit respectively) it can be very helpful to see the result of checks immediately upon logging in. Something like this:

Banner

After a bit of hacking I set up a little Ruby script that outputs exactly that using the magic of a pam_motd banner, so that when you log in you can immediately see how your system is doing. Getting it going is pretty easy and I’ve found it quite helpful so far – if you’re interested in running it as well, here’s how!

1. Remove noupdate from /etc/pam.d/sshd and /etc/pam.d/login

Both the /etc/pam.d/sshd and /etc/pam.d/login files contain lines like this:

1
2
3
4
5
# Print the message of the day upon successful login.
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
session    optional     pam_motd.so  motd=/run/motd.dynamic noupdate
session    optional     pam_motd.so # [1]

You’ll want to comment out noupdate in both files, which prevents pam_motd from updating before login. Normally you don’t want the motd updating before login, since that could be a bit time-consuming and you don’t want to slow down the login process. However, if we don’t update it before login then you’ll get stale data, which is rather pointless for a status banner. And happily my Ruby script is very light-weight and adds less than 50ms to a login. Which, sure, not great, but also, not bad.

So ensure you comment out noupdate before moving on to step 2.

2. Place the statuser.rb script in /etc/update-motd.d/

The script I came up with is pretty lightweight, and I’m sure I’ll spend some time tightening it up, but for my purposes it serves well. I tried to avoid too many abstractions: though my first inclination was to put the memory and disk stats in objects, keeping them as arrays helps make the script minutely faster. Similarly I used oj for JSON parsing since it’s the fastest available JSON parser, though the amount of JSON Consul returns is so small I think any parser would’ve performed adequately.

So, with no further ado:

To speak about the code generally, at the top I define a bunch of constants that you might want to change (like I thought using cute unicode characters for statuses was sensible, but if you don’t have a unicode-compatible system you should probably change those). system_status queries for a lot of miscellaneous statuses and converts them into words and colors that are easily digestible – similarly, monit_status and consul_status do the same for my monitoring services.

Helpers at the bottom format strings and tabularize the data into a more lovely format. I tried to keep the stuff you might want to change at the top, but if you really want to get into the nitty gritty of displaying, tweak the private methods at the bottom of the class.

3. SSH in!

SSH into your server and you should see your new banner displayed proudly!

Banner

If it isn’t working you might just see your system’s standard motd. If that’s the case, try running the statuser manually – hopefully you’ll get an error you can debug a little bit more.

I know the statuser isn’t the most elegant Ruby ever, but it does work, it is fast, and also it’s easily extensible: you could add a lot more useful information to it very simply. I tried to err slightly on the side of conservatism with the data I chose, since I didn’t want the login process to take too long… but I would love to hear suggestions for other interesting tidbits to put in that you might want to see every time you ssh in. And, of course, as I improve it I’ll keep the gist updated.