Remind me: Configuring BIND9 plugin for Munin on FreeBSD (and Linux)

I was attempting to get Munin working on a new FreeBSD machine, monitoring the rate of queries to a Bind9 DNS server. Every time I attempted ‘munin-run bind9′ I was presented with the same error:

2011/01/29-18:09:55 [3581] Error output from bind9:
2011/01/29-18:09:55 [3581]     Died at /usr/local/etc/munin/plugins/bind9 line 41.
2011/01/29-18:09:55 [3581] Service 'bind9' exited with status 2/0.

Digging around in the Bind9 Munin plugin, line 41 complains about a state file that Munin uses. The plugin immediately tries to open the state file, without checking if the file is actually present. (TODO: Check to see what ramifications there are to just creating the file if it is not present.)

Line 41:

    open(Q,"< $STATEFILE") or die;

After digging around to figure out the plugin state directory (/var/munin/plugin-state, for those following along at home), I was back in business.

[root@dns1 ~]# cd /var/munin/plugin-state
[root@dns1 /var/munin/plugin-state]# touch bind9.state
[root@dns1 /var/munin/plugin-state]# chgrp munin bind9.state
[root@dns1 /var/munin/plugin-state]# chmod g+rw bind9.state
[root@dns1 /var/munin/plugin-state]# ls -al
total 4
drwxrwxr-x  2 nobody  munin  512 Jan 29 18:13 .
drwxr-xr-x  3 munin   munin  512 Jan 29 14:47 ..
-rw-rw-r--  1 root    munin    0 Jan 29 18:13 bind9.state

Relevant bind named.conf stanza for query logging:

logging {
  channel default_queries {
    file "/var/log/queries.log" versions 3 size 500k;
    severity info;
    print-severity yes;
    print-category yes;
    print-time yes;
  };
  category queries { default_queries; };
};

With that, ‘munin-run bind9′ worked. I restarted the munin-node process and queries are now being graphed as expected.

[Update 2012-02-20: Getting this working on Ubuntu Server]

After banging my head against the wall trying to get this plugin working on Linux, dying on the same line (about the inability to find the state file), this is how I got it working.

Create the following file with the appropriate permissions.

root@grenache:/var/lib/munin/plugin-state# ls -al bind9.state
-rw-rw-r-- 1 nobody munin 22 2012-02-20 15:39 bind9.state

And now, voila:

 root@grenache:/var/lib/munin/plugin-state# munin-run bind9
 query_PTR.value 25
 query_A.value 109
 query_AAAA.value 199
 query_other.value 0
Posted in Open Source/Internet | Tagged , | Comments Off

Munin monitoring your SB6120 Comcast Cable Modem

For those who have spent time debugging their Comcast Internet connection, we all know the frustration of trying to explain to Comcast that something on their end is the problem. In this case, more data is better: latency history, ping times, traceroutes, etc. You can run Smokeping to monitor latency between your home connection and a remote Internet IP address for example. You can also print out traceroute examples and email them if you have an astute support contact. But if you want to monitor the data your cable modem is seeing, you need to look at the signal to noise ratio of your connection. This ratio refers to how much of your signal has been disturbed by noise on the physical line (Thanks Wikipedia). Newer cable modems will use multiple channels along the same line to increase your download and upload speed, and each channel can be disturbed independently.

Enter Munin, an RRD-graph based tool that creates easy to understand (for the most part) graphs of data over time. Munin plugins can be written to scrape any data you are able to programatically retrieve and whip it into a pretty graph. The plugin I wrote for Munin scrapes the data from a Motorola Surfboard SB6120 modem’s status page, and presents it in an easy-to-digest format for Munin. Previous Munin plugins handled the old SB4120 and SB5120 modems. These are old DOCSIS 2.0 products, and therefore the status page has evolved, and displays the connection data in a way where the old plugin does not work on the SB6120 modem.

Without further adieu, the graph produced by my plugin is:
The graph shows the various downstream and upstream channels, graphing the signal-to-noise ratio dB (decibel) of each respective channel.  Suggested values for Comcast in particular can be found in a FAQ entry from Broadband Reports. These are just suggestions, and different values will have different effects on your Internet connection. A severe dip in the graph could correspond to your modem being unable to stay sycned with Comcast’s infrastructure, which translates to an unstable Internet connection.

Installation instructions follow common Munin plugin practices, by creating the plugin (or a symlink to the plugin) in the /etc/munin/plugins/ directory to the plugin code. Mine is written in Python, so a basic Python install is required on your machine. Source can be found can be found in my munin-surfboard6120 repo on Github.

Enjoy! (Comments/criticisms are welcomed to improve the usefulness of this plugin)

Posted in Open Source/Internet | Comments Off

I Am Lazy: Python, to convert a file’s age in seconds since epoch to a readable format

For my own lazyness, so I don’t need to hunt for this damn chain of syntax.

