Binary Talks

The Top 10 of your most used UNIX commands

Almost three years ago Uwe Hermann posted a one-liner in his blog which was mentioned in an article from IBM called UNIX Productivity tips. It shows you the ten most used commands on your local machine and I think it’s time to revive this habit.

Do the following on your console and see what you’re frequently using:

user@host: ~ $ history|awk '{print $2}'|awk 'BEGIN {FS="|"} {print $1}'|sort|uniq -c|sort -rn|head -10

This is the result of my workstation which now runs for about 1 1/2 months with a current total of 8.000 commands:

   1987 ssh
    767 ls
    746 sudo
    349 for
    267 cd
    259 exit
    231 vim
    156 svn
    154 ping
    130 pwd
Share and Enjoy:
  • del.icio.us
  • Digg
  • Slashdot
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Yigg
  • Netvibes
  • MisterWong
  • Facebook
  • HackerNews
  • Identi.ca
  • FriendFeed
  • NewsVine

Matejunkie

Enjoy the silence

I was on holiday for about a week and a half and I just wanted to say that It’ll be a bit more quiet around here for the next weeks. It’s just way too hot to stay inside. Expect a few updates, but nothing major.

Go out, meet your friends, enjoy the sun and have a nice time! So do I.

Share and Enjoy:
  • del.icio.us
  • Digg
  • Slashdot
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Yigg
  • Netvibes
  • MisterWong
  • Facebook
  • HackerNews
  • Identi.ca
  • FriendFeed
  • NewsVine

Binary Talks

To get Songbird 1.2 up and running under Ubuntu 9.04

Get SongbirdFor those about to rock: Songbird is an Open Source iTunes alternative which aims to be interoperable between Windows, Mac and Linux operating systems.

When I checked out Songbird 1.1 a few weeks ago I was quite astonished in the first place. It comes with a nice and shiny interface, it’s fast and quite stable as well and, of course, there’re various web-services like Shoutcast or Last.fm integrated. The only thing that Songbird 1.1 really lacked off was the non-existing equalizer, which is indispensable in my opinion. Therefore, I switched back to Amarok 1.4 on my Ubuntu desktop (Gnome) and to audacious on my Gentoo desktop (wmii).

Yesterday Songbird 1.2 has been released and besides a lot of other improvements… hell yes, it now has an equalizer onboard which works well at least for my sense of hearing.

To get it running under Ubuntu simply download the tar.gz from the Songbird website, extract it and remove two libvisual plugins that otherwise prevent Songbird from starting up.

user@host: ~ $ sudo aptitude remove libvisual-0.4-plugins libvisual-projectm

If you haven’t checked it out yet, give it a go!

Share and Enjoy:
  • del.icio.us
  • Digg
  • Slashdot
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Yigg
  • Netvibes
  • MisterWong
  • Facebook
  • HackerNews
  • Identi.ca
  • FriendFeed
  • NewsVine

Binary Talks

Update 1.1: nginx Check Plugin for Nagios

logo_nagiosLast week I’ve got an E-Mail by Jordi, who’s blogging at terraquis.net, with a few suggestions to the nginx check plugin I’ve recently released. He made two significant changes to the plugin:

  1. His version runs with bash only, but except bc all external calls have been replaced by bash built-ins
  2. There’s no temporary file anymore which has to be written to a temporary directory, nginx_status page output is saved into a variable

The plugin therefore runs much faster than my initial version of the plugin: 14-16ms plus the 1 second sleep interval between the two nginx_status checks.

And then I realized that writing output to a temporary file is just one thing: plain stupid. Why writing files when an information can be stored in a variable where it stays in memory?
Well, I can’t really say why I walked this way when I’ve written the first plugins, but I eventually had the right idea when I’ve written the Hadoop DFS check. There I already store the information within variables. The only guess why I did this is that I’ve assumed that storing longer output in variables just would be too much.

But anyway, there has to be room for improvements, right? Therefore, expect a few reworks within the next days, …

The script

Below is the revised script I’ve already uploaded yesterday to Nagios and MonitoringExchange. It runs much faster than the initial version and doesn’t write files anymore. You may also stick to the output below or do the SVN way.

user@host: ~ $ svn co svn://svn.matejunkie.com/nagios-plugins/stable/check_nginx/ check_nginx/
#!/bin/sh
 
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
PROGNAME=`basename $0`
VERSION="Version 1.1,"
AUTHOR="2009, Mike Adolphs (http://www.matejunkie.com/)"
 
ST_OK=0
ST_WR=1
ST_CR=2
ST_UK=3
hostname="localhost"
port=80
path_pid=/var/run
name_pid="nginx.pid"
status_page="nginx_status"
pid_check=1
secure=0
 
