<?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>Erics Tech Blog &#187; Perl</title>
	<atom:link href="http://eric.lubow.org/category/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://eric.lubow.org</link>
	<description>Thoughts, musings, and other idealistic (sometimes useful) systems and development hoopla.</description>
	<lastBuildDate>Fri, 18 Nov 2011 14:56:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>Using Unique Keys and Key Groups with Background Jobs in Gearman::Client</title>
		<link>http://eric.lubow.org/2010/perl/perl-modules/using-unique-keys-and-key-groups-with-background-jobs-in-gearmanclient/</link>
		<comments>http://eric.lubow.org/2010/perl/perl-modules/using-unique-keys-and-key-groups-with-background-jobs-in-gearmanclient/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 12:15:35 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Perl Modules]]></category>
		<category><![CDATA[drizzle]]></category>
		<category><![CDATA[gearman]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=739</guid>
		<description><![CDATA[While diving into Gearman using Gearman::Client with MySQL and libdrizzle (I know, a mouthful), I ran into what I thought was a bug. I was only able to add 1 background job of any type at a particular time. The launchpad &#8220;bug note,&#8221; which is available in its entirety here, is rightly labeled won&#8217;t fix. [...]]]></description>
			<content:encoded><![CDATA[<p>While diving into <a href="http://www.gearman.org/">Gearman</a> using <a href="http://search.cpan.org/~dormando/Gearman-1.11/lib/Gearman/Client.pm">Gearman::Client</a> with <a href="http://www.mysql.com/">MySQL</a> and <a href="http://www.drizzle.org/">libdrizzle</a> (I know, a mouthful), I ran into what I thought was a bug.  I was only able to add 1 background job of any type at a particular time.  The launchpad &#8220;bug note,&#8221; which is available in its entirety <a href="https://bugs.launchpad.net/gearmand/+bug/480775">here</a>, is rightly labeled <strong>won&#8217;t fix</strong>.<br />
<span id="more-739"></span><br />
Tracking that post down wasn&#8217;t too difficult, but it would have saved me time if that information was in the Perl documentation.  Using Gearman::Client you can create your unique ID (or UUID).  To create a background job, your code would then look like this:</p>
<div class="codecolorer-container perl default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">use</span> Gearman<span style="color: #339933;">::</span><span style="color: #006600;">Client</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> UUID<span style="color: #339933;">::</span><span style="color: #006600;">Tiny</span> <span style="color: #ff0000;">':std'</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$client</span> <span style="color: #339933;">=</span> Gearman<span style="color: #339933;">::</span><span style="color: #006600;">Client</span><span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span><span style="color: #339933;">;</span><br />
<span style="color: #0000ff;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">dispatch_background</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;send_email&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$json</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span> &nbsp; <br />
&nbsp; &nbsp; &nbsp;on_complete <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <a href="http://perldoc.perl.org/functions/print.html"><span style="color: #000066;">print</span></a> <span style="color: #0000ff;">$</span><span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$_</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp;uniq <span style="color: #339933;">=&gt;</span> create_uuid_as_string<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span> &nbsp; <br />
&nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>This will ensure that you have a unique UUID when INSERTing the job.  But I think that we can do better and this is where the good practice comes into effect (and why the Gearman devs marked it as won&#8217;t fix).  So let&#8217;s think a little more abstractly for a moment. For the <strong>uniq</strong> key (<strong>unique_key</strong> column), how about something like <em>&#8220;${type}_&#8221;.create_uuid_as_string()</em>. This will allow us to group (in this case) our mailing types so that we can monitor the status of our work queue.  Yes, we can easily hop into the database and run this query:</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> function_name<span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">COUNT</span><span style="color: #66cc66;">&#40;</span>function_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> gearman_queue <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> function_name;<br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">---------------+----------------------+</span><br />
<span style="color: #66cc66;">|</span> function_name <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">COUNT</span><span style="color: #66cc66;">&#40;</span>function_name<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">|</span><br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">---------------+----------------------+</span><br />
<span style="color: #66cc66;">|</span> send_email &nbsp; &nbsp;<span style="color: #66cc66;">|</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">---------------+----------------------+</span></div></div>
<p>But wouldn&#8217;t it be nicer to know exactly where we are at with this query:</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> IFNULL<span style="color: #66cc66;">&#40;</span>function_name<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Total'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">FUNCTION</span><span style="color: #66cc66;">,</span> SUBSTRING_INDEX<span style="color: #66cc66;">&#40;</span>unique_key<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'_'</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> mail_type<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">COUNT</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Total<br />
<span style="color: #993333; font-weight: bold;">FROM</span> gearman_queue<br />
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> function_name<span style="color: #66cc66;">,</span> mail_type<br />
<span style="color: #993333; font-weight: bold;">WITH</span> ROLLUP;<br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------+-----------+-------+</span><br />
<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">FUNCTION</span> &nbsp; <span style="color: #66cc66;">|</span> mail_type <span style="color: #66cc66;">|</span> Total <span style="color: #66cc66;">|</span><br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------+-----------+-------+</span><br />
<span style="color: #66cc66;">|</span> send_email <span style="color: #66cc66;">|</span> passreset <span style="color: #66cc66;">|</span> &nbsp; &nbsp; <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">|</span> send_email <span style="color: #66cc66;">|</span> regemail &nbsp;<span style="color: #66cc66;">|</span> &nbsp; &nbsp; <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">|</span> send_email <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span> &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">|</span> &nbsp; &nbsp; <span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">|</span> Total &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span> &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">|</span> &nbsp; &nbsp; <span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------+-----------+-------+</span></div></div>
<p>For reference, here are the <em>unique_key</em> columns that allowed to generate that query:</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> unique_key <span style="color: #993333; font-weight: bold;">FROM</span> gearman_queue;<br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------------------------------------------+</span><br />
<span style="color: #66cc66;">|</span> unique_key &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">|</span><br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------------------------------------------+</span><br />
<span style="color: #66cc66;">|</span> passreset_1cdb347b<span style="color: #66cc66;">-</span>788f<span style="color: #66cc66;">-</span>11df<span style="color: #66cc66;">-</span>ad7d<span style="color: #66cc66;">-</span>b190002f5dcd <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">|</span> passreset_21ed3ae5<span style="color: #66cc66;">-</span>788f<span style="color: #66cc66;">-</span>11df<span style="color: #66cc66;">-</span><span style="color: #cc66cc;">8395</span><span style="color: #66cc66;">-</span>aed7743cedde <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">|</span> regemail_2a40bebe<span style="color: #66cc66;">-</span>788f<span style="color: #66cc66;">-</span>11df<span style="color: #66cc66;">-</span>bda0<span style="color: #66cc66;">-</span>8fb882f63de5 &nbsp;<span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------------------------------------------+</span></div></div>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2009/system-administration/howto-recreate-devnull/' rel='bookmark' title='HOWTO Recreate /dev/null'>HOWTO Recreate /dev/null</a></li>
<li><a href='http://eric.lubow.org/2008/databases/mysql/mysql-encoded-uri-search-and-replace/' rel='bookmark' title='MySQL Encoded URI Search and Replace'>MySQL Encoded URI Search and Replace</a></li>
<li><a href='http://eric.lubow.org/2010/databases/mysql/speeding-up-your-selects-and-sorts/' rel='bookmark' title='Speeding Up Your Selects and Sorts'>Speeding Up Your Selects and Sorts</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/perl/perl-modules/using-unique-keys-and-key-groups-with-background-jobs-in-gearmanclient/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monitoring Services with Nagios::Plugin</title>
		<link>http://eric.lubow.org/2010/perl/perl-modules/monitoring-services-with-nagios-plugin/</link>
		<comments>http://eric.lubow.org/2010/perl/perl-modules/monitoring-services-with-nagios-plugin/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 11:15:03 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Perl Modules]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[nagios]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[system]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=664</guid>
		<description><![CDATA[There are a lot of people who say, &#8220;if it isn&#8217;t monitored, then it isn&#8217;t a service.&#8221; The problem is that I don&#8217;t think enough people outside of the systems world believe that or even understand why its said. I think the primary offenders here are developers. It isn&#8217;t because they don&#8217;t know better, but [...]]]></description>
			<content:encoded><![CDATA[<p>There are a lot of people who say, &#8220;if it isn&#8217;t monitored, then it isn&#8217;t a service.&#8221;  The problem is that I don&#8217;t think enough people outside of the systems world believe that or even understand why its said.  I think the primary offenders here are developers.  It isn&#8217;t because they don&#8217;t know better, but typically developers just want to get the application up and running and then move on to developing the next thing. I also think there is some fault on the side of the administrators and the managers not insisting that part of the completed version of a project includes monitoring.  But I don&#8217;t want to harp on this as much as I would like to show just how easy it is to compensate here by taking advantage of <a href="http://search.cpan.org/~tonvoon/Nagios-Plugin-0.33/lib/Nagios/Plugin.pm">Nagios::Plugin</a>.<br />
<span id="more-664"></span><br />
Nagios::Plugin is a Perl module that can be used to shortcut how easy it is to add a custom check for your application to your <a href="http://www.nagios.org/">Nagios</a> monitoring infrastructure.  It is so easy to write a Nagios plugin that even with comments and performance data, I have written one to check the alive-ness in under 50 lines.</p>
<div class="codecolorer-container perl default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:450px;"><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">use</span> Nagios<span style="color: #339933;">::</span><span style="color: #006600;">Plugin</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> Time<span style="color: #339933;">::</span><span style="color: #006600;">HiRes</span> <a href="http://perldoc.perl.org/functions/qw.html"><span style="color: #000066;">qw</span></a><span style="color: #009900;">&#40;</span> gettimeofday tv_interval <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$np</span> <span style="color: #339933;">=</span> Nagios<span style="color: #339933;">::</span><span style="color: #006600;">Plugin</span><span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; shortname <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'template'</span><span style="color: #339933;">,</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp;<span style="color: #666666; font-style: italic;"># We need a URL to test</span><br />
&nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$url</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;http://www.myapp.com/&quot;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp;<span style="color: #666666; font-style: italic;"># Create the UserAgent</span><br />
&nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$ua</span> <span style="color: #339933;">=</span> LWP<span style="color: #339933;">::</span><span style="color: #006600;">UserAgent</span><span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; agent &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=&gt;</span> &nbsp;<span style="color: #ff0000;">'Nagios Application Check'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; from &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">=&gt;</span> &nbsp;<span style="color: #ff0000;">'webmaster@myapp.com'</span><span style="color: #339933;">,</span><br />
&nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp;<span style="color: #666666; font-style: italic;"># Change the timeout to 10 seconds instead of 3 min (180 seconds)</span><br />
&nbsp;<span style="color: #0000ff;">$ua</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">timeout</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">10</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$t0</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span>gettimeofday<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$resp</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$ua</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$total</span> <span style="color: #339933;">=</span> tv_interval<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$t0</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>gettimeofday<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$content</span><span style="color: #339933;">;</span><br />
&nbsp;<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$resp</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">is_success</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$np</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">nagios_exit</span><span style="color: #009900;">&#40;</span> CRITICAL<span style="color: #339933;">,</span> <span style="color: #0000ff;">$resp</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">status_line</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp;<span style="color: #009900;">&#125;</span><br />
<br />
&nbsp;<span style="color: #666666; font-style: italic;"># Time it</span><br />
&nbsp;<span style="color: #0000ff;">$np</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">add_perfdata</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; label <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;time&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; value <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;${total}&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; uom <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;s&quot;</span><span style="color: #339933;">,</span><br />
&nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp;<span style="color: #0000ff;">$np</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">nagios_exit</span><span style="color: #009900;">&#40;</span>OK<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Test Suggestions Found&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<a href="http://perldoc.perl.org/functions/exit.html"><span style="color: #000066;">exit</span></a> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span></div></div>
<p>By reading the Pod documentation, you&#8217;ll also find that you can get a lot more specific.  You can add command line switches, lots of performance data, and my favorite, some pretty extensive success, warning or critical messages that can be displayed on the dashboard.  </p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/system-administration/nagios-notify-by-campfire-plugin/' rel='bookmark' title='Nagios notify-by-campfire Plugin'>Nagios notify-by-campfire Plugin</a></li>
<li><a href='http://eric.lubow.org/2010/mac/textmate-minimap-plugin/' rel='bookmark' title='Textmate Minimap Plugin'>Textmate Minimap Plugin</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/perl/perl-modules/monitoring-services-with-nagios-plugin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>File Read Write Create with IO::File</title>
		<link>http://eric.lubow.org/2009/perl/file-read-write-create-with-iofile/</link>
		<comments>http://eric.lubow.org/2009/perl/file-read-write-create-with-iofile/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 12:45:53 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=415</guid>
		<description><![CDATA[Ran into an annoying gotchya with Perl&#8217;s IO::File. Apparently opening the file in append mode with read access if the file already exists puts the file position pointer at the end of the file. If it doesn&#8217;t exist, it creates the file. Note the +&#62;&#62;, that opens the file r/w/append. You can also use the [...]]]></description>
			<content:encoded><![CDATA[<p>Ran into an annoying gotchya with Perl&#8217;s <a href="http://search.cpan.org/~gbarr/IO-1.25/lib/IO/File.pm">IO::File</a>.  Apparently opening the file in append mode with read access if the file already exists puts the file position pointer at the end of the file.  If it doesn&#8217;t exist, it creates the file.  Note the <strong>+&gt;&gt;</strong>, that opens the file r/w/append.  You can also use the more common (and more easily recognizable) form of <strong>a+</strong>.</p>
<div class="codecolorer-container perl default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$FH</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> IO<span style="color: #339933;">::</span><span style="color: #006600;">File</span> <span style="color: #ff0000;">&quot;$file&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;+&gt;&gt;&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$line</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$FH</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">getline</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/print.html"><span style="color: #000066;">print</span></a> <span style="color: #ff0000;">&quot;Line: $line<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <br />
&nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/undef.html"><span style="color: #000066;">undef</span></a> <span style="color: #0000ff;">$FH</span><span style="color: #339933;">;</span></div></div>
<p>I noticed that when I tried to read the file (if it already existed), then nothing would be read.  I neglected to realize that you must seek to position 0 in the file if you want to read it.  Therefore the following code will work:</p>
<div class="codecolorer-container perl default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$FH</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> IO<span style="color: #339933;">::</span><span style="color: #006600;">File</span> <span style="color: #ff0000;">&quot;$file&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;+&gt;&gt;&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$FH</span><span style="color: #339933;">-&gt;</span><a href="http://perldoc.perl.org/functions/seek.html"><span style="color: #000066;">seek</span></a><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$line</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$FH</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">getline</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/print.html"><span style="color: #000066;">print</span></a> <span style="color: #ff0000;">&quot;Line: $line<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/undef.html"><span style="color: #000066;">undef</span></a> <span style="color: #0000ff;">$FH</span><span style="color: #339933;">;</span></div></div>
<p>Although it might seem obvious that you need to be at the beginning of the file to read it forward (and it is), I didn&#8217;t realize the file pointer opened a file in append mode to the last position in the file (in hind sight, it does appear to be a bit more obvious).</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/databases/mysql/database-readwrite-splitting-in-frameworksorms/' rel='bookmark' title='Database Read/Write Splitting in Frameworks/ORMs'>Database Read/Write Splitting in Frameworks/ORMs</a></li>
<li><a href='http://eric.lubow.org/2007/perl/filebidirectional/' rel='bookmark' title='File::Bidirectional'>File::Bidirectional</a></li>
<li><a href='http://eric.lubow.org/2007/perl/filefind/' rel='bookmark' title='File::Find'>File::Find</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/perl/file-read-write-create-with-iofile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing For A Number</title>
		<link>http://eric.lubow.org/2009/perl/testing-for-a-number/</link>
		<comments>http://eric.lubow.org/2009/perl/testing-for-a-number/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 14:00:20 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=100</guid>
		<description><![CDATA[Although you generally don&#8217;t have to worry about types in Perl, it is occasionally necessary to ensure that you are working with numbers. Your test cases should notify you that something is amiss when you didn&#8217;t get a number (when you were expecting one). Thankfully Scalar::Util provides a method to deal with this. use Scalar::Util [...]]]></description>
			<content:encoded><![CDATA[<p>Although you generally don&#8217;t have to worry about types in Perl, it is occasionally necessary to ensure that you are working with numbers.  Your test cases should notify you that something is amiss when you didn&#8217;t get a number (when you were expecting one).  Thankfully <a href="http://search.cpan.org/~gbarr/Scalar-List-Utils-1.19/lib/Scalar/Util.pm">Scalar::Util</a> provides a method to deal with this.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">use Scalar::Util qw( looks_like_number );<br />
<br />
my @possibleNumbers = qw(1 5.25 word 4);<br />
<br />
foreach my $nums (@possibleNumbers) {<br />
&amp;nbsp; &amp;nbsp; &nbsp; &nbsp;print &quot;$nums is&quot;, looks_like_number($nums) ? '' : ' not', &quot; a number\n&quot;;<br />
}</div></div>
<p>This will print:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">1 is a number<br />
5.25 is a number<br />
word is not a number<br />
4 is a number</div></div>
<p>This neat little method takes advantage of Perl C API&#8217;s looks_like_number() function.  Since this is virtually native, it will be pretty fast.</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2006/perl/first-attempt-at-poetry-no-substitutes/' rel='bookmark' title='First Attempt at Poetry: No Substitutes'>First Attempt at Poetry: No Substitutes</a></li>
<li><a href='http://eric.lubow.org/2009/perl/mac-perl-problems-after-feb-update/' rel='bookmark' title='Mac Perl Problems After Feb Update'>Mac Perl Problems After Feb Update</a></li>
<li><a href='http://eric.lubow.org/2009/perl/cleaning-up-long-conditionals-with-grep/' rel='bookmark' title='Cleaning Up Long Conditionals With Grep'>Cleaning Up Long Conditionals With Grep</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/perl/testing-for-a-number/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cleaning Up Long Conditionals With Grep</title>
		<link>http://eric.lubow.org/2009/perl/cleaning-up-long-conditionals-with-grep/</link>
		<comments>http://eric.lubow.org/2009/perl/cleaning-up-long-conditionals-with-grep/#comments</comments>
		<pubDate>Tue, 07 Apr 2009 14:00:22 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[grep]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=95</guid>
		<description><![CDATA[Every so often I am faced with testing a few conditionals before dropping into another control structure. If you have to test out a few conditionals, then its likely a dispatch table won&#8217;t be useful. If you have a lot of conditionals to test, you&#8217;ll likely not want to deal with an ugly expression like [...]]]></description>
			<content:encoded><![CDATA[<p>Every so often I am faced with testing a few conditionals before dropping into another control structure.  If you have to test out a few conditionals, then its likely a dispatch table won&#8217;t be useful.  If you have a lot of conditionals to test, you&#8217;ll likely not want to deal with an ugly expression like the following:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">if ( (defined $SITE{$partner}{'foo'} &amp;&amp; ($SITE{$partner}{'foo'} &gt; 0) ) and<br />
&nbsp; &nbsp; &nbsp; &nbsp; ( (defined $assoc{'foo'} &amp;&amp; ($assoc{'foo'} &gt; 0)) or<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (defined $assoc{'bar'} &amp;&amp; ($assoc{'bar'} &gt; 0)))<br />
&nbsp; &nbsp;) {<br />
print &quot;We're here!\n&quot;;<br />
}</div></div>
<p>One of the ways to deal with it to to use <strong>grep</strong>.  Since <strong>grep</strong> returns the number of elements in the array that evaluate to true (when called in a scalar context), I can do the following to make it work:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">my @foo = [ $SITE{$partner}{'foo'}, $assoc{'foo'}, $assoc{'bar'} ];<br />
if ( (grep {defined($_) and $_ &gt; 0} @foo) &gt; 2) { print &quot;We're here!\n&quot;; }</div></div>
<p>The reason this works is that when called in the scalar context, <strong>grep</strong> only returns the number of elements that evaluate to true.  Since there are 3 elements in the array, the return value is greater than 2, then the entire expression evaluates to true.  This is not only a lot easier to read and a lot cleaner to write, but it makes for easy additions to the conditional testing if necessary.  Although changing the context in which functions are called is common, it is easily forgotten.  <strong>Grep</strong> called in scalar context can be easily manipulated (as above) to add readability to your program.</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2009/perl/testing-for-a-number/' rel='bookmark' title='Testing For A Number'>Testing For A Number</a></li>
<li><a href='http://eric.lubow.org/2007/perl/creating-a-process-table-hash-in-perl/' rel='bookmark' title='Creating a Process Table hash in Perl'>Creating a Process Table hash in Perl</a></li>
<li><a href='http://eric.lubow.org/2009/perl/mac-perl-problems-after-feb-update/' rel='bookmark' title='Mac Perl Problems After Feb Update'>Mac Perl Problems After Feb Update</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/perl/cleaning-up-long-conditionals-with-grep/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mac Perl Problems After Feb Update</title>
		<link>http://eric.lubow.org/2009/perl/mac-perl-problems-after-feb-update/</link>
		<comments>http://eric.lubow.org/2009/perl/mac-perl-problems-after-feb-update/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 03:40:18 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[update]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=86</guid>
		<description><![CDATA[When I did my most recent upgrade (the latest Mac software updates), it broke my Perl install. In order to figure out if your Perl is broken like mine was, you will get a result like this: beacon:mail elubow$ perl -MIO IO object version 1.22 does not match bootstrap parameter 1.23 at /System/Library/Perl/5.8.8/darwin-thread-multi-2level/XSLoader.pm line 94. [...]]]></description>
			<content:encoded><![CDATA[<p>When I did my most recent upgrade (the latest Mac software updates), it broke my Perl install.  In order to figure out if your Perl is broken like mine was, you will get a result like this:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">beacon:mail elubow$ perl -MIO<br />
IO object version 1.22 does not match bootstrap parameter 1.23 at /System/Library/Perl/5.8.8/darwin-thread-multi-2level/XSLoader.pm line 94.<br />
Compilation failed in require.<br />
BEGIN failed--compilation aborted.</div></div>
<p>I had a little trouble finding out how to fix this.  So I am posting this here in case it helps someone else out. It was a simple fix (since CPAN doesn&#8217;t work) that you have to do by hand.  Go to the CPAN site and download dist IO <a href="http://search.cpan.org/dist/IO/">here</a>.  Download and untar it and run the following commands:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">beacon:IO-1.2301 elubow$ sudo perl Makefile.PL <br />
Writing Makefile for IO<br />
beacon:IO-1.2301 elubow$ sudo make install<br />
cc -c &nbsp; -arch i386 -arch ppc -g -pipe -fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -Wdeclaration-after-statement -I/usr/local/include -O3 &nbsp; -DVERSION=\&quot;1.23\&quot; -DXS_VERSION=\&quot;1.23\&quot; &nbsp;&quot;-I/System/Library/Perl/5.8.8/darwin-thread-multi-2level/CORE&quot; &nbsp; IO.c<br />
...<br />
&lt;strong&gt;Removed for brevity&lt;/strong&gt;<br />
...<br />
Files found in blib/arch: installing files in blib/lib into architecture dependent library tree<br />
Installing /System/Library/Perl/5.8.8/darwin-thread-multi-2level/auto/IO/IO.bundle<br />
Writing /System/Library/Perl/5.8.8/darwin-thread-multi-2level/auto/IO/.packlist<br />
Appending installation info to /System/Library/Perl/5.8.8/darwin-thread-multi-2level/perllocal.pod</div></div>
<p>This should fix your Perl install.  It also ended up that I had to run CPAN and reinstall <a href="http://search.cpan.org/~gbarr/Scalar-List-Utils-1.19/">Scalar::Util</a> and <a href="http://search.cpan.org/~ams/Storable-2.18/">Storable</a>.</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/mac/capistrano-hangs-on-mac-os-x-leopard/' rel='bookmark' title='Capistrano Hangs on Mac OS X Leopard'>Capistrano Hangs on Mac OS X Leopard</a></li>
<li><a href='http://eric.lubow.org/2007/perl/creating-a-process-table-hash-in-perl/' rel='bookmark' title='Creating a Process Table hash in Perl'>Creating a Process Table hash in Perl</a></li>
<li><a href='http://eric.lubow.org/2009/misc/converting-from-subversion-to-git/' rel='bookmark' title='Converting From Subversion To Git'>Converting From Subversion To Git</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/perl/mac-perl-problems-after-feb-update/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating a Process Table hash in Perl</title>
		<link>http://eric.lubow.org/2007/perl/creating-a-process-table-hash-in-perl/</link>
		<comments>http://eric.lubow.org/2007/perl/creating-a-process-table-hash-in-perl/#comments</comments>
		<pubDate>Fri, 28 Dec 2007 11:00:01 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[process]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/perl/47/creating-a-process-table-hash-in-perl/</guid>
		<description><![CDATA[I came across a situation where I needed to access the process table in Perl. The problem that i found was that the best accessor Proc::ProcessTable only retrieved an array. Since it seems fairly senseless to keep looping over an array to find the exact process id that I want, you may want to turn [...]]]></description>
			<content:encoded><![CDATA[<p>I came across a situation where I needed to access the process table in Perl.  The problem that i found was that the best accessor <a href="http://search.cpan.org/~durist/Proc-ProcessTable-0.41/ProcessTable.pm">Proc::ProcessTable</a> only retrieved an array.  Since it seems fairly senseless to keep looping over an array to find the exact process id that I want, you may want to turn it into a hash.</p>
<pre>
use strict;
use warnings;
use Proc::ProcessTable;

 # Create a new process table object
 my ($pt) = new Proc::ProcessTable;

 # Initialize your process table hash
 my (%pt_hash);

 # Get the fields that your architecture supports
 my (@fields) = $pt->fields;

 # Outer loop for each process id
 foreach my $proc ( @{$pt->table} ) {
    # Inner loop for each field within the process id
    for my $field (@fields) {
       # Add the field to the hash
       $pt_hash{$proc->pid}{$field} = $proc->$field();
    }
 }
</pre>
<p>It&#8217;s just as simple as that.  If you want to be sure that its in there.  At the end of the file add these two lines for proof:</p>
<pre>
use Data::Dumper;
print Dumper \%pt_hash;
</pre>
<p>The hash is organized with the keys being the process ids.  There is another hash underneath it with all the fields as hash keys.</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/ruby/hash-autovivification-in-ruby/' rel='bookmark' title='Hash Autovivification in Ruby'>Hash Autovivification in Ruby</a></li>
<li><a href='http://eric.lubow.org/2007/perl/emailfind/' rel='bookmark' title='Email::Find'>Email::Find</a></li>
<li><a href='http://eric.lubow.org/2007/perl/mailimapclient/' rel='bookmark' title='Mail::IMAPClient'>Mail::IMAPClient</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2007/perl/creating-a-process-table-hash-in-perl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>File::ReadBackwards</title>
		<link>http://eric.lubow.org/2007/perl/filereadbackwards/</link>
		<comments>http://eric.lubow.org/2007/perl/filereadbackwards/#comments</comments>
		<pubDate>Thu, 15 Mar 2007 11:00:21 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[Perl Modules]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/perl/32/filereadbackwards/</guid>
		<description><![CDATA[Description: File::ReadBackwards works similar to the linux shell command tac. It reads the file line by line strarting from the end of the file. CPAN: File::ReadBackwards Example 1: Being a System&#8217;s Administrator, I am usually doing some analysis on a large logfile. Therefore, I may not need all the information contained in the log. This [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Description:</strong> <a href="http://search.cpan.org/~uri/File-ReadBackwards-1.04/ReadBackwards.pm">File::ReadBackwards</a> works similar to the linux shell command <em>tac</em>.  It reads the file line by line strarting from the end of the file.</p>
<p><strong>CPAN:</strong> <a href="http://search.cpan.org/~uri/File-ReadBackwards-1.04/ReadBackwards.pm">File::ReadBackwards</a></p>
<p><strong>Example 1:</strong><br />
Being a System&#8217;s Administrator, I am usually doing some analysis on a large logfile.  Therefore, I may not need all the information contained in the log.  This may be especially true if the logs only get rotated once a day or once a week and I don&#8217;t need all the information in the log file.  Using <a href="http://search.cpan.org/~uri/File-ReadBackwards-1.04/ReadBackwards.pm">File::ReadBackwards</a> in combination with a date and time calculation module, I can take only the amount of time I want to use from the logs and then stop processing there.  Since we aren&#8217;t covering the date calculations here, I will push those out to another subroutine that we will assume works.</p>
<pre>
# Always use these
use strict;
use warnings;

# Use the module itself
use File::ReadBackwards;

# Define the log file to be read
my $log = "/var/log/log_file";

# Open the logfile by tie'ing it to the module
tie *LOG, "File::ReadBackwards", "$log"
   or die ("$log tie error: $!");

# Iterate over the logfile
while (my $line = <LOG>) {

  # Split the log line
  my @entry = split(/\s+/, $line);

  # Take the timestamp and check if we
  #   have hit our threshold yet
  # Break loop if we have
  last if (time_reached($entry[0]) == 1);
}

# Cleanup
untie (*LOG);
</pre>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2007/perl/filebidirectional/' rel='bookmark' title='File::Bidirectional'>File::Bidirectional</a></li>
<li><a href='http://eric.lubow.org/2007/perl/filefind/' rel='bookmark' title='File::Find'>File::Find</a></li>
<li><a href='http://eric.lubow.org/2009/perl/file-read-write-create-with-iofile/' rel='bookmark' title='File Read Write Create with IO::File'>File Read Write Create with IO::File</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2007/perl/filereadbackwards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>File::Bidirectional</title>
		<link>http://eric.lubow.org/2007/perl/filebidirectional/</link>
		<comments>http://eric.lubow.org/2007/perl/filebidirectional/#comments</comments>
		<pubDate>Fri, 09 Mar 2007 12:07:00 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[Perl Modules]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/perl/33/filebidirectional/</guid>
		<description><![CDATA[Description: The author of this module notes that it is best used, especially by him, when reading or manipulating log files. I have a tendency to use it for the exact same thing, especially when looking for context around captured lines. CPAN: File::Bidirectional Note: Although I would like to note that using the tie&#8217;d interface [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Description:</strong> The author of this module notes that it is best used, especially by him, when reading or manipulating log files.  I have a tendency to use it for the exact same thing, especially when looking for context around captured lines.</p>
<p><strong>CPAN:</strong> <a href="http://search.cpan.org/~kianwin/File-Bidirectional-0.01/lib/File/Bidirectional.pm">File::Bidirectional</a></p>
<p><strong>Note:</strong><br />
Although I would like to note that using the tie&#8217;d interface as I have done takes approximately 2 1/2 times as long as a regular file read according to benchmarks, it is still a very handy tool and allows one not to reinvent the wheel.</p>
<p><strong>Example 1:</strong><br />
Here we are going to go through a log file and when we hit the time stamp we want, we are going to change directions and go back through.  There is no real reason to change direction here, I am merely demonstrating how it would be accomplished.  </p>
<pre>
# Always use these
use strict;
use warnings;

# Use the module itself
use File::Bidirectional;

# Define the log file to be read
my $log = "/var/log/log_file";

# Open the logfile by tie'ing it to the module
#  This is exactly the same as File::ReadBackwards
tie *LOG, "File::Bidirectional", "$log", {mode => 'backward'}
   or die ("$log tie error: $!");

# Iterate over the logfile
while (my $line = <LOG>) {

  # Split the log line
  my @entry = split(/\s+/, $line);

  # Take the timestamp and check if we
  #   have hit our threshold yet
  # Get the line # then change direction
  if (time_reached($entry[0]) == 1) {
    $line_num = (tied *LOG)->line_num();
    (tied *LOG)->switch();
  }
}

# Cleanup
untie (*LOG);
</pre>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2007/perl/filereadbackwards/' rel='bookmark' title='File::ReadBackwards'>File::ReadBackwards</a></li>
<li><a href='http://eric.lubow.org/2007/perl/filefind/' rel='bookmark' title='File::Find'>File::Find</a></li>
<li><a href='http://eric.lubow.org/2009/perl/file-read-write-create-with-iofile/' rel='bookmark' title='File Read Write Create with IO::File'>File Read Write Create with IO::File</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2007/perl/filebidirectional/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mail::IMAPClient</title>
		<link>http://eric.lubow.org/2007/perl/mailimapclient/</link>
		<comments>http://eric.lubow.org/2007/perl/mailimapclient/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 19:33:06 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[Perl Modules]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/perl/16/mailimapclient/</guid>
		<description><![CDATA[Description: Recently, I have had the pleasure of getting knee deep into various aspects of Email. One of the things that I consistantly found myself wanting to do was to parse through it. I know the best way to do this is to connect to the IMAP server and download the messages. The best way [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Description:</strong> Recently, I have had the pleasure of getting knee deep into various aspects of Email.  One of the things that I consistantly found myself wanting to do was to parse through it.  I know the best way to do this is to connect to the IMAP server and download the messages.  The best way I have come accross on how to accomplish this task is using <a href="http://search.cpan.org/~conteb/IMAP-Client-0.13/lib/IMAP/Client.pm">Mail::IMAPClient</a>.</p>
<p><strong>CPAN:</strong> <a href="http://search.cpan.org/~conteb/IMAP-Client-0.13/lib/IMAP/Client.pm">Mail::IMAPClient</a></p>
<p><strong>Example 1:</strong><br />
Creating a connection to an IMAP server isn&#8217;t complicated.  And once you are connected there are many things that you can do to manipulate messages.  In this first example, I am merely going to show you how to connect to the mail server and download ALL the messages in specific folders:</p>
<pre>
# Always be safe
use strict;
use warnings;

# Use the module
use Mail::IMAPClient;

 $imap = Mail::IMAPClient->new( Server  => 'mail.server.com:143',
                                User    => 'me',
                              Password  => 'mypass')
        # module uses eval, so we use $@ instead of $!
        or die "IMAP Failure: $@";

 foreach my $box qw( HAM SPAM ) {
   # Which file are the messages going into
   my $file = "mail/$box";

   # Select the mailbox to get messages from
   $imap->select($box)
        or die "IMAP Select Error: $!";

   # Store each message as an array element
   my @msgs = $imap->search('ALL')
        or die "Couldn't get all messages\n";

   # Loop over the messages and store in file
   foreach my $msg (@msgs) {
     # Pipe msgs through 'formail' so they are stored properly
     open my $pipe, "| formail >> $file"
       or die("Formail Open Pipe Error: $!");

     # Send msg through file pipe
     $imap->message_to_file($pipe, $msg);

     # Close the messgae pipe
     close $pipe
       or die("Formail Close Pipe Error: $!");
   }

   # Close the folder
   $imap->close($box);
 }

 # We're all done with IMAP here
 $imap->logout();
</pre>
<p><strong>Example 2:</strong><br />
In this next example, we are going to take advantage of some other methods that are provided by this useful little module.  We will begin by using the same base as is in <strong>Example 1</strong>, but we will add some nuances in the middle for functionality.</p>
<p><strong>Note:</strong> Messages don&#8217;t get immediately deleted with IMAP, only marked for deletion.  They aren&#8217;t actually deleted until the box is <em>expunged</em>.  In this case, it gets done after the looping over each mailbox is complete.  This is to say that if the program gets interrupted in the middle that the messages won&#8217;t be deleted until the mailbox is officially issued an expunge command.</p>
<pre>
# Always be safe
use strict;
use warnings;

# Use the module
use Mail::IMAPClient;

 $imap = Mail::IMAPClient->new( Server  => 'mail.server.com:143',
                                User    => 'me',
                              Password  => 'mypass')
        # module uses eval, so we use $@ instead of $!
        or die "IMAP Failure: $@";

 foreach my $box qw( HAM SPAM ) {
   # How many msgs are we going to process
   print "There are ". $imap->message_count($box).
          " messages in the $box folder.\n";

   # Which file are the messages going into
   my $file = "mail/$box";

   # Select the mailbox to get messages from
   $imap->select($box)
        or die "IMAP Select Error: $!";

   # Store each message as an array element
   my @msgs = $imap->search('ALL')
        or die "Couldn't get all messages\n";

   # Loop over the messages and store in file
   foreach my $msg (@msgs) {
     # Pipe msgs through 'formail' so they are stored properly
     open my $pipe, "| formail >> $file"
       or die("Formail Open Pipe Error: $!");

     # Skip the msg if its over 100k
     if ($imap->size($msg) > 100000) {
       $imap->delete_message($msg);
       next;
     }

     # Send msg through file pipe
     $imap->message_to_file($pipe, $msg);

     # Close the messgae pipe
     close $pipe
       or die("Formail Close Pipe Error: $!");

     # Delete each message after downloading
     $imap->delete_message($msg);

     # If we are just testing and want to leave
     #  leave the messages untouched, then we
     #  can use the following line of code
     # $imap->deny_seeing($msg);
   }

   # Expunge and close the folder
   $imap->expunge($box);
   $imap->close($box);
 }

 # We're all done with IMAP here
 $imap->logout();
</pre>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2007/perl/mailsender/' rel='bookmark' title='Mail::Sender'>Mail::Sender</a></li>
<li><a href='http://eric.lubow.org/2009/mail/backing-up-gmailgoogle-apps-to-a-dovecot-server/' rel='bookmark' title='Backing Up Gmail/Google Apps to a Dovecot Server'>Backing Up Gmail/Google Apps to a Dovecot Server</a></li>
<li><a href='http://eric.lubow.org/2009/mail/transferring-email-from-gmailgoogle-apps-to-dovecot-with-larch/' rel='bookmark' title='Transferring Email From Gmail/Google Apps to Dovecot With Larch'>Transferring Email From Gmail/Google Apps to Dovecot With Larch</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2007/perl/mailimapclient/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