>>> time.strftime(“%Y%m%d-%H%M.%S”, time.gmtime(os.path.getctime(“$path_to_file”)))
’20101213-1948.58′

Posted in Open Source/Internet | Comments Off

Howto: Git, hooks, Nagios, oh my.

At work we have a monitoring configuration workflow where our Nagios config files are parsed and generated before they are allowed to be ‘svn commit’ed. I know this verification has saved me many times when trying to add new hosts or services, since everything might not be ready for prime time. I wanted to see if I could recreate this scenario at home using Git hooks, if only for my own interest and curiosity.

My proposed workflow: Start with a local clone of the Nagios configs. Add a host,  service, or contact to a local nagios Config file. Git commit locally. Git push to the remote repo on the monitoring box. The Nagios config parser would run remotely verifying the syntactic-correctness of the proposed-check in. If these checks fail, reject the push. If parsing succeeds, accept the push, and restart Nagios (hence reloading the new configs). I wanted to alleviate the need for an admin to log into the monitoring machine at all. This would eliminate the need to add sudo permissions to a group of users to allow them to restart the Nagios service.

Without further delay, on to the code. The first piece, was the pre-receive hook with Git. I used this hook specifically because it has the power to accept or reject a push.

Behold, $git_repo/.hooks/pre-receive:

#!/bin/bash
while read OLD_SHA1 NEW_SHA1 REFNAME; do
 export GIT_WORK_TREE=/tmp/nagiosworkdir
 /usr/bin/git checkout -f $NEW_SHA1
 sed -i "s|cfg_dir=CHANGEWITHGIT|cfg_dir=${GIT_WORK_TREE}\/config|g" $GIT_WORK_TREE/nagios.cfg
 sudo -u root /bin/chgrp -R nagios $GIT_WORK_TREE
 sudo -u root /usr/sbin/nagios3 -v $GIT_WORK_TREE/nagios.cfg > $GIT_WORK_TREE/check.out
 NAGIOS_CHECK_STATUS=$?
 echo "Nagios Config Check Exit Status:" $NAGIOS_CHECK_STATUS
 if [ "$NAGIOS_CHECK_STATUS" -ne 0 ]
   then
   echo "Your configs did not parse correctly, there was an error. Output follows."
   cat $GIT_WORK_TREE/check.out
   exit 1
 else
   echo "Your configs look good and parsed correctly."
   exit 0
 fi
done

The operations here flow from checking out the pending push to a ‘temporary directory’ (explained below), and then making a slight modification to the nagios.cfg to handle our temp configs being somewhere other than the Nagios install directory. This is needed since we want to parse our configs, and not the ones currently in-use on the machine. After this is done, we parse the output of that check, and based upon that output, either accept or reject the push. In the case of a rejection, the output of the verification is printed for the user to see. This output is pretty clear when explaining where the error is.

And now the post-receive:

#!/bin/bash
cd /etc/nagios3/testing
/usr/bin/env -i /usr/bin/git pull
echo "Restarting Nagios now"
sudo -u root /usr/sbin/service nagios3 restart

The post-receive happens after the entire process is done [1]. We change into the directory of the Git clone of your monitoring config repository. which itself is inside /etc/nagios3, and execute a ‘git pull.’ The need to wrap it around ‘env’ is because of an issue I also learned in this process. [2] The GIT_DIR directory is set to the directory of your repository. In this case, we must change to another directory on this machine, which is outside of our initial Git repo. Therefore we must ‘unset’ this variable, which is what the ‘env’ execution does.

This is pretty straightforward for the most part. The part of the process new to me was the GIT_WORK_TREE. I received a a pretty simple explanation from the author of Gitolite. He explained that the work tree directory is a directory where the potential new commit can be checked out before it is actually allowed to be pushed into the remote repository. Essentially, the opposite of a bare repository. The reason I do this is because I want to do the parsing check before I actually allow the push. I can’t ‘git pull’ the new repository directly into the Nagios configuration directory before it is actually committed. GIT_WORK_TREE allows this intermediary functionality.

The reasoning for the ‘sed’ modification in that file is that since I will be checking-out the intermediary files into a new directory, I need a Nagios config file that references this intermediary directory. How did I get around this? I copied the nagios.cfg file I would run my install with into the repo, and changed the cfg_dir directory to something I can easily modify during the check in (cfg_dir=CHANGEWITHGIT). This file is not expected to be used on the actual server, so do not copy this one over your actual Nagios.cfg file.

The chgrp magic is because the user who runs the Nagios application must have read access to the configuration files.

Relevant sudoers lines needed:

git ALL=(ALL) NOPASSWD: /bin/chgrp -R nagios /tmp/nagiosworkdir
git ALL=(ALL) NOPASSWD: /usr/sbin/nagios3 -v /tmp/nagiosworkdir/nagios.cfg
git ALL=(ALL) NOPASSWD: /usr/sbin/service nagios3 restart