print_version() {
    echo "$VERSION $AUTHOR"
}
 
print_help() {
    print_version $PROGNAME $VERSION
    echo ""
    echo "$PROGNAME is a Nagios plugin to check whether nginx is running."
    echo "It also parses the nginx's status page to get requests and"
    echo "connections per second as well as requests per connection. You"
    echo "may have to alter your nginx configuration so that the plugin"
    echo "can access the server's status page."
    echo "The plugin is highly configurable for this reason. See below for"
    echo "available options."
    echo ""
    echo "$PROGNAME -H localhost -P 80 -p /var/run -n nginx.pid "
	echo "  -s nginx_statut -o /tmp [-w INT] [-c INT] [-S] [-N]"
    echo ""
    echo "Options:"
    echo "  -H/--hostname)"
    echo "     Defines the hostname. Default is: localhost"
    echo "  -P/--port)"
    echo "     Defines the port. Default is: 80"
    echo "  -p/--path-pid)"
    echo "     Path where nginx's pid file is being stored. You might need"
    echo "     to alter this path according to your distribution. Default"
    echo "     is: /var/run"
    echo "  -n/--name_pid)"
    echo "     Name of the pid file. Default is: nginx.pid"
    echo "  -N/--no-pid-check)"
    echo "     Turn this on, if you don't want to check for a pid file"
    echo "     whether nginx is running, e.g. when you're checking a"
    echo "     remote server. Default is: off"
    echo "  -s/--status-page)"
    echo "     Name of the server's status page defined in the location"
    echo "     directive of your nginx configuration. Default is:"
    echo "     nginx_status"
    echo "  -S/--secure)"
    echo "     In case your server is only reachable via SSL, use this"
    echo "     this switch to use HTTPS instead of HTTP. Default is: off"
    echo "  -w/--warning)"
    echo "     Sets a warning level for requests per second. Default is: off"
    echo "  -c/--critical)"
    echo "     Sets a critical level for requests per second. Default is:"
	echo "     off"
    exit $ST_UK
}
 
while test -n "$1"; do
    case "$1" in
        -help|-h)
            print_help
            exit $ST_UK
            ;;
        --version|-v)
            print_version $PROGNAME $VERSION
            exit $ST_UK
            ;;
        --hostname|-H)
            hostname=$2
            shift
            ;;
        --port|-P)
            port=$2
            shift
            ;;
        --path-pid|-p)
            path_pid=$2
            shift
            ;;
        --name-pid|-n)
            name_pid=$2
            shift
            ;;
        --no-pid-check|-N)
            pid_check=0
            ;;
        --status-page|-s)
            status_page=$2
            shift
            ;;
        --secure|-S)
            secure=1
            ;;
        --warning|-w)
            warning=$2
            shift
            ;;
        --critical|-c)
            critical=$2
            shift
            ;;
        *)
            echo "Unknown argument: $1"
            print_help
            exit $ST_UK
            ;;
        esac
    shift
done
 
get_wcdiff() {
    if [ ! -z "$warning" -a ! -z "$critical" ]
    then
        wclvls=1
 
        if [ ${warning} -ge ${critical} ]
        then
            wcdiff=1
        fi
    elif [ ! -z "$warning" -a -z "$critical" ]
    then
        wcdiff=2
    elif [ -z "$warning" -a ! -z "$critical" ]
    then
        wcdiff=3
    fi
}
 
val_wcdiff() {
    if [ "$wcdiff" = 1 ]
    then
        echo "Please adjust your warning/critical thresholds. The warning \
must be lower than the critical level!"
        exit $ST_UK
    elif [ "$wcdiff" = 2 ]
    then
        echo "Please also set a critical value when you want to use \
warning/critical thresholds!"
        exit $ST_UK
    elif [ "$wcdiff" = 3 ]
    then
        echo "Please also set a warning value when you want to use \
warning/critical thresholds!"
        exit $ST_UK
    fi
}
 
check_pid() {
    if [ -f "$path_pid/$name_pid" ]
    then
        retval=0
    else
        retval=1
    fi
}
 
get_status() {
    if [ "$secure" = 1 ]
    then
        wget_opts="-O- -q -t 3 -T 3 --no-check-certificate"
        out1=`wget ${wget_opts} http://${hostname}:${port}/${status_page}`
        sleep 1
        out2=`wget ${wget_opts} http://${hostname}:${port}/${status_page}`
    else        
        wget_opts="-O- -q -t 3 -T 3"
        out1=`wget ${wget_opts} http://${hostname}:${port}/${status_page}`
        sleep 1
        out2=`wget ${wget_opts} http://${hostname}:${port}/${status_page}`
    fi
 
    if [ -z "$out1" -o -z "$out2" ]
    then
        echo "UNKNOWN - Local copy/copies of $status_page is empty."
        exit $ST_UK
    fi
}
 
