File Coverage

blib/lib/Log/ger/Layout/LTSV.pm
Criterion Covered Total %
statement 86 87 98.8
branch 43 48 89.5
condition 5 18 27.7
subroutine 11 11 100.0
pod 0 1 0.0
total 145 165 87.8


line stmt bran cond sub pod time code
1             package Log::ger::Layout::LTSV;
2              
3             our $DATE = '2019-04-13'; # DATE
4             our $VERSION = '0.003'; # VERSION
5              
6 1     1   3611 use 5.010001;
  1         3  
7 1     1   7 use strict;
  1         2  
  1         20  
8 1     1   4 use warnings;
  1         2  
  1         25  
9              
10 1     1   469 use Devel::Caller::Util;
  1         422  
  1         44  
11 1     1   7 use Log::ger ();
  1         2  
  1         18  
12 1     1   489 use Time::HiRes qw(time);
  1         1261  
  1         4  
13              
14             our $time_start = time();
15             our $time_now = $time_start;
16             our $time_last = $time_start;
17              
18             sub _encode {
19 5     5   10 my ($pkg, $msg) = @_;
20              
21 5         8 my @res;
22 5         21 for my $l (sort keys %$msg) {
23 25         43 my $val = $msg->{$l};
24 25         40 $l =~ s/[:\t\n]+/ /g;
25 25         45 $val =~ s/[\t\n]+/ /g;
26 25         63 push @res, "$l:$val";
27             }
28 5         44 join("\t", @res);
29             }
30              
31             sub _layout {
32 5     5   11 my $pkg = shift;
33 5         10 my ($conf, $msg0, $init_args, $lnum, $level) = @_;
34              
35 5         39 ($time_last, $time_now) = ($time_now, time());
36 5         10 my %per_message_data;
37              
38             my $msg;
39 5 100       14 if (ref $msg0 eq 'HASH') {
40 3         12 $msg = {%$msg0};
41             } else {
42 2         26 $msg = {message => $msg0};
43             }
44              
45 5 100       19 if ($conf->{delete_fields}) {
46 1         2 for my $f (@{ $conf->{delete_fields} }) {
  1         3  
47 2 100       6 if (ref $f eq 'Regexp') {
48 1         3 for my $k (keys %$msg) {
49 2 100       12 delete $msg->{$k} if $k =~ $f;
50             }
51             } else {
52 1         2 delete $msg->{$f};
53             }
54             }
55             }
56              
57 5 100       12 if (my $ff = $conf->{add_fields}) {
58 1         3 for my $f (keys %$ff) {
59 1         3 $msg->{$f} = $ff->{$f};
60             }
61             }
62              
63 5 100       13 if (my $ff = $conf->{add_special_fields}) {
64 1         2 my %mentioned_specials;
65 1         6 for my $f (keys %$ff) {
66 15         28 $mentioned_specials{ $ff->{$f} }++;
67             }
68              
69 1 0 33     15 if (
      0        
      0        
70             $mentioned_specials{Class} ||
71             $mentioned_specials{File} ||
72             $mentioned_specials{Line} ||
73             $mentioned_specials{Location}
74             ) {
75             $per_message_data{caller0} =
76 1         8 [Devel::Caller::Util::caller (0, 0, $conf->{packages_to_ignore}, $conf->{subroutines_to_ignore})];
77             }
78 1 50 33     92 if (
79             $mentioned_specials{Location} ||
80             $mentioned_specials{Method}
81             ) {
82             $per_message_data{caller1} =
83 1         5 [Devel::Caller::Util::caller (1, 0, $conf->{packages_to_ignore}, $conf->{subroutines_to_ignore})];
84             }
85 1 50       94 if ($mentioned_specials{Stack_Trace}) {
86             $per_message_data{callers} =
87 1         4 [Devel::Caller::Util::callers(0, 0, $conf->{packages_to_ignore}, $conf->{subroutines_to_ignore})];
88             }
89              
90 1         166 for my $f (keys %$ff) {
91 15         24 my $sf = $ff->{$f};
92 15         20 my $val;
93 15 100       80 if ($sf eq 'Category') {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
94 1         2 $val = $init_args->{category};
95             } elsif ($sf eq 'Class') {
96 1         3 $val = $per_message_data{caller0}[0];
97             } elsif ($sf eq 'Date_Local') {
98 1         44 my @t = localtime($time_now);
99 1         11 $val = sprintf(
100             "%04d-%02d-%02dT%02d:%02d:%02d",
101             $t[5]+1900, $t[4]+1, $t[3],
102             $t[2], $t[1], $t[0],
103             );
104             } elsif ($sf eq 'Date_GMT') {
105 1         13 my @t = gmtime($time_now);
106 1         5 $val = sprintf(
107             "%04d-%02d-%02dT%02d:%02d:%02d",
108             $t[5]+1900, $t[4]+1, $t[3],
109             $t[2], $t[1], $t[0],
110             );
111             } elsif ($sf eq 'File') {
112 1         2 $val = $per_message_data{caller0}[1];
113             } elsif ($sf eq 'Hostname') {
114 1         529 require Sys::Hostname;
115 1         1072 $val = Sys::Hostname::hostname();
116             } elsif ($sf eq 'Location') {
117             $val = sprintf(
118             "%s (%s:%d)",
119             $per_message_data{caller1}[3] // '',
120             $per_message_data{caller0}[1],
121 1   50     8 $per_message_data{caller0}[2],
122             );
123             } elsif ($sf eq 'Line') {
124 1         3 $val = $per_message_data{caller0}[2];
125             } elsif ($sf eq 'Message') {
126 1         3 $val = $msg0;
127             } elsif ($sf eq 'Method') {
128 1   50     5 $val = $per_message_data{caller1}[3] // '';
129             } elsif ($sf eq 'Level') {
130 1         2 $val = $level;
131             } elsif ($sf eq 'PID') {
132 1         3 $val = $$;
133             } elsif ($sf eq 'Elapsed_Start') {
134 1         2 $val = $time_now - $time_start;
135             } elsif ($sf eq 'Elapsed_Last') {
136 1         2 $val = $time_now - $time_last;
137             } elsif ($sf eq 'Stack_Trace') {
138 6         21 $val = join(", ", map { "$_->[3] called at $_->[1] line $_->[2]" }
139 1         3 @{ $per_message_data{callers} });
  1         3  
140 0         0 } else { die "Unknown special field '$f'" }
141 15         52 $msg->{$f} = $val;
142             }
143             }
144 5         18 $pkg->_encode($msg);
145             }
146              
147             sub _get_hooks {
148 5     5   12 my $pkg = shift;
149 5         12 my %conf = @_;
150              
151             $conf{packages_to_ignore} //= [
152 5   50     32 "Log::ger",
153             "Log::ger::Layout::LTSV",
154             "Try::Tiny",
155             ];
156              
157             return {
158             create_layouter => [
159             $pkg, 50,
160             sub {
161 10     10   7023 my %args = @_;
162              
163 10         44 [sub { $pkg->_layout(\%conf, @_) }];
  5         5692  
164 5         36 }],
165             };
166             }
167              
168             sub get_hooks {
169 5     5 0 10500 __PACKAGE__->_get_hooks(@_);
170             }
171              
172             1;
173             # ABSTRACT: Layout log message as LTSV
174              
175             __END__