File Coverage

blib/lib/Log/Any/Adapter/FileHandle.pm
Criterion Covered Total %
statement 40 41 97.5
branch 12 14 85.7
condition 6 6 100.0
subroutine 10 10 100.0
pod 0 1 0.0
total 68 72 94.4


line stmt bran cond sub pod time code
1             package Log::Any::Adapter::FileHandle;
2             $Log::Any::Adapter::FileHandle::VERSION = '0.009';
3             =head1 NAME
4              
5             Log::Any::Adapter::FileHandle - A basic Log::Any::Adapter to forward messages to a filehandle
6              
7             =head1 VERSION
8              
9             version 0.009
10              
11             =head1 SYNOPSIS
12              
13             use Log::Any qw($log);
14             use Log::Any::Adapter;
15              
16             # Send all logs to Log::Any::Adapter::FileHandle
17             Log::Any::Adapter->set('FileHandle');
18              
19             $log->info("Hello world");
20            
21             =head1 DESCRIPTION
22              
23             This module is a basic adapter that will simply forward log messages to a filehandle, or any object that
24             supports a 'print' method (L, L, Plack's $env->{psgi.errors} object, etc).
25              
26             I've created it so that my scripts running under damontools or runit can output
27             messages to locally defined logs. It does not timestamp messages, that responsbility is
28             delegated to the external log capture mechanism.
29              
30             You can override the default configuration by passing extra arguments to the
31             C set_adapter method:
32              
33             =over
34              
35             =item fh
36              
37             Pass in your IO::Handle-like object here. If this isn't specified, it will
38             default to opening STDERR. If the object supports an autoflush method,
39             autoflush will be enabled, unless no_autoflush is set.
40              
41             =item no_autoflush
42              
43             Disable automatically turning on autoflush on the fh object.
44              
45             =item format
46              
47             A sprintf string that controls the formatting of the message. It is supplied 2
48             arguments: the log level as supplied by Log::Any (usually all-lowercase), and
49             the message to be logged. The default is "[%s] %s\n". This value should
50             contain the log record terminator, such as a newline.
51              
52             =item escape
53              
54             one of 'none' (default), 'newline', or 'nonascii'. Controls how messages are
55             pre-filtered before passing them to a filehandle. This is handy if you want do
56             smoosh messages into a single line (for easier filtering + processing), or if
57             you want to filter non ascii characters for safe terminal printing.
58              
59             =back
60              
61              
62             =head1 COPYRIGHT AND LICENSE
63              
64             Copyright 2014 by Jason Jay Rodrigues
65              
66             Log::Any::Adapter::FileHandle is provided "as is" and without any express or
67             implied warranties, including, without limitation, the implied warranties of
68             merchantibility and fitness for a particular purpose.
69              
70             This program is free software; you can redistribute it and/or modify it under
71             the same terms as Perl itself.
72              
73             =cut
74              
75              
76 3     3   29763 use strict;
  3         6  
  3         97  
77 3     3   12 use warnings;
  3         4  
  3         108  
78 3     3   534 use Log::Any::Adapter::Util qw(make_method);
  3         6156  
  3         138  
79 3     3   17 use Scalar::Util qw(blessed);
  3         3  
  3         206  
80 3     3   13 use IO::Handle;
  3         3  
  3         108  
81 3     3   11 use base qw(Log::Any::Adapter::Base);
  3         5  
  3         1573  
82              
83             sub init {
84 11     11 0 4985 my ($self, %attr) = @_;
85            
86             # if no fh object is set, we default to STDERR.
87 11 50       58 if(!exists($self->{fh})) {
88 0         0 $self->{fh} = IO::Handle->new_from_fd(fileno(STDERR),'w');
89             }
90              
91 11 100 100     190 if($self->{fh}->can('autoflush') && !$self->{no_autoflush}) {
92 6         24 $self->{fh}->autoflush(1);
93             }
94            
95             # if no format is set, we default to a reasonable sane default.
96 11 100       109 if(!exists($self->{format})) {
97 9         20 $self->{format} = "[%s] %s\n";
98             }
99              
100 11 100       33 if(!exists($self->{escape})) {
101 9         29 $self->{escape} = 'none';
102             }
103             }
104              
105              
106             {
107             # setup logging methods, that simply print to the given io object.
108             foreach my $method ( Log::Any->logging_methods() ) {
109             my $logger = sub {
110 22     22   5302 my $self = shift;
111 22         60 my $message = join('',@_);
112 22 100 100     136 if($self->{escape} eq 'newline' || $self->{escape} eq 'nonascii') {
113 5         22 $message =~ s/\n/\\n/sg;
114 5         12 $message =~ s/\r/\\r/sg;
115             }
116 22 100       51 if($self->{escape} eq 'nonascii') {
117 3     3   6244 $message =~ s/(\P{ASCII}|\p{PosixCntrl})/sprintf("\\x{%x}",ord($1))/eg;
  3         21  
  3         31  
  3         31  
  4         24  
118             }
119 22 50       75 if($self->{fh}) {
120 22         157 $self->{fh}->print(sprintf($self->{format}, $method, $message));
121             }
122             };
123             make_method($method, $logger);
124             }
125              
126 9     9   3417 my $true = sub { 1 };
127              
128             # In FileHandle, we log *everything*, and let the
129             # log seperation happen in external programs.
130             foreach my $method ( Log::Any->detection_methods() ) {
131             make_method($method, $true);
132             }
133             }
134              
135              
136              
137             1;