get_vals() {
    tmp1_reqpsec=`echo ${out1}|awk '{print $10}'`
    tmp2_reqpsec=`echo ${out2}|awk '{print $10}'`
    reqpsec=`expr $tmp2_reqpsec - $tmp1_reqpsec`
 
    tmp1_conpsec=`echo ${out1}|awk '{print $9}'`
    tmp2_conpsec=`echo ${out2}|awk '{print $9}'`
    conpsec=`expr $tmp2_conpsec - $tmp1_conpsec`
 
    reqpcon=`echo "scale=2; $reqpsec / $conpsec" | bc -l`
    if [ "$reqpcon" = ".99" ]
    then
        reqpcon="1.00"
    fi
}
 
do_output() {
    output="nginx is running. $reqpsec requests per second, $conpsec \
connections per second ($reqpcon requests per connection)"
}
 
do_perfdata() {
    perfdata="'reqpsec'=$reqpsec 'conpsec'=$conpsec 'conpreq'=$reqpcon"
}
 
# Here we go!
get_wcdiff
val_wcdiff
 
if [ ${pid_check} = 1 ]
then
    check_pid
    if [ "$retval" = 1 ]
    then
        echo "There's no pid file for nginx. Is nginx running? Please \
also make sure whether your pid path and name is correct."
        exit $ST_CR
    fi
fi
 
get_status
get_vals
do_output
do_perfdata
 
if [ -n "$warning" -a -n "$critical" ]
then
    if [ "$reqpsec" -ge "$warning" -a "$reqpsec" -lt "$critical" ]
    then
        echo "WARNING - ${output} | ${perfdata}"
	exit $ST_WR
    elif [ "$reqpsec" -ge "$critical" ]
    then
        echo "CRITICAL - ${output} | ${perfdata}"
	exit $ST_CR
    else
        echo "OK - ${output} | ${perfdata} ]"
	exit $ST_OK
    fi
else
    echo "OK - ${output} | ${perfdata}"
    exit $ST_OK
fi

Jordi’s script

This is Jordi’s bash built-in (plus bc) version which runs even faster. Feel free to copy the output below.

#!/bin/bash
 
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
PROGNAME=`basename $0`
VERSION="Version 1.0,"
AUTHOR="2009, Mike Adolphs (http://www.matejunkie.com/)"
 
ST_OK=0
ST_WR=1
ST_CR=2
ST_UK=3
hostname="localhost"
port=80
path_pid=/var/run
name_pid="nginx.pid"
status_page="nginx_status"
pid_check=1
secure=0
 
print_version() {
    echo "$VERSION $AUTHOR"
}
 
print_help() {
    print_version $PROGNAME $VERSION
    echo ""
    echo "$PROGNAME is a Nagios plugin to check whether nginx is running."
    echo "It also parses the nginx's status page to get requests and"
    echo "connections per second as well as requests per connection. You"
    echo "may have to alter your nginx configuration so that the plugin"
    echo "can access the server's status page."
    echo "The plugin is highly configurable for this reason. See below for"
    echo "available options."
    echo ""
    echo "$PROGNAME -H localhost -P 80 -p /var/run -n nginx.pid "
	echo "  -s nginx_statut -o /tmp [-w INT] [-c INT] [-S] [-N]"
    echo ""
    echo "Options:"
    echo "  -H/--hostname)"
    echo "     Defines the hostname. Default is: localhost"
    echo "  -P/--port)"
    echo "     Defines the port. Default is: 80"
    echo "  -p/--path-pid)"
    echo "     Path where nginx's pid file is being stored. You might need"
    echo "     to alter this path according to your distribution. Default"
    echo "     is: /var/run"
    echo "  -n/--name_pid)"
    echo "     Name of the pid file. Default is: nginx.pid"
    echo "  -N/--no-pid-check)"
    echo "     Turn this on, if you don't want to check for a pid file"
    echo "     whether nginx is running, e.g. when you're checking a"
    echo "     remote server. Default is: off"
    echo "  -s/--status-page)"
    echo "     Name of the server's status page defined in the location"
    echo "     directive of your nginx configuration. Default is:"
    echo "     nginx_status"
    echo "  -o/--output-directory)"
    echo "     Unneeded. The option is preserved for backwards compatibility."
    echo "  -S/--secure)"
    echo "     In case your server is only reachable via SSL, use this"
    echo "     this switch to use HTTPS instead of HTTP. Default is: off"
    echo "  -w/--warning)"
    echo "     Sets a warning level for requests per second. Default is: off"
    echo "  -c/--critical)"
    echo "     Sets a critical level for requests per second. Default is:"
	echo "     off"
    exit $ST_UK
}
 
