File Coverage

blib/lib/Dancer2/Logger/File.pm
Criterion Covered Total %
statement 32 34 94.1
branch 1 2 50.0
condition n/a
subroutine 12 12 100.0
pod n/a
total 45 48 93.7


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.1.0';
4 3     3   346495 use Carp 'carp';
  3         7  
  3         313  
5 3     3   645 use Moo;
  3         11165  
  3         32  
6 3     3   4653 use Dancer2::Core::Types;
  3         11  
  3         51  
7              
8             with 'Dancer2::Core::Role::Logger';
9              
10 3     3   56142 use Fcntl qw(:flock SEEK_END);
  3         9  
  3         649  
11 3     3   1014 use Path::Tiny ();
  3         18390  
  3         107  
12 3     3   702 use IO::File;
  3         12048  
  3         3483  
13              
14             has environment => (
15             is => 'ro',
16             required => 1,
17             );
18              
19             has location => (
20             is => 'ro',
21             required => 1,
22             );
23              
24             has log_dir => (
25             is => 'rw',
26             isa => sub {
27             my $dir = shift;
28              
29             if ( !-d $dir && !mkdir $dir ) {
30             die "log directory \"$dir\" does not exist and unable to create it.";
31             }
32             if ( !-w $dir ) {
33             die "log directory \"$dir\" is not writable."
34             }
35             },
36             lazy => 1,
37             builder => '_build_log_dir',
38             );
39              
40             has _log_dir_path => (
41             is => 'ro',
42             lazy => 1,
43             builder => '_build_log_dir_path',
44             init_arg => undef,
45             );
46              
47             has file_name => (
48             is => 'ro',
49             isa => Str,
50             builder => '_build_file_name',
51             lazy => 1
52             );
53              
54             has log_file => (
55             is => 'ro',
56             isa => Str,
57             lazy => 1,
58             builder => '_build_log_file',
59             );
60              
61             has _log_file_path => (
62             is => 'ro',
63             lazy => 1,
64             builder => '_build_log_file_path',
65             init_arg => undef,
66             );
67              
68             has fh => (
69             is => 'ro',
70             lazy => 1,
71             builder => '_build_fh',
72             );
73              
74 1     1   4512 sub _build_log_dir { Path::Tiny::path( $_[0]->location, 'logs' )->stringify }
75              
76             sub _build_log_dir_path {
77 4     4   113 my $self = shift;
78 4         100 return Path::Tiny::path( $self->log_dir );
79             }
80              
81 1     1   1266 sub _build_file_name {$_[0]->environment . ".log"}
82              
83             sub _build_log_file {
84 4     4   15582 my $self = shift;
85 4         155 return $self->_log_dir_path->child( $self->file_name )->stringify;
86             }
87              
88             sub _build_log_file_path {
89 1     1   17 my $self = shift;
90 1         26 return Path::Tiny::path( $self->log_file );
91             }
92              
93             sub _build_fh {
94 1     1   20 my $self = shift;
95 1         38 my $logfile = $self->_log_file_path->stringify;
96              
97             my $fh = eval {
98 1         16 $self->_log_file_path->filehandle(
99             '>>', ':encoding(UTF-8)',
100             );
101 1 50       270 } or do {
102 0         0 Carp::carp("unable to create or append to $logfile");
103 0         0 return;
104             };
105              
106 1         2444 $fh->autoflush;
107              
108 1         80 return $fh;
109             }
110              
111             sub log {
112             my ( $self, $level, $message ) = @_;
113             my $fh = $self->fh;
114              
115             return unless ( ref $fh && $fh->opened );
116              
117             flock( $fh, LOCK_EX )
118             or carp "locking logfile $self->{logfile} failed: $!";
119             seek( $fh, 0, SEEK_END );
120             $fh->print( $self->format_message( $level => $message ) )
121             or carp "writing to logfile $self->{logfile} failed";
122             flock( $fh, LOCK_UN )
123             or carp "unlocking logfile $self->{logfile} failed: $!";
124             }
125              
126             1;
127              
128             __END__