File Coverage

blib/lib/Clustericious/Log.pm
Criterion Covered Total %
statement 47 63 74.6
branch 14 24 58.3
condition 7 13 53.8
subroutine 11 13 84.6
pod 2 2 100.0
total 81 115 70.4


line stmt bran cond sub pod time code
1             package Clustericious::Log;
2              
3 43     43   5428 use strict;
  43         89  
  43         1093  
4 43     43   202 use warnings;
  43         80  
  43         1085  
5 43     43   220 use List::Util qw( first );
  43         85  
  43         2365  
6 43     43   3998 use Log::Log4perl qw( :easy );
  43         241282  
  43         343  
7 43     43   36069 use MojoX::Log::Log4perl;
  43         87204  
  43         412  
8 43     43   8340 use File::ReadBackwards;
  43         48742  
  43         1139  
9 43     43   2325 use Clustericious;
  43         99  
  43         22786  
10              
11             # ABSTRACT: A Log::Log4perl wrapper for use with Clustericious.
12             our $VERSION = '1.27'; # VERSION
13              
14              
15             sub import {
16 133     133   19611 my $class = shift;
17 133         380 my $dest = caller;
18 133         367 my %args = @_;
19 133 100       520 if (my $app_name = $args{-init_logging}) {
20 2         5 init_logging($app_name);
21             }
22 133         414 @_ = ($class, ':easy');
23 133         928 goto \&Log::Log4perl::import;
24             }
25              
26              
27             our $initPid;
28             sub init_logging {
29 32     32 1 79 my $app_name = shift;
30 32 100       142 $app_name = shift if $app_name eq __PACKAGE__;
31 32 50 33     256 $app_name = $ENV{MOJO_APP} unless $app_name && $app_name ne 'Clustericious::App';
32              
33             # Force reinitialization after a fork
34 32 50 66     272 $Log::Log4perl::Logger::INITIALIZED = 0 if $initPid && $initPid != $$;
35 32         119 $initPid = $$;
36              
37             # Logging
38 32   100     426 $ENV{LOG_LEVEL} ||= 'WARN';
39              
40 32         115 my $l4p_dir; # dir with log config file.
41             my $l4p_pat; # pattern for screen logging
42 32         0 my $l4p_file; # file (global or app specific)
43              
44 32 50 66 32   377 $l4p_dir = first { -d $_ && (-e "$_/log4perl.conf" || -e "$_/$app_name.log4perl.conf") } Clustericious->_config_path;
  32         694  
45 32         227 $l4p_pat = "[%d] [%Z %H %P] %5p: %m%n";
46 32 100       108 if ($l4p_dir) {
47 29     58   224 $l4p_file = first {-e "$l4p_dir/$_"} ("$app_name.log4perl.conf", "log4perl.conf");
  58         732  
48             }
49              
50 32     0   370 Log::Log4perl::Layout::PatternLayout::add_global_cspec('Z', sub {$app_name});
  0         0  
51              
52             my $logger = MojoX::Log::Log4perl->new( $l4p_dir ? "$l4p_dir/$l4p_file":
53             { # default config
54             ($ENV{LOG_FILE} ? (
55 32 50       1362 "log4perl.rootLogger" => "$ENV{LOG_LEVEL}, File1",
    100          
56             "log4perl.appender.File1" => "Log::Log4perl::Appender::File",
57             "log4perl.appender.File1.layout" => "PatternLayout",
58             "log4perl.appender.File1.filename" => "$ENV{LOG_FILE}",
59             "log4perl.appender.File1.layout.ConversionPattern" => "[%d] [%Z %H %P] %5p: %m%n",
60             ):(
61             "log4perl.rootLogger" => "$ENV{LOG_LEVEL}, SCREEN",
62             "log4perl.appender.SCREEN" => "Log::Log4perl::Appender::Screen",
63             "log4perl.appender.SCREEN.layout" => "PatternLayout",
64             "log4perl.appender.SCREEN.layout.ConversionPattern" => "$l4p_pat",
65             )),
66             # These categories (%c) are too verbose by default :
67             "log4perl.logger.Mojolicious" => "WARN",
68             "log4perl.logger.Mojolicious.Plugin.RequestTimer" => "WARN",
69             "log4perl.logger.MojoX.Dispatcher.Routes" => "WARN",
70             });
71              
72 32         63682 INFO("Initialized logger");
73 32 100       470 INFO("Log config found : $l4p_dir/$l4p_file") if $l4p_dir;
74             # warn "# started logging ($l4p_dir/log4perl.conf)\n" if $l4p_dir;
75 32         385 return $logger;
76             }
77              
78              
79             sub tail {
80 0     0 1   my $self = shift;
81 0           my %args = @_;
82 0   0       my $count = $args{lines} || 10;
83 0           my %appenders = %{ Log::Log4perl->appenders };
  0            
84 0           my ($first) = sort keys %appenders;
85 0           my $obj = $appenders{$first}->{appender};
86 0 0         $obj->can("filename") or return "no filename for appender $first";
87 0           my $filename = $obj->filename;
88 0 0         my $fp = File::ReadBackwards->new($filename) or return "Can't read $filename : $!";
89 0           my @lines;
90             my $line;
91 0           while ( defined( $line = $fp->readline ) ) {
92 0           unshift @lines, $line;
93 0 0         last if ( (0 + @lines) >= $count);
94             };
95 0           return join '', @lines;
96             }
97              
98              
99             1;
100              
101             __END__
102              
103             =pod
104              
105             =encoding UTF-8
106              
107             =head1 NAME
108              
109             Clustericious::Log - A Log::Log4perl wrapper for use with Clustericious.
110              
111             =head1 VERSION
112              
113             version 1.27
114              
115             =head1 SYNOPSIS
116              
117             use Clustericious::Log -init_logging => "appname";
118            
119             use Clustericious::Log;
120             INFO "Hi there!";
121              
122             =head1 DESCRIPTION
123              
124             This is a simple wrapper around L<Log::Log4perl> for use with
125             Clustericious. It handles initialization and exporting of
126             convenient logging functions, and a default set of logging
127             patterns. It also makes the name of the application available
128             for logging patterns (see the example).
129              
130             =head1 EXAMPLE
131              
132             Here is a sample C<~/etc/log4perl.conf> :
133              
134             log4perl.rootLogger=TRACE, LOGFILE
135             log4perl.appender.LOGFILE=Log::Log4perl::Appender::File
136             log4perl.appender.LOGFILE.filename=/tmp/some.log
137             log4perl.appender.LOGFILE.mode=append
138             log4perl.appender.LOGFILE.layout=PatternLayout
139             log4perl.appender.LOGFILE.layout.ConversionPattern=[%d{HH:mm:ss}] [%8.8Z] %C (%F{1}+%L) %5p: %m%n
140             # Note 'Z' is the name of the Clustericious application.
141              
142             =head1 METHODS
143              
144             =over
145              
146             =item init_logging
147              
148             Start logging. Looks for C<log4perl.conf> or C<$app.log4perl.conf>
149             in C<~/etc> and C</etc>.
150              
151             =item tail
152              
153             Returns a string with the last $n lines of the logfile.
154              
155             If multiple log files are defined, it only uses the first one alphabetically.
156              
157             =back
158              
159             =head1 ENVIRONMENT
160              
161             The following variables affect logging :
162              
163             LOG_LEVEL
164             LOG_FILE
165             MOJO_APP
166              
167             =head1 SEE ALSO
168              
169             L<Log::Log4perl>, L<Clustericious>
170              
171             =head1 AUTHOR
172              
173             Original author: Brian Duggan
174              
175             Current maintainer: Graham Ollis E<lt>plicease@cpan.orgE<gt>
176              
177             Contributors:
178              
179             Curt Tilmes
180              
181             Yanick Champoux
182              
183             =head1 COPYRIGHT AND LICENSE
184              
185             This software is copyright (c) 2013 by NASA GSFC.
186              
187             This is free software; you can redistribute it and/or modify it under
188             the same terms as the Perl 5 programming language system itself.
189              
190             =cut