while test -n "$1"; do
    case "$1" in
        -help|-h)
            print_help
            exit $ST_UK
            ;;
        --version|-v)
            print_version $PROGNAME $VERSION
            exit $ST_UK
            ;;
        --hostname|-H)
            hostname=$2
            shift
            ;;
        --port|-P)
            port=$2
            shift
            ;;
        --path-pid|-p)
            path_pid=$2
            shift
            ;;
        --name-pid|-n)
            name_pid=$2
            shift
            ;;
        --no-pid-check|-N)
            pid_check=0
            ;;
        --status-page|-s)
            status_page=$2
            shift
            ;;
        --output-directory|-o)
            output_dir=$2
            shift
            ;;
        --secure|-S)
            secure=1
            ;;
        --warning|-w)
            warning=$2
            shift
            ;;
        --critical|-c)
            critical=$2
            shift
            ;;
        *)
            echo "Unknown argument: $1"
            print_help
            exit $ST_UK
            ;;
        esac
    shift
done
 
get_wcdiff() {
    if [ ! -z "$warning" -a ! -z "$critical" ]
    then
        wclvls=1
 
        if [ ${warning} -gt ${critical} ]
        then
            wcdiff=1
        fi
    elif [ ! -z "$warning" -a -z "$critical" ]
    then
        wcdiff=2
    elif [ -z "$warning" -a ! -z "$critical" ]
    then
        wcdiff=3
    fi
}
 
val_wcdiff() {
    if [ "$wcdiff" = 1 ]
    then
        echo "Please adjust your warning/critical thresholds. The warning \
must be lower than the critical level!"
        exit $ST_UK
    elif [ "$wcdiff" = 2 ]
    then
        echo "Please also set a critical value when you want to use \
warning/critical thresholds!"
        exit $ST_UK
    elif [ "$wcdiff" = 3 ]
    then
        echo "Please also set a warning value when you want to use \
warning/critical thresholds!"
        exit $ST_UK
    fi
}
 
check_pid() {
    if [ -f "$path_pid/$name_pid" ]
    then
        retval=0
    else
        retval=1
    fi
}
 
get_status() {
    url="http://${hostname}:${port}/${status_page}"
 
    if [ "$secure" = 1 ] ; then
        wget_opts="-O- -q -t 3 -t 3 --no-check-certificate"
    else
        wget_opts="-O- -q -t 3 -t 3"
    fi
 
    out1=$(wget ${wget_opts} ${url})
    sleep 1
    out2=$(wget ${wget_opts} ${url})
 
    # Both commands must return some content.
    if [ -z "${out1}" -o -z "${out2}" ] ; then
        echo "UNKNOWN - Local copy/copies of $status_page is empty."
        exit $ST_UK
    fi
}
 
get_vals() {
    # Convert into an array.
    values1=(${out1})
    values2=(${out2})
 
    reqpsec=$(( ${values2[9]} - ${values1[9]} ))
    conpsec=$(( ${values2[8]} - ${values1[8]} ))
 
    reqpcon=`echo "scale=2; $reqpsec / $conpsec" | bc -l`
    if [ "$reqpcon" = ".99" ]
    then
        reqpcon="1.00"
    fi
}
 
do_output() {
    output="nginx is running. $reqpsec requests per second, $conpsec \
connections per second ($reqpcon requests per connection)"
}
 
do_perfdata() {
    perfdata="'reqpsec'=$reqpsec 'conpsec'=$conpsec 'conpreq'=$reqpcon"
}
 
# Here we go!
get_wcdiff
val_wcdiff
 
if [ ${pid_check} = 1 ]
then
    check_pid
    if [ "$retval" = 1 ]
    then
        echo "There's no pid file for nginx. Is nginx running? Please \
also make sure whether your pid path and name is correct."
        exit $ST_CR
    fi
fi
 
get_status
get_vals
do_output
do_perfdata
 
if [ -n "$warning" -a -n "$critical" ]
then
    if [ "$reqpsec" -ge "$warning" -a "$reqpsec" -lt "$critical" ]
    then
        echo "WARNING - ${output} | ${perfdata}"
	exit $ST_WR
    elif [ "$reqpsec" -ge "$critical" ]
    then
        echo "CRITICAL - ${output} | ${perfdata}"
	exit $ST_CR
    else
        echo "OK - ${output} | ${perfdata} ]"
	exit $ST_OK
    fi
