File Coverage

blib/lib/Dancer2/Logger/Fluent.pm
Criterion Covered Total %
statement 37 43 86.0
branch 4 18 22.2
condition 2 17 11.7
subroutine 14 15 93.3
pod n/a
total 57 93 61.2


line stmt bran cond sub pod time code
1             package Dancer2::Logger::Fluent;
2              
3 3     3   476040 use strict;
  3         5  
  3         62  
4 3     3   84 use 5.008_005;
  3         8  
5             our $VERSION = '0.06';
6              
7 3     3   906 use Moo;
  3         16259  
  3         13  
8 3     3   3444 use Fluent::Logger;
  3         90689  
  3         75  
9 3     3   19 use IO::Socket::INET;
  3         4  
  3         19  
10 3     3   1300 use IO::Socket::UNIX;
  3         4  
  3         15  
11              
12 3     3   2026 use File::Basename 'basename';
  3         3  
  3         162  
13 3     3   1231 use Time::Moment;
  3         2905  
  3         76  
14 3     3   769 use Sys::Hostname;
  3         1415  
  3         126  
15              
16 3     3   829 use Dancer2::Core::Types;
  3         12433  
  3         2165  
17             with 'Dancer2::Core::Role::Logger';
18              
19             has tag_prefix => (
20             is => 'lazy',
21             isa => Str,
22             );
23              
24             has host => (
25             is => 'ro',
26             isa => Str,
27             );
28              
29             has port => (
30             is => 'ro',
31             isa => Str,
32             );
33              
34             has timeout => (
35             is => 'ro',
36             isa => Num,
37             predicate => '_has_timeout',
38             );
39              
40             has socket => (
41             is => 'ro',
42             isa => Str,
43             );
44              
45             has prefer_integer => (
46             is => 'ro',
47             isa => Str,
48             predicate => '_has_prefer_integer',
49             );
50              
51             has event_time => (
52             is => 'ro',
53             isa => Bool,
54             );
55              
56             has buffer_limit => (
57             is => 'ro',
58             isa => Int,
59             predicate => '_has_buffer_limit',
60             );
61              
62             has buffer_overflow_handler => (
63             is => 'ro',
64             isa => CodeRef,
65             predicate => '_has_buffer_overflow_handler',
66             );
67              
68             has truncate_buffer_at_overflow => (
69             is => 'ro',
70             isa => Bool,
71             );
72              
73             sub _build_tag_prefix {
74 1     1   8170 my $self = shift;
75 1   0     28 return $self->{tag_prefix} || $self->app_name || $ENV{DANCER_APPDIR} || basename($0);
76             }
77              
78             sub _connect {
79 2     2   3 my $self = shift;
80 2 50 50     63 return defined $self->socket
    50 50        
81             ? IO::Socket::UNIX->new( Peer => $self->socket )
82             : IO::Socket::INET->new(
83             PeerAddr => $self->host || '127.0.0.1',
84             PeerPort => $self->port || 24224,
85             Proto => 'tcp',
86             Timeout => $self->_has_timeout ? $self->timeout : 3.0,
87             ReuseAddr => 1,
88             );
89             }
90              
91             sub _fluent {
92 2     2   4 my $self = shift;
93              
94 2 50       8 return unless $self->_connect;
95              
96 0 0       0 unless ( exists $self->{_fluent} ) {
97             $self->{_fluent} = Fluent::Logger->new(
98             host => $self->host || '127.0.0.1',
99             port => $self->port || 24224,
100             timeout => $self->_has_timeout ? $self->timeout : 3.0,
101             socket => $self->socket,
102             prefer_integer => $self->_has_prefer_integer ? $self->prefer_integer : 1,
103             event_time => $self->event_time || 0,
104             buffer_limit => $self->_has_buffer_limit ? $self->buffer_limit : 8388608,
105 0     0   0 buffer_overflow_handler => $self->_has_buffer_overflow_handler ? $self->buffer_overflow_handler : sub { undef },
106 0 0 0     0 truncate_buffer_at_overflow => $self->truncate_buffer_at_overflow || 0,
    0 0        
    0 0        
    0 0        
107             );
108             }
109              
110 0         0 return $self->{_fluent};
111             }
112              
113             sub DESTROY {
114 1     1   6197 my $self = shift;
115 1 50       4 return unless $self->_fluent;
116 0   0       $self->_fluent->{pending} ||= ''; # Fluent::Logger->close performs length checks without checking if value is defined first
117 0           $self->_fluent->close;
118             }
119              
120             sub log {
121             my ($self, $level, $message) = @_;
122              
123             my $fluent_message = {
124             env => $ENV{DANCER_ENVIRONMENT} || $ENV{PLACK_ENV} || 'development',
125             timestamp => Time::Moment->now_utc->strftime("%Y-%m-%dT%H:%M:%S.%6N%Z"),
126             host => hostname(),
127             level => $level,
128             message => $message,
129             pid => $$
130             };
131              
132             # Queue pending messages until connectivity is restored
133             unless ( $self->_fluent ) {
134             push @{ $self->{pending} }, $fluent_message;
135             return;
136             }
137              
138             if ( exists $self->{pending} and @{ $self->{pending} } ) {
139             while ( my $pending_message = shift @{ $self->{pending} } ) {
140             $self->_fluent->post( $self->tag_prefix, $pending_message );
141             }
142             }
143             $self->_fluent->post( $self->tag_prefix, $fluent_message );
144             }
145              
146             1;
147             __END__