File Coverage

blib/lib/Log/Tiny.pm
Criterion Covered Total %
statement 67 68 98.5
branch 14 22 63.6
condition 2 4 50.0
subroutine 12 12 100.0
pod 4 4 100.0
total 99 110 90.0


line stmt bran cond sub pod time code
1             package Log::Tiny;
2              
3 4     4   86622 use strict;
  4         10  
  4         179  
4 4     4   22 use vars qw($AUTOLOAD $VERSION $errstr %formats);
  4         39  
  4         5497  
5              
6             =head1 NAME
7              
8             Log::Tiny - Log data with as little code as possible
9              
10             =head1 VERSION
11              
12             Version 0.9
13              
14             =cut
15              
16             $VERSION = '0.9';
17             $errstr = '';
18              
19             %formats = (
20             c => [ 's', sub { shift }, ], # category: AUTOLOAD
21             C => [ 's', sub { lc shift }, ], # lcategory: AUTOLOAD lc
22             f => [ 's', sub { $0 }, ], # program_file: $0
23             F => [ 's', sub { (caller(2))[1] }, ], # caller_file: caller
24             g => [ 's', sub { scalar gmtime }, ], # gmtime: scalar gmtime
25             L => [ 'd', sub { (caller(2))[2] }, ], # caller_line: caller
26             m => [ 's', sub { shift; shift }, ], # message: args
27             n => [ 's', sub { $/ }, ], # newline: $/
28             o => [ 's', sub { $^O }, ], # osname: $^O
29             p => [ 'd', sub { $$ }, ], # pid: $$
30             P => [ 's', sub { (caller(2))[0] }, ], # caller_pkg: caller
31             r => [ 'd', sub { time - $^T }, ], # runtime: $^T
32             S => [ 's', \&__format_S, sub { my $t = (caller(2))[3]; }, ], # caller_sub: caller
33             t => [ 's', sub { scalar localtime }, ],# localtime: scalar localtime
34             T => [ 'd', sub { time }, ], # unix_time: time
35             u => [ 'd', sub { $> }, ], # effective_uid: $>
36             U => [ 'd', sub { $< }, ], # real_uid: $<
37             v => [ 'd', sub { $] }, ], # long_perl_ver: $]
38             V => [ 's', sub { sprintf("%vd", $^V) }, ], # short_perl_ver
39             );
40              
41 1 50   1   5 sub __format_S { my $t = (caller(2))[3]; if ( $t eq 'Log::Tiny::AUTOLOAD' ) { $t = 'main'; }; $t; }
  1         6  
  1         2  
  1         5  