else
    echo "OK - ${output} | ${perfdata}"
    exit $ST_OK
fi

License

As always this little script is ment to be sh-compliant and released under the terms of the GPL Version 2 only. Feel free to subscribe via rss to get updates on this one. More options will be added in the future.

Share and Enjoy:
  • del.icio.us
  • Digg
  • Slashdot
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Yigg
  • Netvibes
  • MisterWong
  • Facebook
  • HackerNews
  • Identi.ca
  • FriendFeed
  • NewsVine

Matejunkie

Monkey Island Tattoo Project

Over the past months we’ve been working on a little project here: Getting various Monkey Island artworks (2 packshots and an ingame scene) tattooed. Now, the first of three tattoos is finally finished. It’s the packshot of Monkey Island II on the right calf (with a little variation, of course).

But why Monkey Island?
It’s not only because I’m mostly a nerd, but also because Monkey Island builds a bridge to what I’m doing today. I was a teenager when I discovered Monkey Island and got excited right from the start. Simply put, Monkey Island got me addicted to the IT and that’s why I want to keep it in memory this way.

… and because I’m a mighty pirate! Yaaarghw!

Since my tattoo artiste spends her summertime in San Francisco, CA we’ll get back to work in October or November with the packshot of Monkey Island 1 on the left calf. Meaning, it’ll be finished around spring next year.

Share and Enjoy:
  • del.icio.us
  • Digg
  • Slashdot
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Yigg
  • Netvibes
  • MisterWong
  • Facebook
  • HackerNews
  • Identi.ca
  • FriendFeed
  • NewsVine

Binary Talks

How to fix NetworkManager’s OpenVPN plugin in Ubuntu 9.04

The OpenVPN plugin for Gnome’s NetworkManager is somewhat broken, at least in various Ubuntu releases. Even with proper configuration it runs into an “NeedSecrets” error although the same command with the same configuration from shell via sudo work’s just fine.
But fear not mighty roadwarrior! Here’s a fix to let the NetworkManager get back to work.

Needless to say that this is just a temporary solution (a fix is in the making), but the only thing you have to do is to add an at_console policy to /etc/dbus-1/system.d/nm-openvpn-service.conf right between the two already existing policies.

	<policy user="at_console">
		<allow own="org.freedesktop.NetworkManager.vpnc"/>
		<allow send_destination="org.freedesktop.NetworkManager.vpnc"/>
	</policy>

Then the file should look like the following:

<!DOCTYPE busconfig PUBLIC
 "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
	<policy user="root">
		<allow own="org.freedesktop.NetworkManager.openvpn"/>
		<allow send_destination="org.freedesktop.NetworkManager.openvpn"/>
	</policy>
	<policy user="at_console">
		<allow own="org.freedesktop.NetworkManager.vpnc"/>
		<allow send_destination="org.freedesktop.NetworkManager.vpnc"/>
	</policy>
	<policy context="default">
		<deny own="org.freedesktop.NetworkManager.openvpn"/>
		<deny send_destination="org.freedesktop.NetworkManager.openvpn"/>
	</policy>
</busconfig>

Afterwards simply restart the NetworkManager via “sudo /etc/init.d/NetworkManager restart” and it’ll work. For Solutions for other VPN technologies you may also consider Ubuntu’s Launchpad.

Share and Enjoy:
  • del.icio.us
  • Digg
  • Slashdot
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Yigg
  • Netvibes
  • MisterWong
  • Facebook
  • HackerNews
  • Identi.ca
  • FriendFeed
  • NewsVine

Binary Talks

Nagios Exchange opens up

Just a short note from my side:
A week ago Ethan launched Nagios Exchange, an addon and plugin repository similar to MonitoringExchange, which is part of the whole Nagios website framework. I began to add all of my plugins to it as well, but due to the approval process it might take a while till they’re downloadable. I’ll let you know when it’s done.

Nevertheless, from now on you’re even more free from where to download the plugins I’ve written. From now on they’re available via this blog, via SVN, via MonitoringExchange and via Nagios Exchange. I’ll update them on all sources.

Share and Enjoy:
  • del.icio.us
  • Digg
  • Slashdot
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Yigg
  • Netvibes
  • MisterWong
  • Facebook
  • HackerNews
  • Identi.ca
  • FriendFeed
  • NewsVine

Binary Talks

Hadoop DFS Check Plugin for Nagios

logo_nagiosSince I’m currently occupied with kicking off a several terabytes large Hadoop cluster I thought it’d be a good idea to provide a few Nagios plugins related to Hadoop.

