File Coverage

blib/lib/Fsdb/Filter/combined_log_format_to_db.pm
Criterion Covered Total %
statement 15 49 30.6
branch 0 2 0.0
condition n/a
subroutine 5 14 35.7
pod 5 5 100.0
total 25 70 35.7


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             #
4             # combined_log_format_to_db.pm
5             # Copyright (C) 2008 by John Heidemann
6             # $Id: 4124e62011ce3c8d253dfdaef66ec91961cb0010 $
7             #
8             # This program is distributed under terms of the GNU general
9             # public license, version 2. See the file COPYING
10             # in $dblib for details.
11             #
12              
13             package Fsdb::Filter::combined_log_format_to_db;
14              
15             =head1 NAME
16              
17             combined_log_format_to_db - convert Apache Combined Log Format to Fsdb
18              
19             =head1 SYNOPSIS
20              
21             combined_log_format_to_db < access_log > access_log.fsdb
22              
23             =head1 DESCRIPTION
24              
25             Converts logs in Apache Combined-Log-Format into Fsdb format.
26              
27              
28             =head1 OPTIONS
29              
30             No program-specific options.
31              
32             =for comment
33             begin_standard_fsdb_options
34              
35             This module also supports the standard fsdb options:
36              
37             =over 4
38              
39             =item B<-d>
40              
41             Enable debugging output.
42              
43             =item B<-i> or B<--input> InputSource
44              
45             Read from InputSource, typically a file name, or C<-> for standard input,
46             or (if in Perl) a IO::Handle, Fsdb::IO or Fsdb::BoundedQueue objects.
47              
48             =item B<-o> or B<--output> OutputDestination
49              
50             Write to OutputDestination, typically a file name, or C<-> for standard output,
51             or (if in Perl) a IO::Handle, Fsdb::IO or Fsdb::BoundedQueue objects.
52              
53             =item B<--autorun> or B<--noautorun>
54              
55             By default, programs process automatically,
56             but Fsdb::Filter objects in Perl do not run until you invoke
57             the run() method.
58             The C<--(no)autorun> option controls that behavior within Perl.
59              
60             =item B<--help>
61              
62             Show help.
63              
64             =item B<--man>
65              
66             Show full manual.
67              
68             =back
69              
70             =for comment
71             end_standard_fsdb_options
72              
73              
74             =head1 SAMPLE USAGE
75              
76             =head2 Input:
77              
78             foo.example.com - - [01/Jan/2007:00:00:01 -0800] "GET /~moll/wedding/index.html HTTP/1.0" 200 2390 "-" "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)"
79             127.0.0.1 - - [01/Jan/2007:00:00:02 -0800] "GET /hpdc2007/ HTTP/1.1" 304 - "http://grid.hust.edu.cn:8080/call/cfp.jsp" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1; InfoPath.2)"
80             bar.example.com - - [31/Dec/2006:23:51:40 -0800] "GET /nsnam/dist/ns-allinone-2.29.2.tar.gz HTTP/1.1" 206 58394090 "file://D:\\\xce\xd2\xb5\xc4\xce\xc4\xb5\xb5\\ns2\\XP_Using_Cygwin.htm#Windows_Support_for_Ns-2.27_and_Earlier" "Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)"
81             127.0.0.1 - - [01/Jan/2007:00:00:02 -0800] "GET /hpdc2007/hpdc.css HTTP/1.1" 304 - "http://www.isi.edu/hpdc2007/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1; InfoPath.2)"
82              
83             =head2 Command:
84              
85             combined_log_format_to_db
86              
87             =head2 Output:
88              
89             #fsdb -F S client identity userid time method resource protocol status size refer useragent
90             foo.example.com - - [01/Jan/2007:00:00:01 -0800] GET /~moll/wedding/index.html HTTP/1.0 200 2390 "-" "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)"
91             127.0.0.1 - - [01/Jan/2007:00:00:02 -0800] GET /hpdc2007/ HTTP/1.1 304 - "http://grid.hust.edu.cn:8080/call/cfp.jsp" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1; InfoPath.2)"
92             bar.example.com - - [31/Dec/2006:23:51:40 -0800] GET /nsnam/dist/ns-allinone-2.29.2.tar.gz HTTP/1.1 206 58394090 "file://D:\\\xce\xd2\xb5\xc4\xce\xc4\xb5\xb5\\ns2\\XP_Using_Cygwin.htm#Windows_Support_for_Ns-2.27_and_Earlier" "Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)"
93             127.0.0.1 - - [01/Jan/2007:00:00:02 -0800] GET /hpdc2007/hpdc.css HTTP/1.1 304 - "http://www.isi.edu/hpdc2007/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1; InfoPath.2)"
94             # | combined_log_format_to_db
95              
96             =head1 SEE ALSO
97              
98             L.
99             L
100              
101              
102             =head1 CLASS FUNCTIONS
103              
104             =cut
105              
106             @ISA = qw(Fsdb::Filter);
107             $VERSION = 2.0;
108              
109 1     1   3451 use strict;
  1         3  
  1         27  
