File Coverage

blib/lib/Logfile/Base.pm
Criterion Covered Total %
statement 57 195 29.2
branch 14 86 16.2
condition 2 22 9.0
subroutine 10 21 47.6
pod 0 10 0.0
total 83 334 24.8


line stmt bran cond sub pod time code
1             # -*- Mode: Perl -*-
2             # $Basename: Base.pm $
3             # $Revision: 1.3 $
4             # Author : Ulrich Pfeifer
5             # Created On : Mon Mar 25 09:58:31 1996
6             # Last Modified By: Ulrich Pfeifer
7             # Last Modified On: Sun Feb 10 21:53:37 2002
8             # Language : Perl
9             #
10             # (C) Copyright 1996, Universität Dortmund, all rights reserved.
11             #
12              
13             package Logfile::Base;
14 8     8   43 use Carp;
  8         15  
  8         857  
15 8     8   39 use vars qw($VERSION $nextfh);
  8         13  
  8         471  
16 8     8   93 use strict;
  8         11  
  8         19512  
17              
18             # $Format: "$\VERSION = sprintf '%5.3f', ($ProjectMajorVersion$ * 100 + ($ProjectMinorVersion$-1))/1000;"$
19             $VERSION = sprintf '%5.3f', (2 * 100 + (3-1))/1000;
20              
21             $Logfile::MAXWIDTH = 40;
22             my ($HaveParseDate, $HaveGetDate, $HaveDateGetDate);
23             $nextfh = 'fh000';
24              
25             sub isafh {
26 8     8 0 13 my $f = shift;
27 8 50 33     147 ref $f eq 'GLOB'
28             or ref \$f eq 'GLOB'
29             or (ref $f) =~ /^IO::/
30             }
31              
32             sub new {
33 8     8 0 179 my $type = shift;
34 8         42 my %par = @_;
35 8         20 my $self = {};
36 8         22 my $file = $par{File};
37              
38 8 50       35 if (ref $par{Group}) {
39 8         24 $self->{Group} = $par{Group};
40             } else {
41 0         0 $self->{Group} = [$par{Group}];
42             }
43 8 50       24 if ($file) {
44 8 50       35 if (isafh $file) {
45 0         0 $self->{Fh} = $file;
46             } else {
47 8         88 *S = $self->{Fh} = "${type}::".++$nextfh;
48 8 50       39 if ($file =~ /\.gz$/) {
49 0 0       0 open(S, "gzip -cd $file|")
50             or die "Could not open $file: $!\n";
51             } else {
52 8 50       631 open(S, "$file")
53             or die "Could not open $file: $!\n";
54             }
55              
56             }
57             } else {
58 0         0 $self->{Fh} = *ARGV;
59             }
60 8   33     51 bless $self, $type || ref($type);
61 8         72 $self->readfile;
62 0 0       0 close S if $self->{File};
63 0         0 $self;
64             }
65              
66 0     0 0 0 sub norm { $_[2]; } # dummy
67              
68             sub group {
69 0     0 0 0 my ($self, $group) = @_;
70              
71 0 0       0 if (ref($group)) {
72 0         0 join $;, @{$group};
  0         0  
73             } else {
74 0         0 $group;
75             }
76             }
77              
78             sub key {
79 0     0 0 0 my ($self, $group, $rec) = @_;
80 0         0 my $key = '';
81              
82 0 0       0 if (ref($group)) {
83 0         0 $key = join $;, map($self->norm($_, $rec->{$_}), @{$group});
  0         0  
84             } else {
85 0         0 $key = $self->norm($group, $rec->{$group});
86             }
87 0         0 $key;
88             }
89              
90             sub readfile {
91 8     8 0 364 my $self = shift;
92 8         59 my $fh = $self->{Fh};
93 8         18 my @group = @{$self->{Group}};
  8         32  
94 8         13 my $group;
95              
96 8         265 while (!eof($fh)) {
97 8         61 my $rec = $self->next;
98 0 0       0 last unless $rec;
99 0         0 for $group (@group) {
100 0         0 my $gname = $self->group($group);
101 0         0 my $key = $self->key($group, $rec);
102              
103 0 0       0 if (defined $self->{$gname}->{$key}) {
104 0         0 $self->{$gname}->{$key}->add($rec,$group); # !!
105             } else {
106 0         0 $self->{$gname}->{$key} = $rec->copy;
107             }
108             }
109             }
110             }
111              
112             sub report {
113 0     0 0 0 my $self = shift;
114 0         0 my %par = @_;
115 0         0 my $group = $self->group($par{Group});
116 0   0     0 my $sort = $par{Sort} || $group;
117 0   0     0 my $rever = (($sort =~ /Date|Hour/) xor $par{Reverse});
118 0         0 my $list = $par{List};
119 0         0 my ($keys, $key, $val, %keys);
120 0         0 my $mklen = length($group);
121 0 0       0 my $direction = ($rever)?'increasing':'decreasing';
122 0         0 my (@list, %absolute);
123 0         0 my @mklen = map(length($_), split($;, $group));
124              
125 0 0       0 croak "No index for $group\n" unless $self->{$group};
126              
127 0 0       0 if ($list) {
128 0 0       0 if (ref($list)) {
129 0         0 @list = @{$list};
  0         0  
130             } else {
131 0         0 @list = ($list);
132             }
133             } else {
134 0         0 @list = qw(Records);
135             }
136              
137 0         0 @absolute{@list} = (0) x @list;
138 0         0 $sort =~ s/$;.*//;
139             #print STDERR "sort = $sort\n";
140 0         0 while (($key,$val) = each %{$self->{$group}}) {
  0         0  
141 0         0 $keys{$key} = $val->{$sort};
142 0 0       0 if ($key =~ /$;/) {
143 0         0 my @key = split $;, $key;
144 0         0 for (0 .. $#key) {
145 0 0       0 $mklen[$_] = length($key[$_])
146             if length($key[$_]) > $mklen[$_];
147             }
148 0         0 $mklen = $#mklen;
149 0         0 grep ($mklen += $_, @mklen);
150             } else {
151 0 0       0 $mklen = length($key) if length($key) > $mklen;
152             }
153 0         0 for (@list) {
154 0 0       0 $absolute{$_} += $val->{$_} if defined $val->{$_};
155             }
156             }
157             # chop keys to $Logfile::MAXWIDTH chars maximum;
158 0 0       0 grep (($_=($_>$Logfile::MAXWIDTH)?$Logfile::MAXWIDTH:$_), @mklen);
159 0 0       0 if ($group =~ /$;/) {
160 0         0 my @key = split $;, $group;
161 0         0 for (0 .. $#key) {
162 0         0 printf "%-${mklen[$_]}s ", $key[$_];
163             }
164             } else {
165 0         0 printf ("%-${mklen}s ", $group);
166             }
167 0         0 for (@list) {
168 0         0 printf("%16s ", $_);
169             }
170 0         0 print "\n";
171 0         0 print '=' x ($mklen + (@list * 17));
172 0         0 print "\n";
173             #for $key (keys %keys) {
174             # print STDERR "** $key $keys{$key}\n";
175             #}
176 0         0 for $key (sort {&srt($rever, $keys{$a}, $keys{$b})}
  0         0  
177             keys %keys) {
178 0         0 my $val = $self->{$group}->{$key};
179 0 0       0 if ($key =~ /$;/) {
180 0         0 my @key = split $;, $key;
181 0         0 for (0 .. $#key) {
182 0         0 printf "%-${mklen[$_]}s ", substr($key[$_],0,$mklen[$_]);
183             }
184             } else {
185 0         0 printf "%-${mklen}s ", $key;
186             }
187 0         0 for $list (@list) {
188 0 0       0 my $ba = (defined $val->{$list})?$val->{$list}:0;
189 0 0       0 if ($absolute{$list} > 0) {
190 0         0 my $br = $ba/$absolute{$list}*100;
191 0         0 printf "%9d%6.2f%% ", $ba, $br;
192             } else {
193 0         0 printf "%15s ", $ba;
194             }
195             }
196 0         0 print "\n";
197 0 0 0     0 last if defined $par{Top} && --$par{Top} <= 0;
198             }
199 0         0 print "\f";
200             }
201              
202             sub srt {
203 0     0 0 0 my $rev = shift;
204 0         0 my ($y,$x);
205 0 0       0 if ($rev) {
206 0         0 ($x,$y) = @_;
207             } else {
208 0         0 ($y,$x) = @_;
209             }
210              
211 0 0 0     0 if ($x =~ /[^\d.]|^$/o or $y =~ /[^\d.]|^$/o) {
212 0         0 lc $y cmp lc $x;
213             } else {
214 0         0 $x <=> $y;
215             }
216             }
217              
218             sub keys {
219 0     0 0 0 my $self = shift;
220 0         0 my $group = shift;
221              
222 0         0 keys %{$self->{$group}};
  0         0  
223             }
224              
225             sub all {
226 0     0 0 0 my $self = shift;
227 0         0 my $group = shift;
228              
229 0         0 %{$self->{$group}};
  0         0  
230             }
231              
232             package Logfile::Base::Record;
233              
234             BEGIN {
235 8     8   36 eval {require GetDate;};
  8         3686  
236 8 50       66 $HaveGetDate = ($@ eq "") and import GetDate 'getdate';
237 8 50       38 unless ($HaveGetDate) {
238 8         16 eval {require Date::GetDate};
  8         3155  
239 8 50       65 $HaveDateGetDate = ($@ eq "") and import GetDate 'getdate';
240 8 50       26 unless ($HaveDateGetDate) {
241 8         14 eval {
242 8         3389 require Time::ParseDate;
243 0     0   0 sub parsedate { &Time::ParseDate::parsedate(@_) }
244             };
245 8         570 $HaveParseDate = ($@ eq "");
246             }
247             }
248             };
249              
250             unless ($HaveGetDate or $HaveDateGetDate
251             or $HaveParseDate) {
252 8     8   8465 eval join '', ;
  8         17869  
  8         5057  
253             }
254              
255 8     8   7148 use Net::Country;
  8         22  
  8         6213  
