<?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 Modules</title>
	<atom:link href="http://eric.lubow.org/category/perl/perl-modules/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::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>
		<item>
		<title>Sys::Hostname</title>
		<link>http://eric.lubow.org/2007/perl/syshostname/</link>
		<comments>http://eric.lubow.org/2007/perl/syshostname/#comments</comments>
		<pubDate>Fri, 19 Jan 2007 19:36:44 +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/13/syshostname/</guid>
		<description><![CDATA[Description: Sys::Hostname is a relatively small, but very useful module. Just as the module name describes, it gets your system&#8217;s hostname. To paraphrase the module&#8217;s POD documentation, it will try every conceivable way to get the hostname of the current machine. CPAN: Sys::Hostname Example: The one and only use for this module. # Always be [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Description:</strong> <a href="http://search.cpan.org/~nwclark/perl-5.8.8/ext/Sys/Hostname/Hostname.pm">Sys::Hostname</a> is a relatively small, but very useful module.  Just as the module name describes, it gets your system&#8217;s hostname.  To paraphrase the module&#8217;s POD documentation, it will try every conceivable way to get the hostname of the current machine.</p>
<p><strong>CPAN:</strong> <a href="http://search.cpan.org/~nwclark/perl-5.8.8/ext/Sys/Hostname/Hostname.pm">Sys::Hostname</a></p>
<p><strong>Example:</strong><br />
The one and only use for this module.</p>
<pre>
# Always be safe
use strict;
use warnings;

# Use the module
use Sys::Hostname;

# Get the hostname
my $host = Sys::Hostname::hostname();

# The above line can also be written as
#my $host = hostname;

print "You are on: $host\\n";
</pre>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2007/perl/htmlentities/' rel='bookmark' title='HTML::Entities'>HTML::Entities</a></li>
<li><a href='http://eric.lubow.org/2007/perl/iosocketinet/' rel='bookmark' title='IO::Socket::INET'>IO::Socket::INET</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/2007/perl/syshostname/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML::Entities</title>
		<link>http://eric.lubow.org/2007/perl/htmlentities/</link>
		<comments>http://eric.lubow.org/2007/perl/htmlentities/#comments</comments>
		<pubDate>Thu, 18 Jan 2007 17:48:29 +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/15/htmlentities/</guid>
		<description><![CDATA[Description: When taking user input through any number of forms, there could be characters that you aren&#8217;t expecting. This is exactly what HTML::Entities was designed to handle. When getting the user input, it converts it into a form that can help in mitigating certain types of web based scripting attacks. CPAN: HTML::Entities Example 1: The [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Description:</strong> When taking user input through any number of forms, there could be characters that you aren&#8217;t expecting.  This is exactly what <a href="http://search.cpan.org/~gaas/HTML-Parser-3.56/lib/HTML/Entities.pm">HTML::Entities</a> was designed to handle.  When getting the user input, it converts it into a form that can help in mitigating certain types of web based scripting attacks.</p>
<p><strong>CPAN:</strong> <a href="http://search.cpan.org/~gaas/HTML-Parser-3.56/lib/HTML/Entities.pm">HTML::Entities</a></p>
<p><strong>Example 1:</strong><br />
The general example of using</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">encode_entities()</div></div>
<p>is probably also the most common.  It basically says to encode everything in the string that its possible to encode.</p>
<pre>
# Always be safe and smart
use strict;
use warnings;

# Use the module
use HTML::Entities;

 my $html = "bad stuff here&#$%";
 $html = encode_entities($html);
 print "HTML: $html\\n";

__OUTPUT__
HTML: bad stuff here&amp;#0
</pre>
<p><strong>Example 2:</strong><br />
This is the slightly more specific example as it uses only specific sets of characters as the &#8220;unsafe&#8221; characters.</p>
<pre>
# Always be safe and smart
use strict;
use warnings;

# Use the module
use HTML::Entities;

 my $html = "bad stuff here&amp;#$%";
 $html = encode_entities($html, "\\x80-\\xff");
 print "HTML: $html\\n";

__OUTPUT__
HTML: bad stuff here&amp;amp;amp;#0
</pre>
<p><strong>Example 3:</strong><br />
This is an example of</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">decode_entities()</div></div>
<p>which does the reverse.  It checks the string to see if there are any HTML encoded characters and decodes them into their Unicode equivalent.  This is the general version of</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">decode_entities()</div></div>
<p>which is similar to the version of</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">encode_entities()</div></div>
<p>demonstrated in <strong>Example 1</strong>.</p>
<pre>
# Always be safe and smart
use strict;
use warnings;

# Use the module
use HTML::Entities;

 my $html = "encoded: bad stuff here&amp;amp;#0";
 $html = decode_entities($html);
 print "Unicode: $html\\n";

__OUTPUT__
Unicode: encoded: bad stuff here&amp;#0
</pre>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2007/perl/syshostname/' rel='bookmark' title='Sys::Hostname'>Sys::Hostname</a></li>
<li><a href='http://eric.lubow.org/2007/perl/iosocketinet/' rel='bookmark' title='IO::Socket::INET'>IO::Socket::INET</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/htmlentities/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mail::Sender</title>
		<link>http://eric.lubow.org/2007/perl/mailsender/</link>
		<comments>http://eric.lubow.org/2007/perl/mailsender/#comments</comments>
		<pubDate>Wed, 17 Jan 2007 19:42: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/14/mailsender/</guid>
		<description><![CDATA[Description: This is probably one of the modules that I use most frequently. I commonly write reporting and statistic generating scripts. When the data is finished being crunched, I then dump it into a scalar and send it off in an email. This is the module that does my dirty work for me. CPAN: Mail::Sender [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Description:</strong> This is probably one of the modules that I use most frequently.  I commonly write reporting and statistic generating scripts.  When the data is finished being crunched, I then dump it into a scalar and send it off in an email.  This is the module that does my dirty work for me.</p>
<p><strong>CPAN:</strong> <a href="http://search.cpan.org/~jenda/Mail-Sender-0.8.13/Sender.pm">Mail::Sender</a></p>
<p><strong>Example 1:</strong><br />
This is probably the most common implementation of <a href="http://search.cpan.org/~jenda/Mail-Sender-0.8.13/Sender.pm">Mail::Sender</a> that I use.  I generally build up what is going to go in the $EMAIL variable throughout the script and then eval it to ensure it gets put into the message.</p>
<pre>
# Always be safe
use strict;
use warnings;

# Use the module
use Mail::Sender;

# Remove Mail::Sender logo feces from mail header
$Mail::Sender::NO_X_MAILER = 1;

my $EMAIL = "This is the body of the email here.\\n";

  eval {
   # Create the anonymous Mail::Sender object
   (new Mail::Sender)->MailMsg(
   {
     smtp => "mail.mydomain.com",
     from => "\\"Postmaster\\" &lt;postmaster\\@mydomain.com&gt;",
     to   => "\\"Eric Lubow\\" &lt;me\\@mydomain.com.com&gt;",
     cc   => "\\"Tech Support\\" &lt;tech\\@mydomain.com&gt;",
     subject => "Test Email",
     msg  => "$EMAIL"
   })
     # Show the Mail::Sender error since $! isn't set here
     or die "Error Sending Mail: $Mail::Sender::Error";
  };
</pre>
<p><strong>Example 2:</strong><br />
This example sends a mixed multipart message, with text in HTML and alternative text in plaintext.  If the receiving user&#8217;s email client can read HTML messages, then the HTML portion of the message will be shown.  Otherwise, the plaintext (alternative) will show.  The iterative loop sends the email message to as many users as are in the array.  The script just provides a qw (quote words) statement to be used in the loop.  Your best bet would be to create an array of email addresses and iterate over the array:</p>
<pre>
 my @emails = ["eric@mydomain.com","techs@mydomain.com"];
 for my $rcpt (@emails) {
   ...
 }
</pre>
<p><strong>Note:</strong> In this example, I have also included a subroutine to create a message boundary.  I don&#8217;t particularly have anything major against the one&#8217;s that are generated by default, I just think they give away a little too much information for my liking.  Mine is slightly more random.</p>
<pre>
# Always be safe
use strict;
use warnings;

# Use the module
use Mail::Sender;

# Remove Mail::Sender logo feces from mail header
$Mail::Sender::NO_X_MAILER = 1;

 for my $rcpt (qw( me@mydomain.com tech@mydomain.com ) ) {
   my $sender = new Mail::Sender
    { smtp => '127.0.0.1',
       from => "$from_name &lt;postmaster\\@mydomain.com&gt;",
       boundary => make_boundary()
    }
    or die "Error in mailing: $Mail::Sender::Error\\n";

   # Begin the message, tells the header what message type
   $sender->OpenMultipart(
     { to        => "eric\\@mydomain.com",
        subject   => "Test Email",
        headers   => "Return-Path: postmaster\\@mydomain.com\\r\\n",
        multipart => "mixed",
     })
     or die "Can't Open message: $sender->{'error_msg'}\n";

     # Change the content-type
     $sender->Part( { ctype => 'multipart/alternative' });

     # Put the plain text into the email (aka the alternative text)
     $sender->Part(
       { ctype       => 'text/plain',
         disposition => 'NONE',
         msg          => "This is a test message.\n\nHere is the plaintext.\\n"
       });

     # Put the HTML text into the HTML (what SHOULD be displayed)
     $sender->Part(
       { ctype       => 'text/html',
         disposition => 'NONE',
         msg         => "This is a &lt;B&gt;TEST&lt;/B&gt; message.\\n&lt;br&gt;\\n"
       });

     # The message isn't sent until it's Close()'d
     $sender->Close()
       or die "Failed to send message: $sender->{'error_msg'}\\n";
 }

#######################################################
# Function: Creates a random message boundary
# Parameters: None
# Return: Boundary
# Notes: Bounaries are 43 characters in length
#######################################################
sub make_boundary {
  my ($boundary, $char, $wanted) = ('','',43);

  open R, '<', "/dev/urandom";
  while ($wanted) {
    read (R, $char, 1)
      or die "Couldn't read from /dev/urandom: $!\n";
    if ($char =~ /[A-Za-z0-9]/) {
      $boundary .= $char;
      --$wanted;
    }
  }
  close(R);

  return $boundary;
}
</pre>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2007/perl/mailimapclient/' rel='bookmark' title='Mail::IMAPClient'>Mail::IMAPClient</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/2010/mail/list-of-feedback-loops/' rel='bookmark' title='List of Feedback Loops'>List of Feedback Loops</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2007/perl/mailsender/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IO::Socket::INET</title>
		<link>http://eric.lubow.org/2007/perl/iosocketinet/</link>
		<comments>http://eric.lubow.org/2007/perl/iosocketinet/#comments</comments>
		<pubDate>Tue, 16 Jan 2007 20:38:04 +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/12/iosocketinet/</guid>
		<description><![CDATA[Description: When I need to interact with the raw IO of telnetting to a port or creating a hand rolled implementation of my own service, I use IO::Socket. My most recent endeavor was for a need to check weather or not services were running on a regular basis. I will show some excepts from the [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Description:</strong> When I need to interact with the raw IO of telnetting to a port or creating a hand rolled implementation of my own service, I use <a href="http://search.cpan.org/~gbarr/IO-1.2301/IO/Socket.pm">IO::Socket</a>.  My most recent endeavor was for a need to check weather or not services were running on a regular basis. I will show some excepts from the code later on in this post.</p>
<p>Although <a href="http://search.cpan.org/~gbarr/IO-1.2301/IO/Socket::INET.pm">IO::Socket::INET</a> is just a frontend for a good number of Perl&#8217;s builtin functions, I find it handy as it is generally a little more sane.  </p>
<p><strong>CPAN:</strong> <a href="http://search.cpan.org/~gbarr/IO-1.2301/IO/Socket/INET.pm">IO::Socket::INET</a></p>
<p><strong>Note:</strong> <a href="http://search.cpan.org/~gbarr/IO-1.2301/IO/Socket/INET.pm">IO::Socket::INET</a> is a subclass of <a href="http://search.cpan.org/~gbarr/IO-1.2301/IO/Socketpm">IO::Socket</a>.</p>
<p><strong>Example 1:</strong><br />
This example is the socket portion of a script that checks to see if certain daemons are alive.  It does this by connecting to the port that they should be listening on.  If it receives a response, then the daemon is alive, if not, it restarts the daemon and tries contacting it again.  As you can see below, the response itself doesn&#8217;t matter, just that there is a response being received.</p>
<pre>
# Always be safe and smart
use strict;
use warnings;

# Use the module
use IO::Socket;

 # Prototype the socket
 my $socket = new IO::Socket::INET(
                   PeerAddr => "localhost",   # Hostname/IP
                   PeerPort => "smtp(25)",   # Service (Port)
                   Proto    => "tcp",            # Protocol
                   )
   or die "Socket bind error: $!";

 # Create the socket
 $socket
   or die "Socket error: $!";

 # Close the socket
 close $socket
   or die "Socket close error: $!";
</pre>
<p><strong>Example 2:</strong><br />
On the other side of the fence, we can create a listening socket that can act as a server.  If you run this little script and then connect to the specified port it will say something along 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">Welcome 127.0.0.1 to a simple socket server.</div></div>
<p>The server script will listen indefinitely (or at least until you press CTRL-C to make it exit).  To test out the script and ensure you receive something similar to the above response (with your IP instead of 127.0.0.1), from the linux command prompt, type the following (replace with your IP and port):</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">$ telnet localhost 12345</div></div>
<pre>
# Always be safe and smart
use strict;
use warnings;

# Use the module
use IO::Socket;

 # Listen port
 my $port = 12345;

 # Prototype the socket
 my $server = new IO::Socket::INET(
   Listen   => SOMAXCONN, # Max connections allowed by system
   Reuse    => 1,               # Reuse connections
   LocalAddr => "localhost", # Listen hostname
   LocalPort => $port,        # Listen port
   Proto    => "tcp",           # Listen protocol
 ) or die "Socket bind error: $!";

 # Listen for the client until we get a CTRL-C
 while (my $client = $server->accept()) {
   # Force the data out of the stack
   $client->autoflush(1);

   # Say hello to my little client
   print $client "Welcome ". $client->peerhost ." ".
                 "to a simple socket server.\n";
 }

 # Close the server when we are done
 close $server
   or die "Socket close error: $!";
</pre>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2007/perl/syshostname/' rel='bookmark' title='Sys::Hostname'>Sys::Hostname</a></li>
<li><a href='http://eric.lubow.org/2007/perl/mailimapclient/' rel='bookmark' title='Mail::IMAPClient'>Mail::IMAPClient</a></li>
<li><a href='http://eric.lubow.org/2007/perl/htmlentities/' rel='bookmark' title='HTML::Entities'>HTML::Entities</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2007/perl/iosocketinet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>File::Pid</title>
		<link>http://eric.lubow.org/2007/perl/filepid/</link>
		<comments>http://eric.lubow.org/2007/perl/filepid/#comments</comments>
		<pubDate>Thu, 11 Jan 2007 20:01:24 +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/11/filepid/</guid>
		<description><![CDATA[Description: Consistantly writing programs that either act as daemons or take a long time to run depending on the input, I find it necessary to track weather or not they are still running. Lots of programs do this and its generally called state or status tracking. One of the most common ways to do this [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Description:</strong> Consistantly writing programs that either act as daemons or take a long time to run depending on the input, I find it necessary to track weather or not they are still running.  Lots of programs do this and its generally called state or status tracking.  One of the most common ways to do this is to use a pid file.</p>
<p>The most common method is to create a file with the naming scheme <em>program_name.pid</em>.  The contents of the file is the pid of the program.  Then at the conclusion of the program, the file is removed.  The pid file is generally stored in the OS&#8217;s state directory (in linux).  Generally being a <a href="http://www.debian.org/">Debian</a> or <a href="http://www.ubuntu.com/">Ubuntu</a>, the state information is stored in the <em>/var/run/</em> directory.  I also frequently use <a href="http://www.engardelinux.org/">EnGarde Secure Linux</a> which also has a state directory of <em>/var/run/</em>.</p>
<p><strong>CPAN:</strong> <a href="http://search.cpan.org/~cwest/File-Pid-1.01/lib/File/Pid.pm">File::Pid</a></p>
<p><strong>Note:</strong> In the spirit of <a href="http://acronyms.thefreedictionary.com/TIMTOWTDI">TIMTOWTDI</a>, the process itself isn&#8217;t overly complex.  To illustrate that, I will show one method of accomplishing this goal without using a Perl module.  I will also be using the Perl special variable <strong>$$</strong>.  To quote the <a href="http://perldoc.perl.org/perlvar.html#%24PROCESS_ID">Perl Special Variables</a> page:</p>
<blockquote>
<li><b>$PROCESS_ID</b></li>
<li><b>$PID</b></li>
<li><b>$$</b>
<p>The process number of the Perl running this script.  You should consider this variable read-only, although it will be altered across fork() calls.  (Mnemonic: same as shells.)</p>
<p>Note for Linux users: on Linux, the C functions <strong>getpid</strong> and <strong>getppid()</strong> return different values from different threads. In order to be portable, this behavior is not reflected by <strong>$$</strong>, whose value remains consistent across threads. If you want to call the underlying <strong>getpid</strong>, you may use the CPAN module <a href="http://search.cpan.org/~rgarcia/Linux-Pid-0.03/Pid.pm">Linux::Pid</a>.</p>
</blockquote>
<p><P>As you will likely note, although potentially less portable across OS&#8217;s, using <a href="http://search.cpan.org/~cwest/File-Pid-1.01/lib/File/Pid.pm">File::Pid</a> is much cleaner and easier.</p>
<p>
<pre>
# Declare your variables
my $pid_file = "/var/run/myprog.pid";
local *PIDFILE;

# Check for the PID file's existance
if (-e $pid_file) {
  die ("Program already running or ended prematurely\\n");
}

# Create the PID file
# Use the 3 argument form of open for safety
open PIDFILE, ">", $pid_file;
print PIDFILE "$$\\n";
close PIDFILE;

# XXX - Program here

# Remove PID file
unlink $pid_file
  or die "Error unlinking $pid_file: $!";
</pre>
</p>
<p><strong>Example 1:</strong><br />
Using the basic example of just creating the PID file, checking if the program is already running, and removing the PID file, let&#8217;s take a look at the OO (Object Oriented) example:</p>
<pre>
# Always be safe &#038; strict
use strict;
use warnings;
# Use the module
use File::Pid;

 # Create the PID object
 # Ensure you put a name that won't clobber
 #   another program's PID file
 my $PID = File::Pid->new({
   file  => '/var/run/myprog.pid',
 });

 # Write the PID file
 $PID->write;

 # Check for the previous instance
 #  and die if PID file already exists
 if (my $oldPID = $PID->running()) {
   die "myprog already running: $oldPID\n";
 }

 # XXX - Program here

 # Remove the PID file
 $PID->remove;
</pre>


<p>Related posts:<ol><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/2007/perl/filereadbackwards/' rel='bookmark' title='File::ReadBackwards'>File::ReadBackwards</a></li>
<li><a href='http://eric.lubow.org/2007/perl/filebidirectional/' rel='bookmark' title='File::Bidirectional'>File::Bidirectional</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2007/perl/filepid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

