File Coverage

blib/lib/Log/Fine/Handle/File.pm
Criterion Covered Total %
statement 48 49 97.9
branch 15 26 57.6
condition 11 27 40.7
subroutine 11 11 100.0
pod 2 2 100.0
total 87 115 75.6


line stmt bran cond sub pod time code
1              
2             =head1 NAME
3              
4             Log::Fine::Handle::File - Output log messages to a file
5              
6             =head1 SYNOPSIS
7              
8             Provides logging to a file
9              
10             use Log::Fine;
11             use Log::Fine::Handle::File;
12              
13             # Get a new logger
14             my $log = Log::Fine->logger("foo");
15              
16             # Create a file handle (default values shown)
17             my $handle = Log::Fine::Handle::File
18             ->new( name => 'file0',
19             mask => LOGMASK_EMERG | LOGMASK_ALERT | LOGMASK_CRIT | LOGMASK_ERR | LOGMASK_WARNING | LOGMASK_NOTICE | LOGMASK_INFO,
20             dir => "/var/log",
21             file => "myapp.log",
22             autoflush => 0 );
23              
24             # Register the handle
25             $log->registerHandle($handle);
26              
27             # Log something
28             $log->(INFO, "Opened new log handle");
29              
30             =head1 DESCRIPTION
31              
32             Log::Fine::Handle::File provides logging to a file. Note that this
33             module will log messages to a specific file. Support for dynamic
34             time-stamps in file names (e.g., C) is provided by
35             L. Further features, such as log
36             file rotation I L can be added by sub-classing this class.
37              
38             =head2 Constructor Parameters
39              
40             The following parameters can be passed to
41             Log::Fine::Handle::File->new():
42              
43             =over
44              
45             =item * name
46              
47             [optional] Name of this object (see L). Will be autoset if
48             not specified.
49              
50             =item * mask
51              
52             Mask to set the handle to (see L)
53              
54             =item * dir
55              
56             Directory to place the log file
57              
58             =item * file
59              
60             Name of the log file. Note that if the given file is an absolute
61             path, then C will be ignored.
62              
63             =item * autoclose
64              
65             [default: 0] If set to true, will close the filehandle after every
66             invocation of L. B will I slow
67             down logging speed if multiple messages are logged at once. Consider
68             autoflush instead
69              
70             =item * autoflush
71              
72             [default: 0] If set to true, will force file flush after every write or
73             print (see L and L)
74              
75             =back
76              
77             =cut
78              
79 6     6   2186 use strict;
  6         6  
  6         167  
80 6     6   16 use warnings;
  6         6  
  6         176  
81              
82             package Log::Fine::Handle::File;
83              
84 6     6   22 use base qw( Log::Fine::Handle );
  6         6  
  6         1196  
85              
86 6     6   22 use File::Basename;
  6         6  
  6         293  
87 6     6   1181 use File::Spec::Functions;
  6         1601  
  6         341  
88 6     6   1569 use FileHandle;
  6         28511  
  6         28  
89 6     6   1599 use Log::Fine;
  6         12  
  6         2503  
