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 = '1.0.0';
4 2     2   1027 use Carp 'carp';
  2         14  
  2         144  
5 2     2   13 use Moo;
  2         4  
  2         17  
6 2     2   765 use Dancer2::Core::Types;
  2         8  
  2         21  
7              
8             with 'Dancer2::Core::Role::Logger';
9              
10 2     2   28618 use File::Spec;
  2         7  
  2         63  
11 2     2   13 use Fcntl qw(:flock SEEK_END);
  2         5  
  2         331  
12 2     2   17 use Dancer2::FileUtils qw(open_file);
  2         5  
  2         119  
13 2     2   14 use IO::File;
  2         4  
  2         1565  
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   2099 sub _build_log_dir { File::Spec->catdir( $_[0]->location, 'logs' ) }
62              
63 1     1   797 sub _build_file_name {$_[0]->environment . ".log"}
64              
65             sub _build_log_file {
66 4     4   7556 my $self = shift;
67 4         69 return File::Spec->catfile( $self->log_dir, $self->file_name );
68             }
69              
70             sub _build_fh {
71 1     1   16 my $self = shift;
72 1         22 my $logfile = $self->log_file;
73              
74 1         78 my $fh;
75 1 50       11 unless ( $fh = open_file( '>>', $logfile ) ) {
76 0         0 carp "unable to create or append to $logfile";
77 0         0 return;
78             }
79              
80 1         11 $fh->autoflush;
81              
82 1         63 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__
103              
104             =pod
105              
106             =encoding UTF-8
107              
108             =head1 NAME
109              
110             Dancer2::Logger::File - file-based logging engine for Dancer2
111              
112             =head1 VERSION
113              
114             version 1.0.0
115              
116             =head1 DESCRIPTION
117              
118             This is a logging engine that allows you to save your logs to files on disk.
119              
120             Logs are not automatically rotated. Use a log rotation tool like
121             C<logrotate> in C<copytruncate> mode.
122              
123             =head1 METHODS
124              
125             =head2 log($level, $message)
126              
127             Writes the log message to the file.
128              
129             =head1 CONFIGURATION
130              
131             The setting C<logger> should be set to C<File> in order to use this logging
132             engine in a Dancer2 application.
133              
134             The follow attributes are supported:
135              
136             =over 4
137              
138             =item * C<log_dir>
139              
140             Directory path to hold log files.
141              
142             Defaults to F<logs> in the application directory
143              
144             =item * C<file_name>
145              
146             The name of the log file.
147              
148             Defaults to the environment name with a F<.log> suffix
149              
150             =back
151              
152             Here is an example configuration that use this logger and stores logs in F</var/log/myapp>:
153              
154             logger: "File"
155              
156             engines:
157             logger:
158             File:
159             log_dir: "/var/log/myapp"
160             file_name: "myapp.log"
161              
162             =head1 AUTHOR
163              
164             Dancer Core Developers
165              
166             =head1 COPYRIGHT AND LICENSE
167              
168             This software is copyright (c) 2023 by Alexis Sukrieh.
169              
170             This is free software; you can redistribute it and/or modify it under
171             the same terms as the Perl 5 programming language system itself.
172              
173             =cut