File Coverage

blib/lib/Dancer2/Logger/File.pm
Criterion Covered Total %
statement 31 33 93.9
branch 1 2 50.0
condition n/a
subroutine 11 11 100.0
pod n/a
total 43 46 93.4


line stmt bran cond sub pod time code
1             package Dancer2::Logger::File;
2             # ABSTRACT: file-based logging engine for Dancer2
3             $Dancer2::Logger::File::VERSION = '2.0.1';
4 3     3   221545 use Carp 'carp';
  3         10  
  3         318  
5 3     3   592 use Moo;
  3         9463  
  3         33  
6 3     3   4081 use Dancer2::Core::Types;
  3         8  
  3         42  
7              
8             with 'Dancer2::Core::Role::Logger';
9              
10 3     3   49581 use File::Spec;
  3         8  
  3         148  
11 3     3   20 use Fcntl qw(:flock SEEK_END);
  3         7  
  3         632  
12 3     3   467 use Dancer2::FileUtils qw(open_file);
  3         8  
  3         243  
13 3     3   411 use IO::File;
  3         8846  
  3         2877  
14              
15             has environment => (
16             is => 'ro',
17             required => 1,
18             );
19              
20             has location => (
21             is => 'ro',
22             required => 1,
23             );
24              
25             has log_dir => (
26             is => 'rw',
27             isa => sub {
28             my $dir = shift;
29              
30             if ( !-d $dir && !mkdir $dir ) {
31             die "log directory \"$dir\" does not exist and unable to create it.";
32             }
33             if ( !-w $dir ) {
34             die "log directory \"$dir\" is not writable."
35             }
36             },
37             lazy => 1,
38             builder => '_build_log_dir',
39             );
40              
41             has file_name => (
42             is => 'ro',
43             isa => Str,
44             builder => '_build_file_name',
45             lazy => 1
46             );
47              
48             has log_file => (
49             is => 'ro',
50             isa => Str,
51             lazy => 1,
52             builder => '_build_log_file',
53             );
54              
55             has fh => (
56             is => 'ro',
57             lazy => 1,
58             builder => '_build_fh',
59             );
60              
61 1     1   2550 sub _build_log_dir { File::Spec->catdir( $_[0]->location, 'logs' ) }
62              
63 1     1   791 sub _build_file_name {$_[0]->environment . ".log"}
64              
65             sub _build_log_file {
66 4     4   9384 my $self = shift;
67 4         66 return File::Spec->catfile( $self->log_dir, $self->file_name );
68             }
69              
70             sub _build_fh {
71 1     1   13 my $self = shift;
72 1         26 my $logfile = $self->log_file;
73              
74 1         111 my $fh;
75 1 50       8 unless ( $fh = open_file( '>>', $logfile ) ) {
76 0         0 carp "unable to create or append to $logfile";
77 0         0 return;
78             }
79              
80 1         14 $fh->autoflush;
81              
82 1         80 return $fh;
83             }
84              
85             sub log {
86             my ( $self, $level, $message ) = @_;
87             my $fh = $self->fh;
88              
89             return unless ( ref $fh && $fh->opened );
90              
91             flock( $fh, LOCK_EX )
92             or carp "locking logfile $self->{logfile} failed: $!";
93             seek( $fh, 0, SEEK_END );
94             $fh->print( $self->format_message( $level => $message ) )
95             or carp "writing to logfile $self->{logfile} failed";
96             flock( $fh, LOCK_UN )
97             or carp "unlocking logfile $self->{logfile} failed: $!";
98             }
99              
100             1;
101              
102             __END__