1# $Id: Logger.pm,v 1.22 2005/06/10 18:31:32 vipul Exp $
2
3package Razor2::Logger;
4
5use strict;
6use Razor2::Syslog;
7use Time::HiRes qw(gettimeofday);
8use POSIX qw(strftime);
9use IO::File;
10# 2003/09/10 Anne Bennett: syslog of our choice (uses socket,
11# does not assume network listener).
12use Sys::Syslog;
13
14# designed to be inherited module
15# but can stand alone.
16
17sub new {
18
19    my ($class, %args) = @_;
20    my %self = ( %args );
21    my $self = bless \%self, $class;
22
23    my $prefix = $args{LogPrefix} || 'razord2';
24    my $facility = $args{LogFacility} || 'local3';
25    my $loghost = $args{LogHost} || '127.0.0.1';
26
27    if ($self->{LogTo} eq 'syslog') {
28        $$self{syslog} = new Razor2::Syslog (Facility=> $facility, Priority => 'debug', Name => $prefix, SyslogHost => $loghost);
29        $self->{LogType} = 'syslog';
30    } elsif ($self->{LogTo} =~ /^file:(.*)$/) {
31        $self->{LogType} = 'file';
32        my $name = $1; chomp $name;
33        open (LOGF, ">>$name") or do {
34            if ($self->{DontDie}) {
35                open LOGF, ">>/dev/null" or do {
36                    print STDERR "Failed to open /dev/null, $!\n";
37                };
38            } else {
39                die $!;
40            }
41        };
42        LOGF->autoflush(1);
43        $self->{fd} = *LOGF{IO};
44    } elsif ($self->{LogTo} eq 'sys-syslog') {
45        # 2003/09/10 Anne Bennett: syslog of our choice (uses socket,
46        # does not assume network listener).
47        $self->{LogType} = 'sys-syslog';
48        openlog($prefix,"pid",$facility);
49    } elsif ($self->{LogTo} eq 'stdout') {
50        $self->{LogType} = 'file';
51        $self->{fd} = *STDOUT{IO};
52    } elsif ($self->{LogTo} eq 'stderr') {
53        $self->{LogType} = 'file';
54        $self->{fd} = *STDERR{IO};
55    } else {
56        $self->{LogType} = 'file';
57        $self->{fd} = *STDERR{IO};
58    }
59
60    $self->{LogTimeFormat} ||= "%b %d %H:%M:%S";  # formatting from strftime()
61    $self->{LogDebugLevel}   = exists $self->{LogDebugLevel} ? $self->{LogDebugLevel} : 5;
62    $self->{Log2FileDir}   ||= "/tmp";
63
64    # 2002/11/27 Anne Bennett: log this at level 2 so we can set level
65    #   1 (to get errors only) and avoid this unneeded line.
66    $self->log(2,"[bootup] Logging initiated LogDebugLevel=$self->{LogDebugLevel} to $self->{LogTo}");
67
68    return $self;
69
70}
71
72
73sub log {
74
75    my ($self, $prio, $message) = @_;
76
77    return unless $prio <= $self->{LogDebugLevel};
78
79    my ($package, $filename, $line) = caller;
80    $filename =~ s:.*/::;
81
82    if ($self->{LogType} eq 'syslog') {
83
84        my $logstr = sprintf("[%2d] %s\n", $prio, $message);
85        $logstr =~ s/\n+\n$/\n/;
86        $self->{syslog}->send($logstr, Priority => 'debug');
87
88    } elsif ($self->{LogType} eq 'sys-syslog') {
89        # 2003/09/10 Anne Bennett: syslog of our choice (uses socket,
90        # does not assume network listener).
91        my $logstr = sprintf("[%2d] %s\n", $prio, $message);
92        $logstr =~ s/\n+$//g;
93        syslog("debug",$logstr);
94
95    } elsif ($self->{LogType} eq 'file') {
96
97        my $now_string;
98        if ($self->{LogTimestamp}) {
99            my ($seconds, $microseconds) = gettimeofday;
100            $now_string = strftime $self->{LogTimeFormat}, localtime($seconds);
101            $now_string .= sprintf ".%06d ", $microseconds;
102        }
103
104        my $logstr = sprintf("%s[%d]: [%2d] %s\n", $self->{LogPrefix}, $$, $prio, $message);
105        $logstr =~ s/\n+\n$/\n/;
106        my $fd = $self->{fd};
107        print $fd "$now_string$logstr";
108
109    }
110
111    return 1;
112}
113
114sub log2file {
115    my ($self, $prio, $textref, $fn_ext) = @_;
116
117    return unless $prio <= $self->{LogDebugLevel};
118
119    unless (ref($textref) eq 'SCALAR') {
120        print "log2file: not a scalar ref ($fn_ext)\n";
121        return;
122    }
123    my $len = length($$textref);
124    my $fn = "$self->{Log2FileDir}/razor.$$.$fn_ext";
125
126    if (open OUT, ">$fn") {
127        print OUT $$textref;
128        close OUT;
129        $self->log($prio,"log2file: wrote message len=$len to file: $fn");
130    } else {
131        $self->log($prio,"log2file: could not write to $fn: $!");
132    }
133}
134
1351;
136
137