1 package OpenSRF::Utils::Logger;
3 use vars qw($AUTOLOAD @EXPORT_OK %EXPORT_TAGS);
5 use Unix::Syslog qw(:macros :subs);
6 use base qw/OpenSRF Exporter/;
8 use Time::HiRes qw(gettimeofday);
9 use OpenSRF::Utils::Config;
16 my $logger = OpenSRF::Utils::Logger;
17 $logger->error( $msg );
19 For backwards compability, a log level may also be provided to each log
20 function thereby overriding the level defined by the function.
22 i.e. $logger->error( $msg, WARN ); # logs at log level WARN
26 @EXPORT_OK = qw/ NONE ERROR WARN INFO DEBUG INTERNAL /;
27 push @EXPORT_OK, '$logger';
29 %EXPORT_TAGS = ( level => [ qw/ NONE ERROR WARN INFO DEBUG INTERNAL / ], logger => [ '$logger' ] );
31 my $config; # config handle
32 my $loglevel = INFO(); # global log level
33 my $logfile; # log file
34 my $facility; # syslog facility
35 my $actfac; # activity log syslog facility
36 my $actfile; # activity log file
37 my $service; # syslog service name. default provided below.
38 my $service_tag = ''; # default service tag
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?
43 my $max_log_msg_len = 1536; # SYSLOG default maximum is 2048
45 our $logger = "OpenSRF::Utils::Logger";
48 sub ACTIVITY { return -1; }
49 sub NONE { return 0; }
50 sub ERROR { return 1; }
51 sub WARN { return 2; }
52 sub INFO { return 3; }
53 sub DEBUG { return 4; }
54 sub INTERNAL { return 5; }
55 sub ALL { return 100; }
57 my $isclient; # true if we control the osrf_xid
59 # load up our config options
63 return if defined $config and !$force;
65 $config = OpenSRF::Utils::Config->current;
66 if( !defined($config) ) {
68 warn "*** Logger found no config. Using STDERR ***\n";
72 $loglevel = $config->bootstrap->loglevel;
74 if ($config->bootstrap->loglength) {
75 $max_log_msg_len = $config->bootstrap->loglength;
78 $service_tag = $config->bootstrap->logtag;
80 $logfile = $config->bootstrap->logfile;
81 if($logfile =~ /^syslog/) {
84 $logfile = $config->bootstrap->syslog;
87 $facility = _fac_to_const($facility);
88 # OSRF_ADOPT_SYSLOG means we assume syslog is already
89 # opened w/ the correct values. Don't clobber it.
90 openlog($service, 0, $facility) unless $ENV{OSRF_ADOPT_SYSLOG};
92 } else { $logfile = "$logfile"; }
96 # --------------------------------------------------------------
97 # if we're syslogging, see if we have a special syslog facility
98 # for activity logging. If not, use the syslog facility for
100 # --------------------------------------------------------------
101 $act_syslog_enabled = 1;
102 $act_logfile_enabled = 0;
103 $actfac = $config->bootstrap->actlog || $config->bootstrap->syslog;
104 $actfac = _fac_to_const($actfac);
107 # --------------------------------------------------------------
108 # we're not syslogging, use any specified activity log file.
109 # Fall back to the standard log file otherwise
110 # --------------------------------------------------------------
111 $act_syslog_enabled = 0;
112 $act_logfile_enabled = 1;
113 $actfile = $config->bootstrap->actlog || $config->bootstrap->logfile;
116 my $client = OpenSRF::Utils::Config->current->bootstrap->client();
118 if ($ENV{OSRF_LOG_CLIENT} or $ENV{MOD_PERL}) {
127 $isclient = ($client =~ /^true$/iog) ? 1 : 0;
132 return LOG_LOCAL0 unless $name;
133 return LOG_LOCAL0 if $name =~ /local0/i;
134 return LOG_LOCAL1 if $name =~ /local1/i;
135 return LOG_LOCAL2 if $name =~ /local2/i;
136 return LOG_LOCAL3 if $name =~ /local3/i;
137 return LOG_LOCAL4 if $name =~ /local4/i;
138 return LOG_LOCAL5 if $name =~ /local5/i;
139 return LOG_LOCAL6 if $name =~ /local6/i;
140 return LOG_LOCAL7 if $name =~ /local7/i;
146 return $syslog_enabled;
151 return $act_syslog_enabled;
156 return $logfile_enabled;
161 return $act_logfile_enabled;
165 my( $self, $svc ) = @_;
166 return if $ENV{OSRF_ADOPT_SYSLOG};
168 $service .= '/' . $service_tag if (defined $service_tag);
171 openlog($service, 0, $facility);
176 my( $self, $msg, $level ) = @_;
177 $level = ERROR() unless defined ($level);
178 _log_message( $msg, $level );
182 my( $self, $msg, $level ) = @_;
183 $level = WARN() unless defined ($level);
184 _log_message( $msg, $level );
188 my( $self, $msg, $level ) = @_;
189 $level = INFO() unless defined ($level);
190 _log_message( $msg, $level );
194 my( $self, $msg, $level ) = @_;
195 $level = DEBUG() unless defined ($level);
196 _log_message( $msg, $level );
200 my( $self, $msg, $level ) = @_;
201 $level = INTERNAL() unless defined ($level);
202 _log_message( $msg, $level );
206 my( $self, $msg ) = @_;
207 _log_message( $msg, ACTIVITY() );
210 # for backward compability
212 my( $self, $msg, $level ) = @_;
213 $level = DEBUG() unless defined ($level);
214 _log_message( $msg, $level );
218 # ----------------------------------------------------------------------
219 # creates a new xid if necessary
220 # ----------------------------------------------------------------------
222 my $osrf_xid_inc = 0;
224 return unless $isclient;
226 return $osrf_xid = "$^T${$}$osrf_xid_inc";
230 return if $isclient; # if we're a client, we control our xid
234 sub get_osrf_xid { return $osrf_xid; }
235 # ----------------------------------------------------------------------
239 my( $msg, $level ) = @_;
240 return if $level > $loglevel;
242 # apply a sane default service name/tag
243 $logger->set_service($0) unless $service;
248 if ($level == ERROR()) {$l = LOG_ERR; $n = "ERR "; }
249 elsif ($level == WARN()) {$l = LOG_WARNING; $n = "WARN"; }
250 elsif ($level == INFO()) {$l = LOG_INFO; $n = "INFO"; }
251 elsif ($level == DEBUG()) {$l = LOG_DEBUG; $n = "DEBG"; }
252 elsif ($level == INTERNAL()) {$l = LOG_DEBUG; $n = "INTL"; }
253 elsif ($level == ACTIVITY()) {$l = LOG_INFO; $n = "ACT"; $fac = $actfac; }
255 my( undef, $file, $line_no ) = caller(1);
258 # help syslog with the formatting
259 $msg =~ s/\%/\%\%/gso if( is_act_syslog() or is_syslog() );
261 $msg = "[$n:"."$$".":$file:$line_no:$osrf_xid] $msg";
263 # Trim the message to the configured maximum log message length
264 $msg = substr($msg, 0, $max_log_msg_len);
266 # avoid clobbering the adopted syslog facility
267 my $slog_flags = $ENV{OSRF_ADOPT_SYSLOG} ? $l : $fac | $l;
269 if( $level == ACTIVITY() ) {
270 if( is_act_syslog() ) { syslog( $slog_flags, $msg ); }
271 elsif( is_act_filelog() ) { _write_file( $msg, 1 ); }
274 if( is_syslog() ) { syslog( $slog_flags, $msg ); }
275 elsif( is_filelog() ) { _write_file($msg); }
282 my ($msg, $isact) = @_;
283 my $file = $isact ? $actfile : $logfile;
284 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
285 $year += 1900; $mon += 1;
288 sysopen( SINK, $file, O_NONBLOCK|O_WRONLY|O_APPEND|O_CREAT )
289 or die "Cannot sysopen $file: $!";
291 open (SINK, ">&2"); # print to STDERR as warned
293 binmode(SINK, ':utf8');
294 printf SINK "[%04d-%02d-%02d %02d:%02d:%02d] %s %s\n", $year, $mon, $mday, $hour, $min, $sec, $service, $msg;