90              
91             our $VERSION = $Log::Fine::Handle::VERSION;
92              
93             =head1 METHODS
94              
95             =head2 fileHandle
96              
97             Getter for file handle. If a file handle is not defined, then one
98             will be created.
99              
100             Override this method if you wish to support
101             features such as time-stamped and/or rotating files.
102              
103             =head3 Returns
104              
105             A L object
106              
107             =cut
108              
109             sub fileHandle
110             {
111              
112 13     13 1 2334 my $self = shift;
113              
114             # Should we already have a file handle defined, return it
115             return $self->{_filehandle}
116             if ( defined $self->{_filehandle}
117             and ref $self->{_filehandle}
118             and UNIVERSAL::can($self->{_filehandle}, 'isa')
119             and $self->{_filehandle}->isa("IO::File")
120 13 50 66     160 and defined fileno($self->{_filehandle}));
      66        
      33        
      33        
121              
122             # Generate file name
123             my $filename =
124             ($self->{dir} =~ /\w/)
125             ? catdir($self->{dir}, $self->{file})
126 5 50       17 : $self->{file};
127              
128             # Otherwise create a new one
129 5         36 $self->{_filehandle} = FileHandle->new(">> " . $filename);
130              
131             $self->_fatal("Unable to open log file $filename : $!\n")
132 5 50       548 unless defined $self->{_filehandle};
133              
134             # Set autoflush if necessary
135 5         19 $self->{_filehandle}->autoflush($self->{autoflush});
136              
137 5         174 return $self->{_filehandle};
138              
139             } # fileHandle()
140              
141             =head2 msgWrite
142              
143             See L
144              
145             =cut
146              
147             sub msgWrite
148             {
149              
150 11     11 1 12 my $self = shift;
151 11         10 my $lvl = shift;
152 11         14 my $msg = shift;
153 11         8 my $skip = shift;
154              
155             # Grab a ref to our file handle
156 11         29 my $fh = $self->fileHandle();
157              
158             # Should we have a formatter defined, then use that,
159             # otherwise, just print the raw message
160             $msg = $self->{formatter}->format($lvl, $msg, $skip)
161 11 50       54 if defined $self->{formatter};
162              
163 11 50       334 print $fh $msg or $self->_error("Cannot write to file handle : $!");
164              
165             # Should {autoclose} be set, then close the file handle. This
166             # will force the creation of a new filehandle the next time
167             # this method is called
168 11 100       27 if ($self->{autoclose}) {
169             $fh->close()
170             || $self->_error(
171 1 50       5 sprintf("Unable to close filehandle to %s : %s", catdir($self->{dir}, $self->{file}), $!));
172             }
173              
174 11         41 return $self;
175              
176             } # msgWrite()
177              
178             # --------------------------------------------------------------------
179              
180             ##
181             # Initializes our object
182              
183             sub _init
184             {
185              
186 7     7   15 my $self = shift;
187              
188             # Perform any necessary upper class initializations
189 7         29 $self->SUPER::_init();
190              
191             # Default directory is the current directory unless file is an
192             # absolute path
193 7 50 33     52 if ($self->{file} =~ /^\/|^[A-Za-z]:\\/) {
    50          
194 0         0 $self->{dir} = "";
195             } elsif (not defined $self->{dir} or not -d $self->{dir}) {
196 7         14 $self->{dir} = "./";
197             }
198              
199             # Default file name is the name of the invoking program
200             # suffixed with ".log"
201             $self->{file} = basename($0) . ".log"
202 7 50       15 unless defined $self->{file};
203              
204             # autoflush is disabled by default
205             $self->{autoflush} = 0
206 7 50       19 unless defined $self->{autoflush};
207              
208             # autoclose is disabled by default
209             $self->{autoclose} = 0
210 7 100       23 unless defined $self->{autoclose};
211              
212 7         11 return $self;
213              
214             } # _init()
215              
216             ##
217             # Called when this object is destroyed
218              
219             sub DESTROY
220             {
221              
222 5     5   8 my $self = shift;
223              
224             # Close our filehandle if necessary.
225             $self->{_filehandle}->close()
226             if ( defined $self->{_filehandle}
227             and ref $self->{_filehandle}
228             and UNIVERSAL::can($self->{_filehandle}, 'isa')
229             and $self->{_filehandle}->isa("IO::File")
230 5 50 33     157 and defined fileno($self->{_filehandle}));
      33        
      33        
      33        
231              
232             } # DESTROY
233              
234             =head1 BUGS
235              
236             Please report any bugs or feature requests to
237             C, or through the web interface at
238             L.
239             I will be notified, and then you'll automatically be notified of progress on
240             your bug as I make changes.
241              
242             =head1 SUPPORT
243              
244             You can find documentation for this module with the perldoc command.
245              
246             perldoc Log::Fine
247              
248             You can also look for information at:
249              
250             =over 4
251              
252             =item * AnnoCPAN: Annotated CPAN documentation
253              
254             L
255              
256             =item * CPAN Ratings
257              
258             L
259              
260             =item * RT: CPAN's request tracker
261              
262             L
263              
264             =item * Search CPAN
265              
266             L
267              
268             =back
269              
270             =head1 AUTHOR
271              
272             Christopher M. Fuhrman, C<< >>
273              
274             =head1 SEE ALSO
275              
276             L, L, L
277              
278             =head1 COPYRIGHT & LICENSE
279              
280             Copyright (c) 2008, 2010-2011, 2013 Christopher M. Fuhrman,
281             All rights reserved.
282              
283             This program is free software licensed under the...
284              
285             The BSD License
286              
287             The full text of the license can be found in the
288             LICENSE file included with this module.
289              
290             =cut
291              
292             1; # End of Log::Fine::Handle::File