source: tags/5.2.11/LATMOS-Accounts/lib/LATMOS/Accounts/Log.pm @ 1952

Last change on this file since 1952 was 1952, checked in by nanardon, 7 years ago
  • 5.2.11
  • Property svn:keywords set to Id Rev
File size: 4.9 KB
RevLine 
[208]1package LATMOS::Accounts::Log;
2
3use strict;
4use warnings;
[209]5use Sys::Syslog qw(:standard :macros);
[210]6use Exporter ();
[861]7use Mail::Sendmail;
[275]8
9=head1 NAME
10
11LATMOS::Accounts::Log - Log dispatcher for LATMOS::Accounts
12
13=head1 SYNOPSYS
14
15    use LATMOS::Accounts::Log
16    la_log(LA_ERR, "An error has occur");
17
18=head1 DESCRIPTION
19
20This module provide facilities to log to both console, syslog or using callback.
21
22When the environement variable C<LA_DEBUG> is set, all message are print to
23C<stderr>.
24
25=cut
26
27our @loglevels = qw(
[209]28    LA_EMERG
29    LA_ALERT
30    LA_CRIT
31    LA_ERR
[248]32    LA_ERROR
[253]33    LA_WARN
[209]34    LA_WARNING
35    LA_NOTICE
36    LA_INFO
37    LA_DEBUG
38);
[275]39
40use vars qw(@EXPORT_OK @EXPORT %EXPORT_TAGS @ISA);
41@ISA = qw(Exporter);
42@EXPORT = (qw(
43    la_set_log la_log
44    ), @loglevels);
45
[210]46@EXPORT_OK = @EXPORT;
[275]47%EXPORT_TAGS = (LOGLEVELS => [ @loglevels ]);
[208]48
[1952]49our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
[208]50
[299]51my %lastmessages = ();
52
[275]53=head1 LOG LEVEL
54
55=over 4
56
57=item LA_EMERG
58
59=cut
60
[209]61sub LA_EMERG { LOG_EMERG } # system is unusable
62
[275]63=item LA_ALERT
64
65=cut
66
[209]67sub LA_ALERT { LOG_ALERT } # action must be taken immediately
68
[275]69=item LA_CRIT
70
71=cut
[1014]72
[209]73sub LA_CRIT { LOG_CRIT } # critical conditions
74
[1053]75=item LA_ERR, LA_ERROR
[275]76
77=cut
78
[253]79sub LA_ERR   { LOG_ERR } # error conditions
[228]80sub LA_ERROR { LA_ERR } # Alias for ERR
[209]81
[1053]82=item LA_WARN, LA_WARNING
[275]83
84=cut
85
[209]86sub LA_WARNING { LOG_WARNING } # warning conditions
[253]87sub LA_WARN    { LA_WARNING } # warning conditions
[209]88
[275]89=item LA_NOTICE
90
91=cut
92
[209]93sub LA_NOTICE { LOG_NOTICE } # normal, but significant, condition
94
[275]95=item LA_INFO
96
97=cut
98
[209]99sub LA_INFO { LOG_INFO } # informational message
100
[275]101=item LA_DEBUG
102
103=cut
104
[209]105sub LA_DEBUG { LOG_DEBUG } # debug-level message
106
[275]107=back
108
109=cut
110
[208]111my %log_method = (
112    syslog => undef,
[476]113    console => LA_NOTICE,
[208]114    callback => undef,
[861]115    mail => undef,
[208]116);
117
[861]118my @maillog = ();
119
[275]120=head1 FUNCTIONS
121
122=head2 la_set_log(%options)
123
124Set options to log dispatcher:
125
126=over 4
127
128=item syslog
129
130=item console
131
132=item callback
133
134=back
135
136=cut
137
[208]138sub la_set_log {
139    my (%options) = @_;
140    while (my ($key, $val) = each(%options)) {
[210]141        if ($key eq 'syslog') {
142            if ($val) {
143                my ($ident, $logopt, $facility) =  @{ ref $val ? $val : [] };
[278]144                $ident ||= 'LATMOS::Accounts';
[210]145                $logopt ||= 'pid';
146                $facility ||= 'LOG_USER';
147                openlog($ident, $logopt, $facility);
148                $log_method{syslog} = 1;
149            }
[208]150            next;
[210]151        }
[208]152        $log_method{$key} = $val;
153    }
154    1;
155}
156
[1018]157=head2 lastmessage($level)
158
159Return the last message for C<$level> (LA_ERROR by default)
160
161=cut
162
[299]163sub lastmessage {
164    my ($level) = @_;
[861]165    return $lastmessages{$level || LA_ERROR};
[299]166}
167
[275]168=head2 la_log($level, @sprintf_args)
169
170=cut
171
[208]172sub la_log {
173    my ($level, $msg, @args) = @_;
[1053]174    no warnings 'printf';
[1865]175
[1698]176    if (!$msg) {
[1865]177        # Wrong la_log usage
[1698]178        my @call = caller();
179        la_log(LA_WARN, 'empty message at %s:%s', $call[1], $call[2]);
180        return;
181    }
[1915]182    if ($level !~ /^\d$/) {
[1865]183        # Wrong la_log usage
184        my @call = caller();
185        la_log(LA_WARN, 'unrecognize message level %s at %s:%s', $level, $call[1], $call[2]);
186        return;
187    }
188
[1455]189    $lastmessages{$level} = sprintf($msg, map { defined($_) ? $_ : '' } @args);
[208]190    if ($log_method{syslog}) {
[210]191        syslog($level, $msg, @args) unless($level >= LA_DEBUG);
[208]192    }
[248]193    if ($ENV{'LA_DEBUG'}) {
194        my @caller = caller;
195        my $debug = ($level == LA_DEBUG) ? "$caller[0]:$caller[2] " : '';
196        warn sprintf("$debug$msg", @args) . "\n";
197    } elsif ($log_method{console} && $level <= $log_method{console}) {
[210]198        if ($level >= LA_NOTICE && $level < LA_DEBUG) {
[209]199            printf("$msg\n", @args);
200        } else {
[210]201            my $debug = '';
202            if ($level == LA_DEBUG) {
203                my @caller = caller;
204                $debug = "$caller[0]:$caller[2] ";
205            }
[1455]206            warn sprintf("$debug$msg", map { defined($_) ? $_ : '' } @args) . "\n";
[209]207        }
[208]208    }
209    if ($log_method{callback}) {
210        $log_method{callback}->($level, $msg, @args);
211    }
[861]212    if ($log_method{mail}) {
213        # store error to send it later, only ERROR
214        push(@maillog, sprintf($msg, @args)) if ($level <= LA_ERROR);
215    }
[210]216    1;
[208]217}
[861]218
219sub _flush_mail {
220    @maillog = ();
221}
222
223sub _send_mail_log {
224    @maillog or return;
225    sendmail(
226        Subject => "LATMOS::Accounts error from $0",
227        To => $log_method{mail},
228        From => 'LATMOS-Accounts@latmos.ipsl.fr',
229        Message => join("\n", @maillog),
230    ) or la_log(LA_ERR, "Cannot sent mail: " . $Mail::Sendmail::error);
231    _flush_mail();
232}
233
234END {
235    _send_mail_log() if($log_method{mail});
236}
237
[208]2381;
[1014]239
240__END__
241
242=head1 SEE ALSO
243
244=head1 AUTHOR
245
246Thauvin Olivier, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
247
248=head1 COPYRIGHT AND LICENSE
249
250Copyright (C) 2009, 2010, 2011, 2012 by Thauvin Olivier
251
252This library is free software; you can redistribute it and/or modify
253it under the same terms as Perl itself, either Perl version 5.10.0 or,
254at your option, any later version of Perl 5 you may have available.
255
256=cut
257
Note: See TracBrowser for help on using the repository browser.