110 1     1   5 use Pod::Usage;
  1         1  
  1         69  
111 1     1   6 use Carp;
  1         2  
  1         41  
112              
113 1     1   5 use Fsdb::Filter;
  1         1  
  1         15  
114 1     1   4 use Fsdb::IO::Writer;
  1         2  
  1         446  
115              
116              
117             =head2 new
118              
119             $filter = new Fsdb::Filter::combined_log_format_to_db(@arguments);
120              
121             Create a new combined_log_format_to_db object, taking command-line arguments.
122              
123             =cut
124              
125             sub new ($@) {
126 0     0 1   my $class = shift @_;
127 0           my $self = $class->SUPER::new(@_);
128 0           bless $self, $class;
129 0           $self->set_defaults;
130 0           $self->parse_options(@_);
131 0           $self->SUPER::post_new();
132 0           return $self;
133             }
134              
135              
136             =head2 set_defaults
137              
138             $filter->set_defaults();
139              
140             Internal: set up defaults.
141              
142             =cut
143              
144             sub set_defaults ($) {
145 0     0 1   my($self) = @_;
146 0           $self->SUPER::set_defaults();
147             }
148              
149             =head2 parse_options
150              
151             $filter->parse_options(@ARGV);
152              
153             Internal: parse command-line arguments.
154              
155             =cut
156              
157             sub parse_options ($@) {
158 0     0 1   my $self = shift @_;
159              
160 0           my(@argv) = @_;
161             $self->get_options(
162             \@argv,
163 0     0     'help|?' => sub { pod2usage(1); },
164 0     0     'man' => sub { pod2usage(-verbose => 2); },
165             'autorun!' => \$self->{_autorun},
166             'close!' => \$self->{_close},
167             'd|debug+' => \$self->{_debug},
168 0     0     'i|input=s' => sub { $self->parse_io_option('input', @_); },
169             'log!' => \$self->{_logprog},
170 0     0     'o|output=s' => sub { $self->parse_io_option('output', @_); },
171 0 0         ) or pod2usage(2);
172 0           push (@{$self->{_argv}}, @argv);
  0            
173             }
174              
175             =head2 setup
176              
177             $filter->setup();
178              
179             Internal: setup, parse headers.
180              
181             =cut
182              
183             sub setup ($) {
184 0     0 1   my($self) = @_;
185              
186 0           $self->finish_fh_io_option('input');
187              
188 0           $self->finish_io_option('output', -fscode => 'S',
189             -cols => [qw(client identity userid time method resource protocol status size refer useragent)]);
190             }
191              
192             =head2 run
193              
194             $filter->run();
195              
196             Internal: run over each rows.
197              
198             =cut
199             sub run ($) {
200 0     0 1   my($self) = @_;
201 0           my $write_fastpath_sub = $self->{_out}->fastpath_sub();
202 0           my @f;
203             my @s;
204 0           my ($CLIENT, $IDENTITY, $USERID, $TIMESTART, $TIMEZONE, $METHOD, $RESOURCE, $PROTOCOL, $STATUS, $SIZE, $REFER, $USERAGENT0) = (0..20);
205 0           my $in_fh = $self->{_in};
206              
207 0           my $line;
208 0           while (defined($line = $in_fh->getline)) {
209 0           @s = split(' ', $line);
210 0           $s[$METHOD] =~ s/^"//;
211 0           $s[$PROTOCOL] =~ s/"$//; # protocol has trailing "
212 0           my $ua = join(" ", @s[$USERAGENT0 .. $#s]); # UA is all that's left
213 0           @f = ($s[$CLIENT], $s[$IDENTITY], $s[$USERID], $s[$TIMESTART] . " " . $s[$TIMEZONE], $s[$METHOD], $s[$RESOURCE], $s[$PROTOCOL], $s[$STATUS], $s[$SIZE], $s[$REFER], $ua);
214 0           &$write_fastpath_sub(\@f);
215             };
216             }
217              
218             =head1 AUTHOR and COPYRIGHT
219              
220             Copyright (C) 2008 by John Heidemann
221              
222             This program is distributed under terms of the GNU general
223             public license, version 2. See the file COPYING
224             with the distribution for details.
225              
226             =cut
227              
228             1;