source: tags/5.2.10/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
Line 
1package LATMOS::Accounts::Log;
2
3use strict;
4use warnings;
5use Sys::Syslog qw(:standard :macros);
6use Exporter ();
7use Mail::Sendmail;
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(
28    LA_EMERG
29    LA_ALERT
30    LA_CRIT
31    LA_ERR
32    LA_ERROR
33    LA_WARN
34    LA_WARNING
35    LA_NOTICE
36    LA_INFO
37    LA_DEBUG
38);
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
46@EXPORT_OK = @EXPORT;
47%EXPORT_TAGS = (LOGLEVELS => [ @loglevels ]);
48
49our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
50
51my %lastmessages = ();
52
53=head1 LOG LEVEL
54
55=over 4
56
57=item LA_EMERG
58
59=cut
60
61sub LA_EMERG { LOG_EMERG } # system is unusable
62
63=item LA_ALERT
64
65=cut
66
67sub LA_ALERT { LOG_ALERT } # action must be taken immediately
68
69=item LA_CRIT
70
71=cut
72
73sub LA_CRIT { LOG_CRIT } # critical conditions
74
75=item LA_ERR, LA_ERROR
76
77=cut
78
79sub LA_ERR   { LOG_ERR } # error conditions
80sub LA_ERROR { LA_ERR } # Alias for ERR
81
82=item LA_WARN, LA_WARNING
83
84=cut
85
86sub LA_WARNING { LOG_WARNING } # warning conditions
87sub LA_WARN    { LA_WARNING } # warning conditions
88
89=item LA_NOTICE
90
91=cut
92
93sub LA_NOTICE { LOG_NOTICE } # normal, but significant, condition
94
95=item LA_INFO
96
97=cut
98
99sub LA_INFO { LOG_INFO } # informational message
100
101=item LA_DEBUG
102
103=cut
104
105sub LA_DEBUG { LOG_DEBUG } # debug-level message
106
107=back
108
109=cut
110
111my %log_method = (
112    syslog => undef,
113    console => LA_NOTICE,
114    callback => undef,
115    mail => undef,
116);
117
118my @maillog = ();
119
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
138sub la_set_log {
139    my (%options) = @_;
140    while (my ($key, $val) = each(%options)) {
141        if ($key eq 'syslog') {
142            if ($val) {
143                my ($ident, $logopt, $facility) =  @{ ref $val ? $val : [] };
144                $ident ||= 'LATMOS::Accounts';
145                $logopt ||= 'pid';
146                $facility ||= 'LOG_USER';
147                openlog($ident, $logopt, $facility);
148                $log_method{syslog} = 1;
149            }
150            next;
151        }
152        $log_method{$key} = $val;
153    }
154    1;
155}
156
157=head2 lastmessage($level)
158
159Return the last message for C<$level> (LA_ERROR by default)
160
161=cut
162
163sub lastmessage {
164    my ($level) = @_;
165    return $lastmessages{$level || LA_ERROR};
166}
167
168=head2 la_log($level, @sprintf_args)
169
170=cut
171
172sub la_log {
173    my ($level, $msg, @args) = @_;
174    no warnings 'printf';
175
176    if (!$msg) {
177        # Wrong la_log usage
178        my @call = caller();
179        la_log(LA_WARN, 'empty message at %s:%s', $call[1], $call[2]);
180        return;
181    }
182    if ($level !~ /^\d$/) {
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
189    $lastmessages{$level} = sprintf($msg, map { defined($_) ? $_ : '' } @args);
190    if ($log_method{syslog}) {
191        syslog($level, $msg, @args) unless($level >= LA_DEBUG);
192    }
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}) {
198        if ($level >= LA_NOTICE && $level < LA_DEBUG) {
199            printf("$msg\n", @args);
200        } else {
201            my $debug = '';
202            if ($level == LA_DEBUG) {
203                my @caller = caller;
204                $debug = "$caller[0]:$caller[2] ";
205            }
206            warn sprintf("$debug$msg", map { defined($_) ? $_ : '' } @args) . "\n";
207        }
208    }
209    if ($log_method{callback}) {
210        $log_method{callback}->($level, $msg, @args);
211    }
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    }
216    1;
217}
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
2381;
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.