]> jfr.im git - irc/SurrealServices/srsv.git/blame - branches/0.5.0/SrSv/Log.pm
Fix stuff like sending hashes instead of nicks
[irc/SurrealServices/srsv.git] / branches / 0.5.0 / SrSv / Log.pm
CommitLineData
aecfa1fd 1# This file is part of SurrealServices.
2#
3# SurrealServices is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# SurrealServices is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with SurrealServices; if not, write to the Free Software
15# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16package SrSv::Log;
17
18use strict;
19use IO::Handle;
20use English qw(-no_match_var);
21
22use SrSv::Debug;
23use SrSv::Timer qw(add_timer);
24use SrSv::Time;
25use SrSv::Process::InParent qw(write_log open_log close_log rotate_logs close_all_logs);
26use IO::File;
27
28use SrSv::Text::Codes qw( strip_codes );
29
30use SrSv::Conf2Consts qw(main);
31
32use Exporter 'import';
33BEGIN {
34 my %constants = (
35 LOG_DEBUG => 0,
36 LOG_INFO => 1,
37 LOG_WARNING => 2, # A bad thing might happen
38 LOG_ERROR => 3, # A bad thing happened
39 LOG_CRITICAL => 4, # One module is going down
40 LOG_FATAL => 5, # One thread is going down
41 LOG_PANIC => 6, # The entire server is going down
42
43 LOG_OPEN => 1,
44 LOG_CLOSE => 2,
45 LOG_WRITE => 3,
46 LOG_ROTATE => 4,
47 );
48
49 require constant; import constant (\%constants);
50 our @EXPORT = ( qw( wlog write_log open_log close_log ), keys(%constants) );
51 our @EXPORT_OK = ( qw ( rotate_logs close_all_logs ) );
52 our %EXPORT_TAGS = (
53 levels => [keys(%constants)],
54 all => [@EXPORT, @EXPORT_OK],
55 );
56}
57
58our $path = './logs';
59our @levels = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL', 'FATAL', 'PANIC');
60
61open_log('diag', 'services.log');
62open_log('netdump', 'netdump.log') if main::NETDUMP();
63
64sub wlog($$$) {
86a50b12 65
aecfa1fd 66 my ($service, $level, $text) = @_;
67
68 my $prefix;
69 $prefix = "\002\00304" if($level > LOG_INFO);
70 $prefix .= $levels[$level];
7b3a5814 71 my $rsuser = { NICK => $main::rsnick, ID => ircd::getAgentUuid($main::rsnick) };
92c29160 72 ircd::privmsg($rsuser, main_conf_diag, "$prefix\: ($service) $text");
aecfa1fd 73 write_log('diag', '<'.$main::rsnick.'>', "$prefix\: ($service) $text");
74}
75
76my %log_handles;
77my %file_handles;
78
79sub write_log($$@) {
80 my ($handle, $prefix, @payloads) = @_;
81 unless (defined($log_handles{lc $handle})) {
82 ircd::debug_nolog("undefined log-handle $handle, aborting write()") if main::DEBUG();
83 return undef;
84 }
85 foreach (@payloads) {
86 $_ = strip_codes($_);
87 }
88 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime();
89 my $time = sprintf("%02d:%02d:%02d", $hour, $min, $sec);
90 my $payload = $time.$prefix.' '.join("\n".$time.$prefix.' ', @payloads);
91 print {$log_handles{lc $handle}} "$payload\n";
92}
93
94sub open_log($$) {
95 my ($handle, $filename) = @_;
96 if (defined($log_handles{lc $handle})) {
97 ircd::debug_nolog("duplicate log-handle $handle, aborting open()");
98 return undef;
99 }
100 my ($year, $month, undef, $mday) = gmt_date();
101 my $filename2 = $filename.'-'.sprintf('%04d-%02d-%02d', $year, $month, $mday);
102
103 my $fh;
104 if($fh = IO::File->new($path.'/'.$filename2, '>>')) {
105 } else {
106 use SrSv::RunLevel qw( main_shutdown );
107 ircd::debug_nolog(qq(Unable to open "$path/$filename2": $OS_ERROR}));
108 main_shutdown();
109 }
110 $fh->autoflush(1);
111 $log_handles{lc $handle} = $fh;
112 $file_handles{lc $handle} = { BASENAME => $filename, FILENAME => $filename2 };
113}
114
115sub close_log($) {
116 my ($handle) = @_;
117 unless (defined($log_handles{lc $handle})) {
118 ircd::debug_nolog("undefined log-handle $handle, aborting close()");
119 return undef;
120 }
121 $log_handles{lc $handle}->close();
122 delete($log_handles{lc $handle});
123 delete($log_handles{lc $handle});
124}
125
126sub rotate_logs() {
127 foreach my $handle (keys(%file_handles)) {
128 $log_handles{lc $handle}->close();
129 my ($year, $month, undef, $mday) = gmt_date();
130 $file_handles{lc $handle}{FILENAME} =
131 $file_handles{lc $handle}{BASENAME}.'-'.sprintf('%04d-%02d-%02d', $year, $month, $mday);
132 my $new_fh;
133 if($new_fh = IO::File->new($path.'/'.$file_handles{lc $handle}{FILENAME}, '>>')) {
134 } else {
135 use SrSv::RunLevel qw( main_shutdown );
136 my $new_path = "$path/".$file_handles{lc $handle}{FILENAME};
137 ircd::debug_nolog(qq(Unable to open "$new_path": $OS_ERROR}));
138 main_shutdown();
139 }
140 $log_handles{lc $handle} = $new_fh;
141 }
142
143 #add_timer('', get_nextday_time()-time(), __PACKAGE__, 'SrSv::Log::rotate_logs');
144 Event->timer( at => get_nextday_time(), cb => \&SrSv::Log::rotate_logs );
145}
146
147sub close_all_logs() {
148 foreach my $handle (keys(%file_handles)) {
149 close_log($handle);
150 }
151}
152
153# set a timer to rotate logs on day-change
154Event->timer( at => get_nextday_time(), cb => \&SrSv::Log::rotate_logs );
155
1561;