1 package OpenSRF::Utils::Logger;
4 use vars qw($AUTOLOAD @EXPORT_OK %EXPORT_TAGS);
6 use Unix::Syslog qw(:macros :subs);
7 use base qw/OpenSRF Exporter/;
9 use Time::HiRes qw(gettimeofday);
10 use OpenSRF::Utils::Config;
17 my $logger = OpenSRF::Utils::Logger;
18 $logger->error( $msg );
20 For backwards compability, a log level may also be provided to each log
21 function thereby overriding the level defined by the function.
23 i.e. $logger->error( $msg, WARN ); # logs at log level WARN
27 @EXPORT_OK = qw/ NONE ERROR WARN INFO DEBUG INTERNAL /;
28 push @EXPORT_OK, '$logger';
30 %EXPORT_TAGS = ( level => [ qw/ NONE ERROR WARN INFO DEBUG INTERNAL / ], logger => [ '$logger' ] );
32 my $config; # config handle
33 my $loglevel = INFO(); # global log level
34 my $logfile; # log file
35 my $facility; # syslog facility
36 my $actfac; # activity log syslog facility
37 my $actfile; # activity log file
38 my $service = $0; # default service name
39 my $syslog_enabled = 0; # is syslog enabled?
40 my $act_syslog_enabled = 0; # is syslog enabled?
41 my $logfile_enabled = 1; # are we logging to a file?
42 my $act_logfile_enabled = 1; # are we logging to a file?
44 our $logger = "OpenSRF::Utils::Logger";
47 sub ACTIVITY { return -1; }
48 sub NONE { return 0; }
49 sub ERROR { return 1; }
50 sub WARN { return 2; }
51 sub INFO { return 3; }
52 sub DEBUG { return 4; }
53 sub INTERNAL { return 5; }
54 sub ALL { return 100; }
56 my $isclient; # true if we control the osrf_xid
58 # load up our config options
61 return if defined $config;
63 $config = OpenSRF::Utils::Config->current;
64 if( !defined($config) ) {
66 warn "*** Logger found no config. Using STDERR ***\n";
69 $loglevel = $config->bootstrap->loglevel;
71 $logfile = $config->bootstrap->logfile;
72 if($logfile =~ /^syslog/) {
75 $logfile = $config->bootstrap->syslog;
78 $facility = _fac_to_const($facility);
79 openlog($service, 0, $facility);
81 } else { $logfile = "$logfile"; }
85 # --------------------------------------------------------------
86 # if we're syslogging, see if we have a special syslog facility
87 # for activity logging. If not, use the syslog facility for
89 # --------------------------------------------------------------
90 $act_syslog_enabled = 1;
91 $act_logfile_enabled = 0;
92 $actfac = $config->bootstrap->actlog || $config->bootstrap->syslog;
93 $actfac = _fac_to_const($actfac);
96 # --------------------------------------------------------------
97 # we're not syslogging, use any specified activity log file.
98 # Fall back to the standard log file otherwise
99 # --------------------------------------------------------------
100 $act_syslog_enabled = 0;
101 $act_logfile_enabled = 1;
102 $actfile = $config->bootstrap->actlog || $config->bootstrap->logfile;
105 my $client = OpenSRF::Utils::Config->current->bootstrap->client();
110 $isclient = ($client =~ /^true$/iog) ? 1 : 0;
115 return LOG_LOCAL0 unless $name;
116 return LOG_LOCAL0 if $name =~ /local0/i;
117 return LOG_LOCAL1 if $name =~ /local1/i;
118 return LOG_LOCAL2 if $name =~ /local2/i;
119 return LOG_LOCAL3 if $name =~ /local3/i;
120 return LOG_LOCAL4 if $name =~ /local4/i;
121 return LOG_LOCAL5 if $name =~ /local5/i;
122 return LOG_LOCAL6 if $name =~ /local6/i;
123 return LOG_LOCAL7 if $name =~ /local7/i;
129 return $syslog_enabled;
134 return $act_syslog_enabled;
139 return $logfile_enabled;
144 return $act_logfile_enabled;
148 my( $self, $svc ) = @_;
152 openlog($service, 0, $facility);
157 my( $self, $msg, $level ) = @_;
158 $level = ERROR() unless defined ($level);
159 _log_message( $msg, $level );
163 my( $self, $msg, $level ) = @_;
164 $level = WARN() unless defined ($level);
165 _log_message( $msg, $level );
169 my( $self, $msg, $level ) = @_;
170 $level = INFO() unless defined ($level);
171 _log_message( $msg, $level );
175 my( $self, $msg, $level ) = @_;
176 $level = DEBUG() unless defined ($level);
177 _log_message( $msg, $level );
181 my( $self, $msg, $level ) = @_;
182 $level = INTERNAL() unless defined ($level);
183 _log_message( $msg, $level );
187 my( $self, $msg ) = @_;
188 _log_message( $msg, ACTIVITY() );
191 # for backward compability
193 my( $self, $msg, $level ) = @_;
194 $level = DEBUG() unless defined ($level);
195 _log_message( $msg, $level );
199 # ----------------------------------------------------------------------
200 # creates a new xid if necessary
201 # ----------------------------------------------------------------------
203 my $osrf_xid_inc = 0;
205 return unless $isclient;
207 return $osrf_xid = "$^T${$}$osrf_xid_inc";
211 return if $isclient; # if we're a client, we control our xid
215 sub get_osrf_xid { return $osrf_xid; }
216 # ----------------------------------------------------------------------
220 my( $msg, $level ) = @_;
221 return if $level > $loglevel;
226 if ($level == ERROR()) {$l = LOG_ERR; $n = "ERR "; }
227 elsif ($level == WARN()) {$l = LOG_WARNING; $n = "WARN"; }
228 elsif ($level == INFO()) {$l = LOG_INFO; $n = "INFO"; }
229 elsif ($level == DEBUG()) {$l = LOG_DEBUG; $n = "DEBG"; }
230 elsif ($level == INTERNAL()) {$l = LOG_DEBUG; $n = "INTL"; }
231 elsif ($level == ACTIVITY()) {$l = LOG_INFO; $n = "ACT"; $fac = $actfac; }
233 my( undef, $file, $line_no ) = caller(1);
236 # help syslog with the formatting
237 $msg =~ s/\%/\%\%/gso if( is_act_syslog() or is_syslog() );
239 $msg = "[$n:"."$$".":$file:$line_no:$osrf_xid] $msg";
241 $msg = substr($msg, 0, 1536);
243 if( $level == ACTIVITY() ) {
244 if( is_act_syslog() ) { syslog( $fac | $l, $msg ); }
245 elsif( is_act_filelog() ) { _write_file( $msg, 1 ); }
248 if( is_syslog() ) { syslog( $fac | $l, $msg ); }
249 elsif( is_filelog() ) { _write_file($msg); }
255 my( $msg, $isact) = @_;
257 $file = $actfile if $isact;
258 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
259 $year += 1900; $mon += 1;
260 sysopen( SINK, $file, O_NONBLOCK|O_WRONLY|O_APPEND|O_CREAT )
261 or die "Cannot sysopen $logfile: $!";
262 binmode(SINK, ':utf8');
263 printf SINK "[%04d-%02d-%02d %02d:%02d:%02d] %s %s\n", $year, $mon, $mday, $hour, $min, $sec, $service, $msg;