<?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>-= n8v =- &#187; Giving back</title>
	<atom:link href="http://n8v.enteuxis.org/departments/giving-back/feed/" rel="self" type="application/rss+xml" />
	<link>http://n8v.enteuxis.org</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 27 Sep 2011 00:52:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2-beta2-18055</generator>
		<item>
		<title>Integrating Nagios with Test Driven Development</title>
		<link>http://n8v.enteuxis.org/2011/06/integrating-nagios-with-test-driven-development/</link>
		<comments>http://n8v.enteuxis.org/2011/06/integrating-nagios-with-test-driven-development/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 21:31:10 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Giving back]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=444</guid>
		<description><![CDATA[A while back I realized something important: Monitoring tools are to the sysadmin what testing tools are to the developer. Recently I realized that there need to be more ways to bring both toolsets together. Here&#8217;s one, tying the Nagios monitoring toolset to anything that emits the popular Test Anything Protocol. The sysadmin community loves [...]]]></description>
			<content:encoded><![CDATA[<p>A while back I realized something important:</p>

<blockquote>
  <p><strong>Monitoring tools are to the sysadmin what testing tools are to the developer.</strong></p>
</blockquote>

<p>Recently I realized that there need to be more ways to bring both toolsets together. Here&#8217;s one, tying the <a href="http://nagios.com">Nagios monitoring toolset</a> to anything that emits the popular <a href="http://testanything.org">Test Anything Protocol</a>.</p>

<p><span id="more-444"></span></p>

<p><img alt="" src="http://assets.nagios.com/images/header/Nagios.png" title="Nagios® logo" class="alignright" width="212" height="50" style="padding: 2em; margin: 1em" />
The <em>sysadmin community</em> loves monitoring tools. Partly because of <a href="http://www.amazon.com/Management-System-Administrators-Thomas-Limoncelli/dp/0596007833">Tom Limoncelli&#8217;s time management book</a>, I&#8217;ve been using Nagios for several years now to monitor all sorts of IT hardware and software. It includes features for scheduling check scripts and contact rules (page me during weekdays, page someone else at night), and dashboard views for the visually oriented (curiously unnecessary once you have alerting configured well). I&#8217;ve found it takes investment of time and attention to configure all the checks you want, but it&#8217;s worth it. Because of its open-source, extensible nature, Nagios is especially good for monitoring weird things that other enterprise monitoring systems aren&#8217;t even aware of.  There are a lot of <a href="http://www.nagios.org/about/propaganda/books">books about Nagios</a> available, and I&#8217;d recommend them for anyone new to Nagios. I found <a href="http://www.apress.com/9781590596098">James Trumbull&#8217;s book published by APress</a> particularly useful, though it looks like it might be due for a new edition by now.</p>

<p><img alt="" src="http://testanything.org/i/tap.png" title="TAP - Test Anything Protocol" class="alignright" width="135" height="135" style="margin:1em" />
The <em>developer community</em> has become increasingly interested in software quality control and <a href="http://en.wikipedia.org/wiki/Test-driven_development">test driven development (TDD)</a>. I first became interested because of the Perl community&#8217;s emphasis on <a href="http://qa.perl.org/phalanx/kwalitee.html">Kwalitee testing</a> ever so long ago. There are even more good books and online resources about testing than there are about monitoring. I have been noticing everywhere though, that <a href="http://en.wikipedia.org/wiki/Test_Anything_Protocol">Perl&#8217;s simple and ancient Test Anything Protocol</a> has become somewhat of a standard, with <a href="http://en.wikipedia.org/wiki/Test_Anything_Protocol#List_of_TAP_Producers">testing tools in many languages (including JavaScript, PHP, Python, Ruby, Java, C, C++, C#/VB/.NET and database-specific languages) producing it</a>. Everything from <a href="http://jc.ngo.org.uk/trac-bin/trac.cgi/wiki/LibTap">low-level unit tests in C</a> to frontend cross-browser functional testing tools like <a href="http://search.cpan.org/perldoc?Test::WWW::Selenium">Selenium</a>. And TAP is so simple, it&#8217;s easy to wrap a TAP harness around other test frameworks.</p>

<p>One strategy&#8211;from the security world&#8211;on which sysadmins and developers both agree is <strong>enumerating goodness</strong> (take note, <a href="http://www.ranum.com/security/computer_security/editorials/dumb/">&#8220;antivirus&#8221; is Doing It Wrong</a>). Basically, it&#8217;s too hard to guess all the myriad ways your technology might fail and then write monitoring or test scripts for them. Instead, focus your monitoring and testing on covering the important functionality of your product.</p>

<p>But at what level of detail should we monitor?  When the monitoring system wakes you up at 2 am, which do you want it to say?</p>

<ol>
<li><code>CRITICAL</code>. No users can log in to http://myapp/login.</li>
<li><code>CRITICAL</code>. The app can&#8217;t contact the database.</li>
<li><code>CRITICAL</code>. The database server is down/unpingable.</li>
</ol>

<p>My preference is &#8220;4. All of the above&#8221;, because the user-facing effect is sometimes hard to guess from the sysadmin-facing event (and vice versa). Nagios is good at #3 and maybe #2. #1 is more in the realm of functional testing, and your app may already have functional test scripts that could provide this sort of information.</p>

<h2>check_tap.pl</h2>

<p>A Nagios plugin for consuming <a href="http://testanything.org">Test Anything Protocol</a>. Basically it combines <a href="http://search.cpan.org/perldoc?Nagios::Plugin">Test::Harness</a> with <a href="http://search.cpan.org/perldoc?Nagios::Plugin">Nagios::Plugin</a>.</p>

<p><strong><a href="https://gist.github.com/1005409">Read, download, or fork <var>check_tap.pl</var> from the Github Gist</a>.</strong></p>

<h2>Plugin Documentation (more or less straight from <code>check_tap.pl --help</code>)</h2>

<div style="margin: 2em; padding:1em; background:#efd">

<h2>check_tap.pl</h2>

<p>This plugin allows Nagios to check the output of anything that emits
Test Anything Protocol output. So you can wed Nagios&#8217;s monitoring and
alerting infrastructure to your unit and functional tests for deep
application-level monitoring in development or even in production.</p>

<h3>Usage:</h3>

<pre><code>check_tap.pl [ -v|--verbose ] [-t &lt;timeout&gt;]
[ -c|--critical=&lt;critical threshold&gt; ]
[ -w|--warning=&lt;warning threshold&gt; ]
[ -s|--script = '&lt;/full/path/to/test.t&gt;' ] (Required. multiple OK)
[ -e|--exec = '/full/path/to/runnable ARGS'
[ -l|--lib = '/path/to/perl/libs' ] (Multiple OK)
</code></pre>

<h4>-?, &#8211;usage</h4>

<p>Print usage information</p>

<h4>-h, &#8211;help</h4>

<p>Print detailed help screen</p>

<h4>-V, &#8211;version</h4>

<p>Print version information</p>

<h4>&#8211;extra-opts=[section][@file]</h4>

<p>Read options from an ini file. See http://nagiosplugins.org/extra-opts
   for usage and examples.</p>

<h4>-s, &#8211;script=&#8221;/path/to/executable/test.t args&#8221;</h4>

<p>REQUIRED. Defines the path to the test script you want to run.
   Use multiple -s flags to run multiple tests.</p>

<h4>-l, &#8211;lib=&#8221;/path/to/perl/lib/dir&#8221;</h4>

<p>Optional path for Perl libs to add to @INC.
   Use multiple -l flags to specify multiple lib dirs.</p>

<h4>-e, &#8211;exec=&#8221;/path/to/executable args&#8221;</h4>

<p>Defines a non-Perl executable with which you want to run the &#8211;script.</p>

<h4>-w, &#8211;warning=INTEGER:INTEGER</h4>

<p>Minimum and maximum number of allowable test FAILURES, outside of which a
   warning will be generated. Default is 0 tolerable failures.</p>

<h4>-c, &#8211;critical=INTEGER:INTEGER</h4>

<p>Minimum and maximum number of allowable test FAILURES, outside of
   which a critical will be generated. Default is 0 tolerable failures.</p>

<h4>-t, &#8211;timeout=INTEGER</h4>

<p>Seconds before plugin times out (default: 15)</p>

<h4>-v, &#8211;verbose</h4>

<p>Show details for command-line debugging (can repeat up to 3 times)</p>

<h3>Verbosity</h3>

<p>Use <code>-v</code> to see a bit more info in the one line, including the first
test that failed. This is especially useful because Nagios will
include it in the alert/notification.</p>

<p>Use <code>-vv</code> to see test summary and failures.</p>

<p>Use <code>-vvv</code> to see full test script output.</p>

<h2>Warning and Critical Thresholds</h2>

<p>THRESHOLDs for -w and -c specify the allowable amount of test failures
before the plugin returns WARNING or CRITICAL. Use &#8216;max&#8217; or &#8216;min:max&#8217;.</p>

<p>The default of 0 tolerated failures is good for people like you who
have high standards. But you might want to crank up the CRITICAL
threshold if you want to differentiate between WARNING and CRITICAL
amounts of fail.</p>

<p>See more threshold examples at

http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT</p>

<h3>Examples:</h3>


<div class="wp_syntax"><div class="code"><pre class="bash">    check_tap.pl <span class="re5">-s</span> <span class="sy0">/</span>full<span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>testfoo.pl</pre></div></div>


<p>will run &#8216;testfoo.pl&#8217; and return OK if 0 tests fail, but CRITICAL if
any fail. Excluding TODO or SKIPped tests, of course.</p>


<div class="wp_syntax"><div class="code"><pre class="bash">    check_tap.pl <span class="re5">-s</span> <span class="sy0">/</span>full<span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>testfoo.pl <span class="re5">-c</span> <span class="nu0">2</span></pre></div></div>


<p>will return OK if 0 tests fail, WARNING if more than 0 tests fail,
and CRITICAL if more than 2 fail.</p>

<h3>Non-Perl and remote test scripts</h3>


<div class="wp_syntax"><div class="code"><pre class="bash">    check_tap.pl <span class="re5">-e</span> <span class="st_h">'/usr/bin/ruby -w'</span>  <span class="re5">-s</span> <span class="sy0">/</span>full<span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>testfoo.r</pre></div></div>


<p>will run &#8216;testfoo.r&#8217; using Ruby with the -w flag.</p>

<p>You can use any shell command and argument which produces TAP output,
for example:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">    check_tap.pl <span class="re5">-e</span> <span class="st_h">'/usr/bin/curl -sk'</span> <span class="re5">-s</span> <span class="st_h">'http://url/to/mytest.php'</span></pre></div></div>



<div class="wp_syntax"><div class="code"><pre class="bash">    check_tap.pl <span class="re5">-e</span> <span class="st_h">'/usr/bin/cat'</span> <span class="re5">-s</span> <span class="st_h">'/path/to/testoutput.tap'</span></pre></div></div>


<p>In fact, anything TAP::Harness or <code>prove</code> regards as a source or
executable.</p>

<p>Remember that Nagios or NRPE will likely be running this command as a
different, less-privileged user than you&#8217;re using now.</p>

<h3>License</h3>

<p>This nagios plugin is free software, and comes with ABSOLUTELY NO WARRANTY.
It may be used, redistributed and/or modified under the terms of the GNU
General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt).</p>

</div>

<h2>Installation and Nagios configuration</h2>

<p>Save <var>check_tap.pl</var> anywhere that makes sense and the <code>nagios</code> user can access. The default plugin location depends on your distribution. For RHEL and ilk, plugins are in <var>/usr/lib/nagios/plugins/</var>.</p>

<p>In <var>misccommands.cfg</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="co0"># runs Perl test script given in $ARG1$</span>
define <span class="kw3">command</span> <span class="br0">&#123;</span>
        command_name    check_tap
        command_line    <span class="sy0">/</span>usr<span class="sy0">/</span>lib<span class="sy0">/</span>nagios<span class="sy0">/</span>plugins<span class="sy0">/</span>check_tap.pl <span class="re5">-v</span> \
               <span class="re5">-s</span> <span class="re1">$ARG1</span>$ <span class="re5">-w</span> <span class="re1">$ARG2</span>$ <span class="re5">-c</span> <span class="re1">$ARG3</span>$
<span class="br0">&#125;</span>
&nbsp;
<span class="co0"># gets TAP output from the full URL in $ARG1$</span>
define <span class="kw3">command</span> <span class="br0">&#123;</span>
        command_name    check_tap_remote_url
        command_line    <span class="sy0">/</span>usr<span class="sy0">/</span>lib<span class="sy0">/</span>nagios<span class="sy0">/</span>plugins<span class="sy0">/</span>check_tap.pl <span class="re5">-v</span> \
               <span class="re5">-e</span> <span class="st_h">'/usr/bin/curl -sk'</span> <span class="re5">-s</span> <span class="re1">$ARG1</span>$ \
               <span class="re5">-w</span> <span class="re1">$ARG2</span>$ <span class="re5">-c</span> <span class="re1">$ARG3</span>$
<span class="br0">&#125;</span>
&nbsp;
<span class="co0"># gets TAP output from the relative URL in $ARG1$ at host $HOSTADDRESS$</span>
define <span class="kw3">command</span> <span class="br0">&#123;</span>
        command_name    check_tap_remote_host
        command_line    <span class="sy0">/</span>usr<span class="sy0">/</span>lib<span class="sy0">/</span>nagios<span class="sy0">/</span>plugins<span class="sy0">/</span>check_tap.pl <span class="re5">-v</span> \
              <span class="re5">-e</span> <span class="st_h">'/usr/bin/curl -sk'</span> \
              <span class="re5">-s</span> http:<span class="sy0">//</span><span class="re1">$HOSTADDRESS</span>$<span class="re1">$ARG1</span>$ \
              <span class="re5">-w</span> <span class="re1">$ARG2</span>$ <span class="re5">-c</span> <span class="re1">$ARG3</span>$
<span class="br0">&#125;</span></pre></div></div>


<p>You can also use <a href="http://exchange.nagios.org/directory/Addons/Monitoring-Agents/NRPE-%252D-Nagios-Remote-Plugin-Executor/details">NRPE for *nix</a> or <a href="http://www.nsclient.org/nscp/">NSCLient++/nscp</a> 
or <a href="http://exchange.nagios.org/directory/Addons/Monitoring-Agents/NC_Net/details">NC_Net</a>
for Windows (you&#8217;ll also need Perl, like <a href="http://strawberryperl.com/">Strawberry Perl</a>) to run <var>check_tap.pl</var> on a machine other than the Nagios server. I&#8217;ll leave that as an exercise for the reader, or maybe a future blog post.</p>

<p>In <var>services.cfg</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">define service <span class="br0">&#123;</span>
  use                  generic-service
  check_command        check_tap<span class="sy0">!/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>my<span class="sy0">/</span>test.t<span class="sy0">!</span><span class="nu0">0</span><span class="sy0">!</span><span class="nu0">0</span>
  service_description  Local <span class="kw3">test</span> script on Nagios server
<span class="br0">&#125;</span>
&nbsp;
define service <span class="br0">&#123;</span>
  use                  generic-service
  check_command        check_tap_remote_url<span class="sy0">!</span>http:<span class="sy0">//</span>webhost99<span class="sy0">/</span>nagios<span class="sy0">/</span>mytest.php<span class="sy0">!</span><span class="nu0">0</span><span class="sy0">!</span><span class="nu0">0</span>
  service_description  Remote <span class="kw3">test</span> script accessible by URL
<span class="br0">&#125;</span>
&nbsp;
define service <span class="br0">&#123;</span>
  use                  generic-service
  host_name            webhost1, webhost2
  check_command        check_tap_remote_host<span class="sy0">!/</span>nagios<span class="sy0">/</span>mytest.php<span class="sy0">!</span><span class="nu0">0</span><span class="sy0">!</span><span class="nu0">0</span>
  service_description  Remote <span class="kw3">test</span> script
<span class="br0">&#125;</span></pre></div></div>


<h2>Host-based security for URL-accessible test scripts</h2>

<p>It would be good to <a href="http://httpd.apache.org/docs/2.2/howto/access.html">limit access</a> to the URL-accessible test scripts to your Nagios server and development/admin network. So for Apache, <var>.htaccess</var> or <var>httpd.conf</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="apache"><span class="kw1">Order</span> <span class="kw1">deny</span>,<span class="kw1">allow</span>
<span class="kw1">Deny</span> from <span class="kw2">all</span>
<span class="kw1">Allow</span> from nagioshost.example.com
<span class="kw1">Allow</span> from developers.example.com</pre></div></div>


<p>For IIS you can click on stuff for the same result or use the <a href="http://msdn.microsoft.com/en-us/library/8aeskccd.aspx"><code>deny</code> element in your <var>web.config</var> file</a>. For other web servers, RTFM.</p>

<h2>Doughnuts for Developers</h2>

<p>Wow! Now I can use Nagios&#8217;s monitoring, alerting, performance logging, acknowledging, scheduling, dashboarding, and thresholding features for my unit and functional tests! I can run them with different rules in build and production! I can detect random and senseless acts of system administration! I can detect new bugs as soon as I write them! I can hook Nagios up to the sprinkler system to put a damper on that hotheaded programmer in the next cube! I can write frontend functional tests with Selenium or AutoIt or AppleScript and have Nagios alert (the sysadmins of course) when any of my app&#8217;s core functionality breaks!!!</p>

<p>There are plenty of other test harnesses out there, but Nagios has some big advantages, especially for monitoring production systems.</p>

<h2>Shortcuts for Sysadmins</h2>

<p>Two last things which are more good news for sysadmins:</p>

<h3>Custom test scripts for things Nagios won&#8217;t easily check</h3>

<p>Writing your own Nagios plugins is a little bit hard, even with <a href="http://cpansearch.perl.org/src/TONVOON/Nagios-Plugin-0.35/t/check_stuff.pl">the example plugin I worked on ever so long ago</a>. Writing TAP test scripts, on the other hand, is easy! So, after you&#8217;ve set up Nagios monitoring for all the low-hanging fruit like hardware utilization and network availability, write a test script for some of the harder to monitor signs of enumerable goodness. Here&#8217;s an example:</p>


<div class="wp_syntax"><div class="code"><pre class="perl"><span class="co1">#!/usr/bin/perl</span>
<span class="kw2">use</span> warnings<span class="sy0">;</span> <span class="kw2">use</span> strict<span class="sy0">;</span>
&nbsp;
<span class="co1"># This allows the script to run as a CGI or on the command line.</span>
<span class="co1"># We have to output the header in a BEGIN block or Test::Simple will</span>
<span class="co1">#   output the plan too soon.</span>
<span class="kw2">BEGIN</span> <span class="br0">&#123;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$ENV</span><span class="br0">&#123;</span>REQUEST_METHOD<span class="br0">&#125;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span class="kw2">use</span> CGI <a href="http://perldoc.perl.org/functions/qw.html"><span class="kw3">qw</span></a><span class="br0">&#40;</span>header<span class="br0">&#41;</span><span class="sy0">;</span>
        <a href="http://perldoc.perl.org/functions/print.html"><span class="kw3">print</span></a> header<span class="br0">&#40;</span><span class="st0">&quot;text/plain&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw2">use</span> Test<span class="sy0">::</span><span class="me2">Simple</span> tests<span class="sy0">=&gt;</span><span class="nu0">4</span><span class="sy0">;</span>
<span class="kw2">use</span> Test<span class="sy0">::</span><span class="me2">File</span><span class="sy0">;</span>
&nbsp;
<span class="co1"># These use Test::File to test file permissions and size.</span>
<span class="co1"># See http://search.cpan.org/perldoc?Test::File</span>
file_writeable_ok <span class="st0">&quot;path/to/cache&quot;</span><span class="sy0">;</span>  
file_not_writeable_ok <span class="st0">&quot;path/to/index.html&quot;</span><span class="sy0">;</span> 
<span class="kw1">my</span> <span class="re0">$backup_file</span> <span class="sy0">=</span> <span class="st0">&quot;/usr/local/backups/myapp-backup.tar.bz2&quot;</span><span class="sy0">;</span>
file_min_size_ok <span class="re0">$backup_file</span><span class="sy0">,</span> <span class="nu0">911377</span><span class="sy0">;</span>
&nbsp;
<span class="co1"># -M is a file test operator returning the file's last modifed age in days.</span>
<span class="co1"># See http://perldoc.perl.org/functions/-X.html</span>
ok <span class="sy0">-</span>M <span class="re0">$backup_file</span> <span class="sy0">&lt;</span> <span class="nu0">1</span><span class="sy0">,</span> <span class="st0">&quot;Backup file is newer than 1 day old&quot;</span><span class="sy0">;</span></pre></div></div>


<p>Just run that script as a CGI or with NRPE etc. and you&#8217;ve got instant monitoring of things like backup success, which is otherwise kind of hard to hook in to Nagios. You could get even fancier with checksums or whatever you want.</p>

<p><a href="http://search.cpan.org/perldoc?Test::Tutorial">See Test::Tutorial for more.</a> Or look for TAP tools for your favorite language; they&#8217;re probably out there.</p>

<h3>Tolerating ambiguity</h3>

<p>In some cases, a certain amount of failure is acceptable. I&#8217;ve been monitoring connectivity between crucial hosts with a test script. I don&#8217;t want to be bothered by this check if one of our Citrix VMs isn&#8217;t available to the gateway server for a while, but it&#8217;s a problem if they&#8217;re ALL inaccessible because of a firewall issue or something. The configurable warning/critical thresholds on <var>check_tap.pl</var> allow me to define how much aggregate failure is worth getting excited about&#8211;something that&#8217;s hard to do with vanilla Nagios configuration.</p>

<p>Here&#8217;s the gist of my test script. <code>ping_ok()</code> and <code>service_ok()</code> come from a module I wrote 50 years ago to check basic connectivity/responsiveness with <a href="http://search.cpan.org/perldoc?Net::Ping">Net::Ping</a>.</p>


<div class="wp_syntax"><div class="code"><pre class="perl">diag <span class="st0">&quot;Checking Citrix farm connectivity from DMZ<span class="es0">\n</span>&quot;</span><span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">@stas</span> <span class="sy0">=</span> <a href="http://perldoc.perl.org/functions/qw.html"><span class="kw3">qw</span></a><span class="br0">&#40;</span>
   citrixdc01<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
   citrixdc02<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">@stas</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    ping_ok<span class="br0">&#40;</span><span class="co5">$_</span><span class="sy0">,</span> <span class="st_h">'http'</span><span class="br0">&#41;</span><span class="sy0">;</span>	
    service_ok<span class="br0">&#40;</span><span class="co5">$_</span><span class="sy0">,</span> <span class="st_h">'http'</span><span class="sy0">,</span> <span class="st0">&quot;XML service on $_ is responding in some way&quot;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
&nbsp;
&nbsp;
<span class="kw1">my</span> <span class="re0">@citrix_farm</span> <span class="sy0">=</span> <a href="http://perldoc.perl.org/functions/qw.html"><span class="kw3">qw</span></a><span class="br0">&#40;</span>
   citrixps01<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
   citrixps02<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
   <span class="sy0">...</span>
   citrixps29<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
   citrixps30<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">@stas</span><span class="sy0">,</span> <span class="re0">@citrix_farm</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    service_ok<span class="br0">&#40;</span><span class="co5">$_</span><span class="sy0">,</span> <span class="st_h">'1494'</span><span class="sy0">,</span> <span class="st0">&quot;ICA service on $_ is responding in some way&quot;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>


<p>I can just use the &#8220;warning&#8221; and &#8220;critical&#8221; arguments to <var>check_tap.pl</var> to set my thresholds for how many inaccessible servers I want to tolerate.</p>

<p>So there you go. Sysadmins and developers rejoice!</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/06/integrating-nagios-with-test-driven-development/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New WordPress Plugin to configure user timeouts</title>
		<link>http://n8v.enteuxis.org/2010/12/new-wordpress-plugin-to-configure-user-timeouts/</link>
		<comments>http://n8v.enteuxis.org/2010/12/new-wordpress-plugin-to-configure-user-timeouts/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 22:42:17 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Giving back]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=398</guid>
		<description><![CDATA[I published my second plugin for WordPress today. It lets you configure how long user sessions and the &#8220;remember me&#8221; cookie last. By default they&#8217;re only 2 days and 2 weeks, respectively. Twofold impetus: a problem with the internal P2 microblog at work when people like me left their browsers open for long periods, and the [...]]]></description>
			<content:encoded><![CDATA[<p>I published <a href="http://wordpress.org/extend/plugins/configure-login-timeout/">my second plugin for WordPress</a> today.  It lets you configure how long user sessions and the &#8220;remember me&#8221; cookie last. By default they&#8217;re only 2 days and 2 weeks, respectively.</p>

<p><a href="http://wordpress.org/extend/plugins/configure-login-timeout"><img class="aligncenter" title="Plugin screenshot" src="http://s.wordpress.org/extend/plugins/configure-login-timeout/screenshot-1.png?r=314559" alt="" width="387" /></a></p>

<p>Twofold impetus: a problem with the internal <a href="http://p2theme.com/">P2 microblog</a> at work when people like me left their browsers open for long periods, and the fact that I access too many WordPress blogs from too many different computers for the 2 week &#8220;Remember Me&#8221; timeout to be convenient enough.  Cranking it up to 22 years!</p>

<p>The <a href="http://wordpress.org/extend/plugins/configure-login-timeout/">WordPress documentation</a> is pretty great BTW.</p>

<p>And it was a little bit interesting to run in to the <a href="http://en.wikipedia.org/wiki/Year_2038_problem">Year 2038 problem</a> with 32-bit int timestamps.  I don&#8217;t know, it was fun working around the  &#8221;infinity&#8221; ceiling:</p>


<div class="wp_syntax"><div class="code"><pre class="php">  <span class="kw1">if</span> <span class="br0">&#40;</span> PHP_INT_MAX <span class="sy0">-</span> <a href="http://www.php.net/time"><span class="kw3">time</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&lt;</span> <span class="re0">$expire_in</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$expire_in</span> <span class="sy0">=</span>  PHP_INT_MAX <span class="sy0">-</span> <a href="http://www.php.net/time"><span class="kw3">time</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">-</span> <span class="nu0">5</span><span class="sy0">;</span>
  <span class="br0">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2010/12/new-wordpress-plugin-to-configure-user-timeouts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress plugin to make code samples prettier</title>
		<link>http://n8v.enteuxis.org/2009/03/wordpress-plugin-to-make-code-samples-prettier/</link>
		<comments>http://n8v.enteuxis.org/2009/03/wordpress-plugin-to-make-code-samples-prettier/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 00:24:52 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Giving back]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[syntax]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp-syntax]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=215</guid>
		<description><![CDATA[I&#8217;ve always had a weakness for &#8220;preferences&#8221;. I spent hours going through all the available preference panes on the first Mac I had access to (an SE II I think, ca. 1989), tweaking this and that to get it to look as &#8220;customized&#8221; as possible. Hours setting up font and styles on school assignments, days [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve always had a weakness for &#8220;preferences&#8221;.  I spent hours going through all the available preference panes on the first Mac I had access to (an <var>SE II</var> I think, ca. 1989), tweaking this and that to get it to look as &#8220;customized&#8221; as possible.  Hours setting up font and styles on school assignments, days banging on my Emacs config to be more like I want.</p>

<p>So it&#8217;s been secretly irking me for a while that although I installed the very nice <a href="http://wordpress.org/extend/plugins/wp-syntax/">WP-Syntax code highlighting plugin </a>for this WordPress blog, it was hard to get it to display things in reverse-video like I prefer for all my terminal and text editor windows, and like I love in <a href="http://www.symfony-project.org/book/">the online Symfony documentation</a>.  It&#8217;s just nicer on the eyes, you know?  Digging in, I found the <a href="http://qbnz.com/highlighter/">GeSHI syntax highlighter</a> to be impressive in scope but scary in its inline-style-generating detail.</p>

<p>So today, to solve the problem for more than just me, I published <a href="http://wordpress.org/extend/plugins/wp-syntax-hacktify/">my very first WordPress plugin, wp-syntax-hacktify</a>.  Very educational!  I like the plugin system at wordpress.org.</p>

<p>The plugin tells GeSHI to use stylesheets instead and provides a <a href="http://svn.wp-plugins.org/wp-syntax-hacktify/trunk/hacktified.css">slightly more commented/documented stylesheet</a> as an example for if you&#8217;d like to override it with your own color scheme.</p>

<p>So now my code samples can be all nicer and stuff, like this:</p>


<div class="wp_syntax"><div class="code"><pre class="php">  <span class="co4">/**
   * Print a string to the log using 'debug' level.  For printf-style
   * debugging.
   *
   * @param      string $m      The string to log
   * @return     nothing
   */</span>
  <span class="kw2">public</span> static <span class="kw2">function</span> debug <span class="br0">&#40;</span><span class="re0">$m</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>sfConfig<span class="sy0">::</span><span class="me2">has</span><span class="br0">&#40;</span><span class="st_h">'sf_logging_enabled'</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> sfConfig<span class="sy0">::</span><span class="me2">get</span><span class="br0">&#40;</span><span class="st_h">'sf_logging_enabled'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
      <span class="br0">&#123;</span>
        <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$logger</span> <span class="sy0">=</span> sfContext<span class="sy0">::</span><span class="me2">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getLogger</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
          <span class="re0">$logger</span><span class="sy0">-&gt;</span><span class="me1">debug</span><span class="br0">&#40;</span><span class="re0">$m</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span>
      <span class="br0">&#125;</span>
    <span class="kw1">elseif</span> <span class="br0">&#40;</span>sfConfig<span class="sy0">::</span><span class="me2">has</span><span class="br0">&#40;</span><span class="st_h">'bhLDAP_echo_debugging'</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> sfConfig<span class="sy0">::</span><span class="me2">get</span><span class="br0">&#40;</span><span class="st_h">'bhLDAP_echo_debugging'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
      <span class="br0">&#123;</span>
        <span class="kw1">echo</span> <span class="st0">&quot;# <span class="es4">$m</span><span class="es1">\n</span>&quot;</span><span class="sy0">;</span>
      <span class="br0">&#125;</span>
    <span class="kw1">else</span>
      <span class="br0">&#123;</span>
<span class="co1">//      echo $m;</span>
      <span class="br0">&#125;</span>
  <span class="br0">&#125;</span>
&nbsp;
  <span class="co4">/**
   * Dump a data structure to the log at the 'debug' level.  Uses
   * print_r() formatting.
   *
   * @param      mixed $v         The variable/data structure to dump
   * @param      string $label    An optional label to print in front of the dump
   * @return     nothing
   */</span>
  <span class="kw2">public</span> static <span class="kw2">function</span> debugDump <span class="br0">&#40;</span><span class="re0">$v</span><span class="sy0">,</span> <span class="re0">$label</span> <span class="sy0">=</span> <span class="st0">&quot;var dump&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw2">self</span><span class="sy0">::</span><span class="me2">debug</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es4">$label</span>:  &quot;</span> <span class="sy0">.</span> <a href="http://www.php.net/print_r"><span class="kw3">print_r</span></a><span class="br0">&#40;</span><span class="re0">$v</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span></pre></div></div>


<p>Now the code on my blog can look nice even if it&#8217;s terrifically hacky!</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2009/03/wordpress-plugin-to-make-code-samples-prettier/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The intranets!  Let them in!  Let them play!</title>
		<link>http://n8v.enteuxis.org/2008/08/ldap-authn-authz-for-symfony/</link>
		<comments>http://n8v.enteuxis.org/2008/08/ldap-authn-authz-for-symfony/#comments</comments>
		<pubDate>Tue, 05 Aug 2008 18:49:04 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Giving back]]></category>
		<category><![CDATA[AD]]></category>
		<category><![CDATA[intranet]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=32</guid>
		<description><![CDATA[I just released bhLDAPAuthPlugin to the world with permission from my employer.  I&#8217;ve been using symfony (&#8220;PHP on Rails&#8221;) for about a year at work for a few intranet projects, and over and over I have needed to use our enterprise-wide Microsoft Active Directory® for user authentication and authorization. The plugin might work with non-Microsoft [...]]]></description>
			<content:encoded><![CDATA[<p>I just released <a href="http://www.symfony-project.org/plugins/bhLDAPAuthPlugin">bhLDAPAuthPlugin</a> to the world with permission from my employer.  I&#8217;ve been using <a href="http://www.symfony-project.org/">symfony</a> (&#8220;PHP on Rails&#8221;) for about a year at work for a few intranet projects, and over and over I have needed to use our enterprise-wide Microsoft Active Directory® for user authentication and authorization. The plugin might work with non-Microsoft LDAP servers too, but I don&#8217;t have any of them to play with.</p>

<p>Maybe this will help other developers cook up Intranet apps that rock using symfony.</p>

<p>I have been able to rapidly develop some things that users really like with symfony, so I appreciate this chance to give back to the project.  Also, I&#8217;m the only one in my organization doing this sort of thing, so I hope I&#8217;ll be able to get some good feedback and contributions from others.</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2008/08/ldap-authn-authz-for-symfony/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Synchronizing Hiveminder with Outlook</title>
		<link>http://n8v.enteuxis.org/2008/08/synchronizing-hiveminder-with-outlook/</link>
		<comments>http://n8v.enteuxis.org/2008/08/synchronizing-hiveminder-with-outlook/#comments</comments>
		<pubDate>Sat, 02 Aug 2008 01:15:56 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Giving back]]></category>
		<category><![CDATA[gtd]]></category>
		<category><![CDATA[Hiveminder]]></category>
		<category><![CDATA[Outlook]]></category>
		<category><![CDATA[Palm]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=27</guid>
		<description><![CDATA[Whee. I finally did it, though it&#8217;s been on my list for a couple years. I wanted to use the sweet todo-ticketing goodness of Hiveminder.com, but my mesozoic Palm T&#124;X handheld was holding me back, and I&#8217;ve got several reasons for not throwing it out/replacing it with an iPhone/iPod Touch, yet. I&#8217;ve been using the [...]]]></description>
			<content:encoded><![CDATA[<p>Whee.  I finally did it, though it&#8217;s been on my list for a couple years.  I wanted to use the sweet todo-ticketing goodness of <a href="http://hiveminder.com">Hiveminder.com</a>, but my <a href="http://store.palm.com/product/index.jsp?productId=2113009&amp;cp=2114867&amp;parentPage=family">mesozoic Palm T|X handheld </a>was holding me back, and I&#8217;ve got several reasons for not throwing it out/replacing it with an iPhone/iPod Touch, <em>yet</em>.</p>

<p>I&#8217;ve been using the script all this week and it works great!  I&#8217;ve been adding/collecting tasks like crazy, and even getting more done too.</p>

<p>It&#8217;s probably pretty geeky so far.  It&#8217;s a long way from being a polished executable or something.  But it works pretty well for me and I even improved the speed over version 0.1, so I wanted to share it with The World Out There ™</p>

<p>An excerpt from the POD:</p>

<blockquote>
<h4>WHY?</h4>
I use a Palm (TM) handheld for working all my lists offline, but Palm is stuck in the 20th century. Luckily, so is Outlook (TM)!

The Palm knows how to sync with Outlook task list and memos, so this script syncs them with Hiveminder. Hopefully, I can use Hiveminder when I&#8217;m near a computer (online) and still have full read/write access when my Palm is offline.</blockquote>

<ul>
    <li><a href="/pub/sync_outlook_hiveminder.pl">Download the script</a></li>
    <li><a href="/pub/sync_outlook_hiveminder.html">Read the documentation</a></li>
    <li><a href="http://hiveminder.com">Get Hiveminder</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2008/08/synchronizing-hiveminder-with-outlook/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

