<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ball Dawg! &#187; Perl</title>
	<atom:link href="http://www.balldawg.net/index.php/tag/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.balldawg.net</link>
	<description>Just some ninja monkeys, nothing to see here.  Move along.</description>
	<lastBuildDate>Fri, 13 Jan 2012 02:02:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Glovebox v0.2.1 Released</title>
		<link>http://www.balldawg.net/index.php/2009/06/glovebox-v0-2-released/</link>
		<comments>http://www.balldawg.net/index.php/2009/06/glovebox-v0-2-released/#comments</comments>
		<pubDate>Sat, 13 Jun 2009 23:06:02 +0000</pubDate>
		<dc:creator>Andrew Rankin</dc:creator>
				<category><![CDATA[Glovebox]]></category>
		<category><![CDATA[Server Management]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.balldawg.net/?p=219</guid>
		<description><![CDATA[I&#8217;ve released Glovebox Version 0.2.1 on Sourceforge.  It has a few bug fixes as well as the correct database schema included. Other changes include: Modified JavaScript so it would load &#38; function in IE Changed &#8220;class&#8221; to &#8220;clas&#8221; within JS, Perl, and the database. IE didn&#8217;t like using the word &#8220;class&#8221; as a variable name, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released <a href="https://sourceforge.net/projects/glovebox/" target="_blank">Glovebox Version 0.2.1 on Sourceforge</a>.  It has a few bug fixes as well as the correct database schema included.  Other changes include:</p>
<ul>
<li>Modified JavaScript so it would load &amp; function in IE</li>
<li>Changed &#8220;class&#8221; to &#8220;clas&#8221; within JS, Perl, and the database.  IE didn&#8217;t like using the word &#8220;class&#8221; as a variable name, changed else where for consistency.</li>
<li>Stopped opening of &#8220;right-click&#8221; menu when pressed on an interface folder</li>
<li>Fixed DB Schema to include basic information for default OIDs and Interfaces.</li>
<li>Modified Apache configuration so SSIs would work correctly in Apache 2, changed the SSIs to only execute on .shtml files</li>
<li>Renamed index.html to index.shtml</li>
</ul>
<p>There is a database change, so you must run the sql file located in the upgrade folder!</p>
<p>You can download it <a href="https://sourceforge.net/project/showfiles.php?group_id=262902" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.balldawg.net/index.php/2009/06/glovebox-v0-2-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Glovebox Released on SourceForge</title>
		<link>http://www.balldawg.net/index.php/2009/05/glovebox-released-on-sourceforge/</link>
		<comments>http://www.balldawg.net/index.php/2009/05/glovebox-released-on-sourceforge/#comments</comments>
		<pubDate>Tue, 19 May 2009 22:16:16 +0000</pubDate>
		<dc:creator>Andrew Rankin</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Glovebox]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Server Management]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[SourceForge]]></category>

		<guid isPermaLink="false">http://www.balldawg.net/?p=122</guid>
		<description><![CDATA[On the request of my Manager, I have released Glovebox under a GPL license on Sourceforge.  I have yet to update the site with instructions but hope to soon.  I&#8217;ve included a tar ball of the current version as well as imported the full source code in Sourceforge&#8217;s SVN repo. The SourceForge project page is [...]]]></description>
			<content:encoded><![CDATA[<p>On the request of my Manager, I have released Glovebox under a GPL license on <a href="http://sourceforge.net/" target="_blank">Sourceforge</a>.  I have yet to update the site with instructions but hope to soon.  I&#8217;ve included a tar ball of the current version as well as imported the full source code in <a href="http://glovebox.svn.sourceforge.net/viewvc/glovebox/" target="_blank">Sourceforge&#8217;s SVN repo</a>.</p>
<p>The SourceForge project page is located <a href="http://sourceforge.net/projects/glovebox/" target="_blank">here</a>.<br />
The project home page is located <a href="http://www.balldawg.net/index.php/glovebox/" target="_self">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.balldawg.net/index.php/2009/05/glovebox-released-on-sourceforge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Your Own Hobbit / Xymon Tests</title>
		<link>http://www.balldawg.net/index.php/2009/05/creating-your-own-hobbit-xymon-tests/</link>
		<comments>http://www.balldawg.net/index.php/2009/05/creating-your-own-hobbit-xymon-tests/#comments</comments>
		<pubDate>Sat, 09 May 2009 14:54:00 +0000</pubDate>
		<dc:creator>Andrew Rankin</dc:creator>
				<category><![CDATA[Hobbit / Xymon]]></category>
		<category><![CDATA[Server Monitoring]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[xymon]]></category>

		<guid isPermaLink="false">http://www.balldawg.net/?p=96</guid>
		<description><![CDATA[Over the years I&#8217;ve had to write plenty of Hobbit / Xymon scripts to monitor various different things within my employers systems.   Since most all of our applications are custom there are not always built in tests that will work for us.   For example, we use Xen for our development virtual machines and being able to [...]]]></description>
			<content:encoded><![CDATA[<p>Over the years I&#8217;ve had to write plenty of Hobbit / Xymon scripts to monitor various different things within my employers systems.   Since most all of our applications are custom there are not always built in tests that will work for us.   For example, we use Xen for our development virtual machines and being able to track what was going on with those virtual machines is important and being able to identify a VM within Xymon at a moments glance is important to us, so we created a test that does just that.   We have created in house scripts for MySQL Status, MySQL Running Queries, our in house distributed services, Lighttpd (as discussed earlier on this blog), Apache, Memcached, etc.   This doesnt include the hundreds of different snmp tests we&#8217;ve added to Devmon for monitoring our network equiptment.</p>
<p><span id="more-96"></span></p>
<p>Since I&#8217;ve had to write quite a few of these I thought I&#8217;d share a simple recipe for getting started with these scripts.   Most all our scripts are written in Perl, its just what I&#8217;m used too and what most people in our company is fluent in.   Our older scripts (from when we actually ran Big Brother) are almost all shell scripts and I have written at least one in Python since that particular service&#8217;s library was in python.   For this example I&#8217;m going to use Perl default template:</p>
<pre class="brush: perl">
#!/usr/bin/perl -w
#############################################################################
# $Id: $
#############################################################################
use strict;

## BB and related test constants
#############################################################################

use constant GREEN =&gt; &#039;green&#039;;
use constant YELLOW =&gt; &#039;yellow&#039;;
use constant RED =&gt; &#039;red&#039;;

## BB Global variables
#############################################################################

my $prev_run_log = &quot;$ENV{BBTMP}/$ENV{MACHINE}.lighttpd.data&quot;;
my $bbtest = &#039;testname&#039;;
my $color = GREEN;
my $status = $bbtest . &quot; OK&quot;;

## Main Program
#############################################################################
{

my $DATA = &quot;&quot;;

## TEST STUFF HERE

## Send to Hobbit
#############################################################################
my $report_date = `/bin/date`;
chomp($report_date);

system(&quot;$ENV{BB} $ENV{BBDISP} &#039;status $ENV{MACHINE}.$bbtest $color $report_date - $status\n\n$DATA&#039;\n&quot;);

}
</pre>
<p>This script by itself will send a test called &#8216;testname&#8217;, which is green and has the status of &#8216;OK&#8217;.  Since we have not defined anything to test it won&#8217;t contain any data with it.  To run this script you need to be within Xymon&#8217;s &#8220;shell&#8221;, which is basically sh, with some enviroment variables set.  To get there, go to &#8217;bin&#8217; directory within your hobbit client installation, in my case this is: &#8220;/home/hobbit/client/bin&#8221;, you&#8217;ll need to run &#8216;bbcmd&#8217;, this will drop you to a prompt which looks something like this:</p>
<pre class="brush: perl">
[rar@apollo bin]$ ./bbcmd
2009-05-09 10:10:35 Using default environment file /home/hobbit/client/etc/hobbitclient.cfg
sh-3.2$
</pre>
<p>Lets change the test name to something else and gather some data from the system we are running on.   To change the test name to say &#8216;modules&#8217;, just change the $bbtest to &#8216;modules&#8217;.   How about testing what kernel modules are loaded &#8211; or basically just parse the output of &#8216;lsmod&#8217;.   To do this we&#8217;d need to capture the output of the command, this is easy enough in perl, something like this would work just fine:</p>
<pre class="brush: perl">
my $lsmod = `/sbin/lsmod`;
</pre>
<p>With the output of &#8217;lsmod&#8217; captured we can do whatever we want with it.  Lets say we just want the modules, and no other info about them in an array:</p>
<pre class="brush: perl">
my $lsmod = `/sbin/lsmod`;
my @modules = split(/\n/, $lsmod);
my @module_names;

foreach my $module (@modules){
my ($name, $junk) = split(/\s.+/, $module);
push @module_names, $name;
}
</pre>
<p>Now that we have our array created that we can easily loop through for tests, lets run a test on them to see if we have loaded any modules for &#8216;ext&#8217; file systems:</p>
<pre class="brush: perl">
foreach my $module (@module_names) {
if ($module =~ &quot;ext&quot;){
$color = RED;
$status = $bbtest . &quot; NOT OK&quot;
}
}
</pre>
<p>OK,  since we&#8217;d like a list of modules that are loaded on our hobbit test page, we can add all those modules to the &#8216;$DATA&#8217; variable, and finish off this example test.  Within that last look we added, you&#8217;d just push that modules name into &#8216;$DATA&#8217;:</p>
<pre class="brush: perl">
[...]
$status = $bbtest . &quot; NOT OK&quot;
}

$DATA .= $module . &quot;\n&quot;;
}
</pre>
<p>So what kindof output does this give us?  If you want to just see what would be run in the system() call at the bottom of the script, just change &#8216;system&#8217; to &#8216;print&#8217;, the output should be something like the following:</p>
<pre class="brush: perl">
/home/hobbit/client/bin/bb hobbitserver.xipnet.net &#039;status apollo.modules red Sat May  9 10:35:18 EDT 2009 - modules NOT OK

Module
iptable_filter
ip_tables
rfcomm
l2cap
bluetooth
af_packet
nf_conntrack_netbios_ns
ipt_REJECT
nf_conntrack_ipv4
xt_state
nf_conntrack
ip6t_REJECT
xt_tcpudp
ip6table_filter
ip6_tables
x_tables
ipv6
binfmt_misc
dm_multipath
parport_pc
lp
parport
nvram
evbug
usbcore
ext3
jbd
mbcache
evdev
raid10
raid456
async_xor
async_memcpy
async_tx
xor
raid1
raid0
multipath
linear
md_mod
dm_mirror
dm_snapshot
dm_mod
fuse
loop
8250
serial_core
&#039;
</pre>
<p>Now the test is red and has the status of &#8220;NOT OK&#8221; since we tested for any ext file system and I&#8217;m running ext3.   To have the data sent to hobbit, simply set the print back to a system call and setup the approprate section within &#8216;clientlaunch.cfg&#8217;, for our example I&#8217;d use:</p>
<pre class="brush: perl">
[modules]
ENVFILE $HOBBITCLIENTHOME/etc/hobbitclient.cfg
CMD $HOBBITCLIENTHOME/ext/bb-modules.pl
LOGFILE $HOBBITCLIENTHOME/logs/hobbitclient.log
INTERVAL 5m
</pre>
<p>I know this is a pretty basic example, but its a place to start &#8211; just let the imagination go from here on the millions of tests you could come up with.  Keep in mind I&#8217;m sending this data in on the &#8220;status&#8221; channel in Xymon &#8211; there is also a &#8220;data&#8221; channel which won&#8217;t create a column and with the test approprately setup within hobbit to capture its data to rrd&#8217;s, you can create graphs that just show up in the &#8220;trends&#8221; column if alarming is not necessary.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.balldawg.net/index.php/2009/05/creating-your-own-hobbit-xymon-tests/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Glovebox: My Solution to Managing Servers</title>
		<link>http://www.balldawg.net/index.php/2009/05/glovebox-my-solution-to-managing-servers/</link>
		<comments>http://www.balldawg.net/index.php/2009/05/glovebox-my-solution-to-managing-servers/#comments</comments>
		<pubDate>Sat, 09 May 2009 01:39:05 +0000</pubDate>
		<dc:creator>Andrew Rankin</dc:creator>
				<category><![CDATA[Glovebox]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Server Management]]></category>
		<category><![CDATA[libvirt]]></category>

		<guid isPermaLink="false">http://www.balldawg.net/?p=58</guid>
		<description><![CDATA[When I started in the &#8220;Technology&#8221; department at my current employer, I found myself apart of a team that was tasked with taking care of hundreds of IBM blade servers, and tens of other IBM system x servers.  For the most part we could keep up with our servers by where they were in our [...]]]></description>
			<content:encoded><![CDATA[<p>When I started in the &#8220;Technology&#8221; department at my current employer, I found myself apart of a team that was tasked with taking care of hundreds of IBM blade servers, and tens of other IBM system x servers.  For the most part we could keep up with our servers by where they were in our monitoring software, but if we needed to know exactly where they were in either a blade center, by remote console name, or what Domain-0 they lived on for our Xen based virtual machines &#8211; we had to relate back to a usually out of date spreadsheet that showed where to go.</p>
<p><span id="more-58"></span></p>
<p>After a year of this mess I decided to go a different route &#8211; a dynamic web application that would update it self based on data pulled from the blade centers via SNMP.  Glovebox was born.  Well, actually it was called &#8220;the dashboard&#8221; in the beginning &#8211; unfortunately for me my co-workers have no issue pointing out when things aren&#8217;t named quite right, a sarcastic &#8220;well it ain&#8217;t a dashboard&#8230; how about Glovebox!&#8221; decided the name fate of it.   The product took almost a year to get to its current self, but manages to keep track of all our blades, IBM RSA II consoles and our Xen virtual machines without the input from anyone on staff.</p>
<p>For the IBM blades and RSA II cards it uses a set of OIDs I gathered from sifting through their respective snmp output.  In the case of the blades, those OIDs are:</p>
<pre class="brush: sql">
| 1.3.6.1.4.1.2.3.51.2.2.21.1.1.3    | bladecenters | serial          |
| 1.3.6.1.4.1.2.3.51.2.2.8.1.1       | bladecenters | error           |
| 1.3.6.1.4.1.2.3.51.2.2.21.1.1.2    | bladecenters | family          |
| 1.3.6.1.4.1.2.3.51.2.2.21.1.1.1    | bladecenters | model           |
| 1.3.6.1.4.1.2.3.51.2.22.3.1.1.1.15 | switches     | error           |
| 1.3.6.1.4.1.2.3.51.2.22.3.1.7.1.6  | switches     | address         |
| 1.3.6.1.4.1.2.3.51.2.2.21.5.1.1.6  | servers      | bios            |
| 1.3.6.1.4.1.2.3.51.2.2.21.4.1.1.6  | servers      | serial          |
| 1.3.6.1.4.1.2.3.51.2.2.21.4.1.1.7  | servers      | model           |
| 1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.6  | servers      | hostname        |
| 1.3.6.1.4.1.2.3.51.2.2.21.5.3.1.6  | servers      | bsmp            |
| 1.3.6.1.4.1.2.3.51.2.2.8.2.1.1.7   | servers      | error           |
| 1.3.6.1.4.1.2.3.51.2.2.8.2.1.1.4   | servers      | power           |
| 1.3.6.1.4.1.2.3.51.2.2.21.4.1.1.20 | servers      | storage         |
| 1.3.6.1.4.1.2.3.51.2.2.21.4.1.1.12 | servers      | family          |
| 1.3.6.1.4.1.2.3.51.2.22.3.1.7.1.5  | switches     | serial          |
| 1.3.6.1.4.1.2.3.51.2.3.4.2.1.2     | bladecenters | eventlog        |
| 1.3.6.1.4.1.2.3.51.2.4.5.1         | bladecenters | name            |
| 1.3.6.1.4.1.2.3.51.2.2.10.5.1.2    | bladecenters | watts           |
| 1.3.6.1.4.1.2.3.51.2.2.10.5.1.3    | bladecenters | btus            |
| 1.3.6.1.4.1.2.3.51.2.4.9.1.1.3     | bladecenters | hostname        |
| 1.3.6.1.4.1.2.3.51.2.2.8.1.2       | bladecenters | infoled         |
| 1.3.6.1.4.1.2.3.51.2.2.8.1.3       | bladecenters | templed         |
| 1.3.6.1.4.1.2.3.51.2.2.8.1.4       | bladecenters | identled        |
| 1.3.6.1.4.1.2.3.51.2.22.4.25       | bladecenters | installedblades |
| 1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.3  | mm           | firmware        |
| 1.3.6.1.4.1.2.3.51.2.22.4.30       | bladecenters | installedmms    |
| 1.3.6.1.4.1.2.3.51.2.2.21.2.1.1.9  | mm           | serial          |
| 1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.6  | mm           | firmware_date   |
| 1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.2  | mm           | name            |
| 1.3.6.1.4.1.2.3.51.2.22.5.1.1.3    | mm           | address         |
| 1.3.6.1.4.1.2.3.51.2.22.5.1.1.5    | mm           | error           |
| 1.3.6.1.4.1.2.3.51.2.22.5.1.1.4    | mm           | primary         |
</pre>
<p>From the list you can see I monitor not just the blades but also the management modules, the chassis, and the blade switches.  The snmp output on the IBM Advanced Management Modules is quite complete and they provide good MIBs to be able to decipher the information.</p>
<p>I have a similar list for the RSA II cards which was added after a re-write of the initial version of Glovebox mid last year, the re-write was to make the software be able to use &#8220;modules&#8221; for each device, this was so adding future additions was easy.   The Xen virtual machines are added via libvirt and its associated Perl module, I have setup keys between the server that this application runs on and each Domain-0, allowing it connection and figure out whats running on there.   Since it based off modules you very well could add anything you wanted &#8211; it even has a shared development libary that allows for easy additions without re-inventing the wheel.</p>
<p>So whats it look like?  Well it looks like any application written with ExtJS as the front end &#8211; quite good.  I&#8217;m not a designer, I can&#8217;t do graphics, but with the help of ExtJS it came out quite nicely.  How about a peak:</p>
<p>
<a href='http://www.balldawg.net/index.php/2009/05/glovebox-my-solution-to-managing-servers/eventlog/' title='Blade Center Event Log'><img width="150" height="115" src="http://www.balldawg.net/wp-content/uploads/2009/05/eventlog.jpg" class="attachment-thumbnail" alt="Blade Center Event Log" title="Blade Center Event Log" /></a>
<a href='http://www.balldawg.net/index.php/2009/05/glovebox-my-solution-to-managing-servers/list_bc_opt/' title='Blade Center Options: Open Slots'><img width="150" height="115" src="http://www.balldawg.net/wp-content/uploads/2009/05/list_bc_opt.jpg" class="attachment-thumbnail" alt="Blade Center Options: Open Slots" title="Blade Center Options: Open Slots" /></a>
<a href='http://www.balldawg.net/index.php/2009/05/glovebox-my-solution-to-managing-servers/plugins/' title='Container Plugins Menu'><img width="150" height="115" src="http://www.balldawg.net/wp-content/uploads/2009/05/plugins.jpg" class="attachment-thumbnail" alt="Container Plugins Menu" title="Container Plugins Menu" /></a>
<a href='http://www.balldawg.net/index.php/2009/05/glovebox-my-solution-to-managing-servers/updating/' title='Updating From Devices'><img width="150" height="115" src="http://www.balldawg.net/wp-content/uploads/2009/05/updating.jpg" class="attachment-thumbnail" alt="Updating From Devices" title="Updating From Devices" /></a>
<br />
Sorry for blocking out some of the data, but some of the info needs to stay in house. The back end is entirely Perl and all data is kept in a MySQL database.  It ended up being a rather larger application in the end, but really makes life quite a bit easier.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.balldawg.net/index.php/2009/05/glovebox-my-solution-to-managing-servers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monitoring lighttpd in Xymon / Hobbit</title>
		<link>http://www.balldawg.net/index.php/2009/05/monitoring-lighttpd-in-xymon-hobbit/</link>
		<comments>http://www.balldawg.net/index.php/2009/05/monitoring-lighttpd-in-xymon-hobbit/#comments</comments>
		<pubDate>Fri, 08 May 2009 17:36:07 +0000</pubDate>
		<dc:creator>Andrew Rankin</dc:creator>
				<category><![CDATA[Hobbit / Xymon]]></category>
		<category><![CDATA[Lighty]]></category>
		<category><![CDATA[mod_status]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[rrd]]></category>
		<category><![CDATA[Server Monitoring]]></category>

		<guid isPermaLink="false">http://www.balldawg.net/?p=5</guid>
		<description><![CDATA[My employer starting using lighttpd on one layer of our architecture about a year or so ago, until now that layer has kind of been a black box to the majority of the technical staff due to not having mod_status enabled.  In preparation for it being turned on (I requested it be so after using [...]]]></description>
			<content:encoded><![CDATA[<p>My employer starting using lighttpd on one layer of our architecture about a year or so ago, until now that layer has kind of been a black box to the majority of the technical staff due to not having mod_status enabled.  In preparation for it being turned on (I requested it be so after using it on my own servers), I have created a Xymon Monitor (formally know as Hobbit) script which hits the /server-status page on the localhost and reports that data back to Xymon.  The data it reports includes requests per second and &#8220;amount increase since last script run&#8221; for the &#8220;Total KBytes&#8221; and &#8220;Total Accesses&#8221; numbers.  I also created a graph for the requests per seconds stat. </p>
<p>The Graph definition is as follows:</p>
<pre class="brush: php">
[lighttpd]
TITLE lighttpd Requests/Second
YAXIS # reqs/sec
DEF:RPS=lighttpd.rrd:reqpersec:AVERAGE
LINE2:RPS#0000CC:reqs/sec
COMMENT:
GPRINT:RPS:LAST:Requests per Second   : %5.1lf (cur)
GPRINT:RPS:MAX: : %5.1lf (max)
GPRINT:RPS:MIN: : %5.1lf (min)
GPRINT:RPS:AVERAGE: : %5.1lf (avg)
</pre>
<p><span id="more-5"></span>The Xymon scripts source code is:</p>
<pre class="brush: perl">
#!/usr/bin/perl -w
#############################################################################
# $Id: mi-lighttpd.pl 21 2009-05-07 19:22:28Z rar $
#############################################################################

use strict;
use File::Slurp;
use LWP::Simple;
use Data::Dumper;

my $port = 80;
my $bbtest = &#039;lighttpd&#039;;

#############################################################################
## BB and related test constants
#############################################################################

use constant CLEAR  =&gt; &#039;clear&#039;;
use constant GREEN =&gt;  &#039;green&#039;;
use constant YELLOW =&gt; &#039;yellow&#039;;
use constant RED    =&gt; &#039;red&#039;;
use constant PURPLE =&gt; &#039;purple&#039;;

{

#############################################################################
## Setup Variables
#############################################################################
	my $DATA    = &amp;quot;&amp;quot;;
	my $color   = GREEN;
	my $status  = $bbtest . &amp;quot; OK&amp;quot;;
	my $previous_run;
	my $current_run;
	my $restarted   = 0;
	my @delta_tests = ( &#039;total_kbytes&#039;, &#039;total_accesses&#039;, &#039;uptime&#039; );
	my @counter_tests   = ( &#039;total_accesses&#039;, &#039;total_kbytes&#039;, &#039;uptime&#039;, &#039;reqpersec&#039; );
	my @write_log;
	my $backup_log    = &amp;quot;$ENV{BBTMP}/$ENV{MACHINE}.lighttpd.data&amp;quot;;
	my %lighttpd_states = (
		&#039;_&#039; =&amp;gt; &#039;awaiting_conn&#039;,
		&#039;.&#039; =&amp;gt; &#039;connect&#039;,
		&#039;r&#039; =&amp;gt; &#039;reading_req&#039;,
		&#039;R&#039; =&amp;gt; &#039;reading_req_post&#039;,
		&#039;s&#039; =&amp;gt; &#039;sending_reply&#039;,
		&#039;S&#039; =&amp;gt; &#039;sending_reply_end&#039;,
		&#039;q&#039; =&amp;gt; &#039;request_start&#039;,
		&#039;Q&#039; =&amp;gt; &#039;request_end&#039;,
		&#039;W&#039; =&amp;gt; &#039;write&#039;,
		&#039;h&#039; =&amp;gt; &#039;handle_request&#039;,
		&#039;C&#039; =&amp;gt; &#039;close&#039;,
		&#039;E&#039; =&amp;gt; &#039;hard_error&#039;,
	);
	my %error_states = (
		&#039;reqpersec&#039; =&amp;gt; &#039;100&#039;,
		&#039;sending_reply&#039; =&amp;gt; &#039;100&#039;
	);

	my %warn_states = (
		&#039;reqpersec&#039; =&amp;gt; &#039;75&#039;,
		&#039;sending_reply&#039; =&amp;gt; &#039;75&#039;
	);

#############################################################################
## Gather previous run data &amp;amp;amp; current data
#############################################################################

	# Get Last Status
	if ( -e $backup_log ) {

		#Split Apart Data
		my @data = read_file($backup_log);
		if (@data) {
			foreach my $line (@data) {
				chomp($line);
				my ( $key, $value ) = split( /=/, $line, 2 );
				$previous_run-&amp;gt;{$key} = $value;
			}
		}
		else {
			$previous_run = 0;
		}
	}

	my $status_data = get &amp;quot;http://localhost:$port/server-status?auto&amp;quot;;

#############################################################################
## Munge the data up to get what we want
#############################################################################

	if ( defined($status_data) ) {

		my @data = split( /n/, $status_data );
		foreach my $line (@data) {
			chomp($line);
			my ( $key, $value ) = split( /: /, $line );
			$key =~ s/ /_/g;
			$key = lc($key);
			$current_run-&amp;gt;{$key} = $value;
		}

		# Create array of new values to save for our next run
		foreach ( keys %{$current_run} ) {
			push @write_log, &amp;quot;$_=$current_run-&amp;gt;{$_}n&amp;quot;;
		}

		# Calculate Incremental Data
		if ($previous_run) {
			# We need to check if we restarted here to avoid negitives
			if ($current_run-&amp;gt;{uptime} &amp;gt; $previous_run-&amp;gt;{uptime} ){
				foreach (@delta_tests) {
						$current_run-&amp;gt;{$_} = $current_run-&amp;gt;{$_} - $previous_run-&amp;gt;{$_};
				}
			}
			else {
				$status = $bbtest . &amp;quot; Restarted&amp;quot;;
				$color = YELLOW;
				$restarted = 1;
			}
		}

		# Break out scoreboard data
		foreach ( keys %lighttpd_states ) {
			$current_run-&amp;gt;{ $lighttpd_states{$_} } = 0;
		}
		foreach ( split( //, $current_run-&amp;gt;{scoreboard} ) ) {
			$current_run-&amp;gt;{ $lighttpd_states{$_} }++;
		}

		if ( !$restarted ) {
			# Get Req/Sec since last check
			$current_run-&amp;gt;{reqpersec} = sprintf &amp;quot;%.2F&amp;quot;, ( $current_run-&amp;gt;{total_accesses} / $current_run-&amp;gt;{uptime} ) if $current_run-&amp;gt;{uptime};

			## save our counter tests for the next run incase we
			## lighttpd gets restarted we have some non-zero data to send in
			foreach (@counter_tests) {
				push @write_log, &amp;quot;cur_$_=$current_run-&amp;gt;{$_}n&amp;quot;;
			}    

			# Check for warning states
			foreach ( keys %warn_states ) {
				if ( $current_run-&amp;gt;{$_} &amp;gt; $warn_states{$_} ) {
					$color  = YELLOW;
					$status = $bbtest . &amp;quot; $_ &amp;gt; $warn_states{$_}&amp;quot;;
				}
			}

			# Check for error states
			foreach ( keys %error_states ) {
				if ( $current_run-&amp;gt;{$_} &amp;gt; $error_states{$_} ) {
					$color  = RED;
					$status = $bbtest . &amp;quot; $_ &amp;gt; $error_states{$_}&amp;quot;;
				}
			}
		}
		else {
			## So we restarted, and we don&#039;t want to send nothing
			## and we don&#039;t want to send negitives on calculated tests
			## since we saved them last run for this purpose, we&#039;ll send in
			## our last run stats to keep from having huge drops in the
			## graphs.
			foreach (@counter_tests) {
				$current_run-&amp;gt;{$_} = sprintf &amp;quot;%.2F&amp;quot;, $previous_run-&amp;gt;{ &amp;quot;cur_&amp;quot;.$_ };
			}
		}

		# Delete Some Unwanted Data
		delete $current_run-&amp;gt;{scoreboard};
		delete $current_run-&amp;gt;{uptime};

		# Create Hobbit Data
		foreach ( sort keys %{$current_run} ) {
			$DATA .= &amp;quot;$_:$current_run-&amp;gt;{$_}n&amp;quot;;
		}

		# Actually Write last run file
		write_file( $backup_log, @write_log );

	}
	else {
		$status = $bbtest . &amp;quot; unable to get server-status&amp;quot;;
		$color  = CLEAR;
	}

#############################################################################
## Give data to hobbit
#############################################################################

	# hobbit formatted output
	my $report_date = `/bin/date`;
	chomp($report_date);

	## DEV DEBUG
	#print &amp;quot;$ENV{BB} $ENV{BBDISP} &#039;status apollo,xipnet,net.$bbtest $color $report_date - $statusnn$DATA&#039;n&amp;quot;;
	system(&amp;quot;$ENV{BB} $ENV{BBDISP} &#039;status apollo,xipnet,net.$bbtest $color $report_date - $statusnn$DATA&#039;n&amp;quot;);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.balldawg.net/index.php/2009/05/monitoring-lighttpd-in-xymon-hobbit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

