#-*- perl -*- # # Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008 Ken'ichi Fukamachi # # $FML: Log.pm,v 1.37 2007/01/17 15:42:56 fukachan Exp $ # package FML::Log; require Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw(Log LogWarn LogError); use strict; use Carp; use FML::Config; use FML::Credential; use POSIX qw(strftime); =head1 NAME FML::Log - logging functions. =head1 SYNOPSIS To import log function Log(), use FML::Log qw(Log LogWarn LogError); Log( $log_message ); or specify arguments in the hash reference use FML::Log qw(Log LogWarn LogError); Log( $log_message , { log_file => $log_file, priority => $priority, facility => $facility, level => $level, }); =head1 DESCRIPTION FML::Log contains several interfaces to write log messages, for example, log files and syslog. =head2 Log($message [, $args]) The required argument is the message to log. You can specify C, C and C as an optional. $args = { log_file => $log_file, priority => $priority, facility => $facility, level => $level, }; This routine depends on C and C. $config->{ log_format_type } defines the format sytle. C to log is taken from C object. Key C changes the log format. By default, our log format is same as fml 4.0 format. =head2 LogWarn( $message [, $args]) same as Log("warn: $message", $args); =head2 LogError( $message [, $args]) same as Log("error: $message", $args); =cut # Descriptions: write message $msg to logfile et.al. # Arguments: STR($mesg) HASH_REF($args) # Side Effects: update logfile. # Return Value: none sub Log { my ($mesg, $args) = @_; my $config = new FML::Config; my $log_file = ''; my $priority = ''; my $facility = ''; my $level = ''; my $rdate = ''; # clean up $mesg =~ s/[\s\r\n]*$//; # simple check: null $mesg string is invalid. return undef unless defined $mesg; return undef unless $mesg; # XXX allow "log_type = file, syslog", o.k.? if ($config->{ log_type } =~ /syslog/) { my $ident = $config->{ log_syslog_ident } || 'fml8'; my $logopt = $config->{ log_syslog_options } || 'pid'; my $facility = $config->{ log_syslog_facility } || 'local0'; my $priority = $config->{ log_syslog_priority } || 'info'; my $hosts = $config->get_as_array_ref('log_syslog_servers') || []; use Sys::Syslog; for my $host (@$hosts) { if ($host) { $Sys::Syslog::host = $host;} openlog($ident, $logopt, $facility); syslog($priority, $mesg); closelog(); } } elsif ($config->{ log_type } =~ /file/) { ; # do nothing } else { carp("undefined log function type."); return; } # parse arguments $log_file = $args->{ log_file } if defined $args->{ log_file }; $priority = $args->{ priority } if defined $args->{ priority }; $facility = $args->{ facility } if defined $args->{ facility }; $level = $args->{ level } if defined $args->{ level }; # reference to "date" object eval q{ use Mail::Message::Date; $rdate = new Mail::Message::Date; }; if ($@) { croak("Mail::Message::Date not found"); } # open the $file by using FileHandle.pm use FileHandle; # When the second argument is not defined, use the default log_file. my $style = $config->{ log_format_type } || 'fml4_compatible'; my $file = $log_file || $config->{ log_file } || undef; my $fh = undef; my $sender = FML::Credential->sender; # expand % in log file name by POSIX::strftime(). if ($file =~ /\%/o) { $file = strftime($file, localtime); } if (defined $file) { my $old_mask = umask(077); $fh = new FileHandle ">> $file"; umask($old_mask); $fh = \*STDERR unless $fh; } else { $fh = \*STDERR; } if (defined $fh) { # fml <= 4.x style if ($style eq 'fml4_compatible') { my $date = $rdate->{'log_file_style'}; my $from = defined $sender ? "($sender)" : ""; printf $fh "%s %s %s\n", $date, $mesg, $from; } # fml 8.x style else { use File::Basename; my $name = basename($0); my $pid = $config->{ _pid }; my $iam = sprintf("%s[%d]", $name, $pid); printf $fh "%s %s %s\n", $rdate->{'log_file_style'}, $iam, $mesg; } } else { croak("cannot open $file"); } } # Descriptions: write message "warn: $msg", call Log() ASAP. # send the message into stderr if Log() failed. # Arguments: STR($mesg) HASH_REF($args) # Side Effects: none # Return Value: none sub LogWarn { my ($mesg, $args) = @_; eval q{ Log("warn: $mesg", $args); }; if ($@) { # XXX valid use of STDERR print STDERR "warn: ", $mesg, "\n"; } } # Descriptions: write message "error: $msg", call Log() ASAP. # send the message into stderr if Log() failed. # Arguments: STR($mesg) HASH_REF($args) # Side Effects: none # Return Value: none sub LogError { my ($mesg, $args) = @_; eval q{ Log("error: $mesg", $args); }; if ($@) { # XXX valid use of STDERR print STDERR "error: ", $mesg, "\n"; } } =head1 SEE ALSO L, L, L, =head1 CODING STYLE See C on fml coding style guide. =head1 AUTHOR Ken'ichi Fukamachi > =head1 COPYRIGHT Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008 Ken'ichi Fukamachi All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 HISTORY FML::Log first appeared in fml8 mailing list driver package. See C for more details. =cut 1;