X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=SMGLog.pm;fp=SMGLog.pm;h=ddff2502bb0ac066b12aa2e1811c95d401fe7621;hb=9a9679bb16f6676d568db58d46ac0bbe85da2a4c;hp=0000000000000000000000000000000000000000;hpb=3e913f5e4a04510bc7144639da5fa97b20d335e2;p=dweather.git diff --git a/SMGLog.pm b/SMGLog.pm new file mode 100644 index 0000000..ddff250 --- /dev/null +++ b/SMGLog.pm @@ -0,0 +1,205 @@ +# +# the general purpose logging machine +# +# This module is designed to allow you to log stuff in SMG format +# +# The idea is that you give it a prefix which is a directory and then +# the system will log stuff to a directory structure which looks like:- +# +# ./logs//yyyy/mmdd.[log|new("sys_log"); +} + +# create a log object that contains all the useful info needed +# prefix is the main directory off of the data directory +# suffix is the suffix after the month/day +sub new +{ + my ($pkg, $prefix, $suffix) = @_; + my $ref = {}; + my $dir = "$path/$prefix"; + $ref->{prefix} = $dir; + $ref->{suffix} = $suffix || 'log'; + + # make sure the directory exists + mkpath($dir, 0, 0777) unless -d $dir; + die "cannot create or access $dir $!" unless -d $dir; + + my $self = bless $ref, $pkg; + $open{$self} = $self; + return $self; +} + +sub mode +{ + my $self = shift; + $self->{mode} = shift if @_; + return $self->{mode}; +} + +# open the appropriate data file +sub open +{ + my ($self, $dayno, $mode) = @_; + + my ($year, $month, $day) = (gmtime($dayno * 86400))[5,4,3]; + $year += 1900; + $month += 1; + + # if we are writing, check that the directory exists + if (defined $mode) { + my $dir = "$self->{prefix}/$year"; + mkdir($dir, 0777) if ! -e $dir; + } + + $self->{fn} = sprintf "$self->{prefix}/$year/%02d%02d", $month, $day; + $self->{fn} .= ".$self->{suffix}" if $self->{suffix}; + + $self->{mode} = $mode || 'r'; + + my $fh = new IO::File $self->{fn}, $mode, 0666; + return unless $fh; + + $fh->autoflush(0) if $mode ne 'r'; # disable autoflushing if writable + $self->{fh} = $fh; + + $self->{year} = $year; + $self->{month} = $month; + $self->{day} = $day; + $self->{dayno} = $dayno; + +# DXDebug::dbg("dxlog", "opening $self->{fn}\n"); + + return $self->{fh}; +} + +# open the previous log file in sequence +sub openprev +{ + my $self = shift; + return $self->open($self->{dayno} - 1, @_); +} + +# open the next log file in sequence +sub opennext +{ + my $self = shift; + return $self->open($self->{dayno} + 1, @_); +} + +# write (actually append) to a file, opening new files as required +sub write +{ + my ($self, $dayno, $line) = @_; + if (!$self->{fh} || $self->{mode} ne "r" || $dayno != $self->{dayno}) { + $self->open($dayno, ">>") or confess "can't open $self->{fn} $!"; + } + + return $self->{fh}->print("$line\n"); +} + +# read a line from an opened file +sub read +{ + my $self = shift; + confess "can't read $self->{fh} $!" unless $self->{fh}; + return $self->{fh}->getline; +} + +# write (actually append) using the current date to a file, opening new files as required +sub writenow +{ + my ($self, $line) = @_; + my $dayno = int (time / 86400); + return $self->write($dayno, $line); +} + +# write (actually append) using a unix time to a file, opening new files as required +sub writeunix +{ + my ($self, $t, $line) = @_; + my $dayno = int ($t / 86400); + return $self->write($dayno, $line); +} + +# close the log file handle +sub close +{ + my $self = shift; + undef $self->{fh}; # close the filehandle + delete $self->{fh}; +} + +sub DESTROY +{ + my $self = shift; + + delete $open{$self}; + undef $self->{fh}; # close the filehandle + delete $self->{fh} if $self->{fh}; +} + +sub flush +{ + $_[0]->{fh}->flush if $_[0]->{fh}; +} + +sub flushall +{ + foreach my $v (values %open) { + $v->flush; + } +} + +sub flush_all { goto &flushall } + + +sub Log +{ + my $l = ref $_[0] ? shift : $log; + return unless $l; + my $t = time; + my $ts = sprintf("%02d:%02d:%02d", (gmtime($t))[2,1,0]); + $l->writeunix($t, "$ts $_") for @_; +} + +sub LogDbg +{ + Log(@_); + Debug::dbg(@_) if Debug::isdbg('chan'); +} + +1;