File Coverage

blib/lib/Log/Dispatch/File/Alerts.pm
Criterion Covered Total %
statement 81 84 96.4
branch 9 12 75.0
condition 4 9 44.4
subroutine 14 14 100.0
pod 2 2 100.0
total 110 121 90.9


line stmt bran cond sub pod time code
1             ## no critic
2             package Log::Dispatch::File::Alerts;
3            
4 6     6   149839 use 5.006001;
  6         26  
  6         285  
5 6     6   39 use strict;
  6         9  
  6         240  
6 6     6   34 use warnings;
  6         13  
  6         180  
7            
8 6     6   20643 use Log::Dispatch::File '2.37';
  6         52100  
  6         169  
9 6     6   8280 use Log::Log4perl::DateFormat;
  6         11222  
  6         202  
10 6     6   47 use Fcntl ':flock'; # import LOCK_* constants
  6         10  
  6         2332  
11            
12             our @ISA = qw(Log::Dispatch::File);
13            
14             our $VERSION = '1.04';
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 6     6   12 eval { require Time::HiRes; };
  6         11393  
24 6 50       12689 if ($@) {
25 0         0 $TIME_HIRES_AVAILABLE = 0;
26             } else {
27 6         5458 $TIME_HIRES_AVAILABLE = 1;
28             }
29             }
30            
31             # Preloaded methods go here.
32            
33             sub new {
34 4     4 1 3633 my $proto = shift;
35 4   33     32 my $class = ref $proto || $proto;
36            
37 4         15 my %p = @_;
38            
39 4         14 my $self = bless {}, $class;
40            
41             # only append mode is supported
42 4         11 $p{mode} = 'append';
43             # 'close' mode is always used
44 4         9 $p{close_after_write} = 1;
45            
46             # base class initialization
47 4         45 $self->_basic_init(%p);
48            
49             # split pathname into path, basename, extension
50 4 100       958 if ($p{filename} =~ /^(.*)\%d\{([^\}]*)\}(.*)$/) {
    100          
51 2         9 $self->{rolling_filename_prefix} = $1;
52 2         7 $self->{rolling_filename_postfix} = $3;
53 2         18 $self->{rolling_filename_format} = Log::Log4perl::DateFormat->new($2);
54 2         79 $self->{filename} = $self->_createFilename(0);
55             } elsif ($p{filename} =~ /^(.*)(\.[^\.]+)$/) {
56 1         3 $self->{rolling_filename_prefix} = $1;
57 1         3 $self->{rolling_filename_postfix} = $2;
58 1         8 $self->{rolling_filename_format} = Log::Log4perl::DateFormat->new('-yyyy-MM-dd-$!');
59 1         185 $self->{filename} = $self->_createFilename(0);
60             } else {
61 1         4 $self->{rolling_filename_prefix} = $p{filename};
62 1         3 $self->{rolling_filename_postfix} = '';
63 1         11 $self->{rolling_filename_format} = Log::Log4perl::DateFormat->new('.yyyy-MM-dd-$!');
64 1         227 $self->{filename} = $self->_createFilename(0);
65             }
66            
67 4         38 $self->_make_handle();
68            
69 4         32 return $self;
70             }
71            
72             sub log_message { # parts borrowed from Log::Dispatch::FileRotate, Thanks!
73 5     5 1 2871 my $self = shift;
74 5         17 my %p = @_;
75 5         12 my $try = 1;
76 5         13 my $firstfilename = $self->_createFilename(0); # if this is generated, we are done
77            
78 5         22 while (defined $try) {
79 6         51 $self->{filename} = $self->_createFilename($try);
80            
81 6 50 66     107 if (($try > 1 and $firstfilename eq $self->{filename}) or $try < 1) { # later checks for integer overflow
      33        
82 0         0 die 'could not find an unused file for filename "'
83             . $self->{filename}
84             . '". Did you use "!"?';
85             }
86            
87 6         39 $self->_open_file;
88 6         796 $self->_lock();
89 6         10 my $fh = $self->{fh};
90 6 100       58 if (not -s $fh) {
91             # if the file is zero-sized, it is fresh.
92             # else someone else already used it.
93 5         245 print $fh $p{message};
94 5         10 $try = undef;
95             } else {
96 1         2 $try++;
97             }
98 6         17 $self->_unlock();
99 6         59 close($fh);
100 6         56 $self->{fh} = undef;
101             }
102             }
103            
104             sub _lock { # borrowed from Log::Dispatch::FileRotate, Thanks!
105 6     6   8 my $self = shift;
106 6         43 flock($self->{fh},LOCK_EX);
107             # Make sure we are at the EOF
108 6         33 seek($self->{fh}, 0, 2);
109 6         9 return 1;
110             }
111            
112             sub _unlock { # borrowed from Log::Dispatch::FileRotate, Thanks!
113 6     6   8 my $self = shift;
114 6         31 flock($self->{fh},LOCK_UN);
115 6         13 return 1;
116             }
117            
118             sub _current_time { # borrowed from Log::Log4perl::Layout::PatternLayout, Thanks!
119             # Return secs and optionally msecs if we have Time::HiRes
120 15 50   15   32 if($TIME_HIRES_AVAILABLE) {
121 0         0 return (Time::HiRes::gettimeofday());
122             } else {
123 15         69 return (time(), 0);
124             }
125             }
126            
127             sub _createFilename {
128 15     15   24 my $self = shift;
129 15         18 my $try = shift;
130 15         49 return $self->{rolling_filename_prefix}
131             . $self->_format($try)
132             . $self->{rolling_filename_postfix};
133             }
134            
135             sub _format {
136 15     15   20 my $self = shift;
137 15         23 my $try = shift;
138 15         43 my $result = $self->{rolling_filename_format}->format($self->_current_time());
139 15         846 $result =~ s/(\$+)/sprintf('%0'.length($1).'.'.length($1).'u', $$)/eg;
  9         79  
140 15         55 $result =~ s/(\!+)/sprintf('%0'.length($1).'.'.length($1).'u', substr($try, -length($1)))/eg;
  12         77  
141 15         73 return $result;
142             }
143            
144             1;
145             __END__