The three lines above are as such. (1) Allow the git user to, without a password, change the group of the temporary Nagios work dir. (2) Allow the git user to, without password, run the verification of the to-be-committed files. (3) Actually restart the Nagios service.

A successful commit, including a restart of Nagios looks like the following:

jforman@merlot:~/devel/testing/config$ git commit . && git push
[master 2f796e3] testing for the blog post
 1 files changed, 1 insertions(+), 1 deletions(-)
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 394 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Previous HEAD position was ca6dd74... fix now
remote: HEAD is now at 2f796e3... testing for the blog post
remote: Nagios Config Check Exit Status: 0
remote: Your configs look good and parsed correctly.
remote: From /home/git/repositories/testing
remote:    ca6dd74..2f796e3  master     -> origin/master
remote: Updating ca6dd74..2f796e3
remote: Fast-forward
remote:  config/contacts_nagios2.cfg |    2 +-
remote:  1 files changed, 1 insertions(+), 1 deletions(-)
remote: Restarting Nagios now
remote:  * Restarting nagios3 monitoring daemon nagios3
remote:
remote:    ...done.
To git@monitor:testing.git
   ca6dd74..2f796e3  master -> master

This was definitely an eye-opening learning process for me into all the moving parts of Git. I hope this Howto helps those out there looking for a solution like this. Enjoy!

Addendum:

For those wondering about the various permissions of the git_work_tree directory and also the repo checkout inside /etc/Nagios3:

monitor:/tmp/nagiosworkdir

drwxrwxr-x  3 git  nagios  4096 2010-11-16 16:13 nagiosworkdir

monitor:/etc/nagios3/testing

drwxr-xr-x  4 git  nagios  4096 2010-11-15 08:36 testing

[1] http://progit.org/book/ch7-3.html

[2] http://debuggable.com/posts/git-tip-auto-update-working-tree-via-post-receive-hook:49551efe-6414-4e86-aec6-544f4834cda3

Posted in General, Open Source/Internet | 1 Comment

Hiking the Sugarloaf Trail

It only took me four years of living in Boston to get myself a good pair of hiking boots and get up into New Hampshire to explore the mountains. Having grown up in Florida, I am still enamored with the way the leaves change color up here, and how it makes the color of the landscape explode. My wife was going out of town, so I figured Columbus Day Weekend 2010 was a great way to start to restart this hobby.

I picked up a couple books from Amazon on hiking in the White Mountains of New Hampshire. I also ended up finding a great blog called Live Free and Hike New Hampshire. Thanks to a recent post about the Sugarloaf Trail being an easy day-hike, I ventured off up to New Hampshire on Saturday morning.

The drive up I-93 was gorgeous, especially at 7:15am with little traffic and the sun beginning to come over the mountains. I got to the trailhead around 9am, and set off.

IMG_0705.JPG

There is a 0.9 mile hike from the trail head to where the path splits, to the left is Middle Sugarloaf, and to the right is North Sugarloaf. I trekked to the right first, encountering some massive boulders. As I walked through, it smelled like Christmas, and I came upon this incredibly pink leaf sitting on a dark green pine tree. The picture does not do it justice, the color of the leaf popped a lot more in person.

P1000933.RW2

P1000932.JPG

As I hiked a bit more towards North, a few feet of the trail I noticed a gap in the Earth. When I walked over, it was two huge boulders literally split down the middle. The chasm between looked to be at least 10-15 feet deep.

P1000935.JPG

As both guide books mentioned, when you think you’ve arrived at the summit, which is actually just a large viewing area, hike a bit further. This extra five minutes gives an even broader view out to the mountains ahead. The clouds looked almost as if they were sliding along an invisible plane in the sky. I couldn’t help but ask a passerby to take a photo of me as I stopped for a snack.

P1000942.JPG

I trekked back down and headed towards Middle Sugarloaf. These woods went from fir and evergreen trees to birch, which gave a much different feeling as different line shone through from above. With the wind kicking up on this summit, it was time to set the self-timer on the camera and get another shot.

P1000955.JPG

On the way back down, there is an extension loop to the Sugarloaf Trail called Trestle Path. Unfortunately, I reached a part in the path that seems to be an impasse. A wooden bridge that was once here looks to be long gone. I could see a yellow blaze painted on a tree across the river, so I knew I was on the right path. Anyone know if his path is indeed currently incomplete?

P1000959.JPG

All in all, it was a great day, both weather and scenery for a day trip hike. One tip, do not drive back through Conway, NH if headed back towards Boston. I easily ate up 30 minutes sitting in traffic to wind my way back to MA. I can’t wait to explore more of this area in all four seasons.

For a link to the entire image gallery, check out the Picasa Album

Posted in Outdoors | Comments Off