Thu 27 Mar 2008
I wasted 15 minutes the other day trying to remember how to do this,
so here it is for the future: to find out if and when a perl module
got added to the core, you want Richard Clamp's excellent
Module::CoreList.
Recent versions have a 'corelist' frontend command, so I typically
use that e.g.
$ corelist File::Basename
File::Basename was first released with perl 5
$ corelist warnings
warnings was first released with perl 5.006
$ corelist /^File::Spec/
File::Spec was first released with perl 5.00405
File::Spec::Cygwin was first released with perl 5.006002
File::Spec::Epoc was first released with perl 5.006001
File::Spec::Functions was first released with perl 5.00504
File::Spec::Mac was first released with perl 5.00405
File::Spec::OS2 was first released with perl 5.00405
File::Spec::Unix was first released with perl 5.00405
File::Spec::VMS was first released with perl 5.00405
File::Spec::Win32 was first released with perl 5.00405
$ corelist URI::Escape
URI::Escape was not in CORE (or so I think)
Wed 19 Mar 2008
A little whole ago at one of my client sites we decided that we wanted to
monitor the bulk of our Nagios notifications via RSS
rather than via email or jabber. The centralised river-of-news architecture
of RSS is just a much better fit for high-volume notification flow than the
individual silos and persistent messaging nature of email.
There are a few nice RSS solutions out there for Nagios, including the
following:
We quite liked Altinity's RSS4NAGIOS because it was notifications (rather than
alerts) based, and because it was pretty easy to just drop in and use. The
only thing we didn't really like was that it was still relatively static - it
provides nice per-user feeds, but you can't carve those feeds up or drill down
to subsets of the data very easily. We wanted to be able to slice-and-dice
things a bit more dynamically - be able to look at feeds for per-host,
per-hostgroup, per-status, or date-filtered notifications, for example.
I'm also a blosxom developer, so I quickly
realised that I could do everything I wanted pretty trivially using blosxom.
All I needed was a script to capture and tag notifications as blosxom posts,
and then I could have dynamic filtering, multi-dimensional tag-based feeds,
etc., all pretty much for free.
So a couple of afternoons later, Blosxom4Nagios was up and running. It's
basically a single-purpose blosxom install that you drop into a directory
somewhere (/var/log/nagios/blosxom, by default), hook into apache for
display, hook into nagios to accept notifications, and away you go.
Notifications are tagged by type (host/service), state (OK, WARNING, CRITICAL
etc.), hostname, hostgroup, service name, service group, contact, and date,
so you can filter notifications based on any of these, and produce feeds (both
RSS2 and atom) on any of them as well e.g.
- http://www.example.com/nagios/blosxom/tags/nagiosadmin
- http://www.example.com/nagios/blosxom/tags/hostgroup1/rss
- http://www.example.com/nagios/blosxom/tags/myhost/atom
- http://www.example.com/nagios/blosxom/tags/servicegroup2
- http://www.example.com/nagios/blosxom/tags/randomservice
- http://www.example.com/nagios/blosxom/tags/CRITICAL/atom
- http://www.example.com/nagios/blosxom/2008/03/tags/nagiosadmin
- http://www.example.com/nagios/blosxom/2008/03/19/tags/myhost/rss
etc.
Screenshots:
Default View
Filtering by date
Filtering by host
Blosxom4Nagios is available here:
and is licensed under the same MIT Licence as blosxom itself.
Comments and feedback welcome.
Mon 17 Mar 2008
Saw this post fly past in the twitter stream today:
http://linuxshellaccount.blogspot.com/2008/03/perl-directory-permissions-difference.html.
It's a script by Mike Golvach to do something like a diff -r, but also
showing differences in permissions and ownership, rather than just content.
I've written a CPAN module to do stuff like this -
File::DirCompare - so
thought I'd check how straightforward this would be using File::DirCompare:
#!/usr/bin/perl
use strict;
use File::Basename;
use File::DirCompare;
use File::Compare qw(compare);
use File::stat;
die "Usage: " . basename($0) . " dir1 dir2\n" unless @ARGV == 2;
my ($dir1, $dir2) = @ARGV;
File::DirCompare->compare($dir1, $dir2, sub {
my ($a, $b) = @_;
if (! $b) {
printf "Only in %s: %s\n", dirname($a), basename($a);
} elsif (! $a) {
printf "Only in %s: %s\n", dirname($b), basename($b);
} else {
my $stata = stat $a;
my $statb = stat $b;
# Return unless different
return unless compare($a, $b) != 0 ||
$stata->mode != $statb->mode ||
$stata->uid != $statb->uid ||
$stata->gid != $statb->gid;
# Report
printf "%04o %s %s %s\t\t%04o %s %s %s\n",
$stata->mode & 07777, basename($a),
(getpwuid($stata->uid))[0], (getgrgid($stata->gid))[0],
$statb->mode & 07777, basename($b),
(getpwuid($statb->uid))[0], (getgrgid($statb->gid))[0];
}
}, { ignore_cmp => 1 });
So this reports all entries that are different in content or permissions or
ownership e.g. given a tree like this (slightly modified from Mike's
example):
$ ls -lR scripts1 scripts2
scripts1:
total 28
-rw-r--r-- 1 gavin gavin 0 Mar 17 16:41 script1
-rw-r--r-- 1 gavin gavin 0 Mar 17 16:41 script1.bak
-rw-r--r-- 1 gavin gavin 0 Mar 17 16:41 script2
-rw-r--r-- 1 gavin gavin 0 Mar 17 16:41 script2.bak
-rw-r--r-- 1 gavin gavin 0 Mar 17 16:41 script3
-rw-r--r-- 1 gavin gavin 0 Mar 17 16:41 script3.bak
-rw-r--r-- 1 gavin gavin 0 Mar 17 16:49 script4
scripts2:
total 28
-rw-r--r-- 1 gavin users 0 Mar 17 16:41 script1
-rw-r--r-- 1 gavin users 0 Mar 17 16:41 script1.bak
-rw-r--r-- 1 gavin gavin 0 Mar 17 16:41 script2
-rw-r--r-- 1 gavin gavin 0 Mar 17 16:41 script2.bak
-rwxr-xr-x 1 gavin gavin 0 Mar 17 16:41 script3*
-rwxr-xr-x 1 gavin gavin 0 Mar 17 16:41 script3.bak*
-rw-r--r-- 1 gavin gavin 0 Mar 17 16:49 script5
it will give output like the following:
$ ./pdiff2 scripts1 scripts2
0644 script1 gavin gavin 0644 script1 gavin users
0644 script1.bak gavin gavin 0644 script1.bak gavin users
0644 script3 gavin gavin 0755 script3 gavin gavin
0644 script3.bak gavin gavin 0755 script3.bak gavin gavin
Only in scripts1: script4
Only in scripts2: script5
This obviously has dependencies that Mike's version doesn't have, but it
comes out much shorter and clearer, I think. It also doesn't fork and parse
an external ls, so it should be more portable and less fragile. I should
probably be caching the getpwuid lookups too, but that would have made it
5 lines longer. ;-)
Tue 11 Mar 2008
Nice w3schools page on html latin-1 entities: http://www.w3schools.com/tags/ref_entities.asp.
Wed 05 Mar 2008
Was thinking in the weekend about places where I waste time, areas of
inefficiency in my extremely well-ordered life (cough splutter).
One of the more obvious was bill handling. I receive paper bills during
the month from the likes of Energy Australia, Sydney Water, David Jones,
our local council for rates, etc. These all go into a pending file in the
filing cabinet, in date order, and I then periodically check that file
during the month and pay any bills that are coming due. If I get busy or
forgetful I may miss a due date and pay a bill late. If a bill gets lost
in the post I may not pay it at all. And the process is all dependent on
me polling my billing file at some reasonable frequency.
There are variants to this process too. Some of my friends do all their
bills once a month, and just queue the payments in their bank accounts
for future payment on or near the due date. That's a lower workload
system than mine, but for some (mostly illogical) reason I find myself
not really trusting future-dated bill payments in the same way as
immediate ones.
There's also a free (for users) service available in Australia called
BPay View
which allows you to receive your bills electronically directly into your
internet banking account, and pay them from there. This is nice in that
it removes the paper and data entry pieces of the problem, but it's
still a pull model - I still have to remember to check the BPay View
page periodically - and it's limited to vendors that have signed up for
the program.
As I see it, there are two main areas of friction in this process:
using a pull model i.e. the process all being dependent on me
remembering to check my bill status periodically and pay those that
are coming due. My mental world is quite cluttered enough without
having to remember administrivia like bills.
the automation friction around paper-based or PDF-based bills,
and the consequent data entry requirements, the scope for user
errors, etc.
BPay View mostly solves the second of these, but it's a solution that's
closely coupled with your Internet Banking provider. This has security
benefits, but it also limits you to your Internet Banking platform. For
me, the first of these is a bigger issue, so I'd probably prefer a
solution that was decoupled from my internet banking, and accept a few
more issues with #2.
So here's what I want:
a billing service that receives bills from vendors on my behalf
and enters them into its system. Ideally this is via email (or even
a web service) and an XML bill attachment; in the real world it
probably still involves paper bills and data entry for the short to
medium term.
a flexible notification system that pushes alerts to me when bills
are due based on per-vendor criteria I configure. This should
include at least options like email, IM, SMS, twitter, etc.
Notifications could be fire-once or fire-until-acknowledged, as the
user chooses.
for bonus points, an easy method of transferring bills into my
internet banking. The dumb solution is probably just a per-bill
view from which I can cut and paste fields; smarter solutions
would be great, but are probably dependent on the internet
banking side. Or maybe we do some kind of per-vendor pay online
magic, if it's possible to figure out the security side of not
storing credit card info. Hmmm.
That sounds pretty tractable. Anyone know anything like this?
Tue 04 Mar 2008
Nice recent blog summary of free chart/graph solutions: http://tutorialblog.org/free-chart-and-graph-solutions/.
Mon 03 Mar 2008
Twitter2blosxom script seems to be working nicely - one more test before bed.
Mon 03 Mar 2008
Testing twitter to blosxom script.
Mon 03 Mar 2008
Find goodness (with a recent-ish find for the '-delete'):
find -L . -type l
find -L . -type l -delete