256              
257             sub new {
258 8     8   22 my $type = shift;
259 8         53 my %par = @_;
260 8         14 my $self = {};
261 8         15 my ($sec,$min,$hours,$mday,$mon,$year, $time);
262              
263 8         32 %{$self} = %par;
  8         30  
264              
265 8 50       51 if ($par{Date}) {
266             #print "$par{Date} => ";
267 8 50       63 if ($HaveGetDate) {
    50          
    50          
268 0         0 $par{Date} =~ s!(\d\d\d\d):!$1 !o;
269 0         0 $par{Date} =~ s!/! !go;
270 0         0 $time = getdate($par{Date});
271             } elsif ($HaveDateGetDate) {
272 0         0 $par{Date} =~ s!(\d\d\d\d):!$1 !o;
273 0         0 $par{Date} =~ s!/! !go;
274 0         0 $time = Date::GetDate::getdate($par{Date});
275             } elsif ($HaveParseDate) {
276              
277 0         0 $time = parsedate($par{Date},
278             FUZZY => 1,
279             NO_RELATIVE => 1);
280             } else {
281 8         2567 $time = &Time::String::to_time($par{Date});
282             }
283 0           ($sec,$min,$hours,$mday,$mon,$year) = localtime($time);
284             #print "$par{Date} => (s>$sec,m>$min,h>$hours,m>$mday,m>$mon,y>$year)\n";
285 0   0       $self->{Hour} = sprintf "%02d", $self->{Hour}||$hours;
286 0           $self->{Date} = sprintf("%02d%02d%02d", $year%100, $mon+1, $mday);
287             }
288 0 0         if ($par{Host}) {
289 0           my $host = $self->{Host} = lc($par{Host});
290 0 0         if ($host =~ /[^\d.]/) {
291 0 0         if ($host =~ /\./) {
292 0           $self->{Domain} = Net::Country::Name((split /\./, $host)[-1]);
293             } else {
294 0           $self->{Domain} = 'Local';
295             }
296             } else {
297 0           $self->{Domain} = 'Unresolved';
298             }
299             }
300 0           $self->{Records} = 1;
301              
302 0           bless $self, $type;
303             }
304              
305             sub add {
306 0     0     my $self = shift;
307 0           my $other = shift;
308 0           my $ignore = shift;
309              
310 0           for (keys %{$other}) {
  0            
311 0 0         next if $_ eq $ignore;
312 0 0         next unless defined $other->{$_};
313 0 0         next unless length($other->{$_});
314 0 0         next if $other->{$_} =~ /\D/;
315 0           $self->{$_} += $other->{$_};
316             }
317              
318 0           $self;
319             }
320              
321             sub copy {
322 0     0     my $self = shift;
323 0           my %new = %{$self};
  0            
324              
325 0           bless \%new, ref($self);
326             }
327              
328 0     0     sub requests {$_[0]->{Records};}
329              
330             1;
331              
332             __DATA__