File Coverage

blib/lib/Log/Delimited.pm
Criterion Covered Total %
statement 104 123 84.5
branch 33 74 44.5
condition 13 39 33.3
subroutine 15 18 83.3
pod 0 12 0.0
total 165 266 62.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             package Log::Delimited;
4              
5 2     2   17981 use strict;
  2         5  
  2         83  
6 2     2   11 use vars qw(@EXPORT @EXPORT_OK @ISA $LOG_BASE_DIR $VERSION);
  2         3  
  2         207  
7              
8 2     2   10 use Exporter;
  2         6  
  2         159  
9             @ISA = ('Exporter');
10             @EXPORT = qw(log);
11             @EXPORT_OK = qw($LOG_BASE_DIR);
12              
13 2     2   11 use File::Path qw(mkpath);
  2         4  
  2         152  
14 2     2   2124 use Storable qw(freeze);
  2         10346  
  2         178  
15 2     2   1831 use Sys::Hostname qw(hostname);
  2         2974  
  2         6357  
16              
17             $LOG_BASE_DIR = "/tmp/logs";
18             $VERSION = '0.90';
19              
20             sub O_RDWR () { 2 }
21             sub O_CREAT () { 64 }
22              
23              
24             sub new {
25 1     1 0 210 my $type = shift;
26 1 50       5 my @PASSED_ARGS = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
  1         7  
27 1         9 my @DEFAULT_ARGS = (
28             base_dir => $LOG_BASE_DIR,
29              
30             delimiter => '|',
31             log_cols => '',
32              
33             # log_info is an array ref of the info you would like to log
34             log_info => '',
35             log_name => '',
36             log_node => 'main',
37              
38             no_hostname => 0,
39             no_pid => 0,
40             no_time => 0,
41             );
42 1         10 my %ARGS = (@DEFAULT_ARGS, @PASSED_ARGS);
43 1         2 foreach(qw(log_node log_name)) {
44 2 50       8 unless($ARGS{$_}) {
45 0   0     0 ($ARGS{$_}) = ($0 =~ m@.*/(.+)@) || $0;
46             }
47             }
48 1         4 my $self = bless \%ARGS, $type;
49 1 50       12 die "need a \$self->{log_name}" unless($self->{log_name});
50 1         6 $self->handle_dirs;
51 1         5 $self->mkpath_dirs;
52 1         6 return $self;
53             }
54              
55             sub URLEncode {
56 12     12 0 11 my $arg = shift;
57 12 50       142 my ($ref,$return) = ref($arg) ? ($arg,0) : (\$arg,1) ;
58              
59 12         66 $$ref =~ s/([^\w\.\ -])/sprintf("%%%02X",ord($1))/eg;
  10         41  
60 12         18 $$ref =~ tr/\ /+/;
61              
62 12 50       28 return $return ? $$ref : '';
63             }
64              
65             sub handle_dirs {
66 1     1 0 2 my $self = shift;
67 1 50       7 return if($self->{handled_dirs});
68 1 50       4 die "need a \$self->{base_dir}" unless($self->{base_dir});
69 1 50       9 die "need a \$self->{log_name}" unless($self->{log_name});
70 1   33     12 $self->{log_dir} ||= "$self->{base_dir}/$self->{log_node}";
71 1   33     9 $self->{log_filename} ||= "$self->{log_dir}/$self->{log_name}";
72 1   33     7 $self->{zip_filename} ||= "$self->{log_dir}/$self->{log_name}.gz";
73 1         3 $self->{handled_dirs} = 1;
74             }
75              
76             sub mkpath_dirs {
77 1     1 0 3 my $self = shift;
78 1 50       4 return if($self->{mkpathd});
79 1         2 foreach(keys %{$self}) {
  1         4  
80 13 100 66     52 next unless(/_dir$/ && $self->{$_} =~ m@^/@);
81 2 50       547 mkpath ($self->{$_}) unless(-d $self->{$_});
82 2 50       41 die "couldn't mkpath $self->{$_}" unless(-d $self->{$_});
83             }
84 1         5 $self->{mkpathd} = 1;
85             }
86              
87             sub handle_log_cols {
88 1     1 0 613 my $self = shift;
89 1 50 33     11 if(ref $self->{log_cols} eq 'ARRAY' && !$self->{cols_string}) {
90 1 50 33     10 unshift @{$self->{log_cols}}, 'hostname' unless($self->{unshifted_hostname} || $self->{no_hostname});
  1         12  
91 1 50 33     13 unshift @{$self->{log_cols}}, 'pid' unless($self->{unshifted_pid} || $self->{no_pid});
  1         3  
92 1 50 33     7 unshift @{$self->{log_cols}}, 'time' unless($self->{unshifted_time} || $self->{no_time});
  1         3  
93 1         7 $self->{cols_string} = join($self->{delimiter}, @{$self->{log_cols}});
  1         5  
94             } else {
95 0         0 $self->{cols_string} = $self->{log_cols};
96             }
97             }
98              
99             sub handle_log_info {
100 2     2 0 3 my $self = shift;
101 2         3 my $ref = shift;
102 2 50       4 die "\$self->{log_info} is required" unless($ref);
103 2 50 33     12 die "\$self->{log_info} needs to be an array ref" unless(ref $ref && ref $ref eq 'ARRAY');
104 2 50       6 unshift @{$ref}, hostname unless($self->{no_hostname});
  2         9  
105 2 50       23 unshift @{$ref}, $$ unless($self->{no_pid});
  2         15  
106 2 50       5 unshift @{$ref}, time unless($self->{no_time});
  2         5  
107             }
108              
109             sub ref2string {
110 2     2 0 3 my $self = shift;
111 2         2 my $ref = shift;
112 2 50 33     26 unless(ref $ref && ref $ref eq 'ARRAY') {
113 0         0 $ref = [$ref];
114             }
115 2         3 my @this_array = @{$ref};
  2         94  
116 2         5 foreach(@this_array) {
117 12 50 33     369 $_ = '' unless((defined $_) && length $_);
118 12 50 33     24 if(ref $_ && ref $_ eq 'HASH') {
119 0         0 $_ = freeze $_;
120             }
121 12 50       145 URLEncode \$_ unless($self->{no_URLEncode});
122             }
123 2         7 my $string = join($self->{delimiter}, @this_array);
124 2         7 return $string;
125             }
126              
127             sub log {
128 2     2 0 133 my $self = shift;
129 2 50       7 die "need a " . __PACKAGE__ . " object" unless(ref $self eq __PACKAGE__);
130              
131 2 50       253 open(LOG, ">>$self->{log_filename}") || die "couldn't opendir $self->{log_filename}: $!";
132 2 100       44 if(!-s $self->{log_filename}) {
133 1 50       5 if($self->{log_cols}) {
134 1         5 $self->handle_log_cols;
135 1         15 print LOG "$self->{cols_string}\n";
136             }
137             }
138              
139 2 50       8 unless(ref $self->{log_info}[0] eq 'ARRAY') {
140 2         5 $self->{log_info} = [$self->{log_info}];
141             }
142              
143 2         4 for(my $i=0;$i<@{$self->{log_info}};$i++) {
  4         12  
144 2         3 my (@this_array) = @{$self->{log_info}[$i]};
  2         6  
145 2         8 $self->handle_log_info(\@this_array);
146 2         5 my $this_string = $self->ref2string(\@this_array);
147 2         850 print LOG "$this_string\n";
148             }
149 2         161 close(LOG);
150 2         12 delete $self->{log_info};
151             }
152              
153             sub wipe {
154 1     1 0 79 my $self = shift;
155 1 50       21 if(-e $self->{log_filename}) {
156 1         122 return unlink $self->{log_filename};
157             }
158             }
159              
160             sub zip {
161 0     0 0   my $self = shift;
162 0 0         die "need a \$self->{log_filename}" unless($self->{log_filename});
163 0 0         die "need a \$self->{zip_filename}" unless($self->{zip_filename});
164 0 0         return unless(-s $self->{log_filename});
165 0           system("gzip -c < $self->{log_filename} > $self->{zip_filename}");
166             }
167              
168             sub unzip {
169 0     0 0   my $self = shift;
170 0 0         die "need a \$self->{log_filename}" unless($self->{log_filename});
171 0 0         die "need a \$self->{zip_filename}" unless($self->{zip_filename});
172 0 0         return unless(-s $self->{zip_filename});
173 0           system("gzip -dc < $self->{zip_filename} > $self->{log_filename}");
174             }
175              
176             sub log_zipped {
177 0     0 0   my $self = shift;
178 0           $self->unzip;
179 0           $self->log;
180 0           $self->zip;
181 0           $self->wipe;
182             }
183              
184             1;
185              
186             __END__