sourcecode
coolmichael
<code>
#!perl -w
# Log.pm -- a simple logger which uses DBI and DBD::CSV to
# handle all the file locking. All log entries are kept in
# a text file, to make reading it much easier than if they
# had been put into a real database.
# copyright September 23, 2001 by Michael S. Joyce
# michaeljoyce@telus.net
# This code may be used and distributed under the same terms
# as Perl.
# TODO:
# add an option to make database connections
# happen with each call to logger(), instead of
# maintaining the connection for the lifetime of
# the program
use DBI;
use strict;
package Logger;
use vars qw($tbldefault $dbdefault);
# default name for the log file
$tbldefault="errlog";
# default directory for the log files
$dbdefault='E:\\\\log';
# check to see if a log file exists,
# and create it if it doesn't.
sub tblexists {
my $dbh = shift;
my $tblname = shift;
# $dbh->tables() is a new method in DBI version 1.09
unless (scalar grep {$_ eq $tblname} $dbh->tables())
{
my $crtstr=<<ENDQ;
CREATE TABLE $tblname(
date CHAR(24),
filename CHAR(24),
lineno CHAR(8),
message VARCHAR(256)
)
ENDQ
$dbh->do($crtstr) or die "creating table: $!\n$dbh->errstr";
}
}
# initialize the logger
# put a statement handle and database handle
# into self, as well as other potentially useful information
sub initialize {
my $self = shift;
$self->{'tblname'}=shift || $tbldefault;
$self->{'dbname'}=shift || $dbdefault;
$self->{'constr'}="DBI:CSV:f_dir=$self->{'dbname'}";
my $dbh = DBI->connect($self->{'constr'})
or die "No Database Connection Made: $!\n $DBI::errstr\n";
$self->{'dbhandle'}=$dbh;
tblexists($dbh, $self->{'tblname'});
my $instr="INSERT INTO $self->{'tblname'} VALUES (?,?,?,?)";
my $sth=$dbh->prepare($instr);
$self->{'sthandle'}=$sth;
}
# simple constructor
# most of the work is done in initialize()
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$self->initialize(@_);
return $self;
}
# member function to log a message
sub logger {
my $self = shift;
my $sth = $self->{'sthandle'};
my $time=localtime();
my $message = shift;
my ($package, $filename, $line) = caller;
$sth->execute($time, $filename, "line $line", $message);
}
# Destructor to cleanup database connections
sub DESTROY {
my $self = shift;
my $dbh = $self->{'dbhandle'};
$dbh->disconnect();
}
1;
</code>
This module uses the DBI and DBD::CSV to handle all the file locking necessary for a simple logging facility.<p>I needed something like this for some of my CGI scripts. Appending to a table was a problem, as the file would sometimes loose some. I couldn't get flock to work, wanted to try writing object oriented perl.<p>Sample useage:<code>
my $log=Logger->new("logfile", "/home/michael/logs");
open FILE, "myfile" or {
$log->logger("something bad happened: $!");
die;
}
</code>
I found it useful to have two log files open at the same time, one for fatal errors and one for warnings generated by bad input, or other non-fatal (recoverable) problems.<p>
Please comment.
Miscellaneous
Michael Joyce, [coolmichael]