Just in case you don’t know: Hadoop is a free Java software framework that supports data intensive distributed applications. It got its own filesystem called HDFS which scales up to petabytes of storage running on top of the operating system’s filesystem. Hadoop is inspired by Google’s MapReduce and GFS, the Google File System.

Yahoo for example uses several Hadoop Clusters with 100.000 CPUs total in 20.000 boxes (2.000 boxes per cluster) according to the official Hadoop website. If you haven’t checked it out yet, do so! This is – sorry for that – crazy shit and it’s working!
For the beginning I’d recommend reading the Wikipedia article, the offical documentation and, of course, watching the Hadoop related lectures over at Cloudera.

Anyway, the first plugin is almost finished and checks the amount of running DataNodes and the capacity of the DFS. It’s working, but I want to add a few more features so that the plugin become more flexible. Nevertheless, feel free to give it a try if you’re in the mood.

The Script

Hadoop is completely operated by the hadoop user and since it got its own filesystem it got its own permissions as well. To keep things clean and safe we won’t give hadoop related permissions to the Nagios user. We’ll rather enable the Nagios user to run a small shell script as root which contains a command ran by the hadoop user to get information about the cluster.

Add the following small script to a directory of your choice, e.g. /usr/local/sbin:

#!/bin/sh
su -s /bin/bash - hadoop -c 'hadoop dfsadmin -report'

Afterwards alter its permissions so that it’s only read-, write and accessible by root:

user@host: ~ $ sudo chmod 700 /usr/local/sbin/get-dfsreport.sh

Then enable the Nagios user to sudo run the script via /etc/sudoers (or better visudo):

nagios          ALL=(ALL)       NOPASSWD: /usr/local/sbin/get-dfsreport.sh

This is it for the prerequisites. You may then run the script provided for copy’n'pasting below (or svn co, your choice).
If you’ve chosen another directory than /usr/local/sbin you have to provide the path via -s/–path-sh when running the script.

user@host: ~ $ svn co svn://svn.matejunkie.com/nagios-plugins/stable/check_hadoop-dfs/ check_hadoop-dfs/
#!/bin/sh
 
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
PROGNAME=`basename $0`
VERSION="Version 1.0,"
AUTHOR="2009, Mike Adolphs (http://www.matejunkie.com/)"
 
ST_OK=0
ST_WR=1
ST_CR=2
ST_UK=3
 
path_sh="/usr/local/sbin"
 
print_version() {
    echo "$VERSION $AUTHOR"
}
 
print_help() {
    print_version $PROGNAME $VERSION
    echo ""
    echo "$PROGNAME is a Nagios plugin to check the status of HDFS, Hadoop's"
    echo "underlying, redundant, distributed file system."
    echo ""
    echo "$PROGNAME -s /usr/local/sbin [-w 10] [-c 5]"
    echo ""
    echo "Options:"
    echo "  -s|--path-sh)"
    echo "     Path to the shell script that is mentioned in the"
    echo "     documentation. Default is: /usr/local/sbin"
    echo "  -w|--warning)"
    echo "     Defines the warning level for available datanodes. Default"
    echo "     is: off"
    echo "  -c|--critical)"
    echo "     Defines the critical level for available datanodes. Default"
    echo "     is: off"
    exit $ST_UK
}
 
while test -n "$1"; do
    case "$1" in
        -help|-h)
            print_help
            exit $ST_UK
            ;;
        --version|-v)
            print_version $PROGNAME $VERSION
            exit $ST_UK
            ;;
        --path-sh|-s)
            path_sh=$2
            shift
            ;;
        --warning|-w)
            warning=$2
            shift
            ;;
        --critical|-c)
            critical=$2
            shift
            ;;
        *)
            echo "Unknown argument: $1"
            print_help
            exit $ST_UK
            ;;
        esac
    shift
done
 
get_wcdiff() {
    if [ ! -z "$warning" -a ! -z "$critical" ]
    then
        wclvls=1
 
        if [ ${warning} -lt ${critical} ]
        then
            wcdiff=1
        fi
    elif [ ! -z "$warning" -a -z "$critical" ]
    then
        wcdiff=2
    elif [ -z "$warning" -a ! -z "$critical" ]
    then
        wcdiff=3
    fi
}
 
val_wcdiff() {
    if [ "$wcdiff" = 1 ]
    then
        echo "Please adjust your warning/critical thresholds. The warning \
must be higher than the critical level!"
        exit $ST_UK
    elif [ "$wcdiff" = 2 ]
    then
        echo "Please also set a critical value when you want to use \
warning/critical thresholds!"
        exit $ST_UK
    elif [ "$wcdiff" = 3 ]
    then
        echo "Please also set a warning value when you want to use \
warning/critical thresholds!"
        exit $ST_UK
    fi
}
 
