Initial commit: Imported yaala 0.7.3.
[yaala.git] / lib / Yaala / Parser / Bind9.pm
1 package Yaala::Parser;
2
3 # Written by David Augros <david@lightship.net>
4
5 use strict;
6 use warnings;
7 use vars qw(%DATAFIELDS);
8
9 use Exporter;
10 use Yaala::Parser::WebserverTools qw#%MONTH_NUMBERS#;
11 use Yaala::Data::Persistent qw#init#;
12
13 @Yaala::Parser::EXPORT_OK = qw#%DATAFIELDS parse extra#;
14 @Yaala::Parser::ISA = ('Exporter');
15
16 our $LASTDATE = init ('$LASTDATE', 'scalar');
17 our $EXTRA = init ('$EXTRA', 'hash');
18
19 if (!$$LASTDATE) { $$LASTDATE = 0; }
20 if (!defined ($EXTRA->{'total'})) { $EXTRA->{'total'} = 0; }
21 if (!defined ($EXTRA->{'days'} )) { $EXTRA->{'days'}  = {}; }
22
23 our %severity = map
24         { $_ => 1 }
25         (qw#kern user mail daemon auth syslog lpr
26         news uucp cron authpriv ftp
27         local0 local1 local2 local3
28         local4 local5 local6 local7#);
29
30 %DATAFIELDS = (
31         date            => 'key:date',
32         hour            => 'key:hour',
33         client          => 'key:host',
34         
35         query           => 'key',
36         class           => 'key',
37         type            => 'key',
38
39         severity        => 'key',
40         category        => 'key',
41         
42         requests        => 'agg'
43 );
44
45 require Yaala::Data::Core;
46 import Yaala::Data::Core qw#store#;
47
48 my ($default_second, $default_minute, $default_hour, $default_day, $default_year) = (localtime ())[0,1,2,3,5];
49 my $default_month = (split (m/\s+/, scalar (localtime ())))[1];
50 $default_year += 1900;
51
52 my $VERSION = '$Id: Bind9.pm,v 1.4 2003/12/07 15:01:33 octo Exp $';
53 print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);
54
55 return (1);
56
57 sub parse
58 {
59         my $line = shift or return undef;
60         #if ($line =~ m/^(?:(\w{3}) (\d+) (\d\d)[\d:\.]+ )?(?:(\w+): )?(?:(\w+): )?client ([\d\.])#\d+: query: (\S+) (\S+) (\S+)$/)
61         if ($line =~ m/^(?:(\w{3}) (\d+) (\d\d):(\d\d):(\d\d)\.(\d\d\d) )?(?:(\w+): )?(?:(\w+): )?client ([\d\.]+)#\d+: query: (\S+) (\S+) (\S+)$/)
62         {
63                 my ($client, $query, $class, $type) = ($9, $10, $11, $12);
64
65                 my ($month, $day, $hour, $minute, $second, $frac) =
66                 (
67                         $default_month, $default_day, $default_hour,
68                         $default_minute, $default_second, '000'
69                 );
70                 
71                 if (defined ($1) and $1)
72                 {
73                         ($month, $day, $hour, $minute, $second, $frac) = ($MONTH_NUMBERS{$1},
74                                 $2, $3, $4, $5, $6);
75
76                         print STDERR $/, __FILE__, ": $1" if (!$month);
77                         
78                         my $tmp = int (sprintf ("%04u%02u%02u%02u%02u%02u%03u",
79                                         $default_year, $month, $day, $hour,
80                                         $minute, $second, $frac));
81
82                         if ($tmp < $$LASTDATE) 
83                         {
84                                 print STDERR $/, __FILE__, ": Skipping.. ($tmp < $$LASTDATE)" if ($::DEBUG & 0x0200);
85                                 return (undef); 
86                         }
87                         else { $$LASTDATE = $tmp; }
88                 }
89
90                 my $date = sprintf ("%04u-%02u-%02u",
91                         $default_year, $month, $day);
92
93                 my $category = '*UNKNOWN*';
94                 my $severity = '*UNKNOWN*';
95                 if (defined ($7) and $7 and defined ($8) and $8)
96                 {
97                         $category = $7;
98                         $severity = $8;
99                 }
100                 elsif (defined ($7) and $7)
101                 {
102                         if (defined ($severity{$7})) { $severity = $7; }
103                         else { $category = $7; }
104                 }
105                 elsif (defined ($8) and $8)
106                 {
107                         if (defined ($severity{$8})) { $severity = $8; }
108                         else { $category = $8; }
109                 }
110
111                 if ($query =~ m/in-addr\.arpa$/)
112                 {
113                         my @tmp = reverse (split (m/\./, $query));
114                         splice (@tmp, 0, 2);
115
116                         $query = join ('.', @tmp);
117                 }
118                         
119                 $EXTRA->{'total'}++;
120                 $EXTRA->{'days'}{$date}++;
121
122                 my %combined = (
123                         date            => $date,
124                         hour            => $hour,
125                         client          => $client,
126         
127                         query           => $query,
128                         class           => $class,
129                         type            => $type,
130                         
131                         severity        => $severity,
132                         category        => $category,
133
134                         requests        => 1
135                 );
136
137                 store (\%combined);
138         }
139         elsif ($::DEBUG)
140         {
141                 chomp ($line);
142                 print $/, __FILE__, ": Unable to parse: $line";
143         }
144 }
145
146 sub extra
147 {
148         my ($average, $days) = (0, 1);
149         
150         return (0) unless ($EXTRA->{'total'});
151         
152         $days = scalar (keys (%{$EXTRA->{'days'}}));
153         
154         $::EXTRA->{'Total requests'} = $EXTRA->{'total'};
155         $::EXTRA->{'Average requests per day'} = sprintf ("%.1f", $EXTRA->{'total'} / $days);;
156         $::EXTRA->{'Reporting period'} = "$days days";
157 }