File Coverage

lib/Badger/Log/File.pm
Criterion Covered Total %
statement 39 39 100.0
branch 7 10 70.0
condition 7 10 70.0
subroutine 11 11 100.0
pod 9 9 100.0
total 73 79 92.4


line stmt bran cond sub pod time code
1             #========================================================================
2             #
3             # Badger::Log::File
4             #
5             # DESCRIPTION
6             # Subclass of Badger::Log for logging messages to a file.
7             #
8             # AUTHOR
9             # Andy Wardley
10             #
11             #========================================================================
12              
13             package Badger::Log::File;
14              
15             use Badger::Class
16 1         8 version => 0.02,
17             base => 'Badger::Log',
18             filesystem => 'FS',
19             utils => 'Now',
20             config => [
21             'filesystem|method:FS',
22             'filename|class:FILENAME',
23             'filename_format|class:FILENAME_FORMAT',
24             'keep_open|class:KEEP_OPEN=0',
25             ],
26             messages => {
27             no_filename => 'No filename or filename_format specified for log file',
28             started => 'Started logging',
29 1     1   471 };
  1         2  
30              
31             our $FORMATS = {
32             DATE => '%Y-%m-%d',
33             TIME => '%H-%M-%S',
34             YEAR => '%Y',
35             MONTH => '%m',
36             DAY => '%d',
37             HOURS => '%H',
38             MINUTES => '%M',
39             SECONDS => '%S',
40             };
41              
42             sub init {
43 2     2 1 5 my ($self, $config) = @_;
44 2         10 $self->init_log($config);
45 2         7 $self->init_file($config);
46 2         5 return $self;
47             }
48              
49             sub init_file {
50 2     2 1 4 my ($self, $config) = @_;
51              
52             # init_log() has already called configured() which will copy the filename
53             # parameter into $self. We don't make the filename parameter mandatory
54             # in the config schema because that will report missing parameters
55             # using error_msg() which has been redefined in Badger::Log. So we
56             # check for it here and use our "backdoor" _error_msg() method.
57             return $self->_error_msg('no_filename')
58             unless defined $self->{ filename }
59 2 50 66     22 || defined $self->{ filename_format };
60              
61             # if filename is set but not filename_format then this is a no-op
62             # as expand_filename() will return the filename
63 2         4 $self->{ filename } = $self->expand_filename;
64              
65 2         11 $self->info_msg('started');
66             }
67              
68             sub expand_filename {
69 10     10 1 20 my $self = shift;
70 10   100     24 my $format = $self->{ filename_format } || return $self->{ filename };
71 5         12 my $strftime = $format;
72             # expand any markers to convert to strftime format
73 5 50       63 $strftime =~ s/<(\w+)>/$FORMATS->{ $1 } || $1/ge;
  10         68  
74             # now format using strftime
75 5         25 return Now->format($strftime);
76             }
77              
78             sub filename_changed {
79 8     8 1 10 my $self = shift;
80 8         16 my $filename = $self->expand_filename;
81             return $filename ne $self->{ filename }
82 8 100       51 ? ($self->{ filename } = $filename)
83             : undef;
84             }
85              
86             sub file {
87 3     3 1 4 my $self = shift;
88 3         8 my $filename = $self->{ filename };
89 3         24 return ($self->{ file } = $self->{ filesystem }->file($filename));
90             }
91              
92             sub filehandle {
93 8     8 1 13 my $self = shift;
94 8 100       24 if ($self->filename_changed) {
95 1         10 $self->release;
96             }
97 8         82 return $self->acquire;
98             }
99              
100             sub acquire {
101 8     8 1 12 my $self = shift;
102              
103             # Badger::Filesystem::File::append() method returns file handle open for append
104             return $self->{ handle }
105 8   66     33 ||= $self->file->append;
106             }
107              
108             sub release {
109 3     3 1 8 my $self = shift;
110 3   50     18 my $fh = delete $self->{ handle } || return;
111 3         21 $fh->close;
112             }
113              
114              
115             sub log {
116 8     8 1 23 my ($self, $level, $message) = @_;
117 8         21 my $handle = $self->filehandle;
118 8         41 my $output = sprintf($self->format($level, $message));
119 8         19 $output =~ s/\n+$//;
120 8         37 $handle->printflush($output, "\n");
121              
122 8 50       794 $self->release unless $self->{ keep_open };
123             }
124              
125              
126             sub DESTROY {
127 2     2   14 shift->release;
128             }
129              
130              
131             1;
132              
133             __END__