get_vals() {
    tmp_vals=`sudo ${path_sh}/get-dfsreport.sh`
    dn_avail=`echo -e "$tmp_vals" | grep -m1 "Datanodes available:" | awk '{print $3}'`
    dfs_used=`echo -e "$tmp_vals" | grep -m1 "Used raw bytes:" | awk '{print $4}'`
    dfs_used=`expr ${dfs_used} / 1024 / 1024`
    dfs_used_p=`echo -e "$tmp_vals" | grep -m1 "% used:" | awk '{print $3}'`
    dfs_total=`echo -e "$tmp_vals" | grep -m1 "Total raw bytes:" | awk '{print $4}'`
    dfs_total=`expr ${dfs_total} / 1024 / 1024`
}
 
do_output() {
    output="Datanodes up and running: ${dn_avail}, DFS total: \
${dfs_total} MB, DFS used: ${dfs_used} MB (${dfs_used_p})"
}
 
do_perfdata() {
    perfdata="'datanodes_available'=${dn_avail} 'dfs_total'=${dfs_total} \
'dfs_used'=${dfs_used}"
}
 
# Here we go!
get_wcdiff
val_wcdiff
 
get_vals
 
do_output
do_perfdata
 
if [ -n "$warning" -a -n "$critical" ]
then
    if [ "$dn_avail" -le "$warning" -a "$dn_avail" -gt "$critical" ]
    then
        echo "WARNING - ${output} | ${perfdata}"
	exit $ST_WR
    elif [ "$dn_avail" -le "$critical" ]
    then
        echo "CRITICAL - ${output} | ${perfdata}"
	exit $ST_CR
    else
        echo "OK - ${output} | ${perfdata} "
	exit $ST_OK
    fi
else
    echo "OK - ${output} | ${perfdata}"
    exit $ST_OK
fi

Output example:

If everything went fine you should see output like the following:

user@host: ~ $ ./check_hadoop-dfs.sh -s /var/nagios/home/bin
OK - Datanodes up and running: 50, DFS total: 20147365 MB, DFS used: 0 MB (0%) | 'datanodes_available'=50 'dfs_total'=20147365 'dfs_used'=0
user@host: ~ $ ./check_hadoop-dfs.sh -s /var/nagios/home/bin -w 40 -c 30
OK - Datanodes up and running: 50, DFS total: 20147365 MB, DFS used: 0 MB (0%) | 'datanodes_available'=50 'dfs_total'=20147365 'dfs_used'=0
user@host: ~ $ ./check_hadoop-dfs.sh -s /var/nagios/home/bin -w 60 -c 40
WARNING - Datanodes up and running: 50, DFS total: 20147365 MB, DFS used: 0 MB (0%) | 'datanodes_available'=50 'dfs_total'=20147365 'dfs_used'=0
user@host: ~ $ ./check_hadoop-dfs.sh -s /var/nagios/home/bin -w 70-c 60
CRITICAL - Datanodes up and running: 50, DFS total: 20147365 MB, DFS used: 0 MB (0%) | 'datanodes_available'=50 'dfs_total'=20147365 'dfs_used'=0
user@host: ~ $ ./check_hadoop-dfs.sh -s /var/nagios/home/bin -w 20 -c 40
Please adjust your warning/critical thresholds. The warning must be higher than the critical level!
user@host: ~ $ ./check_hadoop-dfs.sh -s /var/nagios/home/bin -w 30
Please also set a critical value when you want to use warning/critical thresholds!
user@host: ~ $ ./check_hadoop-dfs.sh -s /var/nagios/home/bin -c 30
Please also set a warning value when you want to use warning/critical thresholds!

The License

As always this little script is ment to be sh-compliant and released under the terms of the GPL Version 2 only. Feel free to subscribe via rss to get updates on this one. More options will be added in the future.

Share and Enjoy:
  • del.icio.us
  • Digg
  • Slashdot
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Yigg
  • Netvibes
  • MisterWong
  • Facebook
  • HackerNews
  • Identi.ca
  • FriendFeed
  • NewsVine

Binary Talks

PNP Template for Process Check Plugin

Just a short note:
Here’s the appropriate PNP Template to the process check plugin which I’ve recently written to create nice and shiny graphs:

#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

#   PNP Template for check_ps.sh
#   Author: Mike Adolphs (http://www.matejunkie.com/

$opt[1] = "--vertical-label \"percent\" -u 100 -l 0 -r --title \"CPU/Memory Usage for $hostname / $servicedesc\" ";
$opt[2] = "--vertical-label \"minutes\" -u 100 -l 0 -r --title \"cputime for $hostname / $servicedesc\" ";
 
