File Coverage

blib/lib/Log/Dispatch/File/Rolling.pm
Criterion Covered Total %
statement 78 90 86.6
branch 11 16 68.7
condition 6 14 42.8
subroutine 14 14 100.0
pod 2 2 100.0
total 111 136 81.6


line stmt bran cond sub pod time code
1             ## no critic
2             package Log::Dispatch::File::Rolling;
3            
4 7     7   216211 use 5.006001;
  7         30  
  7         279  
5 7     7   41 use strict;
  7         13  
  7         221  
6 7     7   36 use warnings;
  7         16  
  7         214  
7            
8 7     7   7413 use Log::Dispatch::File '2.37';
  7         49970  
  7         312  
9 7     7   7819 use Log::Log4perl::DateFormat;
  7         23536  
  7         845  
10 7     7   56 use Fcntl ':flock'; # import LOCK_* constants
  7         14  
  7         3609  
11            
12             our @ISA = qw(Log::Dispatch::File);
13            
14             our $VERSION = '1.09';
15            
16             our $TIME_HIRES_AVAILABLE = undef;
17            
18             BEGIN { # borrowed from Log::Log4perl::Layout::PatternLayout, Thanks!
19             # Check if we've got Time::HiRes. If not, don't make a big fuss,
20             # just set a flag so we know later on that we can't have fine-grained
21             # time stamps
22            
23 7     7   16 eval { require Time::HiRes; };
  7         8377  
24 7 50       16014 if ($@) {
25 0         0 $TIME_HIRES_AVAILABLE = 0;
26             } else {
27 7         11673 $TIME_HIRES_AVAILABLE = 1;
28             }
29             }
30            
31             # Preloaded methods go here.
32            
33             sub new {
34 4     4 1 1889 my $proto = shift;
35 4   33     30 my $class = ref $proto || $proto;
36            
37 4         14 my %p = @_;
38            
39 4         15 my $self = bless {}, $class;
40            
41             # only append mode is supported
42 4         14 $p{mode} = 'append';
43            
44             # base class initialization
45 4         45 $self->_basic_init(%p);
46            
47             # split pathname into path, basename, extension
48 4 100       890 if ($p{filename} =~ /^(.*)\%d\{([^\}]*)\}(.*)$/) {
    100          
49 1         5 $self->{rolling_filename_prefix} = $1;
50 1         3 $self->{rolling_filename_postfix} = $3;
51 1         10 $self->{rolling_filename_format} = Log::Log4perl::DateFormat->new($2);
52 1         40 $self->{filename} = $self->_createFilename();
53             } elsif ($p{filename} =~ /^(.*)(\.[^\.]+)$/) {
54 2         11 $self->{rolling_filename_prefix} = $1;
55 2         9 $self->{rolling_filename_postfix} = $2;
56 2         20 $self->{rolling_filename_format} = Log::Log4perl::DateFormat->new('-yyyy-MM-dd');
57 2         1786 $self->{filename} = $self->_createFilename();
58             } else {
59 1         4 $self->{rolling_filename_prefix} = $p{filename};
60 1         2 $self->{rolling_filename_postfix} = '';
61 1         8 $self->{rolling_filename_format} = Log::Log4perl::DateFormat->new('.yyyy-MM-dd');
62 1         259 $self->{filename} = $self->_createFilename();
63             }
64            
65 4         183 $self->{rolling_fh_pid} = $$;
66 4         56 $self->_make_handle();
67            
68 4         4590 return $self;
69             }
70            
71             sub log_message { # parts borrowed from Log::Dispatch::FileRotate, Thanks!
72 5     5 1 2282 my $self = shift;
73 5         18 my %p = @_;
74            
75 5         19 my $filename = $self->_createFilename();
76 5 50       31 if ($filename ne $self->{filename}) {
77 0         0 $self->{filename} = $filename;
78 0         0 $self->{rolling_fh_pid} = 'x'; # force reopen
79             }
80            
81 5 50 50     173 if ( $self->{close} ) {
    100 33        
      66        
82 0         0 $self->_open_file;
83 0         0 $self->_lock();
84 0         0 my $fh = $self->{fh};
85 0         0 print $fh $p{message};
86 0         0 $self->_unlock();
87 0         0 close($fh);
88 0         0 $self->{fh} = undef;
89             } elsif (defined $self->{fh} and ($self->{rolling_fh_pid}||'') eq $$ and defined fileno $self->{fh}) { # flock won't work after a fork()
90 4         73 my $inode = (stat($self->{fh}))[1]; # get real inode
91 4         54 my $finode = (stat($self->{filename}))[1]; # Stat the name for comparision
92 4 50 33     36 if(!defined($finode) || $inode != $finode) { # Oops someone moved things on us. So just reopen our log
93 0         0 $self->_open_file;
94             }
95 4         18 $self->_lock();
96 4         9 my $fh = $self->{fh};
97 4         248 print $fh $p{message};
98 4         19 $self->_unlock();
99             } else {
100 1         3 $self->{rolling_fh_pid} = $$;
101 1         5 $self->_open_file;
102 1         58 $self->_lock();
103 1         2 my $fh = $self->{fh};
104 1         37 print $fh $p{message};
105 1         5 $self->_unlock();
106             }
107             }
108            
109             sub _lock { # borrowed from Log::Dispatch::FileRotate, Thanks!
110 5     5   35 my $self = shift;
111 5         160 flock($self->{fh},LOCK_EX);
112             # Make sure we are at the EOF
113 5         36 seek($self->{fh}, 0, 2);
114 5         11 return 1;
115             }
116            
117             sub _unlock { # borrowed from Log::Dispatch::FileRotate, Thanks!
118 5     5   33 my $self = shift;
119 5         36 flock($self->{fh},LOCK_UN);
120 5         46 return 1;
121             }
122            
123             sub _current_time { # borrowed from Log::Log4perl::Layout::PatternLayout, Thanks!
124             # Return secs and optionally msecs if we have Time::HiRes
125 9 50   9   27 if($TIME_HIRES_AVAILABLE) {
126 0         0 return (Time::HiRes::gettimeofday());
127             } else {
128 9         50 return (time(), 0);
129             }
130             }
131            
132             sub _createFilename {
133 9     9   19 my $self = shift;
134 9         35 return $self->{rolling_filename_prefix}
135             . $self->_format()
136             . $self->{rolling_filename_postfix};
137             }
138            
139             sub _format {
140 9     9   13 my $self = shift;
141 9         33 my $result = $self->{rolling_filename_format}->format($self->_current_time());
142 9         599 $result =~ s/(\$+)/sprintf('%0'.length($1).'.'.length($1).'u', $$)/eg;
  2         24  
143 9         41 return $result;
144             }
145            
146             1;
147             __END__