Parser/WebserverTools.pm: Updated the browser recognition.
[yaala.git] / lib / Yaala / Parser / Xferlog.pm
1 package Yaala::Parser;
2
3 use strict;
4 use warnings;
5 use vars qw(%DATAFIELDS);
6
7 use Exporter;
8 use Yaala::Parser::WebserverTools qw(%MONTH_NUMBERS);
9 use Yaala::Data::Persistent qw#init#;
10 use Yaala::Config qw#get_config#;
11
12 @Yaala::Parser::EXPORT_OK = qw(parse extra %DATAFIELDS);
13 @Yaala::Parser::ISA = ('Exporter');
14
15 our $LASTDATE = init ('$LASTDATE', 'scalar');
16 our $EXTRA = init ('$EXTRA', 'hash');
17
18 if (!$$LASTDATE) { $$LASTDATE = 0; }
19 if (!defined ($EXTRA->{'total'})) { $EXTRA->{'total'} = 0; }
20 if (!defined ($EXTRA->{'days'} )) { $EXTRA->{'days'}  = {}; }
21
22 %DATAFIELDS = (
23         host            => 'key:host',
24         user            => 'key',
25         access_mode     => 'key',
26         
27         date            => 'key:date',
28         hour            => 'key:hour',
29         
30         file            => 'key',
31         completion_status => 'key',
32         direction       => 'key',
33         transfer_type   => 'key',
34         transfer_time   => 'key:numeric',
35         special_action  => 'key',
36
37         bytes           => 'agg:bytes',
38         count           => 'agg'
39 );
40
41 # This needs to be done at runtime, since Data uses Setup which relies on
42 # %DATAFIELDS to be defined  -octo
43 require Yaala::Data::Core;
44 import Yaala::Data::Core qw#store#;
45
46 my $VERSION = '$Id: Xferlog.pm,v 1.4 2003/12/07 16:49:56 octo Exp $';
47 print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);
48
49 return (1);
50
51 sub parse
52 {
53         my $line = shift;
54         my @fields = split(m/\s+/, $line);
55         my ($hour, $minute, $second) = split (m/:/, $fields[3]);
56
57         if (scalar (@fields) != 18)
58         {
59                 print STDERR $/, __FILE__, ': There were ',
60                 scalar (@fields), ' when 18 where expected..'
61                 if ($::DEBUG);
62         }
63
64         {
65                 my $tmp = int (sprintf ("%04u%02u%02u%02u%02u%02u",
66                                 $fields[4], $MONTH_NUMBERS{$fields[1]}, $fields[2],
67                                 $hour, $minute, $second));
68
69                 if ($tmp < $$LASTDATE)
70                 {
71                         print STDERR $/, __FILE__, ": Skipping.. ($tmp < $$LASTDATE)" if ($::DEBUG & 0x0200);
72                         return (undef);
73                 }
74                 else { $$LASTDATE = $tmp; }
75         }
76         
77         my $date = sprintf ("%04u-%02u-%02u", $fields[4], $MONTH_NUMBERS{$fields[1]}, $fields[2]);
78
79         my $file = $fields[8];
80         my $bytes = $fields[7];
81         
82         my $transfer_time = $fields[5];
83
84         my $host = $fields[6];
85         my $user = $fields[13];
86
87         my $transfer_type = ($fields[9] eq 'a' ? 'ascii' : 'binary');
88         my $completion_status = ($fields[17] eq 'c' ? 'complete' : 'incomplete');
89         
90         my $special_action;
91         if ($fields[10] eq '_')
92         {
93                 $special_action = "none";
94         }
95         elsif ($fields[10] eq 'C')
96         {
97                 $special_action = 'compressed';
98         }
99         elsif ($fields[10] eq 'U')
100         {
101                 $special_action = 'uncompressed';
102         }
103         elsif ($fields[10] eq 'T')
104         {
105                 $special_action = "tar'ed";
106         }
107         else
108         {
109                 print STDERR $/, __FILE__, ': Unknown special_action: ',
110                 $fields[10] if ($::DEBUG);
111                 return (0);
112         }
113         
114         my $direction;
115         if ($fields[11] eq 'i')
116         {
117                 $direction = 'incoming';
118         }
119         elsif ($fields[11] eq 'o')
120         {
121                 $direction = 'outgoing';
122         }
123         elsif ($fields[11] eq 'd')
124         {
125                 $direction = 'deleted';
126         }
127         else
128         {
129                 print STDERR $/, __FILE__, ': Unknown direction: ',
130                 $fields[11] if ($::DEBUG);
131                 return (0);
132         }
133         
134         my $access_mode;
135         if ($fields[12] eq 'a')
136         {
137                 $access_mode = 'anonymous';
138         }
139         elsif ($fields[12] eq 'g')
140         {
141                 $access_mode = 'guest';
142         }
143         elsif ($fields[12] eq 'r')
144         {
145                 $access_mode = 'real';
146         }
147         else
148         {
149                 print STDERR $/, __FILE__, ': Unknown access-method: ',
150                 $fields[12] if ($::DEBUG);
151                 return (0);
152         }
153         
154         $EXTRA->{'total'}++;
155         $EXTRA->{'days'}{$date}++;
156         
157         # 14: service-name
158         # 15: authentication-method
159         # 16: authentication-user-id
160
161         my %data_set = (
162                 host            => $host,
163                 user            => $user,
164                 access_mode     => $access_mode,
165         
166                 date            => $date,
167                 hour            => $hour,
168         
169                 file            => $file,
170                 completion_status => $completion_status,
171                 direction       => $direction,
172                 transfer_type   => $transfer_type,
173                 transfer_time   => $transfer_time,
174                 special_action  => $special_action,
175
176                 bytes           => $bytes,
177                 count           => 1
178         );
179         store (\%data_set);
180 }
181
182 sub extra
183 {
184         $::EXTRA->{'Requests Total'} = $EXTRA->{'total'};
185         
186         my $days = scalar (keys (%{$EXTRA->{'days'}}));
187
188         $::EXTRA->{'Reporting period'} = "$days days";
189
190         $::EXTRA->{'Average requests per day'} = sprintf ("%.1f", $EXTRA->{'total'} / $days);
191 }