File Coverage

CGI/AppBuilder/Log.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package CGI::AppBuilder::Log;
2              
3 1     1   25086 use warnings;
  1         3  
  1         33  
4 1     1   5 use Carp;
  1         2  
  1         91  
5 1     1   962 use IO::File;
  1         12092  
  1         178  
6 1     1   1147 use POSIX qw(strftime);
  1         7801  
  1         8  
7              
8 1     1   3800 use CGI::AppBuilder;
  0            
  0            
9              
10             # require Exporter;
11             @ISA = qw(Exporter CGI::AppBuilder);
12             our @EXPORT = qw();
13             our @EXPORT_OK = qw(start_log end_log
14             );
15             our %EXPORT_TAGS = (
16             all => [@EXPORT_OK],
17             log => [qw(start_log end_log)],
18             );
19             $CGI::AppBuilder::Log::VERSION = 0.12;
20              
21             =head1 NAME
22              
23             CGI::AppBuilder::Log - Gather and write log entries for CGI applications
24              
25             =head1 SYNOPSIS
26              
27             my $self = bless {}, "main";
28             use CGI::AppBuilder::Log /:log/;
29              
30             =head1 DESCRIPTION
31              
32             The package contains the methods for gathering and creating log file.
33              
34             =head3 new (ifn => 'file.cfg', opt => 'hvS:')
35              
36             This is a inherited method from CGI::AppBuilder. See the same method
37             in CGI::AppBuilder for more details.
38              
39             =cut
40              
41             sub new {
42             my ($s, %args) = @_;
43             return $s->SUPER::new(%args);
44             }
45              
46             =head2 start_log($dtl, $brf, $cns, $arg, $lvl)
47              
48             Input variables:
49              
50             $dtl - file name for detailed log
51             $brf - file name for brief log
52             $cns - a list of fields which are stored in brief log
53             $arg - command line arguments
54             $lvl - log levle
55             1 - default:start_time,end_time,elapsed_time,user,args,result
56             2 - 1 plus: remote_addr,http_user_agent,http_accept_language,
57             http_accept_charset
58              
59             Variables used or routines called:
60              
61             echoMSG - print debug messages
62              
63             How to use:
64              
65             use CGI::AppBuilder::Log qw(:log);
66             my $self= bless {}, "main";
67             my $ar = $self->start_log('details.log','brief.log',
68             'start_time,end_time,elapsed_time,file_tranferred,status');
69              
70             Return: a hash array containing the fields in $cns.
71              
72             This method creates log files if they do not exist and prepare a
73             hash array to store needed fields for end_log. The hash array has
74             the following elements:
75              
76             cns - a list of field names separated by commas
77             fld - a hash array containing the field defined in cns.
78             fn_brf - file name for brief log
79             fh_brf - file handler for brief log
80             fn_dtl - file name for detail log
81             fh_dtl - file handler for detail log
82              
83             If the I is not specifed, then it defaults to
84             start_time,end_time,elapsed_time,user,args,result.
85              
86             =cut
87              
88             sub start_log {
89             my $s = shift;
90             my ($dtl,$brf,$cns,$arg,$lvl) = @_;
91             my $ar = bless {}, ref($s);
92             return $ar if ! $dtl;
93              
94             $lvl = 1 if !$lvl;
95             $s->echoMSG(" -- start logging in $dtl...",1);
96             my ($cn1,$cn2) = ("","");
97             if (!$cns) {
98             $cn1='start_time,end_time,elapsed_time,user,args,result';
99             $cns = $cn1;
100             if ($lvl>1) {
101             $cn2 = "REMOTE_ADDR,HTTP_USER_AGENT,HTTP_ACCEPT_LANGUAGE,";
102             $cn2 .= "HTTP_ACCEPT_CHARSET";
103             }
104             }
105             foreach my $k (split /,/, $cns) {
106             $k = lc $k; ${$ar}{fld}{$k} = "";
107             }
108             if ($cn2) {
109             foreach my $k (split /,/, $cn2) {
110             my $i = lc $k;
111             ${$ar}{fld}{$i} = $ENV{$k} if exists $ENV{$k};
112             ${$ar}{fld}{$i} = "" if !exists $ENV{$k};
113             }
114             $cns .= lc ",$cn2";
115             }
116             $ar->{user} = ($^O =~ /(linux|solaris)/i) ? `/usr/ucb/whoami` : "";
117             $ar->{args} = (exists $ENV{QUERY_STRING})?
118             $ENV{QUERY_STRING}:$arg;
119             my ($tx1, $txt);
120             my $fh_dtl = new IO::File ">> $dtl";
121             croak "ERR: could not write to $dtl: $!\n" if !defined($fh_dtl);
122             ${$ar}{fld}{start_time} = time;
123             $ENV{FH_DEBUG_LOG} = $fh_dtl;
124             ${$ar}{cns} = $cns;
125             ${$ar}{fn_dtl} = $dtl;
126             ${$ar}{fh_dtl} = $fh_dtl;
127             my $stm = strftime "%a %b %e %H:%M:%S %Y",
128             localtime(${$ar}{fld}{start_time});
129             $tx1 = "# File Name: $dtl\n# Start at $stm\n";
130             print $fh_dtl $tx1;
131             return $ar if ! $brf;
132              
133             my ($pkg, $fn, $line, $subroutine, $hasargs, $wantarray,
134             $evaltext, $is_require, $hints, $bitmask) = caller(3);
135             $subroutine = 'start_log' if ! $subroutine;
136             $tx1 = "# File Name: $brf\n# Generated By: $subroutine\n";
137             $tx1 .= "# Fields: (elapsed times are in seconds)\n";
138             $cn1 = $cns; $cn1 =~ s/,/\|/g;
139             $tx1 .= "# $cn1\n";
140             $txt = $tx1 if ! -f $brf;
141             my $dbg = $s->debug;
142             $s->debug(1) if !$dbg; # we at least log message at level 1
143             my $fh_brf = new IO::File ">> $brf";
144             print $fh_brf "$txt" if $txt;
145             $ar->{fn_brf} = $brf;
146             $ar->{fh_brf} = $fh_brf;
147             return $ar;
148             }
149              
150             =head2 end_log($ar)
151              
152             Input variables:
153              
154             $ar - array ref returned from start_log. The elements can
155             be populated in before end_log.
156              
157             Variables used or routines called:
158              
159             strftime - time formater from POSIX
160             disp_param - display parameters
161              
162             How to use:
163              
164             use CGI::AppBuilder::Log qw(:log);
165             my $self= bless {}, "main";
166             my $ar = $self->start_log('details.log','brief.log');
167             $self->end_log($ar);
168              
169             Return: none.
170              
171             =cut
172              
173             sub end_log {
174             my $s = shift;
175             my ($ar) = @_;
176             $s->echoMSG(" -- end logging ...",1);
177             my %b = %{${$ar}{fld}};
178             # my $f = "%a %b %e %H:%M:%S %Y";
179             my $f = "%Y%m%d.%H%M%S";
180             my $fh1 = ${$ar}{fh_brf};
181             my $fh2 = ${$ar}{fh_dtl};
182             my $cns = ${$ar}{cns};
183             $b{end_time} = time;
184             $b{elapsed_time} = $b{end_time} - $b{start_time};
185             $b{start_time} = strftime $f, localtime($b{start_time});
186             $b{end_time} = strftime $f, localtime($b{end_time});
187             $b{result} = 'OK';
188            
189             my ($txt) = ("");
190             foreach my $k (split /,/, $cns) { $txt .= "$b{$k}|"; }
191             $txt =~ s/\|$//;
192              
193             $s->disp_param(\%b);
194             print $fh1 "$txt\n";
195             print $fh2 "# End at $b{end_time} $b{result}\n";
196             undef $fh1; # close breif file hanlder
197             undef $fh2; # close detail file handler
198             }
199              
200             1;
201              
202             =head1 CODING HISTORY
203              
204             =over 4
205              
206             =item * Version 0.10
207              
208             Extract start_log and end_log from Debug::EchoMessage.
209              
210             =item * Version 0.11
211              
212             =back
213              
214             =head1 FUTURE IMPLEMENTATION
215              
216             =over 4
217              
218             =item * no plan yet
219              
220             =back
221              
222             =head1 AUTHOR
223              
224             Copyright (c) 2004 Hanming Tu. All rights reserved.
225              
226             This package is free software and is provided "as is" without express
227             or implied warranty. It may be used, redistributed and/or modified
228             under the terms of the Perl Artistic License (see
229             http://www.perl.com/perl/misc/Artistic.html)
230              
231             =cut
232