File Coverage

blib/lib/Apache2/LogNotify.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Apache2::LogNotify;
2              
3 1     1   693 use strict;
  1         1  
  1         38  
4 1     1   394 use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED SERVER_ERROR);
  0            
  0            
5             use Apache2::Const qw(:common :log :cmd_how :http HTTP_BAD_REQUEST);
6             use Apache2::Connection qw(get_remote_host);
7             use Apache2::RequestUtil qw(dir_config);
8             use Apache2::RequestRec ();
9             use Apache2::ServerRec;
10             use Apache2::ServerUtil qw(server get_server_version);
11             use Apache2::Log;
12             use Apache2::Process;
13             use APR::Table;
14             use APR::Finfo ();
15             use Mail::Mailer;
16             use IPC::Cache;
17             use Data::Dumper;
18              
19             our $VERSION = 0.10;
20             my $cache = new IPC::Cache( { namespace => 'LogNotify',
21             expires_in => 86400 } );
22             $cache->purge();
23              
24             sub handler {
25             my $r = shift;
26             my $s = $r->server();
27             my $args = $r->args;
28             my $user = $r->user;
29             my $debug = undef;
30             my $dir_cfg = getConfig($r->server , $r->per_dir_config);
31              
32             $debug = 1 if ( $dir_cfg->{Debug} eq "On" );
33             $r->log_error(__PACKAGE__.": ", ' Debug: ['. $dir_cfg->{Debug} . ']');
34             foreach my $key ( keys %{$dir_cfg} ) {
35             my $value = $dir_cfg->{$key};
36             if ( $debug ) {
37             if ( ref($value ) eq "SCALAR" ){
38             $r->log_error(__PACKAGE__.": ", $key, ': ['. $value .']');
39             }
40             if ( ref($value ) eq "ARRAY" ){
41             $r->log_error(__PACKAGE__.": ", $key, ': ['. join(", ", @{$value} ) .']');
42             }
43             }
44             }
45             # LogError On
46             $r->log_error(__PACKAGE__.': LogError CODE: ['. $dir_cfg->{LogError}->[0] .']') if ( $debug );
47             return Apache2::Const::OK unless ( $dir_cfg->{LogError} !~ /^[Oo][Nn]$/ );
48              
49             #ErrorType 300 400 500
50             #my @errorType = split( /\s+,\s+/, join(' ',@{$dir_cfg->{ErrorType}}) );
51             my @errorType = split( /\s+/, join(' ',@{$dir_cfg->{ErrorType}}) );
52             $r->log_error(__PACKAGE__. "==========: ErrorType: ". Dumper ($dir_cfg->{ErrorType}) ) if ( $debug );
53             $r->log_error(__PACKAGE__.'==========: ERROR TYPE: ['. @{$dir_cfg->{ErrorType}} .']') if ( $debug );
54             $r->log_error(__PACKAGE__.'==========: ERROR TYPE 2: ['. join(", ", @errorType ) .']') if ( $debug );
55             # $r->log_error(__PACKAGE__.'==========: HOSTNAME: ['. $s->server_hostname() .']') if ( $debug );
56              
57             foreach my $errorTest ( @errorType ) {
58             #$r->log_error(__PACKAGE__.'==========: errorType: Test: ['. $errorTest .']') if ( $debug );
59             if ( $r->status() == $errorTest ) {
60             $r->log_error(__PACKAGE__.'==========: PURGE CACHE: ') if ( $debug );
61             $cache->purge();
62             my $seen = $cache->get( $r->uri() );
63             my $seenCount = $cache->get("SeenCount");
64             $r->log_error(__PACKAGE__.'==========: SEEN: <' . $seenCount . '>') if ( $debug );
65             if ( ! $seen || $seenCount % 10 == 0 ) {
66             $cache->set($r->uri(), 1, 30 );
67             $cache->set("SeenCount", 1, 30 );
68             $r->log_error(__PACKAGE__.'==========: SENDING MAIL ON: <'. $r->uri().'>' ) if ( $debug );
69             &sendMail($r);
70             }
71             else {
72             $r->log_error(__PACKAGE__.'==========: NO MAIL MAIL <' . $seen . '> <'. $r->uri().'>') if ( $debug );
73             $cache->set("SeenCount", $seenCount + 1, 30 );
74             }
75             }
76             }
77              
78             $r->log_error(__PACKAGE__.'==========: RESPONSE CODE: ['. $r->status() .']') if ( $debug );
79             $r->log_error(__PACKAGE__.'==========: NotifyMode CODE: ['. $dir_cfg->{NotifyMode}->[0] .']') if ( $debug );
80            
81             return Apache2::Const::HTTP_UNAUTHORIZED;
82             }
83              
84             sub sendMail {
85             my $r = shift @_;
86             my $s = $r->server();
87              
88             my $dir_cfg = getConfig($r->server , $r->per_dir_config);
89             my $debug = undef;
90             $debug = 1 if ( $dir_cfg->{Debug} eq "On" );
91              
92             my $email = {};
93             $email->{From} = $s->server_admin();
94             $email->{To} = shift( @{ $dir_cfg->{Admins} } );
95             my @message = ();
96             my %mailList;
97             if ( $dir_cfg->{NotifyMode}->[0] eq "All" || $dir_cfg->{NotifyMode}->[0] eq "Admins" ) {
98             $r->log_error(__PACKAGE__.': NotifyMode CODE OPTION: [ADMIN]') if ( $debug );
99             foreach my $mail ( @{$dir_cfg->{Admins}} ) {
100             $mailList{$mail} = 1;
101             }
102             }
103            
104             if ( $dir_cfg->{NotifyMode}->[0] eq "All" || $dir_cfg->{NotifyMode}->[0] eq "AppOwners" ) {
105             $r->log_error(__PACKAGE__.': NotifyMode CODE OPTION: [APPOWNERS]') if ( $debug );
106             foreach my $mail ( @{$dir_cfg->{AppOwners}} ) {
107             $mailList{$mail} = 1;
108             }
109             }
110            
111             $r->log_error(__PACKAGE__.': EMAILS: [' . join(', ', keys %mailList ) . ']');
112             $email->{Subject} = "Apache: ERROR: " . $s->server_hostname(). ": " . $r->status_line();
113             $email->{Cc} = join(",", (keys %mailList) );
114              
115             my $c = $r->connection;
116             my $httpURL = "http://". $s->server_hostname()."". $r->unparsed_uri();
117             push( @message, "USER Request: " . $httpURL );
118             push( @message, "STATUS LINE: " . $r->status_line() );
119             push( @message, "STATUS: " . $r->status() );
120             push( @message, "REQUEST: " . $r->the_request());
121             push( @message, "UNPARSED URI: " . $r->unparsed_uri() );
122             push( @message, "URI: " . $r->uri() );
123             push( @message, "USER: " . $r->user() );
124              
125             push( @message, "PORT: " . $s->port() );
126             push( @message, "SHORT_NAME: " . $s->process()->short_name() );
127             push( @message, "SERVER HOSTNAME: " . $s->server_hostname() );
128             push( @message, "BASE SERVER: " . $c->base_server()->server_hostname() );
129            
130             push( @message, "AUTH TYPE: " . $r->ap_auth_type() );
131             push( @message, "QUERY STRING: " . $r->args() );
132              
133             push( @message, "BYTES SENT: " . $r->bytes_sent() ) ;
134             push( @message, "REMOTE HOST IP: " . $r->connection()->get_remote_host() );
135             push( @message, "REMOTE HOST NAME: " . $r->connection()->remote_host() );
136             push( @message, "FILE NAME: " . $r->filename() );
137             my $finfo = $r->finfo();
138            
139             push( @message, "INODE: " . $finfo->inode );
140            
141             push( @message, "PROTECTION: " . $finfo->protection );
142             push( @message, "NLINK: " . $finfo->nlink );
143             push( @message, "GROUP: " . $finfo->group );
144             push( @message, "USER: " . $finfo->user );
145             push( @message, "SIZE: " . $finfo->size );
146             push( @message, "ATIME: " . scalar localtime($finfo->atime) );
147             push( @message, "MTIME: " . scalar localtime($finfo->mtime) );
148             push( @message, "CTIME: " . scalar localtime($finfo->ctime) );
149            
150             my $headersIn = $r->headers_in() ;
151             foreach my $key (keys %{$headersIn}) {
152             push( @message, $key.": " . $headersIn->{$key} );
153             }
154              
155             my $headersOut = $r->headers_out() ;
156             foreach my $key (keys %{$headersOut}) {
157             push( @message, $key.": " . $headersOut->{$key} );
158             }
159              
160             push( @message, "HOST NAME: " . $r->hostname() );
161            
162             push( @message, "METHOD: " . $r->method() );
163             push( @message, "MTIME: " . $r->mtime() );
164             push( @message, "PROTOCOL: " . $r->protocol());
165             push( @message, "REQUEST TIME: " . $r->request_time());
166             push( @message, "OBJECT SERVER NAME: " . $r->server() );
167             push( @message, "RESPONSE STATUS: " . $r->status() );
168              
169             my $env = $r->subprocess_env() ;
170             foreach my $key (keys %{$env}) {
171             push( @message, $key.": " . $env->{$key} );
172             }
173              
174             push( @message, "STATUS LINE: " . $r->status_line() );
175             push( @message, "STATUS: " . $r->status() );
176             push( @message, "REQUEST: " . $r->the_request());
177             push( @message, "UNPARSED URI: " . $r->unparsed_uri() );
178             push( @message, "URI: " . $r->uri() );
179             push( @message, "USER: " . $r->user() );
180              
181             foreach my $key (keys %{$email}) {
182             push( @message, "EMAIL: ". $key.": " . $email->{$key} );
183             }
184              
185             my $sendmail=Mail::Mailer->new("sendmail");
186             $sendmail->open( $email );
187             print $sendmail join("\n", @message);
188             $sendmail->close;
189             $r->log_error(__PACKAGE__.': MESSAGE: [' . join(', ', @message ) . ']') if ( $debug );
190            
191             }
192              
193             sub getConfig {
194             Apache2::Module::get_config(__PACKAGE__.'::Parameters', @_);
195             }
196              
197             1;
198             __END__