42              
43             =head1 SYNOPSIS
44              
45             This module aims to be a light-weight implementation
46             *similiar* to L for logging data to a file.
47              
48             Its use is very straight forward:
49              
50             use Log::Tiny;
51              
52             my $log = Log::Tiny->new( 'myapp.log' ) or
53             die 'Could not log! (' . Log::Tiny->errstr . ')';
54              
55             foreach ( 1 .. 20 ) {
56             $log->DEBUG( "Performing extensive computations on $_" ) if $DEBUG;
57             unless ( extensively_compute( $_ ) ) {
58             $log->WARN(
59             "Investigating error (this may take a while)..."
60             );
61             $log->ERROR( find_error() );
62             save_state();
63             exit 1;
64             } else {
65             $log->INFO( "Everything's A-OK!" );
66             }
67             }
68              
69             =head1 FUNCTIONS
70              
71             =head2 new
72              
73             Create a new Log::Tiny object. You must define a log file
74             to append to, and, optionally, a format.
75              
76             =cut
77              
78             sub new {
79 3     3 1 160 my $pkg = shift;
80 3   50     16 my $logfile = shift || return _error('No logfile provided');
81 3   50     14 my $format = shift || '[%t] %f:%p (%c) %m%n';
82 3 50       352 open ( LOG, '>>' . $logfile ) ||
83             return _error( "Could not open $logfile: $!" );
84 3         21 my $self = bless {
85             format => $format,
86             methods_only => [],
87             }, $pkg;
88 3         23 $self->format();
89 3         11 return $self;
90             }
91              
92             =head2 format
93              
94             You may, at any time, change the format. The log format is
95             similiar in style to the sprintf you know and love; and, as
96             a peek inside the source of this module will tell you, sprintf
97             is used internally. However, be advised that these log formats
98             B.
99              
100             Interpolated data are specified by an percent sign (C< % >),
101             followed by a character. A literal percent sign can be
102             specified via two in succession ( C< %% > ). You may use any
103             of the formatting attributes as noted in L, under
104             "sprintf" (C).
105              
106             Internally, the format routine uses a data structure (hash)
107             that can be seen near the beggining of this package. Any
108             unrecognized interpolation variables will be returned
109             literally. This means that, assuming $format{d} does not
110             exist, "%d" in your format will result in "%d" being outputted
111             to the log file. No interpolation will occur.
112              
113             You may, of course, decide to modify the format data structure.
114             I have done my best to ensure a wide range of variables for your
115             usage, however. They are (currently) as follows:
116              
117             c => category => The method called (see below for more info)
118             C => lcategory => lowercase category
119             f => program_file => Value of $0
120             F => caller_file => Calling file
121             g => gmtime => Output of scalar L (localized date string)
122             L => caller_line => Calling line
123             m => message => Message sent to the log method
124             n => newline => Value of $/
125             o => osname => Value of $^O
126             p => pid => Value of $$
127             P => caller_pkg => Calling package
128             r => runtime => Seconds the current process has been running for
129             S => caller_sub => Calling subroutine
130             t => localtime => Output of scalar L (localized date
131             string)
132             T => unix_time => Time since epoch (L
133             u => effective_uid => Value of $>
134             U => real_uid => Value of $<
135             v => long_perl_ver => Value of $] (5.008008)
136             V => short_perl_ver => A "short" string for the version ("5.8.8")
137              
138             See L for information on the used global variables, and
139             L (under "caller") or C for information
140             on the "calling" variables. Oh, and make sure you add %n if you want
141             newines.
142              
143             =cut
144              
145             sub format {
146 3     3 1 7 my $self = shift;
147 3 50       14 if ( $_[0] ) {
148 0         0 $self->{format} = shift;
149             }
150 3         23 $self->{args} = [];
151             # make real format
152 3         34 my $format = join '', keys %formats;
153 3         177 $self->{format} =~
154 6         23 s/%(-?\d*(?:\.\d+)?)([$format])/_replace($self, $1, $2);/gex;
155             # thanks, mschilli
156 3         13 return $self->{format};
157             }
158              
159             sub _replace {
160 6     6   21 my ( $self, $num, $op ) = @_;
161 6 50       24 return '%%' if $op eq '%';
162 6 50       19 return "%%$op" unless defined $formats{$op};
163 6         10 push @{ $self->{args} }, $op;
  6         18  
164 6         43 return "%$num" . $formats{$op}->[ 0 ];
165             }
166              
167             =head2 WHATEVER_YOU_WANT (log a message)
168              
169             This method is whatever you want it to be. Any method called
170             on a Log::Tiny object that is not reserved will be considered
171             an attempt to log in the category named the same as the method
172             that was caleld. Currently, only in-use methods are reserved;
173             However, to account for expansion, please only use uppercase
174             categories. See formats above for information on customizing
175             the log messages.
176              
177             =cut
178              
179             sub AUTOLOAD {
180 17     17   603 my $self = shift;
181 17         28 my $method = $AUTOLOAD;
182 17         73 $method =~ s/.*:://;
183 17 50       54 return _error( "Log routine ($method) is not a class method" )
184             unless defined ref $self;
185 17 100       19 if (@{ $self->{methods_only} }) {
  17         55  
186 3         5 my $in = 0;
187 3         5 foreach (@{ $self->{methods_only} }) {
  3         9  
188 6 100       22 $in++ if uc $method eq uc $_;
189             }
190 3 100       13 return _error( "Log category '$method' not in whitelist" )
191             unless $in;
192             }
193 16         23 my $tmp = '';
194             $tmp .= sprintf (
195             $self->{format},
196             $self->_mk_args( $method, $_ ),
197 16         66 ) foreach @_;
198 16         25 my $ret;
199             {
200 16         20 my $autoflush = $|++;
  16         34  
201 16         85 $ret = print LOG $tmp;
202 16         32 $| = $autoflush;
203             }
204 16         62 return $ret;
205             }
206              
207             sub _mk_args {
208 16     16   24 my $self = shift;
209 16         28 my ( $method, $msg ) = @_;
210 16 50       38 $msg = '' unless defined $msg;
211 16         20 my @ret = @{ $self->{args} };
  16         48  
212 16         34 my %need = map { $_ => undef } @ret;
  30         82  
213 16         45 foreach ( keys %need ) {
214 30         71 $need{ $_ } = $formats{ $_ }->[ 1 ]->( $method, $msg );
215             }
216 16         71 s/^(\w)$/$need{$1}/e foreach @ret;
  30         132  
217 16         131 return @ret;
218             }
219              
220 3 50   3   345 sub DESTROY { close LOG or warn "Couldn't close log file: $!"; }
221              
222             =head2 errstr
223              
224             Called as a class method, C< Log::Tiny->errstr > reveals the
225             error that Log::Tiny encountered in creation or invocation.
226              
227             =cut
228              
229 2     2 1 1769 sub errstr { $errstr; }
230 1     1   3 sub _error { $errstr = shift; undef; }
  1         4  
231              
232             =head2 log_only
233              
234             Log only the given categories
235              
236             =cut
237              
238             sub log_only {
239 1     1 1 2 my $self = shift;
240 1         5 $self->{methods_only} = \@_;
241             }
242              
243             =head1 AUTHOR
244              
245             Jordan M. Adler, C<< >>
246              
247             =head1 BUGS
248              
249             Please report any bugs or feature requests to
250             C, or through the web interface at
251             L.
252             I will be notified, and then you'll automatically be notified of progress on
253             your bug as I make changes.
254              
255             =head1 SUPPORT
256              
257             You can find documentation for this module with the perldoc command.
258              
259             perldoc Log::Tiny
260              
261             You can also look for information at:
262              
263             =over 4
264              
265             =item * AnnoCPAN: Annotated CPAN documentation
266              
267             L
268              
269             =item * CPAN Ratings
270              
271             L
272              
273             =item * RT: CPAN's request tracker
274              
275             L
276              
277             =item * Search CPAN
278              
279             L
280              
281             =back
282              
283             =head1 ACKNOWLEDGEMENTS
284              
285             Much thanks to Michael Schilli C for his great work on
286             Log::Log4perl.
287              
288             =head1 COPYRIGHT & LICENSE
289              
290             Copyright 2007-2010 Jordan M. Adler, all rights reserved.
291              
292             This program is free software; you can redistribute it and/or modify it
293             under the same terms as Perl itself.
294              
295             =cut
296              
297             1; # End of Log::Tiny