$def[1] =  "DEF:cpu=$rrdfile:$DS[1]:AVERAGE " ;
$def[1] .=  "DEF:memory=$rrdfile:$DS[2]:AVERAGE " ;
$def[2] .=  "DEF:cputime=$rrdfile:$DS[3]:AVERAGE " ;
 
$def[1] .= "COMMENT:\"\\t\\t\\tLAST\\t\\t\\tAVERAGE\\t\\t\\tMAX\\n\" " ;
$def[2] .= "COMMENT:\"\\t\\t\\tLAST\\t\\t\\tAVERAGE\\t\\t\\tMAX\\n\" " ;
 
$def[1] .= "LINE2:cpu#E80C3E:\"CPU\\t\\t\" " ;
$def[1] .= "GPRINT:cpu:LAST:\"%6.2lf %%\\t\\t\" " ;
$def[1] .= "GPRINT:cpu:AVERAGE:\"%6.2lf \\t\\t\" " ;
$def[1] .= "GPRINT:cpu:MAX:\"%6.2lf \\n\" " ;
 
$def[1] .= "LINE2:memory#008000:\"Memory\\t\" " ;
$def[1] .= "GPRINT:memory:LAST:\"%6.2lf %%\\t\\t\" " ;
$def[1] .= "GPRINT:memory:AVERAGE:\"%6.2lf \\t\\t\" " ;
$def[1] .= "GPRINT:memory:MAX:\"%6.2lf \\n\" " ;
 
$def[2] .= "AREA:cputime#E80C3E:\"CPUTime\\t\" " ;
$def[2] .= "GPRINT:cputime:LAST:\"%6.2lf min\\t\\t\" " ;
$def[2] .= "GPRINT:cputime:AVERAGE:\"%6.2lf min\\t\\t\" " ;
$def[2] .= "GPRINT:cputime:MAX:\"%6.2lf min\\n\" " ;
Share and Enjoy:
  • del.icio.us
  • Digg
  • Slashdot
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Yigg
  • Netvibes
  • MisterWong
  • Facebook
  • HackerNews
  • Identi.ca
  • FriendFeed
  • NewsVine

World wide web

Microsoft’s Bing vs. Google search

Microsoft just relaunched its search engine Live and renamed it to Bing to make a fresh start. Despite the fact that it has several interesting features like playing flash videos within the actual search results by hovering or additional site information to the right of almost every search result, it – sorry to say – still disappoints.

se_bing_01For example, searching for Linux in Bing shows Microsoft product placement within the search suggestions. Though this lets every IT professional grin from ear to ear, it could have major impact on “not so professional” people when they want to see what “this so called Linux” is about and rely on search suggestions.

se_google_01Google instead shows suggestions that are pretty useful, when someone wants to get in touch with Linux.
In general it seems that Google tries to avoid product placement within the suggestions. Searching for “reader” for example doesn’t show any related content to Google Reader.

The same applies to the search for SQL. On the Bing hand it shows product placement for Microsoft’s SQL related products, Google on its hand offers way more universal suggestions.

Don’t get me wrong. Although I’m an open source addict, I’m not a Microsoft hater. I’d actually use Microsoft software in several areas if I have to. SQL Server 2008 for example is an awesome piece of software, but when it comes to the Internet they still seem to struggle.
If I’m searching for something I want to get to the result and not being bothered by subtle advertising and I definitely want to get a proper, almost universally valid search result, of course. Google makes this just right and I guess that’ll last a couple more years since there’s still no real competitor in the race. They still claim that search is their main product, of course.

Google’s power is simplicity, Microsoft makes it too complicated. It’s that easy.

The background picture at bing.com that changes every 24 hours and comes with several overlays to get additional information is a really nice idea to pass time and actually makes Bing more pleasant. How often do I browse the wikipedia clicking from one article to another to learn stuff I haven’t even heard of last week? Two times a week at least.
But why do I have to install Silverlight when I want to go back to last days picture? Couldn’t this have been done without the need to install additional software? This way it’s kinda obvious that Microsoft wants to push its alternative to Flash through their search engine and as I said, it’s all about the results and not about binding people to its own solutions.

The Internet is all about interoperability. Something that Microsoft obviously still don’t get and that’s sad because a little more competition in the search engine business would be quite nice.

Share and Enjoy:
  • del.icio.us
  • Digg
  • Slashdot
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Yigg
  • Netvibes
  • MisterWong
  • Facebook
  • HackerNews
  • Identi.ca
  • FriendFeed
  • NewsVine