File Coverage

blib/lib/Dancer/Logger/File/PerRequest.pm
Criterion Covered Total %
statement 44 78 56.4
branch 3 32 9.3
condition 1 23 4.3
subroutine 13 16 81.2
pod 1 2 50.0
total 62 151 41.0


line stmt bran cond sub pod time code
1             package Dancer::Logger::File::PerRequest;
2              
3 1     1   223619 use strict;
  1         1  
  1         30  
4 1     1   4 use warnings;
  1         2  
  1         21  
5 1     1   17 use 5.008_005;
  1         6  
  1         47  
6             our $VERSION = '0.01';
7              
8 1     1   3 use Carp;
  1         1  
  1         52  
9 1     1   4 use base 'Dancer::Logger::Abstract';
  1         1  
  1         65  
10 1     1   5 use Dancer::FileUtils qw(open_file);
  1         1  
  1         40  
11 1     1   4 use Dancer::Config 'setting';
  1         1  
  1         33  
12 1     1   4 use Dancer::Hook;
  1         1  
  1         14  
13 1     1   3 use IO::File;
  1         1  
  1         113  
14 1     1   4 use Fcntl qw(:flock SEEK_END);
  1         1  
  1         100  
15 1     1   5 use Scalar::Util ();
  1         1  
  1         479  
16              
17             sub init {
18 1     1 1 27 my $self = shift;
19 1         6 $self->SUPER::init(@_);
20              
21 1         3 my $logdir = logdir();
22 1 50       3 return unless ($logdir);
23 1 50       17 mkdir($logdir) unless -d $logdir;
24              
25             my $logfile_callback = setting('logfile_callback') || sub {
26 0     0   0 my @d = localtime();
27 0         0 my $file = sprintf('%04d%02d%02d%02d%02d%02d', $d[5] + 1900, $d[4] + 1, $d[3], $d[2], $d[1], $d[0]);
28 0         0 return $file . '_' . $$ . '.log';
29 1   50     3 };
30 1         11 $self->{logfile_callback} = $logfile_callback;
31              
32             # per request
33 1         3 Scalar::Util::weaken $self;
34             Dancer::Hook->new('on_route_exception' => sub {
35 0     0   0 undef $self->{fh};
36 1         7 });
37             }
38              
39             sub _log {
40 0     0   0 my ($self, $level, $message) = @_;
41              
42 0         0 my $fh = $self->{fh};
43 0 0       0 unless ($fh) {
44 0         0 my $logfile = $self->{logfile_callback}->();
45 0 0       0 my $logdir = logdir() or return;
46 0         0 $logfile = File::Spec->catfile($logdir, $logfile);
47              
48 0 0       0 unless($fh = open_file('>>', $logfile)) {
49 0         0 carp "unable to create or append to $logfile";
50 0         0 return;
51             }
52              
53             # looks like older perls don't auto-convert to IO::File
54             # and can't autoflush
55             # see https://github.com/PerlDancer/Dancer/issues/954
56 0         0 eval { $fh->autoflush };
  0         0  
57              
58 0         0 $self->{fh} = $fh;
59             }
60              
61 0 0 0     0 return unless(ref $fh && $fh->opened);
62              
63 0 0       0 flock($fh, LOCK_EX)
64             or carp "locking logfile $self->{logfile} failed";
65 0 0       0 seek($fh, 0, SEEK_END)
66             or carp "seeking to logfile $self->{logfile} end failed";
67 0 0       0 $fh->print($self->format_message($level => $message))
68             or carp "writing to logfile $self->{logfile} failed";
69 0 0       0 flock($fh, LOCK_UN)
70             or carp "unlocking logfile $self->{logfile} failed";
71             }
72              
73             # Copied from Dancer::Logger::File
74             sub logdir {
75 1 50   1 0 5 if ( my $altpath = setting('log_path') ) {
76 1         13 return $altpath;
77             }
78              
79 0           my $logroot = setting('appdir');
80              
81 0 0 0       if ( $logroot and ! -d $logroot and ! mkdir $logroot ) {
      0        
82 0           carp "app directory '$logroot' doesn't exist, am unable to create it";
83 0           return;
84             }
85              
86 0 0         my $expected_path = $logroot ?
87             Dancer::FileUtils::path($logroot, 'logs') :
88             Dancer::FileUtils::path('logs');
89              
90 0 0 0       return $expected_path if -d $expected_path && -x _ && -w _;
      0        
91              
92 0 0 0       unless (-w $logroot and -x _) {
93 0           my $perm = (stat $logroot)[2] & 07777;
94 0           chmod($perm | 0700, $logroot);
95 0 0 0       unless (-w $logroot and -x _) {
96 0           carp "app directory '$logroot' isn't writable/executable and can't chmod it";
97 0           return;
98             }
99             }
100 0           return $expected_path;
101             }
102              
103             1;
104             __END__