File Coverage

blib/lib/DBIx/LogProfile.pm
Criterion Covered Total %
statement 16 71 22.5
branch 0 26 0.0
condition 0 3 0.0
subroutine 6 10 60.0
pod 2 3 66.6
total 24 113 21.2


line stmt bran cond sub pod time code
1             package DBIx::LogProfile;
2 1     1   55384 use strict;
  1         2  
  1         24  
3 1     1   4 use warnings;
  1         2  
  1         21  
4 1     1   354 use parent 'DBI::Profile';
  1         251  
  1         4  
5 1     1   18876 use Log::Any;
  1         8488  
  1         4  
6 1     1   418 use Sub::Util 1.40;
  1         243  
  1         659  
7              
8             our $VERSION = 0.02;
9              
10             sub new {
11              
12 0     0 1   my $pkg = shift;
13              
14 0           my $self = $pkg->SUPER::new(
15             Log => 'Any',
16             OrderByDesc => 'longest_duration',
17             Limit => undef,
18             Level => 'trace',
19             @_,
20             );
21              
22             # sanity check the method name. if something like debugf is
23             # specified, strange things may happen, but not dangerous.
24 0 0         die unless $self->{Level} =~ /^[a-z]+$/;
25              
26 0 0         if ($self->{Log} eq 'Any') {
    0          
27              
28             } elsif ($self->{Log} eq 'Log4perl') {
29 0           eval "require Log::Log4perl";
30 0           eval "require Log::Log4perl::MDC";
31              
32             } else {
33 0           die "Bad Log parameter `$self->{Log}`. Must be Any or Log4perl."
34              
35             }
36              
37 0           DBI->trace_msg("$self: @{[ %$self ]}\n", 0)
38 0 0 0       if $self->{Trace} && $self->{Trace} >= 2;
39              
40 0           return $self;
41             }
42              
43             sub flush_to_logger {
44 0     0 1   my $self = shift;
45 0           my $class = ref $self;
46 0           my $data = $self->{Data};
47 0           my $method = $self->{Level};
48              
49 0           my @fields = qw/
50             count
51             total_duration
52             first_duration
53             shortest_duration
54             longest_duration
55             time_of_first_sample
56             time_of_last_sample
57             /;
58              
59             my @nodes = map {
60 0           my ($statistics, @keys) = @$_;
  0            
61              
62 0           my %h;
63 0           @h{ @fields } = @$statistics;
64              
65             my @mapped_path = map {
66 0           s/^&DBI::ProfileSubs::/&/;
67 0           $_
68             } map {
69 0 0         'CODE' eq ref($_)
70             ? '&' . Sub::Util::subname($_)
71             : $_
72 0           } @{ $self->{Path} };
  0            
73              
74 0           $h{path} = join ':', @mapped_path;
75              
76 0           for my $ix ( 0 .. @keys - 1 ) {
77 0           $h{ $mapped_path[ $ix ] } = $keys[ $ix ];
78             }
79              
80 0           \%h;
81              
82             } $self->as_node_path_list();
83              
84 0           my @sorted;
85            
86 0 0         if ($self->{OrderByDesc} !~ /^[^a-z]/) {
87             @sorted = sort {
88 0           $b->{ $self->{OrderByDesc} }
89             <=>
90             $a->{ $self->{OrderByDesc} }
91 0           } @nodes;
92              
93             } else {
94             @sorted = sort {
95 0           $b->{ $self->{OrderByDesc} }
96             cmp
97             $a->{ $self->{OrderByDesc} }
98            
99 0           } @nodes;
100            
101             }
102              
103 0           my $counter = 0;
104              
105 0           eval {
106              
107 0           for my $h (@sorted) {
108              
109 0 0         if ($self->{Log} eq 'Log4perl') {
    0          
110 0           my $ctx = Log::Log4perl::MDC->get_context();
111              
112 0           local @{ $ctx }{ keys %$h } = values %$h;
  0            
113              
114 0           Log::Log4perl->get_logger()->$method(__PACKAGE__);
115              
116             } elsif ($self->{Log} eq 'Any') {
117 0           Log::Any->get_logger()->$method(__PACKAGE__, $h);
118              
119             }
120              
121 0 0         if (defined $self->{Limit}) {
122 0 0         last if ++$counter >= $self->{Limit};
123             }
124             }
125              
126             };
127              
128 0 0         if ($@) {
129              
130 0           Log::Any->get_logger()->errorf(
131             "%s caught exception: %s",
132             __PACKAGE__,
133             $@
134             );
135              
136             }
137              
138 0           $self->empty();
139              
140             }
141              
142             sub on_destroy {
143 0     0 0   my ($self) = @_;
144 0 0         return if ${^GLOBAL_PHASE} eq 'DESTRUCT';
145 0           $self->flush_to_logger();
146             }
147              
148             sub DESTROY {
149 0     0     on_destroy(@_);
150             }
151              
152             END {
153              
154             DBI->visit_handles(sub {
155 0           my ($dbh, $info) = @_;
156 0 0         return unless UNIVERSAL::isa($dbh->{Profile}, __PACKAGE__);
157 0           $dbh->{Profile}->flush_to_logger();
158 1     1   170 });
159              
160             };
161              
162             1;
163              
164             __END__