<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1811416185910478273</id><updated>2012-02-16T20:57:15.673+11:00</updated><category term='mason'/><category term='blogger'/><category term='evaluation'/><category term='frameworks'/><category term='dns'/><category term='data portability'/><category term='security'/><category term='rails'/><category term='politics'/><category term='perl'/><category term='trivia'/><category term='nagios'/><category term='email'/><category term='teeny-tiny-toolkit'/><category term='catalyst'/><category term='solaris'/><category term='django'/><category term='osx'/><category term='hair'/><title type='text'>Hissohathair</title><subtitle type='html'>A weblog by no-one of consequence. Mainly about web and software development. :-)</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-2364661950994634946</id><published>2011-02-02T17:13:00.001+11:00</published><updated>2011-02-02T17:44:14.993+11:00</updated><title type='text'>The "Super" Difference</title><content type='html'>&lt;iframe src="http://www.youtube.com/embed/diOWLKwxsv8?fs=1" allowfullscreen="" frameborder="0" height="295" width="480"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;Megamind:&lt;/i&gt; You dare challenge Megamind?&lt;br /&gt;&lt;i&gt;Villain:&lt;/i&gt; This town isn't big enough for two super-villains!&lt;br /&gt;&lt;i&gt;Megamind:&lt;/i&gt; Oh, you're a villain alright. Just not a super one.&lt;br /&gt;&lt;i&gt;Villain: &lt;/i&gt;Yeah? What's the difference?&lt;br /&gt;&lt;i&gt;[music reaches its crescendo, the enormous flying Megamind head opens wide, spits out its tongue to reveal Megamind himself]&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Megamind: &lt;/i&gt;&lt;b&gt;Presentation!&lt;/b&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-2364661950994634946?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/2364661950994634946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=2364661950994634946' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/2364661950994634946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/2364661950994634946'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2011/02/super-difference.html' title='The &quot;Super&quot; Difference'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/diOWLKwxsv8/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-4247015963145177741</id><published>2009-09-25T17:47:00.001+10:00</published><updated>2009-11-30T23:30:53.150+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hair'/><title type='text'>The Real Mr His So Hat Hair</title><content type='html'>Awesome.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Avx-Y9MMm3c&amp;hl=en&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Avx-Y9MMm3c&amp;hl=en&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-4247015963145177741?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/4247015963145177741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/4247015963145177741'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/09/real-mr-his-so-hat-hair.html' title='The Real Mr His So Hat Hair'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-6511649559734498530</id><published>2009-06-03T10:58:00.001+10:00</published><updated>2010-08-15T00:24:29.771+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='catalyst'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Using CruiseControl.rb to manage a Perl Catalyst project</title><content type='html'>&lt;span style="font-family: Arial; font-size: 13px;"&gt;We're working with the &lt;a href="http://www.catalystframework.org/"&gt;Catalyst framework&lt;/a&gt; again, porting an old Perl 5 &lt;a href="http://www.masonhq.com/"&gt;HTML::Mason&lt;/a&gt; site to Catalyst and introducing some modern Perl coding standards to a fairly old stack.&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;One of the things we needed was a Continuous Integration tool for the project. Since we're already using &lt;a href="http://cruisecontrolrb.thoughtworks.com/"&gt;CruiseControl.rb&lt;/a&gt; for the Rails projects I thought it should be pretty easy to incorporate the Perl project into it.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;And indeed it was:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$&amp;nbsp;./cruise add CatalystProject --url https://svn.work.com/svn/catalystproject/trunk/&lt;/div&gt;&lt;/div&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;CruiseControl will run a "rake" task whenever a commit is made. So we need a small Rakefile with just enough code in it to run the standard Perl tools:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;$ cat Rakefile&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="command-line command-line-output"&gt;require 'rake'&lt;br /&gt;&lt;br /&gt;task :default =&amp;gt; :test&lt;br /&gt;&lt;br /&gt;desc "Runs make test"&lt;br /&gt;task :test do&lt;br /&gt;&amp;nbsp;&amp;nbsp;t &amp;nbsp;= system("eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib) &amp;amp;&amp;amp; perl Makefile.PL &amp;amp;&amp;amp; make test")&lt;br /&gt;&amp;nbsp;&amp;nbsp;rc = $?&lt;br /&gt;&amp;nbsp;&amp;nbsp;puts "\nMake finished with t=#{t} rc=#{rc.exitstatus}"&lt;br /&gt;&amp;nbsp;&amp;nbsp;raise "Perl make failed (rc=#{rc.exitstatus})" unless t&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;The eval line in the system call is there because we're using local::lib to manage our Perl library dependencies and we need to set the environment variables so that they can be found. To propagate any "make test" errors back out to rake we throw an exception on non-zero exit codes.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-6511649559734498530?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/6511649559734498530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=6511649559734498530' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/6511649559734498530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/6511649559734498530'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/06/using-cruisecontrolrb-to-manage-perl.html' title='Using CruiseControl.rb to manage a Perl Catalyst project'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-7090114304598438029</id><published>2009-05-12T01:36:00.003+10:00</published><updated>2009-05-12T02:01:16.343+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dns'/><category scheme='http://www.blogger.com/atom/ns#' term='osx'/><title type='text'>How to set your DNS search list in OSX</title><content type='html'>Here's how to set your &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;DNS&lt;/span&gt; search path in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;OSX&lt;/span&gt;, which is something you'll want to do if you're getting &lt;a href="http://hissohathair.blogspot.com/2009/05/search-path-fix-for-aszcomau-is-only.html"&gt;redirected to eBay when you try to go to Google&lt;/a&gt;, or are experiencing other odd behaviour from your browser.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Open System Preferences.&lt;/li&gt;&lt;li&gt;Open Network settings.&lt;/li&gt;&lt;li&gt;Your active network connection should be selected on the left. Select it if it is not. Click the "Advanced" button towards the bottom right hand corner.&lt;/li&gt;&lt;li&gt;Select the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;DNS&lt;/span&gt; tab.&lt;/li&gt;&lt;li&gt;On the right hand side is a column "&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;Search&lt;/span&gt; Domains." It will probably already have your domain name listed, but it will be "greyed" out so that you can't remove it. That's OK. Click the "+" sign at the bottom of the column, and type the domain name again.&lt;/li&gt;&lt;li&gt;You should now have the domain name listed twice. One will be grey, the other black. This is good, &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;believe&lt;/span&gt; it or not. :-)&lt;/li&gt;&lt;li&gt;Click OK.&lt;/li&gt;&lt;li&gt;Click Apply.&lt;/li&gt;&lt;/ol&gt;Here's a screen capture that steps through it.&lt;br /&gt;&lt;br /&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-fb15b96d35085db1" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v17.nonxt6.googlevideo.com/videoplayback?id%3Dfb15b96d35085db1%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331566707%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D6267FB6420188657C614212427FBE4583269A95A.71D5196346A551C904B09BFD4179FECBE71443E%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Dfb15b96d35085db1%26offsetms%3D5000%26itag%3Dw160%26sigh%3DAJVslLcTqQg6fD2HWR4XCseQO1g&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v17.nonxt6.googlevideo.com/videoplayback?id%3Dfb15b96d35085db1%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331566707%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D6267FB6420188657C614212427FBE4583269A95A.71D5196346A551C904B09BFD4179FECBE71443E%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Dfb15b96d35085db1%26offsetms%3D5000%26itag%3Dw160%26sigh%3DAJVslLcTqQg6fD2HWR4XCseQO1g&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-7090114304598438029?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='enclosure' type='video/mp4' href='http://www.blogger.com/video-play.mp4?contentId=fb15b96d35085db1&amp;type=video%2Fmp4' length='0'/><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/7090114304598438029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=7090114304598438029' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/7090114304598438029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/7090114304598438029'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/05/how-to-set-your-dns-search-list-in-osx.html' title='How to set your DNS search list in OSX'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-6772016484986915471</id><published>2009-05-07T14:28:00.000+10:00</published><updated>2009-05-07T14:28:21.881+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dns'/><title type='text'>The "search path fix" for ASZ.COm.Au is only a partial fix</title><content type='html'>Feel I need to clarify my fix to the &lt;a href="http://hissohathair.blogspot.com/2009/04/welcome-to-aszcomau-or-resolver-library.html"&gt;"eBay/ASZ redirection problem" discussed in my last post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Adding your domain name to your DNS search path will stop your DNS resolver from asking the "au.com.au" and "com.com.au" name servers for "google.com.au.com.au". So you shouldn't get "Welcome to ASZ.COm.Au" or be redirected to eBay or other unexpected behaviour.&lt;br /&gt;&lt;br /&gt;What you'll get instead is "site not found". That's what I mean by a partial fix. If your ISPs name server is losing DNS responses (or is too slow to return them) then you'll still have problems: namely you'll get an error message when you try and visit some sites. However clicking "Refresh" or "Reload" will generally solve that problem. Once your at the site the address will be in your resolver's cache so things will be stable for a while.&lt;br /&gt;&lt;br /&gt;Meanwhile I've written to the &lt;a href="http://www.auda.org.au/"&gt;auDA&lt;/a&gt; guys asking for their opinion on defining DNS entries for other peoples domain names as sub-domains of yours.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-6772016484986915471?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/6772016484986915471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=6772016484986915471' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/6772016484986915471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/6772016484986915471'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/05/search-path-fix-for-aszcomau-is-only.html' title='The &quot;search path fix&quot; for ASZ.COm.Au is only a partial fix'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-6552751901736530796</id><published>2009-04-30T17:43:00.087+10:00</published><updated>2009-05-01T12:20:03.335+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dns'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Welcome to ASZ.COm.Au (Or, The Resolver Library is Broken)</title><content type='html'>A few days ago, I did a Google search and &lt;a href="https://twitter.com/hissohathair/status/1603388672"&gt;got the strangest error&lt;/a&gt;: a 404 (File Not Found) page that claimed to be from Apache with PHP and Frontpage extensions loaded. Google doesn't run Apache.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_KWodxN74zfY/Sfkrj81NhQI/AAAAAAAAAEY/f8zHoS2Lpcs/s1600-h/Picture+1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_KWodxN74zfY/Sfkrj81NhQI/AAAAAAAAAEY/f8zHoS2Lpcs/s400/Picture+1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Since that was A Very Odd Thing Indeed I went to the Google home page. This time &lt;a href="https://twitter.com/hissohathair/status/1603417959"&gt;I got a new message&lt;/a&gt;: "Welcome to ASZ.COm.Au" (for some reason, I feel it's important to preserve the capitalisation).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_KWodxN74zfY/SfksAiictII/AAAAAAAAAEg/iF5NRzsQkMQ/s1600-h/Picture+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_KWodxN74zfY/SfksAiictII/AAAAAAAAAEg/iF5NRzsQkMQ/s400/Picture+2.png" /&gt;&lt;/a&gt;&lt;/div&gt;My first guess was that my &lt;a href="http://en.wikipedia.org/wiki/DNS_cache_poisoning"&gt;DNS cache had been poisoned&lt;/a&gt;. Or that I'd picked up a virus somehow. When I looked on Twitter I saw that &lt;a href="http://search.twitter.com/search?q=ASZ.com.au"&gt;I was not alone&lt;/a&gt;: a few people were reporting similar problems trying to access &lt;a href="http://www.facebook.com/"&gt;Facebook&lt;/a&gt;, &lt;a href="http://www.youtube.com/"&gt;YouTube&lt;/a&gt;, &lt;a href="http://www.google.com.au/"&gt;Google&lt;/a&gt; and even &lt;a href="http://www.ebay.com.au/"&gt;eBay&lt;/a&gt;. A &lt;a href="http://forums.whirlpool.net.au/forum-replies.cfm?t=1184992"&gt;discussion about the issue&lt;/a&gt; had started on &lt;a href="http://whirlpool.net.au/"&gt;Whirlpool&lt;/a&gt;. In most cases, the issue appeared to resolve itself eventually, or after a DNS cache flush.&lt;br /&gt;&lt;br /&gt;In my case, the issue persisted for a little while and then stopped. I was able to access Google again.&lt;br /&gt;&lt;br /&gt;It took some time for me to figure out what was going on (hey -- I'm &lt;a href="http://science.slashdot.org/article.pl?sid=09/03/17/148217"&gt;over 27&lt;/a&gt;). The intermittent nature of the issue made debugging difficult. It wasn't until my partner mentioned that she'd seen the same screen when she'd tried to access the &lt;a href="http://www.bom.gov.au/"&gt;Bureau of Meteorology&lt;/a&gt;&amp;nbsp; that I was able to make progress. Visiting &lt;a href="http://bom.gov.au/"&gt;http://bom.gov.au/&lt;/a&gt; (but not &lt;a href="http://www.bom.gov.au/"&gt;http://www.bom.gov.au/&lt;/a&gt;) consistently reproduced the problem.&lt;br /&gt;&lt;br /&gt;I chased down a few theories: malware, cache-poisoning, an "optus issue".&amp;nbsp; But I finally worked out that this was the result of a documented feature of the common UNIX resolver library.&lt;br /&gt;&lt;br /&gt;When you visit a web page your computer needs to "resolve" the &lt;a href="http://en.wikipedia.org/wiki/Hostname"&gt;host name&lt;/a&gt; (eg "google.com.au") to an Internet address. That's the job of the &lt;a href="http://en.wikipedia.org/wiki/Resolver_%28DNS%29#DNS_resolvers"&gt;&lt;i&gt;resolver&lt;/i&gt;&lt;/a&gt;, which in turn uses something called a &lt;a href="http://en.wikipedia.org/wiki/Name_server"&gt;domain name server&lt;/a&gt;. Your browser asks the resolver "what's the address of Google.com.au" and the resolver answers. Either the resolver already knows the answer because it's looked it up before and kept a copy (a cache), or it doesn't know, and so it asks the domain name server. The domain name server in turn may ask other domain name servers, until someone, somewhere, knows the answer. The answer is then sent back through the chain, ultimately to your resolver (called the "client").&lt;br /&gt;&lt;br /&gt;So if the resolver doesn't know an address it asks the domain name server and waits for an answer. But it will not wait forever. In fact, it typically won't wait longer than several seconds. It's an impatient little thing and if it hasn't heard back quickly enough it assumes that maybe the hostname is wrong -- maybe the user just typed &lt;b&gt;part&lt;/b&gt; of the hostname. Or maybe the domain name server &lt;b&gt;does&lt;/b&gt; answer in time but the resolver cannot use the answer -- the domain name server may reply with "no one knows that hostname." Either way, the resolver will start to guess what the real (or "fully qualified") hostname might be.&lt;br /&gt;&lt;br /&gt;There are two strategies a resolver can use when it starts searching for the fully qualified hostname.&lt;br /&gt;&lt;br /&gt;The first is to use an explicit list of search paths. You usually provide this list yourself when configuring your network settings. If you haven't set such a list, then it will employ the second strategy. (That's going to turn out to be quite handy...)&lt;br /&gt;&lt;br /&gt;The second thing your resolver can do is a "domain name search". It takes your domain name, prepends the hostname you're looking for and does a lookup on that. I'm with Optusnet, so my domain name is "optusnet.com.au". My reslover then might lookup "bom.gov.au.optusnet.com.au" if it doesn't get a useful answer for "bom.gov.au". If it &lt;b&gt;still&lt;/b&gt; doesn't get a useful answer (and it this case, it won't) then it starts searching "up" the domain name -- it removes the first part of the domain name and repeats the search. So its second search is for "bom.gov.au.com.au". See what it did there? It deleted "optusnet" and tried again.&amp;nbsp; (Technical note: the behaviour is documented in the &lt;a href="http://www.manpagez.com/man/3/resolver/"&gt;resolver man page&lt;/a&gt; -- see RES_DNSRCH)&lt;br /&gt;&lt;br /&gt;That right there is the flaw and the root cause of the problem.&lt;br /&gt;&lt;br /&gt;Someone owns the domain names "au.com.au" and "com.com.au". And they have name servers. And they've set them up to answer queries for a whole host of things, among them, bom.gov.au.com.au, google.com.au.com.au and facebook.com.com.au. And our resolvers are querying them and merrily sending our browsers there &lt;b&gt;if&lt;/b&gt; the real name servers for those domains don't get their answers back in time.&lt;br /&gt;&lt;br /&gt;Now we know enough to say what's going on:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You try and visit Google, Facebook, Twitter (or the BoM). It's been a while so the address isn't in your resolver's cache. So it does a lookup by asking your domain name server -- this is usually provided by your ISP.&lt;/li&gt;&lt;li&gt;For whatever reason, your ISP's name server is either too slow to respond or the response is lost altogether. So your resolver "times out" and starts to "search". Your domain name ends in ".com.au" and so eventually, your resolver looks up "google.com.au.com.au" (or whatever site you're trying to visit, with ".com.au" added to the end). The name servers at "au.com.au" (or "com.com.au" depending on what you're looking up) &lt;b&gt;do respond&lt;/b&gt; and do so in time.&lt;/li&gt;&lt;li&gt;Your resolver gives the bogus address to the browser &lt;b&gt;and stores it in the DNS cache&lt;/b&gt;. The "TTL" (time to live) for those addresses is 4 hours, so you're going to be stuck with that address in your cache for at most 4 hours.&lt;/li&gt;&lt;li&gt;Eventually, your cache times out. Or maybe you know how to flush it. Either way, a second attempt by the resolver to get the right IP address works and the problem appears to be resolved.&lt;/li&gt;&lt;/ol&gt;Multiple things are going wrong here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; The ISPs name server is either too slow to respond or perhaps "dropping" packets (DNS packets are typically using &lt;a href="http://en.wikipedia.org/wiki/User_Datagram_Protocol"&gt;UDP&lt;/a&gt; which is &lt;a href="http://en.wikipedia.org/wiki/User_Datagram_Protocol#Comparison_of_UDP_and_TCP"&gt;not a guaranteed delivery mechanism like TCP&lt;/a&gt;). I've seen this with Optusnet before but in the past I just got a "site not found". Such responses aren't cached so if you hit "Refresh" in your browser you typically find the site just fine the second time.&lt;/li&gt;&lt;li&gt;The name servers for "com.com.au" and "au.com.au" have records that match other peoples sites. They shouldn't. Right now, it's just confusing and annoying but its potential for &lt;a href="http://en.wikipedia.org/wiki/Phishing"&gt;phishing&lt;/a&gt; is obvious. It's not necessarily malicious but it should be changed.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The algorithm used by the resolver in both UNIX and Windows has a security flaw: it should not search all the way back to ".com.au". &lt;/li&gt;&lt;/ul&gt;To me the ultimate problem is that last one: UDP packets, and hence DNS responses, are not guaranteed to be delivered. It should be expected that sometimes, things will get busy and responses will be lost. The resolver is in error by searching the domain name all the way back to ".com.au" -- IMHO that's a security hole similar to the &lt;a href="http://homepages.paradise.net.nz/%7Eglineham/cookiemonster.html"&gt;old "cookie monster" bug&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;There's a fix&lt;/b&gt; though, which at least works on OSX (Mac). If you &lt;b&gt;set an explicit search path&lt;/b&gt;, then the resolver won't use the second strategy described above. It will search the search path(s) and then stop there. I've set my search path to "optusnet.com.au", the same as my domain name, and can no longer reproduce the problem.&lt;br /&gt;&lt;br /&gt;There are other things that can help:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If your ISP's domain name server is not reliable use &lt;a href="http://www.opendns.com/"&gt;OpenDNS&lt;/a&gt;. There is some anecdotal evidence that the possibility of DNS replies being late or dropped is lower. Getting the "Welcome to ASZ.COm.Au" page for Google or Facebook depended on your computer not getting the DNS response in time (or at all) so having a reliable domain name server will stop the problem happening.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Add a "." to the end of your hostnames when typing into the browser (for example, "google.com.au."). The trailing "." prevents the domain name searching from kicking in.&lt;/li&gt;&lt;li&gt;If you're able, configure firewalls to drop packets from the name servers at "com.com.au" and "au.com.au".&lt;/li&gt;&lt;/ul&gt;Oh, if you're wondering why "bom.gov.au" could reproduce the problem every time: Their name server &lt;b&gt;does&lt;/b&gt; respond quickly but not with an "A" record for that domain. Which is to say, it's not a response that the resolver can use to answer the question "what's bom.gov.au's IP address". So even though the resolver gets an answer it still embarks on its domain name search until it looks up "bom.gov.au.com.au" and gets an answer (an "A" record). To reproduce the proglem with Google etc, you need to wait for the DNS response packet to go missing in order to trigger the domain search by your resolver.&lt;br /&gt;&lt;br /&gt;Other things can be explained:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It appeared to be an "Optus problem" at one stage because their domain name servers are occasionally overloaded and therefore slow. The Optus domain ends in "com.au" and so the domain name search would go all the way back to ".com.au". TPG seems to have similar issues.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I couldn't reproduce the problem at work because my domain name there is "work.com". The resolver is smart enough not to search as far back as ".com" -- it just missed the case where a country domain has subclassifications (such as ".com.au", ".co.nz" or ".co.uk"). That's the limitation to the "counting dots" method of deciding how far to walk back.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Switching to OpenDNS would appear to solve the problem because the resolver didn't need to start a domain name search if it got the right answer right away.&lt;/li&gt;&lt;li&gt; Flushing the DNS cache would appear to solve the problem because it's only occasionally that DNS replies get lost. You have a good chance on your second attempt of getting the right address.&lt;/li&gt;&lt;/ul&gt;Thanks to &lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;a class="screen-name" href="https://twitter.com/objects" title="Mick Barry"&gt;objects&lt;/a&gt;&lt;/b&gt;, &lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;a class="screen-name" href="https://twitter.com/pixelgroup" title="Stephen Marovitch"&gt;pixelgroup&lt;/a&gt;&lt;/b&gt; and &lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;a class="screen-name" href="https://twitter.com/3buffalogirls" title="Renee"&gt;3buffalogirls&lt;/a&gt;&lt;/b&gt; for responding to my Twitter enquiries with additional information, and the posters on the Whirlpool forums.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-6552751901736530796?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/6552751901736530796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=6552751901736530796' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/6552751901736530796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/6552751901736530796'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/04/welcome-to-aszcomau-or-resolver-library.html' title='Welcome to ASZ.COm.Au (Or, The Resolver Library is Broken)'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_KWodxN74zfY/Sfkrj81NhQI/AAAAAAAAAEY/f8zHoS2Lpcs/s72-c/Picture+1.png' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-8778783584661204895</id><published>2009-03-13T08:00:00.001+11:00</published><updated>2009-03-13T08:00:00.809+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Monitoring Rails builds with CruiseControl.rb and CCTray</title><content type='html'>More for my own memory than anything else...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;CruiseControl.NET&lt;/a&gt; comes with a tool called &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/CCTray"&gt;CCTray &lt;/a&gt;&amp;nbsp;that gives you a handy way of monitoring the build status of multiple CruiseControl environments. It works out of the box with other CruiseControl.NET installations but needs a little trick to monitor the &lt;a href="http://cruisecontrolrb.thoughtworks.com/"&gt;Ruby &lt;/a&gt;&amp;nbsp;and &lt;a href="http://cruisecontrol.sourceforge.net/"&gt;Java &lt;/a&gt;&amp;nbsp;versions (why we need the same app implemented three times is a subject for a rant one day I'm sure...).&lt;br /&gt;&lt;br /&gt;For Ruby on Rails projects, set the monitoring URL in CCTray to this:&lt;br /&gt;&lt;blockquote&gt;http://hostname.of.cruisecontrol.rb:3333/XmlStatusReport.aspx&lt;/blockquote&gt;It's not a real ASPX page but it returns XML that CCTray is expecting.&lt;br /&gt;&lt;br /&gt;Cruise Control for Java is similar, but different ('natch):&lt;br /&gt;&lt;blockquote&gt;http://hostname.of.cruisecontrol:3333/dashboard/cctray.xml&lt;/blockquote&gt;&amp;nbsp;Had trouble Googling that. :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-8778783584661204895?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/8778783584661204895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=8778783584661204895' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/8778783584661204895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/8778783584661204895'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/03/monitoring-rails-builds-with.html' title='Monitoring Rails builds with CruiseControl.rb and CCTray'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-3576117663622225606</id><published>2009-03-09T10:10:00.005+11:00</published><updated>2009-03-09T10:21:39.773+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teeny-tiny-toolkit'/><title type='text'>Keep yourself logged in to a website with anti-idle</title><content type='html'>At $work I need to use a time sheet application which has a session timeout feature. I want a way to stay "logged in". So I've conceived a little plug-in for my personal web developer's proxy that will re-load certain web pages periodically in the background.&lt;br /&gt;&lt;br /&gt;Could work like this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Start your personal proxy with the anti-idle plug-in in the chain (below).&lt;/li&gt;&lt;li&gt;In your browser, go to the page you want to periodically re-load.&lt;/li&gt;&lt;li&gt;At the end of the URL, append a CGI argument. For example you could append "?ttt_anti_idle=300" to reload the page every 5 minutes. If there are already CGI arguments in the URL just append: "&amp;amp;ttt_anti_idle=300".&lt;/li&gt;&lt;li&gt;Load the new URL you've just typed. The anti-idle plug-in will strip out the extra argument you've appended prior to giving the URL to the "real" server.&lt;/li&gt;&lt;li&gt;The anti-idle plug-in monitors its stream for "ttt_anti_idle" arguments and builds a list of pages to reload at certain intervals. It discards the result of course.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Here's how I imagine I'd set up the pipeline:&lt;/div&gt;&lt;br /&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$ proxy | anti_idle --use_cgi=ttt_anti_idle | respond&lt;/div&gt;&lt;div class="command-line command-line-output"&gt;&lt;br /&gt;[...]&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-3576117663622225606?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/3576117663622225606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=3576117663622225606' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/3576117663622225606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/3576117663622225606'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/03/keep-yourself-logged-in-to-website-with.html' title='Keep yourself logged in to a website with anti-idle'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-8849273037914067282</id><published>2009-03-06T14:51:00.000+11:00</published><updated>2009-03-06T14:51:00.499+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nagios'/><title type='text'>Initial Load Values for Nagios Load Checks (Cheat Sheet)</title><content type='html'>I've put together a cheat sheet to show how you might want to initially configure your Nagios load checks. The thinking behind these initial values is set out in &lt;a href="http://hissohathair.blogspot.com/2008/07/tuning-nagios-load-checks.html"&gt;Tuning Nagios Load Checks&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;     &lt;th&gt;Use&lt;/th&gt;  &lt;th&gt;OS&lt;/th&gt; &lt;th&gt;Cores&lt;/th&gt; &lt;th&gt;Warning&lt;/th&gt; &lt;th&gt;Critical&lt;/th&gt; &lt;th&gt;Notes&lt;/th&gt;   &lt;/tr&gt;&lt;/thead&gt;  &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;CMS (Teamsite)&lt;/td&gt; &lt;td&gt;Solaris&lt;/td&gt; &lt;td&gt;1&lt;/td&gt; &lt;td&gt;10,7,5&lt;/td&gt;  &lt;td&gt;20,15,10&lt;/td&gt;     &lt;td&gt;Testing shows this app to be responsive up until these loads.&lt;/td&gt;   &lt;/tr&gt;&lt;tr&gt;     &lt;td&gt;Web Server&lt;/td&gt; &lt;td&gt;Linux&lt;/td&gt; &lt;td&gt;2 x 4&lt;/td&gt; &lt;td&gt;16,10,4&lt;/td&gt;  &lt;td&gt;32,24,20&lt;/td&gt;     &lt;td&gt;Web servers are paired, so want to know if reaching 50% capacity regularly. Testing shows performance degradation from a load of 20.&lt;/td&gt;   &lt;/tr&gt;&lt;tr&gt;     &lt;td&gt;DB Server&lt;/td&gt; &lt;td&gt;Linux&lt;/td&gt; &lt;td&gt;2 x 4&lt;/td&gt; &lt;td&gt;16,10,4&lt;/td&gt;  &lt;td&gt;32,24,20&lt;/td&gt;     &lt;td&gt;Same hardware, different use. Nevertheless, using same thresholds.&lt;/td&gt;   &lt;/tr&gt;&lt;tr&gt;     &lt;td&gt;Nagios&lt;/td&gt; &lt;td&gt;Linux&lt;/td&gt; &lt;td&gt;1 x 2&lt;/td&gt; &lt;td&gt;6,4,2&lt;/td&gt;  &lt;td&gt;12,10,7&lt;/td&gt;     &lt;td&gt;Small box, paired with backup.&lt;/td&gt;   &lt;/tr&gt;&lt;/tbody&gt;  &lt;tfoot&gt;  &lt;/tfoot&gt; &lt;/table&gt;&lt;br /&gt;General notes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The UNIX servers (particularly the Sun SPARC ones) seem to be able to stay up and responsive even under heavy load. And they don't count processes waiting for I/O in their load counts the way Linux does. I have no explanation for this. :-)&lt;/li&gt;&lt;li&gt;We track these loads over time to predict demand growth for capacity planning -- the thresholds are not a long term goal but rather a short term alert threshold.&lt;/li&gt;&lt;li&gt;Transaction or revenue-earning web servers might have lower thresholds because of the different commercial implications of performance degradation. YMMV.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;For more information on the Nagios check_load command, see&amp;nbsp;&lt;a href="http://hissohathair.blogspot.com/2008/07/tuning-nagios-load-checks.html"&gt;Tuning Nagios Load Checks&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-8849273037914067282?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/8849273037914067282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=8849273037914067282' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/8849273037914067282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/8849273037914067282'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/03/initial-load-values-for-nagios-load.html' title='Initial Load Values for Nagios Load Checks (Cheat Sheet)'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-3291235135623573121</id><published>2009-03-06T10:06:00.005+11:00</published><updated>2009-03-06T11:50:59.599+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teeny-tiny-toolkit'/><title type='text'>No more stupid YouTube comments</title><content type='html'>Prompted by Mark Damon Hughes' &lt;a href="http://kuoi.com/~kamikaze/read.php?topic=Web&amp;id=223"&gt;Stupid Comments Be Gone&lt;/a&gt; I wrote a small script that took YouTube HTML in on stdin, stripped out the comments, and spat the remainder out on stdout (Mark's trick uses CSS to hide them).&lt;br /&gt;&lt;br /&gt;Now I can do this:&lt;br /&gt;&lt;br /&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$ proxy | connect | kill_youtube_comments | respond&lt;br /&gt;&lt;/div&gt;&lt;div class="command-line command-line-output"&gt;[...]&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;And lo! Works in all browsers. :-)&lt;br /&gt;&lt;br /&gt;Breaking it down:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The &lt;b&gt;proxy&lt;/b&gt; command listens on port 8080 (I configure my browser to proxy to localhost:8080). It spits all requests it sees to stdout.&lt;/li&gt;&lt;li&gt;The &lt;b&gt;connect&lt;/b&gt; command reads a HTTP request on stdin, connects to the remote server, fetches the content, and spits a HTTP request on stdout.&lt;/li&gt;&lt;li&gt;The &lt;b&gt;kill_youtube_comments&lt;/b&gt; command reads in HTML and strips out the div that contains YouTube comments.&lt;/li&gt;&lt;li&gt;The &lt;b&gt;respond&lt;/b&gt; command reads a HTTP response and sends that (via named pipe) back to the &lt;b&gt;proxy&lt;/b&gt; command so that it can return it to the browser.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I sometimes wonder if anyone else in the world would find a personal, hackable proxy useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-3291235135623573121?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/3291235135623573121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=3291235135623573121' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/3291235135623573121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/3291235135623573121'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/03/no-more-stupid-youtube-comments.html' title='No more stupid YouTube comments'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-7299686940302632689</id><published>2009-01-16T14:31:00.010+11:00</published><updated>2009-02-10T11:20:04.428+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='data portability'/><title type='text'>Using Blogger's new Import Blog function to import an RSS-based blog</title><content type='html'>I've been playing with &lt;a href="http://bloggerindraft.blogspot.com/2008/06/new-feature-import-and-export.html"&gt;Blogger's Import Blog feature&lt;/a&gt;&amp;nbsp;, made available in &lt;a href="http://draft.blogger.com/"&gt;Blogger in Draft&lt;/a&gt; last year.&lt;br /&gt;&lt;br /&gt;Google explicitly state that only Blogger exported blogs are supported. Blogger exports its blogs in Atom format. I thought perhaps that I could convert an RSS feed to Atom and then import that into Blogger and thereby move some old non-Blogger blogs over to Blogger.&lt;br /&gt;&lt;br /&gt;Alas, no joy! The Blogger Import tool is quite fussy about its Atom. For example, if you export a blog in Atom format, and then run that through an XML formatting tool and re-import, you'll find that Blogger complains about the uploaded file.&lt;br /&gt;&lt;br /&gt;However, I've kept at it, and now have a simple script that can take an RSS feed and convert it to an Atom format that Blogger seems happy with. It's not quite there -- a few posts are silently dropped for reasons I haven't figured out yet. I'm toying with the idea of eventually releasing it. Of course, &lt;a href="http://code.google.com/p/lj2blogger/"&gt;I'm not the only one&lt;/a&gt;&amp;nbsp;.&lt;br /&gt;&lt;br /&gt;via hissohathair.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-7299686940302632689?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/7299686940302632689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=7299686940302632689' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/7299686940302632689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/7299686940302632689'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/01/using-bloggers-new-import-blog-function.html' title='Using Blogger&apos;s new Import Blog function to import an RSS-based blog'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-135799865533219261</id><published>2009-01-15T16:06:00.000+11:00</published><updated>2009-01-15T16:08:44.730+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trivia'/><title type='text'>Oh! Look! Time_t party coming!</title><content type='html'>At 10:30:31 on Friday the 14th of February this year (Sydney time) the UNIX epoch time will be "1234567890".&lt;br /&gt;&lt;br /&gt;Time for a &lt;a href="http://en.wikipedia.org/wiki/Time_t#time_t_parties"&gt;time_t party&lt;/a&gt;&amp;nbsp;!&lt;br /&gt;&lt;br /&gt;via hissohathair.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-135799865533219261?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/135799865533219261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=135799865533219261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/135799865533219261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/135799865533219261'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2009/01/oh-look-timet-party-coming.html' title='Oh! Look! Time_t party coming!'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total><georss:featurename>Australia</georss:featurename><georss:point>-33.9433599465788 151.171875</georss:point><georss:box>-43.036343446578805 136.2304685 -24.8503764465788 166.1132815</georss:box></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-3262126346799505506</id><published>2008-11-21T15:57:00.002+11:00</published><updated>2009-03-06T11:59:32.512+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teeny-tiny-toolkit'/><title type='text'>Making it useful</title><content type='html'>Played a bit more the the small web developer's toolkit in my last post. This time in a real-world production setting.&lt;br /&gt;&lt;br /&gt;Although other tools could have given the answer as well it was kinda fun to watch this work:&lt;br /&gt;&lt;br /&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$ proxy --port 8082 | log | connect | respond -e | log&lt;br /&gt;&lt;/div&gt;&lt;div class="command-line command-line-output"&gt;proxy: Proxy started at http://macbook.local:8082/&lt;br /&gt;[14:41:26] GET http://google.com/ HTTP/1.1 -&amp;gt; [14:41:27] HTTP/1.1 301 Moved Permanently&lt;br /&gt;[14:41:27] GET http://www.google.com/ HTTP/1.1 -&amp;gt; [14:41:28] HTTP/1.1 302 Found&lt;br /&gt;[14:41:28] GET http://www.google.com.au/ HTTP/1.1 -&amp;gt; [14:41:28] HTTP/1.1 200 OK&lt;br /&gt;[...]&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The "log" command is just printing out interesting things it sees -- by default the request and response lines and adds a timestamp.&amp;nbsp; In real life I wasn't debugging Google BTW. :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-3262126346799505506?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/3262126346799505506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=3262126346799505506' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/3262126346799505506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/3262126346799505506'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/11/making-it-useful.html' title='Making it useful'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-5322837626157813994</id><published>2008-11-17T16:33:00.020+11:00</published><updated>2009-03-06T11:59:14.640+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teeny-tiny-toolkit'/><title type='text'>An idea for a teeny-tiny web developer's toolkit</title><content type='html'>Every now and then I need to work out what's gone wrong with a production web server. Maybe it was a deployment issue, or a configuration issue or maybe something has broken. I'm sometimes wondering "what on Earth is that server saying to this browser?"&lt;br /&gt;&lt;br /&gt;I use &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt;, &lt;a href="http://livehttpheaders.mozdev.org/"&gt;HTTP Live Headers&lt;/a&gt; and &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/966"&gt;Tamper Data&lt;/a&gt; in Firefox a fair bit. But they only work in Firefox and MSIE sends different request headers which can affect the outcome. There's also the excellent &lt;a href="http://www.charlesproxy.com/"&gt;Charles Web Debugging Proxy&lt;/a&gt; which is &lt;a href="http://www.charlesproxy.com/wiki/features"&gt;so awesome&lt;/a&gt; it lets you &lt;a href="http://www.charlesproxy.com/wiki/ssl_debugging"&gt;observe SSL encrypted traffic between client and server&lt;/a&gt;, serve local files to the browser instead of server files and &lt;a href="http://www.charlesproxy.com/wiki/spoof_dns"&gt;"spoof" DNS addresses&lt;/a&gt; to make browsers talk to specific servers.&lt;br /&gt;&lt;br /&gt;Some days though I find myself typing this a lot:&lt;br /&gt;&lt;br /&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$ telnet app.example.com 80&lt;/div&gt;&lt;div class="command-line command-line-output"&gt;&lt;br /&gt;Trying 127.0.0.1...&lt;br /&gt;Connected to app.example.com.&lt;br /&gt;Escape character is '^]'.&lt;/div&gt;&lt;div class="command-line command-line-input"&gt;&lt;br /&gt;GET / HTTP/1.1&lt;br /&gt;Host: app.example.com&lt;/div&gt;&lt;div class="command-line command-line-output"&gt;&lt;br /&gt;HTTP/1.1 302 Found&lt;br /&gt;[...]&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;When you're doing that over and over again you start to look for little tricks to make it go quicker. For example, I might do this so that I can use the bash command line history to replay something quicker:&lt;br /&gt;&lt;br /&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$ printf "GET / HTTP/1.1\nHost: app.example.com\n\n" | telnet app.example.com 80&lt;/div&gt;&lt;div class="command-line command-line-output"&gt;&lt;br /&gt;Trying 127.0.0.1...&lt;br /&gt;Connected to app.example.com.&lt;br /&gt;Escape character is '^]'.&lt;br /&gt;Connection closed by foreign host.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Urgh. Except that didn't work because telnet got an interrupt when printf sent the end of file. Try this instead:&lt;br /&gt;&lt;br /&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$ (printf "GET / HTTP/1.1\nHost: westfield.com\n\n" ; sleep 2) | telnet westfield.com 80&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Yeah, OK. So now it's on one line and I can scroll back through the command history buffer. But what I'd really like to do is this:&lt;br /&gt;&lt;br /&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$ get --be-like=firefox http://app.example.com/ | no-cache | connect | tee connect.out&lt;/div&gt;&lt;div class="command-line command-line-output"&gt;&lt;br /&gt;HTTP/1.1 200 OK&lt;br /&gt;Cache-Control: no-cache&lt;br /&gt;Connection: Close&lt;br /&gt;[...]&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Now I don't have to remember to type the "Host" header and the "get" tool can add other useful headers (for example, to emulate Firefox or MSIE).&lt;br /&gt;&lt;br /&gt;Or this:&lt;br /&gt;&lt;br /&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$ get --be-like=msie http://app.example.com/ | remove_header accept-encoding | spoof app.example.com as 127.0.0.1 | connect | headers&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Basically what you could do is build a HTTP request and response stream out of UNIX pipes. Each step in the pipe chain would modify the request (or response) before passing it on. Eventually things get passed to the command "connect" which is responsible for actually making the request from the real web server and spitting out the reply. The reply can go through a similar chain of pipes.&lt;br /&gt;&lt;br /&gt;Kinda like &lt;a href="http://pipes.yahoo.com/pipes/"&gt;Yahoo! Pipes&lt;/a&gt;. Only... with &lt;a href="http://www.softpanorama.org/Scripting/pipes.shtml"&gt;actual pipes&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And if I substitute the "get" command (which really is just printing out HTTP request objects as text) with a "proxy" command (which listens to port 8080 for web browser requests) then I could test Apache configurations with something like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$ proxy --port 8080 | spoof app.example.com as 127.0.0.1 | connect | respond -e | tee logs/respond.out&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Here's the most complicated pipe chain I've gotten to work so far:&lt;br /&gt;&lt;br /&gt;&lt;div class="command-line"&gt;&lt;div class="command-line command-line-prompt"&gt;$ proxy --port=8081 | tee logs/proxy.log | connect | tee logs/connect.log | filter text/html tidy -i -c -asxhtml -utf8 -f /dev/null | tee logs/filter.log | respond -e &amp;gt; logs/respond.log&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;That comand:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Listens to local port 8081 for web browser proxy requests&lt;/li&gt;&lt;li&gt;Logs the browser requests to logs/proxy.log&lt;/li&gt;&lt;li&gt;Connects to the appropriate web server to get the content just requested by the browser. By default, the connect command handles any content transfer decoding&lt;/li&gt;&lt;li&gt;Logs the server response to logs/connect.log&lt;/li&gt;&lt;li&gt;Runs the server response through HTML Tidy ("tidy") which reformats the HTML with indentation, corrects any HTML errors and transforms it to XHTML if required (UTF-8 encoded of course). HTML Tidy's error messages and report is sent to /dev/null.&lt;/li&gt;&lt;li&gt;Save the output of HTML Tidy to logs/filter.log&lt;/li&gt;&lt;li&gt;Send the final response stream back to the browser, but also echo the response on stdout; and&lt;/li&gt;&lt;li&gt;Save the final response to logs/response.log (the contents of which should be identical to filter.log -- I was debugging).&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I had initially had an idea for a much more complicated Charles-like tool with a GUI and threads and select() polling and plug-ins and the like. But this seems to capture the essence of what I was trying to do. It's the smallest implementation that will work -- and no smaller. :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-5322837626157813994?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/5322837626157813994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=5322837626157813994' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/5322837626157813994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/5322837626157813994'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/11/idea-for-teeny-tiny-web-developers.html' title='An idea for a teeny-tiny web developer&apos;s toolkit'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-8320422145441873774</id><published>2008-11-03T22:25:00.002+11:00</published><updated>2008-11-03T22:44:11.549+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='email'/><title type='text'>Email Client Market Share</title><content type='html'>A program called &lt;a href="http://fingerprintapp.com/"&gt;Fingerprint&lt;/a&gt; from &lt;a href="http://litmusapp.com/"&gt;Litmus&lt;/a&gt; is generating statistics on &lt;a href="http://fingerprintapp.com/email-client-stats"&gt;e-mail client market share&lt;/a&gt;. I was surprised to see &lt;a href="https://mail.google.com/"&gt;Gmail's&lt;/a&gt; share so low (6% amongst business users, 4% amongst consumers) but also how old most Outlook client installs are (7% business users using Outlook 2007 versus 29% using Outlook 2003 or earlier).&lt;br /&gt;&lt;br /&gt;At least Lotus Notes is down to 0.2% of business users.&lt;br /&gt;&lt;br /&gt;The authors suggest running their software on your own mailing list. Presumably their analysis is a bit more sophisticated than what you'd get by looking at the Browsers dimension in Google Analytics for a specific "e-mail only" image.&lt;br /&gt;&lt;br /&gt;More discussion on the &lt;a href="http://litmusapp.com/blog/email-client-market-share"&gt;Litmus Blog&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-8320422145441873774?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/8320422145441873774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=8320422145441873774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/8320422145441873774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/8320422145441873774'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/11/email-client-market-share.html' title='Email Client Market Share'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-9153602149255546901</id><published>2008-10-27T23:37:00.003+11:00</published><updated>2008-10-28T00:09:47.711+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>Reminder: The Boy Who Cried "Wolf" Got Eaten</title><content type='html'>Parents and children will be familiar with the Aesop's fable, &lt;a href="http://www.storyarts.org/library/aesops/stories/boy.html"&gt;The Boy Who Cried Wolf.&lt;/a&gt; It's often told by parents to teach their children the importance of not raising false alarms and of telling the truth. While the moral for children is obvious there's a moral for parents as well: after all, the boy shepherd does in fact eventually confront a wolf.&lt;br /&gt;&lt;br /&gt;Australian MPs have threatened total Internet censorship and regulation for so long now that one is tempted to assume that the latest threats of mandatory Internet censorship are just more cries of "wolf! wolf!" But Senator Conroy is not "crying wolf." Senator Conroy &lt;span style="font-weight: bold;"&gt;is&lt;/span&gt; the wolf.&lt;br /&gt;&lt;br /&gt;Senator Conroy has been dishonest, aggressive and offensive in his plan for mandatory Internet censorship.&lt;br /&gt;&lt;br /&gt;Dishonest, because he did not disclose the mandatory nature of the plan prior to the election. It is clear however that this has always been his plan.&lt;br /&gt;&lt;br /&gt;Aggressive, because he has not consulted the Australian public nor listened to those who have raised serious and valid concerns about the fairness and practicality of his totalitarian scheme. His staff have &lt;a href="http://www.smh.com.au/news/technology/biztech/how-government-tried-to-gag-censor-critics/2008/10/23/1224351430987.html"&gt;attempted to silence critics by pressuring their employers&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And offensive, because when people have disagreed with his plan, &lt;a href="http://www.abc.net.au/news/stories/2007/12/31/2129471.htm"&gt;he has accused them of being pro-child pornography&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The Senator is wrong, and his plan for mandatory Internet censorship is also wrong. It's bad policy. It's bad tech. It's &lt;a href="http://en.wikipedia.org/wiki/Security_theater"&gt;security theatre&lt;/a&gt;. Give the $44M to law enforcement instead. And &lt;a href="http://nocleanfeed.com/"&gt;sack Senator Conroy&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-9153602149255546901?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/9153602149255546901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=9153602149255546901' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/9153602149255546901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/9153602149255546901'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/10/reminder-boy-who-cried-wolf-got-eaten.html' title='Reminder: The Boy Who Cried &quot;Wolf&quot; Got Eaten'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-4474537919036617225</id><published>2008-10-26T23:06:00.007+11:00</published><updated>2009-07-03T06:31:26.427+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='solaris'/><title type='text'>Bulk Change of Passwords on Solaris (Repost)</title><content type='html'>Just filing this one for future use.&lt;br /&gt;&lt;br /&gt;I needed to change the password of a large number of accounts on a Solaris box. Unfortunately, I didn't have anything rational like &lt;a href="http://expect.nist.gov/"&gt;Expect&lt;/a&gt;. Also, the Solaris &lt;code&gt;&lt;a href="http://www.cs.bgu.ac.il/%7Earik/usail/man/solaris/passwd.1.html"&gt;passwd&lt;/a&gt;&lt;/code&gt; command won't read from stdin. Probably a good thing. :-)&lt;br /&gt;&lt;br /&gt;Here's a script that might come in handy. Should only be used on Solaris boxes, unless you grok the Linux shadow password format. But on Linux you can probably get Expect running and that would be a less... primitive way of getting the job done. The problem with this script is that it bypasses PAM so if you're using anything other than shadow files it won't work.&lt;br /&gt;&lt;br /&gt;The code is below. If it's getting corrupted then you can also &lt;a href="http://hissohathair.com/mason/code/change_lotsa_passwords.pl.html"&gt;download the script&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;#!/usr/bin/perl -w&lt;br /&gt;#&lt;br /&gt;# change_lotsa_passwords.pl&lt;br /&gt;#&lt;br /&gt;# Usage: ./change_lotsa_passwords.pl [/etc/shadow [list of account names]]&lt;br /&gt;#&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;use warnings;&lt;br /&gt;use strict;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# List your accounts here. Or just say @accounts = @ARGV if you&lt;br /&gt;# want to list them on the command line&lt;br /&gt;#&lt;br /&gt;my $shadow_file = shift @ARGV || '/etc/shadow';&lt;br /&gt;my @accounts    = @ARGV;&lt;br /&gt;&lt;br /&gt;# Other defaults&lt;br /&gt;use constant PASSWORD_LENGTH =&amp;gt; 8;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Doing it this way lets us make one pass over /etc/shadow and preserve&lt;br /&gt;# its line order&lt;br /&gt;#&lt;br /&gt;my %new_passwords = ();&lt;br /&gt;foreach my $a (@accounts) {&lt;br /&gt;    $new_passwords{$a} = generate_password();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Backup /etc/shadow&lt;br /&gt;#&lt;br /&gt;my $backup_file = $shadow_file . ".BACKUP";&lt;br /&gt;system("cp -p $shadow_file $backup_file");&lt;br /&gt;die "cp failed to backup $shadow_file to $backup_file"&lt;br /&gt;  if ( $? != 0 );&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Re-write /etc/shadow&lt;br /&gt;#&lt;br /&gt;open( my $backup, '&amp;lt;', $backup_file )&lt;br /&gt;  || die "open: Unable to read $backup_file ($!)\n";&lt;br /&gt;open( my $shadow, '&amp;gt;', $shadow_file )&lt;br /&gt;  || die "open: Unable to write $shadow_file ($!)\n";&lt;br /&gt;&lt;br /&gt;process_shadow( $backup, $shadow );&lt;br /&gt;&lt;br /&gt;close($backup);&lt;br /&gt;close($shadow);&lt;br /&gt;&lt;br /&gt;exit(0);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# process_shadow&lt;br /&gt;#   Given two file handles, read in the first file handle and copy to the second.&lt;br /&gt;#   When the first file handle reads in a shadow record for a user whose password&lt;br /&gt;#   we are changing, we will swap out the password and print the new password&lt;br /&gt;#   on stdout.&lt;br /&gt;#&lt;br /&gt;sub process_shadow {&lt;br /&gt;    my ( $backup, $shadow ) = @_;&lt;br /&gt;&lt;br /&gt;    # Days since UNIX epoch, the time format used by Solaris in /etc/shadow&lt;br /&gt;    my $last_changed = int( time() / ( 60 * 60 * 24 ) );&lt;br /&gt;&lt;br /&gt;    # Read each line from backup, modify if the user is having their password&lt;br /&gt;    # changed, and print the new password on stdout&lt;br /&gt;    #&lt;br /&gt;    my $line = 0;&lt;br /&gt;    while (&amp;lt;$backup&amp;gt;) {&lt;br /&gt;        $line++;&lt;br /&gt;        if (/^ ([^:]+) : ([^:]{2})/x) {&lt;br /&gt;            my $user = $1;&lt;br /&gt;            my $salt = generate_password(2);&lt;br /&gt;&lt;br /&gt;            if ( defined( $new_passwords{$user} ) ) {&lt;br /&gt;                print "$user,$new_passwords{$user}\n";&lt;br /&gt;                my $hashed = crypt( $new_passwords{$user}, $salt );&lt;br /&gt;                s/^ ([^:]+:) [^:]+ : \d+:/$1$hashed:$last_changed:/x;&lt;br /&gt;            }&lt;br /&gt;            print $shadow $_;&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;        else {&lt;br /&gt;            warn "$shadow: Unable to parse line $line\n";&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# Return a new (random) password.&lt;br /&gt;# Props: http://perl.about.com/od/perltutorials/a/genpassword.htm&lt;br /&gt;#&lt;br /&gt;sub generate_password {&lt;br /&gt;    my ($length) = @_;&lt;br /&gt;    $length ||= PASSWORD_LENGTH;&lt;br /&gt;&lt;br /&gt;    my $ALLOWED =&lt;br /&gt;      'abcdefghjkmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWXYZ!@$%^&amp;amp;*();.';&lt;br /&gt;&lt;br /&gt;    my $password = '';&lt;br /&gt;    while ( length($password) &amp;lt; $length ) {&lt;br /&gt;        $password .= substr( $ALLOWED, ( int( rand( length $ALLOWED ) ) ), 1 );&lt;br /&gt;    }&lt;br /&gt;    return $password;&lt;br /&gt;}&lt;br /&gt;&lt;code&gt;&lt;backup&gt;&lt;br /&gt;&lt;/backup&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Here endeth the hackery. :-)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Postscript:&lt;/span&gt; The was originally filed as "Mass Change of Passwords on Solaris" 26 Oct 2008. It was re-posted 2 July 2009 because the code had become corrupted somehow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-4474537919036617225?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/4474537919036617225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=4474537919036617225' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/4474537919036617225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/4474537919036617225'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/10/mass-change-of-passwords-on-solaris.html' title='Bulk Change of Passwords on Solaris (Repost)'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-1669568101661266059</id><published>2008-10-06T02:48:00.009+11:00</published><updated>2009-03-06T11:58:45.237+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mason'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Invalidating Page Caches in Mason</title><content type='html'>We have a number of websites that use &lt;a href="http://masonhq.com/"&gt;Mason&lt;/a&gt;, a (relatively) old Perl library reportedly used by &lt;a href="http://www.masonhq.com/?MasonPoweredSites"&gt;Amazon and Salon&lt;/a&gt; among other sites. It has built-in and flexible support for &lt;a href="http://www.masonhq.com/docs/manual/Devel.html#data_caching"&gt;caching&lt;/a&gt; at pretty much any level the developer needs, but often the easiest thing to do is to cache the output of an entire component, which looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;%init&amp;gt;&lt;br /&gt;return if $m-&amp;gt;cache_self(key =&amp;gt; $key,&lt;br /&gt;expires_in =&amp;gt; '3 hours' );&lt;br /&gt;[...]&lt;br /&gt;&amp;lt;%/init&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What I wanted to do was invalidate the cache when the users browser had a Cache-Control or Pragma directive that indicated they did not want cached content (for example, when the user holds down the Shift key and clicks "Refresh" or "Reload").&lt;br /&gt;&lt;br /&gt;The naive implementation does not work:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;%init&amp;gt;&lt;br /&gt;# Somewhere, $cache_ok is set to 0 if Cache-Control&lt;br /&gt;# indicates no caching wanted&lt;br /&gt;if ( $cache_ok ) {&lt;br /&gt;return if $m-&amp;gt;cache_self(key =&amp;gt; $key,&lt;br /&gt;expires_in =&amp;gt; '3 hours' );&lt;br /&gt;}&lt;br /&gt;[...]&lt;br /&gt;&amp;lt;/%init&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I mean, it &lt;span style="font-weight: bold;"&gt;does&lt;/span&gt; work for the initial request but all subsequence requests will &lt;span style="font-weight: bold;"&gt;continue&lt;/span&gt; to get the &lt;span style="font-weight: bold;"&gt;old&lt;/span&gt; cached content because the cache has not been invalidated, only skipped. The very next request for that component will get the old, cached content -- not a cached copy of the freshly calculated content.&lt;br /&gt;&lt;br /&gt;Slightly less naive implementations didn't work either because of the way cache_self works. I was basically trying variations of "expires yesterday" but this parameter was not being consulted when Mason considered whether or not to return the cached content.&lt;br /&gt;&lt;br /&gt;Cutting a long story short (well, not that long but kinda boring) here's how I got the page cache to be invalidated ("expired") when the user hits Shift-Refresh:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    if (  $cache_ok ) {&lt;br /&gt;$m-&amp;gt;cache_self(key =&amp;gt; $page_cache_key, expire_if =&amp;gt; sub { 1 }  );&lt;br /&gt;} else  {&lt;br /&gt;return if $m-&amp;gt;cache_self(key =&amp;gt;  $page_cache_key, &lt;br /&gt;expires_in =&amp;gt; '4 hours'  );&lt;br /&gt;}&lt;br /&gt;[... continue with component...]&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The variable &lt;code&gt;$cache_ok&lt;/code&gt; defaults to "1" but is set to "0" if no-cache is found in the Cache-Control request header (for completeness, also check the Pragma directive althought that might indicate the presence of a browser so old it wears flares).&lt;br /&gt;&lt;br /&gt;What this code does is returns the cached content (provided it's younger than 4 hours) most of the time. But if the requesting client has indicated it does not want cached content then it invalidates Mason's copy of the cached output and then falls through to the bottom of the if block where normal. non-cached processing occurs.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Post-script:&lt;/b&gt; Since publishing this post I've changed and reformatted the source code slightly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-1669568101661266059?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/1669568101661266059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=1669568101661266059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/1669568101661266059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/1669568101661266059'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/10/invalidating-page-caches-in-mason.html' title='Invalidating Page Caches in Mason'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-4993744606862050961</id><published>2008-07-11T09:36:00.003+10:00</published><updated>2009-03-06T14:57:22.372+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nagios'/><title type='text'>Tuning Nagios Load Checks</title><content type='html'>[See also: &lt;a href="http://hissohathair.blogspot.com/2009/03/initial-load-values-for-nagios-load.html"&gt;check_load initial values cheat sheet&lt;/a&gt;].&lt;br /&gt;&lt;br /&gt;The standard &lt;a href="http://nagiosplugins.org/"&gt;Nagios plugins&lt;/a&gt; include a "&lt;a href="http://nagiosplugins.org/man/check_load"&gt;check_load&lt;/a&gt;" command which will raise a warning or error if the load averages for the target machine exceed some threshold. A little while ago the ops manager and I were discussing what those thresholds should be.&lt;br /&gt;&lt;br /&gt;The usage for the check_load command is as follows:&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;Usage: check_load -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15&lt;/code&gt;&lt;/blockquote&gt;Without looking at the source I'm pretty sure that the program is either just opening a pipe to uptime or using the /dev/proc file system to read the load averages for the past 1, 5 and 15 minutes. Should be safe to assume then that Nagios' concept of load is exactly the same as uptime's and that the figures are ultimately is coming from the kernel scheduler. (Note: Yup. :-) Just checked the source.)&lt;br /&gt;&lt;br /&gt;So the first question is: what does "load" actually measure?&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Unix and Linux Load&lt;/h2&gt;Breifly, when Unix machines report their "load" (usually through &lt;a href="http://linux.die.net/man/1/uptime"&gt;uptime&lt;/a&gt;, &lt;a href="http://linux.die.net/man/1/top"&gt;top&lt;/a&gt; or &lt;a href="http://linux.die.net/man/1/w"&gt;who&lt;/a&gt;) they are reporting a weighted average of the &lt;span style="font-weight: bold;"&gt;number of processes either running or waiting&lt;/span&gt; for the CPU (Linux will also count processes that may be blocked waiting on I/O). This average is calculated over 1, 5 and 15 minutes (hence the three values) based on values that are sampled every 5 seconds (on Linux at least). Dr Neil Gunther has written &lt;a href="http://www.teamquest.com/resources/gunther/display/5/index.htm"&gt;more than you might ever want to know about how those load averages are calculated&lt;/a&gt; and what they mean. It's an excellent series of articles&amp;nbsp;(see also the inevitable&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Load_average"&gt;Wikipedia article&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;So assuming we have a single-core CPU, a load value of "1.0" would suggest that the CPU has been 100% utilised over whatever reporting period that figure was calculated for. A load of "2.0" would mean that whenever one process had the CPU there was another that was forced to wait. However, if we have 2 cores, the same "2.0" load value would suggest that both processes got the CPU time they needed, while a load of "1.0" would suggest the CPU had only been at 50% capacity.&lt;br /&gt;&lt;br /&gt;On a simple web server, running a single 2-core CPU a load average of "2.0, 1.0, 0.5" suggests that, over the last minute, the CPU has been 100% utilised; over the last 5 minutes it's been 50% utilised; and over the last 15 minutes, it's been 25% utilised. Halve those values if 4 cores are available and double them if only one is in the system.&lt;br /&gt;&lt;br /&gt;You can see then that sensible threshold values for warning and critical states requires you to consider how many CPUs and CPU cores your system has. You're therefore probably going to want to set your thresholds &lt;span style="font-weight: bold;"&gt;per machine&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt; or at least set them differently for each different type of configuration.&lt;br /&gt;&lt;br /&gt;For example, one of our Solaris boxes has 12 cores so a load of "6.0" is nothing to be concerned about. However that same load figure on another, single-core box might be worthy of a warning or even critical alert, depending on how sensitive we were to process queue lengths on that box. Except if that box is a Linux box with a lot of I/O and slow devices (like a tape drive) and is counting processes that are sitting idle and waiting for an I/O operation to finish. And what is the application running on it? Is it threaded? How is your kernel counting threads in that total -- or is it just counting processes?&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Setting the Check_Load Thresholds&lt;/h2&gt;So determining an appropriate warning and critical set of threshold values for check_load will depend on what you think a reasonable process queue length will be; how your specific system treats threads; how your applications on that system behave (and their expected responsiveness levels); and how many CPUs / cores your system has. Oh -- and your performance targets or SLAs.&lt;br /&gt;&lt;br /&gt;This is why experienced admins use a time honoured, complicated heuristic process to set an initial value and then continually adjust that value based on the correlation of alerts raised and actual performance and hence user impact.&lt;br /&gt;&lt;br /&gt;In other words: we rub our bellies and take a guess and then change the values if we get too many or too few alerts. We're experienced sysadmins -- how much time do you think we have? :-)&lt;br /&gt;&lt;br /&gt;In our case, for web servers, we decided that over 5 and 15 minute periods we expect spare capacity on the box -- but we only want to be alerted if the box is basically maxing out on CPU over a significant period. Over 1 minute we expect the occasional spike and don't really want an alert unless it's way beyond expectations. We're using Apache with no threading so 1 load point = 1 process using or waiting for CPU.&lt;br /&gt;&lt;br /&gt;We've set warning levels for 15 minute load average at number of CPU cores times 2 (plus one!). For 5 minutes increase the threshold by 5. For one minute, increase it by 5 again. Critical threshold starts at number of CPU cores times 4 and then follows the same pattern for the 5 and 1 minute warning.&lt;br /&gt;&lt;br /&gt;Here's a sample nrpe.cfg config file for a web server with 2 cores:&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;command[check_load]=/path/check_load -w 15,10,5 -c 30,25,20&lt;/code&gt;&lt;/blockquote&gt;It's important to actually test this set up. Use &lt;a href="http://httpd.apache.org/docs/2.0/programs/ab.html"&gt;ApacheBench&lt;/a&gt; or &lt;a href="http://jakarta.apache.org/jmeter/"&gt;JMeter&lt;/a&gt; or similar tool to get your load average up and test performance under those thresholds to see if it's acceptable. If your application is unacceptably slow from a user perspective at lower load values then lower your thresholds.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;More Information&lt;/h2&gt;I've put together a little &lt;a href="http://hissohathair.blogspot.com/2009/03/initial-load-values-for-nagios-load.html"&gt;check_load cheat sheet&lt;/a&gt; that has some initial values for some common configurations. It might be a useful starting point if you're just starting to configure check_load in your Nagios environment.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;[Note: This post has been edited since initial publication.]&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-4993744606862050961?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/4993744606862050961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=4993744606862050961' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/4993744606862050961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/4993744606862050961'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/07/tuning-nagios-load-checks.html' title='Tuning Nagios Load Checks'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-6149721641474982181</id><published>2008-07-04T21:52:00.008+10:00</published><updated>2009-03-06T11:57:52.366+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='osx'/><title type='text'>Cisco VPN Software Breaks When Upgrading to Leopard</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_KWodxN74zfY/SG4SSk9w65I/AAAAAAAAADE/IZz9ob39ap8/s1600-h/Picture+1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_KWodxN74zfY/SG4SSk9w65I/AAAAAAAAADE/IZz9ob39ap8/s320/Picture+1.png" alt="" id="BLOGGER_PHOTO_ID_5219129128538663826" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I recently upgraded my MacBook to OS X 10.5 ("Leopard"). By and large it's been a pretty painless experience except for the fact that the work issued Cisco VPN client often starts up with an error. The error says, in part "Unable to communicate with the VPN subsystem."&lt;br /&gt;&lt;br /&gt;Googling around the suggested fix is to restart the Cisco kernel extension. The following terminal command takes care of things nicely:&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;blockquote&gt;&lt;code&gt;$ sudo /System/Library/StartupItems/CiscoVPN/CiscoVPN restart&lt;/code&gt;&lt;/blockquote&gt;I'm running version 4.9.01 by the way.&lt;br /&gt;&lt;br /&gt;What the hell, here's a video of it if the command line is not where your heart truly lies.&lt;br /&gt;&lt;br /&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-ba59ee009feeea3d" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v14.nonxt8.googlevideo.com/videoplayback?id%3Dba59ee009feeea3d%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331566707%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D6783EAB32F55088947D3F22A940AA0F1C5386631.29DA5777935EFD68621E760E494C95C25FF9C5BE%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Dba59ee009feeea3d%26offsetms%3D5000%26itag%3Dw160%26sigh%3D5mH3zZw0ougM7rbIbTCPLLUSr9Q&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v14.nonxt8.googlevideo.com/videoplayback?id%3Dba59ee009feeea3d%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331566707%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D6783EAB32F55088947D3F22A940AA0F1C5386631.29DA5777935EFD68621E760E494C95C25FF9C5BE%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Dba59ee009feeea3d%26offsetms%3D5000%26itag%3Dw160%26sigh%3D5mH3zZw0ougM7rbIbTCPLLUSr9Q&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-6149721641474982181?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='enclosure' type='video/mp4' href='http://www.blogger.com/video-play.mp4?contentId=ba59ee009feeea3d&amp;type=video%2Fmp4' length='0'/><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/6149721641474982181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=6149721641474982181' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/6149721641474982181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/6149721641474982181'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/07/cisco-vpn-software-breakes-when.html' title='Cisco VPN Software Breaks When Upgrading to Leopard'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_KWodxN74zfY/SG4SSk9w65I/AAAAAAAAADE/IZz9ob39ap8/s72-c/Picture+1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-275534185367163459</id><published>2008-05-20T00:10:00.002+10:00</published><updated>2009-03-06T11:57:24.341+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><title type='text'>First Look at Django</title><content type='html'>&lt;h2&gt;Django is MVC... kinda&lt;br /&gt;&lt;/h2&gt;Django (and all of the frameworks I'm looking at) is based on the "MVC" software architecture pattern. Since these are largely personal notes (can't imagine anyone else reading this) I'm not going to cover the basics here. You can find that in the &lt;a href="http://www.djangobook.com/en/1.0/chapter05/"&gt;Django Book&lt;/a&gt; or on &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;Wikipedia&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;But here's an interesting quote from &lt;a href="http://www.djangobook.com/en/1.0/chapter05/"&gt;Chapter 5 of the Django Book&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;Because the “C” is handled by the framework itself and most of the excitement in Django happens in models, templates, and views, Django has been referred to as an MTV framework. In the MTV development pattern,&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;M&lt;/b&gt; stands for “Model,” the data access layer. This layer contains anything and everything about the data: how to access it, how to validate it, which behaviors it has, and the relationships between the data.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;T&lt;/span&gt; stands for “Template,” the presentation layer. This layer contains presentation-related decisions: how something should be displayed on a Web page or other type of document.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;V&lt;/span&gt; stands for “View,” the business logic layer. This layer contains the logic that access the model and defers to the appropriate template(s). You can think of it as the bridge between models and templates.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;If you’re familiar with other MVC Web-development frameworks, such as Ruby on Rails, you may consider Django views to be the “controllers” and Django templates to be the “views.” [...] Neither interpretation is more “correct” than the other. The important thing is to understand the underlying concepts.&lt;/blockquote&gt;This sounds like a subtle but possibly important distinction, particularly as I move between frameworks. I have some initial concerns about Django's interpretation of MVC but I'll keep that to myself until I've really given it time to make sense (basically, how does the split of business logic between Django "model" and "view" manifest itself in the design of your code, and can it lead to &lt;a href="http://en.wikipedia.org/wiki/Anemic_Domain_Model"&gt;anemic domain models&lt;/a&gt;?).&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Why Django?&lt;br /&gt;&lt;/h2&gt;Behind the 8-ball here. Not only is Django new to me but Python isn't a language I code in regularly -- in fact it's been some time since I've played with it. I like the look of Python. I've coded some trivial programs with it. The "white space thing" doesn't bother me and I don't really understand why it would bother anyone. Then again it's not the first language I've seen that does it. The first language that I saw that particular feature in was Occam, and I really liked Occam (not that I ever did anything useful with it).&lt;br /&gt;&lt;br /&gt;So why Django?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It's based on Python and Python seems like it should be a really good language to work in. I'm a Perl refugee in some ways. I'm finding it hard to recruit really good Perl coders (as opposed to just plain old Perl coders) and I suspect that people who have taken the trouble to learn Python (or Ruby, or Scala, or LISP) are more likely to care about good code. Not because C# and Java programmers don't but ... well, in this market why would you learn Python if it wasn't because you cared about being a better programmer?&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;There are other Python frameworks that look very interesting: &lt;a href="http://turbogears.org/"&gt;TurboGears&lt;/a&gt; and &lt;a href="http://pylonshq.com/"&gt;Pylons&lt;/a&gt; for example. But I have limited time and Django appears to have an edge for reasons I can't yet articulate. I'll probably drill down into TurboGears later.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Django is the first framework supported by Google App Engine.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;The Django core team say sensible things about web development and the community appears active and supportive. A little smug sometimes but hey, wouldn't you be, if you were working in the One True Language too? :-)&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-275534185367163459?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/275534185367163459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=275534185367163459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/275534185367163459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/275534185367163459'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/05/first-look-at-django.html' title='First Look at Django'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-5999635148624426586</id><published>2008-05-16T22:24:00.002+10:00</published><updated>2008-05-16T22:49:27.409+10:00</updated><title type='text'>Notes on "Mental Detox"</title><content type='html'>So apparently of three that set out I was the only one to make it to Friday, which is not even a full week. For shame &lt;a href="http://carruthk.blogspot.com/2008/05/mental-detox-fail-what-did-i-learn.html"&gt;Kate&lt;/a&gt;, for shame. :-)&lt;br /&gt;&lt;br /&gt;In the 5 days during my self imposed personal net exile:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I clocked up a modest amount of spam (219 messages), mailing list messages (184 conversations) and personal e-mail.&lt;/li&gt;&lt;li&gt;There were 634 RSS items in Google Reader.&lt;/li&gt;&lt;li&gt;There were 19 podcasts downloaded by iTunes.&lt;/li&gt;&lt;/ul&gt;And I learned:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;That I don't miss, like or need Facebook. But it seems rude to delete my account...&lt;/li&gt;&lt;li&gt;That I follow far too many total freakin' strangers on Twitter.  I need some &lt;a href="http://www.randsinrepose.com/archives/2007/09/11/the_twitter_equilibrium.html"&gt;Twitter Equilibrium&lt;/a&gt; :-)&lt;/li&gt;&lt;li&gt;I have too many RSS feeds that don't really tell me anything I need to know.&lt;/li&gt;&lt;/ul&gt;Well. Just some random notes from no-one of consequence. Seriously, why are you reading this?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-5999635148624426586?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/5999635148624426586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=5999635148624426586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/5999635148624426586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/5999635148624426586'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/05/notes-on-mental-detox.html' title='Notes on &quot;Mental Detox&quot;'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-6445124847429623941</id><published>2008-05-11T21:35:00.002+10:00</published><updated>2008-05-11T22:17:52.891+10:00</updated><title type='text'>Mental Detox Week (redux)</title><content type='html'>&lt;a href="http://carruthk.blogspot.com/2008/04/time-for-mental-detox-week.html"&gt;Mental Detox week&lt;/a&gt; was 21 - 27 April but I missed it completely (despite being an Adbusters subscriber).  So &lt;a href="http://www.carruthk.blogspot.com/"&gt;Kate Carruthers&lt;/a&gt; and some of her friends (including me) are doing a Mental Detox week from &lt;a href="http://carruthk.blogspot.com/2008/05/mental-detox-week-12-17-may-2007.html"&gt;May 12 to 17&lt;/a&gt;. Which isn't actually a full week but baby steps people, baby steps.&lt;br /&gt;&lt;br /&gt;Given that I'll still be working I'll still need to use a computer. But&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No IM&lt;/li&gt;&lt;li&gt;No personal e-mail&lt;/li&gt;&lt;li&gt;No Facebook (that one will be easy)&lt;/li&gt;&lt;li&gt;No iPod (that one will be hard)&lt;/li&gt;&lt;li&gt;No TV, radio or Google Reader.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;And no Twitter.&lt;/li&gt;&lt;/ul&gt;Don't watch TV anyway and the &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?i=260230609&amp;amp;id=260230600&amp;amp;s=143460"&gt;radio sucks&lt;/a&gt;  but not sure what the policy is on the print version of newspapers. Not reading my RSS feeds in Google Reader leaves me with the feeling that I might "miss something." What if they announce the next Google App Engine next week? On the other hand, &lt;a href="http://news.google.com/news?hl=en&amp;amp;ned=&amp;amp;q=burma&amp;amp;btnG=Search+News"&gt;real news&lt;/a&gt; can put that kind of event into perspective.&lt;br /&gt;&lt;br /&gt;In hindsight it was pointless to commit to this during a working week. There's still an awful lot of noise to deal with at work. Next time I'll try this kind of electronic-blackout during annual leave but I'm committed now so...&lt;br /&gt;&lt;br /&gt;See you in a week. :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-6445124847429623941?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/6445124847429623941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=6445124847429623941' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/6445124847429623941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/6445124847429623941'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/05/mental-detox-week-redux.html' title='Mental Detox Week (redux)'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-8598569511073119989</id><published>2008-05-09T06:26:00.000+10:00</published><updated>2008-05-09T06:26:00.723+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='evaluation'/><title type='text'>About the Application</title><content type='html'>The application is going to be small "to do" app loosely based on &lt;a href="http://en.wikipedia.org/wiki/David_Allen_%28author%29"&gt;David Allen's&lt;/a&gt; &lt;a href="http://www.davidco.com/"&gt;Getting Things Done&lt;/a&gt;. Not that the world needs another "to do" app (or even another &lt;a href="http://en.wikipedia.org/wiki/Getting_Things_Done"&gt;GTD&lt;/a&gt; app) but it fits the basic criteria: it's small but not trivial, capable of being built in a few days and the problem is well understood enough that I can concentrate on learning the basics of the framework rather than solving some other problem.&lt;br /&gt;&lt;br /&gt;Here's a short summary of the requirements:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Users need to be able to register with a user name and password to save and access their lists. The "stretch target" would be to allow users to start making lists anonymously, and then to save that work upon registering. If they already have an account, then the anonymous list and previously saved list should be merged sensibly.&lt;/li&gt;&lt;li&gt;Users will make lists of tasks. So we have the concept of a "list" (users must have at least one). A list should have a name and, when users are looking at the "list of lists" should be able to be sorted arbitrarily (in other words, users should be able to force a particular list to the "top" or above another list).&lt;/li&gt;&lt;li&gt;Lists contain tasks. A task needs a name, some notes, and the same sorting behaviour as lists (ie give users full control over the order of the list).&lt;/li&gt;&lt;li&gt;Each task can have exactly one context. A context is a GTD concept -- it's basically the things you need to get a task done. Example context might be "at work", "at home", "online" -- so that a task that has the context "at work" is something to do at work. Each user can have their own set of unique contexts but it's expected that the application will provide some sensible defaults.&lt;/li&gt;&lt;li&gt;Stretch target: Allow tasks to have an arbitrary number of contexts which represent the intersection of those requirements. A task that has the context "home" and "online" is one that requires an Internet connection from home to do. Not very "GTD-y" to make things overly complex though...&lt;/li&gt;&lt;li&gt;There is the concept of a context being "current." In other words, you tell the application "I am at work" and it will only show you the "at work" tasks.&lt;/li&gt;&lt;li&gt;Stretch target: When a user logs on, the default context should be the last context they were using from that particular device. For example, if they've logged on from their iPhone and have set their current context to "errands" then the next time they log on from their iPhone that should be the default context. However, if they log on from work immediately after, the default context will be "at work." It is anticipated that the browser string will be unique enough for this.&lt;/li&gt;&lt;li&gt;Stretch target: Mobile and Twitter support.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So, there you have it. Will not set the world on fire but I'm confident that we can get to know some of the frameworks well enough to get a "feel" for how they see the problem and how much code it takes to get it going.&lt;br /&gt;&lt;br /&gt;I shall call it "lulztodo", because we're doing it for the lulz (thanks &lt;a href="http://twitter.com/NickHodge/statuses/788229570"&gt;Nick&lt;/a&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-8598569511073119989?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/8598569511073119989/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=8598569511073119989' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/8598569511073119989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/8598569511073119989'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/05/about-application.html' title='About the Application'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-7547493240704930288</id><published>2008-05-08T06:07:00.001+10:00</published><updated>2008-05-08T06:07:01.446+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evaluation'/><title type='text'>Method and Approach to the Evaluation</title><content type='html'>I think we learn best by doing. I learn best by doing. So I'm going to attempt to build an application in some of the frameworks I'm looking at.&lt;br /&gt;&lt;br /&gt;The application will need to be&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Small:&lt;/span&gt; Nothing too fancy -- the point is to learn a little about web development with a given framework, not solve an actual real problem. That will come later.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Well understood:&lt;/span&gt; In order to concentrate on learning the framework, I'm not going to try and solve the &lt;a href="http://en.wikipedia.org/wiki/Traveling_salesman_problem"&gt;Travelling Salesman&lt;/a&gt; problem in O(1) time.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Non-trivial:&lt;/span&gt; Despite the above, it will need to be a bit more fancy than "Hello World." It should require persistent data storage, authentication and do something vaguely useful.&lt;/li&gt;&lt;/ul&gt;So, if I develop the same application over and over again in different frameworks each time I hope to get roughly comparable results.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-7547493240704930288?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/7547493240704930288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=7547493240704930288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/7547493240704930288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/7547493240704930288'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/05/method-and-approach-to-evaluation.html' title='Method and Approach to the Evaluation'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-2695021726178651194</id><published>2008-05-07T23:20:00.005+10:00</published><updated>2009-03-06T11:56:35.237+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frameworks'/><title type='text'>Searching for the One True Framework</title><content type='html'>No, I don't really believe there is One True Framework. But I &lt;span style="font-weight: bold;"&gt;am&lt;/span&gt; thinking about future web architecture directions for our group.&lt;br /&gt;&lt;br /&gt;I'm going to write a series of posts comparing and contrasting a few different languages and framework combinations. These frameworks seem to be emerging as leaders in their language / platform niche:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt; (Python)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.catalystframework.org/"&gt;Catalyst&lt;/a&gt; (Perl)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.cakephp.org/"&gt;CakePHP&lt;/a&gt; (PHP)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.rubyonrails.org/"&gt;Rails&lt;/a&gt; (Ruby)&lt;/li&gt;&lt;li&gt;&lt;a href="http://wicket.apache.org/"&gt;Wicket&lt;/a&gt; (Java)&lt;/li&gt;&lt;li&gt;&lt;a href="http://grails.codehaus.org/"&gt;Grails&lt;/a&gt; (Groovy)&lt;/li&gt;&lt;/ul&gt;That list in no particular order by the way.    I don't think I could sensibly look at all of them or do them justice. And it might be smarter to pick a language first and then evaluate the frameworks available for it. But at this stage I'm going for "breadth" first and then I'll drill down into more detail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-2695021726178651194?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/2695021726178651194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=2695021726178651194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/2695021726178651194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/2695021726178651194'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/05/searching-for-one-true-framework.html' title='Searching for the One True Framework'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-2722747154825758217</id><published>2008-05-04T23:58:00.000+10:00</published><updated>2008-05-07T23:58:58.097+10:00</updated><title type='text'>Purpose and Function</title><content type='html'>To aid memory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-2722747154825758217?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/2722747154825758217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/2722747154825758217'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/05/purpose-and-function.html' title='Purpose and Function'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-1811416185910478273.post-4875761507049736440</id><published>2008-05-03T16:30:00.003+10:00</published><updated>2008-05-03T21:30:30.359+10:00</updated><title type='text'>Who are you?</title><content type='html'>&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://www.youtube.com/v/X3gfFVmw0kA&amp;hl=en"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/X3gfFVmw0kA&amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Who are you?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;No-one of consequence.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;I must know!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Get used to disappointment.&lt;br /&gt;&lt;br /&gt;;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1811416185910478273-4875761507049736440?l=hissohathair.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hissohathair.blogspot.com/feeds/4875761507049736440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1811416185910478273&amp;postID=4875761507049736440' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/4875761507049736440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1811416185910478273/posts/default/4875761507049736440'/><link rel='alternate' type='text/html' href='http://hissohathair.blogspot.com/2008/05/who-are-you.html' title='Who are you?'/><author><name>hissohathair</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_KWodxN74zfY/SgpoieSA5PI/AAAAAAAAAHI/rETqEJ1AQ2A/S220/Indiana.jpg'/></author><thr:total>0</thr:total></entry></feed>
