File Coverage

blib/lib/DBIx/Class/UnicornLogger.pm
Criterion Covered Total %
statement 66 69 95.6
branch 20 22 90.9
condition 12 15 80.0
subroutine 11 11 100.0
pod 3 4 75.0
total 112 121 92.5


line stmt bran cond sub pod time code
1             package DBIx::Class::UnicornLogger;
2             $DBIx::Class::UnicornLogger::VERSION = '0.001004';
3             # ABSTRACT: Pretty Printing DebugObj with nicer logging features
4              
5 5     5   80745 use Moo;
  5         57848  
  5         29  
6             extends 'DBIx::Class::Storage::Statistics';
7              
8 5     5   10164 use SQL::Abstract::Tree;
  5         172055  
  5         323  
9 5     5   11926 use Log::Structured;
  5         39171  
  5         271  
10 5     5   3470 use Log::Sprintf;
  5         207704  
  5         6479  
11              
12             my %code_to_method = (
13             C => 'log_package',
14             c => 'log_category',
15             d => 'log_date',
16             F => 'log_file',
17             H => 'log_host',
18             L => 'log_line',
19             l => 'log_location',
20             M => 'log_subroutine',
21             P => 'log_pid',
22             p => 'log_priority',
23             r => 'log_milliseconds_since_start',
24             R => 'log_milliseconds_since_last_log',
25             T => 'log_stacktrace',
26             );
27              
28             sub BUILDARGS {
29 8     8 0 14169 my ($self, @rest) = @_;
30              
31 8         37 my %args = (
32             @rest == 1
33 8 50       35 ? %{$rest[0]}
34             : @rest
35             );
36              
37 8   100     138 $args{_sqlat} = SQL::Abstract::Tree->new($args{tree} || {});
38              
39 8         9837 return \%args
40             }
41              
42             has _sqlat => (
43             is => 'ro',
44             );
45              
46             has _clear_line_str => (
47             is => 'ro',
48             init_arg => 'clear_line',
49             );
50              
51             has _executing_str => (
52             is => 'ro',
53             init_arg => 'executing',
54             );
55              
56             has _show_progress => (
57             is => 'ro',
58             init_arg => 'show_progress',
59             );
60              
61             has _last_sql => (
62             is => 'rw',
63             default => sub { '' },
64             init_arg => undef,
65             );
66              
67             has _squash_repeats => (
68             is => 'ro',
69             init_arg => 'squash_repeats',
70             );
71              
72             has _structured_logger => (
73             is => 'rw',
74             lazy => 1,
75             builder => '_build_structured_logger',
76             );
77              
78             sub _build_structured_logger {
79 6     6   1620 my $self = shift;
80              
81 6 100 66     58 if ($self->_format || $self->_multiline_format) {
82 3   50     7 my $format = $self->_format || '%m';
83              
84 3         24 my $log_sprintf = Log::Sprintf->new({ format => $format });
85              
86 3 100       26 my $per_line_log_sprintf = Log::Sprintf->new({
87             format => $self->_multiline_format
88             }) if $self->_multiline_format;
89              
90 3         7 my %formats = %{{
  9         78  
91 18         174 map { $_->{conversion} => 1 }
92 5         307 grep { ref $_ }
93 3         13 map @{$log_sprintf->_formatter->format_hunker->($log_sprintf, $_)},
94             grep $_,
95             $log_sprintf->{format},
96             $per_line_log_sprintf->{format}
97             }};
98              
99             my $sub = $self->_multiline_format
100             ? sub {
101 2     2   251 my %struc = %{$_[1]};
  2         12  
102 2         14 my (@msg, undef) = split /\n/, delete $struc{message};
103 2         15 $self->debugfh->print($log_sprintf->sprintf({
104             %struc,
105             message => shift @msg,
106             }) . "\n");
107             $self->debugfh->print($per_line_log_sprintf->sprintf({
108             %struc,
109             message => $_,
110 2         439 }) . "\n") for @msg;
111             }
112             : sub {
113 1     1   93 my %struc = %{$_[1]};
  1         6  
114 1         5 my (@msg, undef) = split /\n/, delete $struc{message};
115             $self->debugfh->print($log_sprintf->sprintf({
116             %struc,
117             message => $_,
118 1         5 }) . "\n") for @msg;
119 3 100       36 };
120             return
121 3         73 Log::Structured->new({
122             category => 'DBIC',
123             priority => 'TRACE',
124             caller_depth => 2,
125             log_event_listeners => [$sub],
126 7         12 map { $code_to_method{$_} => 1 }
127 3         10 grep { exists $code_to_method{$_} }
128             keys %formats
129             })
130             }
131             }
132              
133             has _format => (
134             is => 'ro',
135             init_arg => 'format',
136             );
137              
138             has _multiline_format => (
139             is => 'ro',
140             init_arg => 'multiline_format',
141             );
142              
143             sub print {
144 11     11 1 15 my $self = shift;
145 11         15 my $string = shift;
146 11   50     31 my $bindargs = shift || [];
147              
148 11         10 my ($lw, $lr);
149 11         93 ($lw, $string, $lr) = $string =~ /^(\s*)(.+?)(\s*)$/s;
150              
151 11 100 100     65 local $self->_sqlat->{fill_in_placeholders} = 0 if defined $bindargs->[0]
152             && $bindargs->[0] eq q('__BULK_INSERT__');
153              
154 11         53 my $use_placeholders = !!$self->_sqlat->fill_in_placeholders;
155              
156 11         21 my $sqlat = $self->_sqlat;
157 11         13 my $formatted;
158 11 100 100     56 if ($self->_squash_repeats && $self->_last_sql eq $string) {
159 3         3 my ( $l, $r ) = @{ $sqlat->placeholder_surround };
  3         7  
160 3         13 $formatted = '... : ' . join(', ', map "$l$_$r", @$bindargs)
161             } else {
162 8         25 $self->_last_sql($string);
163 8         28 $formatted = $sqlat->format($string, $bindargs);
164 8 100       6019 $formatted = "$formatted : " . join ', ', @{$bindargs}
  2         7  
165             unless $use_placeholders;
166             }
167              
168 11 100       167 if ($self->_structured_logger) {
169 3         3706 $self->_structured_logger->log_event({
170             message => "$lw$formatted$lr",
171             })
172             } else {
173 8         101 $self->next::method("$lw$formatted$lr", @_)
174             }
175             }
176              
177             sub query_start {
178 11     11 1 4687 my ($self, $string, @bind) = @_;
179              
180 11 50       58 if(defined $self->callback) {
181 0         0 $string =~ m/^(\w+)/;
182 0         0 $self->callback->($1, "$string: ".join(', ', @bind)."\n");
183 0         0 return;
184             }
185              
186 11         49 $string =~ s/\s+$//;
187              
188 11         40 $self->print("$string\n", \@bind);
189              
190 11 100       1533 $self->debugfh->print($self->_executing_str) if $self->_show_progress
191             }
192              
193             sub query_end {
194 3 100   3 1 510 $_[0]->debugfh->print($_[0]->_clear_line_str) if $_[0]->_show_progress
195             }
196              
197             1;
198              
199             __END__