Initial commit: Imported yaala 0.7.3.
[yaala.git] / lib / Yaala / Parser / Squid.pm
1 package Yaala::Parser;
2
3 use strict;
4 use warnings;
5 use vars qw(%DATAFIELDS);
6
7 use Exporter;
8 use Yaala::Data::Persistent qw#init#;
9 use Yaala::Config qw#get_config#;
10
11 @Yaala::Parser::EXPORT_OK = qw#parse extra %DATAFIELDS#;
12 @Yaala::Parser::ISA = ('Exporter');
13
14 our $LASTDATE = init ('$LASTDATE', 'scalar');
15 our $EXTRA = init ('$EXTRA', 'hash');
16
17 if (!$$LASTDATE) { $$LASTDATE = 0; }
18 if (!defined ($EXTRA->{'total'})) { $EXTRA->{'total'} = 0; }
19 if (!defined ($EXTRA->{'start'})) { $EXTRA->{'start'} = 0; }
20 if (!defined ($EXTRA->{'end'}  )) { $EXTRA->{'end'}   = 0; }
21 if (!defined ($EXTRA->{'days'} )) { $EXTRA->{'days'}  = {}; }
22
23 %DATAFIELDS = (
24         'date'          => 'key:date',
25         'hour'          => 'key:hour',
26         'client'        => 'key:host',
27         'server'        => 'key:host',
28         'peer'          => 'key:host',
29         'protocol'      => 'key',
30         'method'        => 'key',
31         'mime'          => 'key',
32         'httpstatus'    => 'key:numeric',
33         'resultcode'    => 'key',
34         'hierarchycode' => 'key',
35         'ident'         => 'key',
36         'bytes'         => 'agg:bytes',
37         'elapsed'       => 'agg:time',
38         'requests'      => '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: Squid.pm,v 1.11 2003/12/07 16:46:50 octo Exp $';
47 print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);
48
49 return (1);
50
51 sub parse
52 {
53         my $line = shift or return undef;
54         #if ($line =~ m#^(\S+)\s+(\d+)\s(\S+)\s([^/]+)/(\d+)\s(\d+)\s(\S+)\s(\S+)\s(\S+)\s([^/]+)/(\S+)\s(.*)$#)
55         if ($line =~ m#^(\S+)\s+(\d+) (\S+) ([^/]+)/(\d+) (\d+) (\S+) (\S+) (\S+) ([^/]+)/(\S+) (.*)$#)
56         {
57                 my ($epoch, $duration, $client, $result_code, $http_code,
58                         $size, $method, $url, $ident, $hierarchy_code,
59                         $origin_host, $mime) = 
60                 ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);
61
62                 if ($epoch < $$LASTDATE)
63                 {
64                         print STDERR $/, __FILE__, ": Skipping.. ($epoch < $$LASTDATE)" if ($::DEBUG & 0x0200);
65                         return (undef);
66                 }
67                 else { $$LASTDATE = $epoch; }
68
69                 return undef if ($url eq '*');
70
71                 my $hour  = sprintf ("%02u", (localtime ($epoch))[2]);
72                 my $day   = sprintf ("%02u", (localtime ($epoch))[3]);
73                 my $month = sprintf ("%02u", (localtime ($epoch))[4] + 1);
74                 my $year  = sprintf ("%04u", (localtime ($epoch))[5] + 1900);
75
76                 my $date = sprintf ("%04u-%02u-%02u", $year, $month, $day);
77
78                 $EXTRA->{'total'}++;
79                 $EXTRA->{'days'}{$date}++;
80                 $EXTRA->{'start'} = $epoch if (($epoch < $EXTRA->{'start'}) or !$EXTRA->{'start'});
81                 $EXTRA->{'end'}   = $epoch if ($epoch > $EXTRA->{'end'});
82
83                 my ($protocol, $server, $path);
84                 if ($url =~ m#^([^:]+)://([^:/]+)(?::\d+)?(/[^\?]*)#)
85                 {
86                         ($protocol, $server, $path) = ($1, $2, $3);
87                 }
88                 elsif ($url =~ /^([\w\d\-\.]+):443$/)
89                 {
90                         ($protocol, $server, $path) = ('https', $1, '');
91                 }
92                 else
93                 {
94                         print STDERR $/, __FILE__, ": Unable to parse URL: ``$url''" if ($::DEBUG);
95                         return (0);
96                 }
97
98                 if ($ident eq '-') { $ident = '*UNKNOWN*'; }
99                 
100                 my %combined=(
101                             'client'        => $client,
102                             'resultcode'    => uc ($result_code),
103                             'httpstatus'    => $http_code,
104                             'method'        => $method,
105                             'mime'          => $mime,
106                             'bytes'         => $size,
107                             'server'        => $server,
108                             'protocol'      => uc ($protocol),
109                             'hierarchycode' => uc ($hierarchy_code),
110                             'ident'         => uc ($ident),
111                             'peer'          => $origin_host,
112                             'date'          => $date,
113                             'hour'          => $hour,
114                             'elapsed'       => $duration,
115                             'requests'      => 1,
116                             );
117                 store (\%combined);
118         }
119         elsif ($::DEBUG)
120         {
121                 chomp ($line);
122                 print STDERR $/, __FILE__, ": Unable to parse: ``$line''";
123         }
124 }
125
126 sub extra 
127 {
128         my $start = scalar (localtime ($EXTRA->{'start'}));
129         my $end   = scalar (localtime ($EXTRA->{'end'}));
130         my $days  = scalar (keys (%{$EXTRA->{'days'}}));
131         my $average = 0;
132         if ($days) { $average = sprintf ("%.1f", ($EXTRA->{'total'} / $days)); }
133
134         $::EXTRA->{'Total requests'} = $EXTRA->{'total'};
135         $::EXTRA->{'Reporting period'} = "$days Days";
136         $::EXTRA->{'Average requests per day'} = $average;
137         $::EXTRA->{'Start date'} = $start;
138         $::EXTRA->{'End date'} = $end;
139 }