File Coverage

blib/lib/Log/ger/Output/Screen.pm
Criterion Covered Total %
statement 45 62 72.5
branch 24 40 60.0
condition 0 9 0.0
subroutine 9 9 100.0
pod 0 4 0.0
total 78 124 62.9


line stmt bran cond sub pod time code
1             package Log::ger::Output::Screen;
2              
3             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
4             our $DATE = '2021-03-25'; # DATE
5             our $DIST = 'Log-ger-Output-Screen'; # DIST
6             our $VERSION = '0.017'; # VERSION
7              
8 2     2   4419 use strict;
  2         4  
  2         54  
9 2     2   9 use warnings;
  2         3  
  2         113  
10              
11             if ($^O eq 'MSWin32') {
12             eval { require Win32::Console::ANSI };
13             }
14              
15 2     2   10 use Log::ger::Util;
  2         5  
  2         1392  
16              
17             our %colors_16 = (
18             10 => "\e[31m" , # fatal , red
19             20 => "\e[35m" , # error , magenta
20             30 => "\e[1;34m", # warning, light blue
21             40 => "\e[32m" , # info , green
22             50 => "", # debug , no color
23             60 => "\e[33m" , # trace , orange
24             );
25              
26             our %colors_256 = (
27             # pastel'ish, all brighter and avoid pure red/blue which is hard to see on
28             # laptop screen in a bright environment
29              
30             10 => "\e[1;38;5;160m", # fatal , bright red3
31             20 => "\e[1;38;5;163m", # error , bright magenta3
32             30 => "\e[1;38;5;69m" , # warning, bright cornflowerblue
33             40 => "\e[1;38;5;113m", # info , bright darkolivegreen3
34             50 => "" , # debug , no color
35             60 => "\e[1;38;5;130m", # trace , bright darkorange3
36             );
37              
38             our %level_map;
39              
40             sub meta { +{
41 4     4 0 5834 v => 2,
42             } }
43              
44             sub _pick_color {
45 1     1   1 my ($level, $color_depth) = @_;
46 1 50       16 my $colors = $color_depth >= 256 ? \%colors_256 : \%colors_16;
47 1 50       5 if (defined(my $c = $colors->{$level})) {
48 1         23 return $c;
49             }
50 0 0       0 if (defined(my $clevel = $level_map{$level})) {
51 0         0 return $colors->{$clevel};
52             }
53              
54             # find the nearest
55 0         0 my ($dist, $clevel);
56 0         0 for my $k (keys %$colors) {
57 0         0 my $d = abs($k - $level);
58 0 0 0     0 if (!defined($dist) || $dist > $d) {
59 0         0 $dist = $d;
60 0         0 $clevel = $k;
61             }
62             }
63 0         0 $level_map{$level} = $clevel;
64 0         0 return $colors->{$clevel};
65             }
66              
67             sub hook_before_log {
68 7     7 0 15 my ($ctx, $msg) = @_;
69             }
70              
71             sub hook_after_log {
72 7     7 0 13 my ($ctx, $msg) = @_;
73 7 50       25 print { $ctx->{_fh} } "\n" unless $msg =~ /\R\z/;
  7         83  
74             }
75              
76             sub get_hooks {
77 4     4 0 46 my %plugin_conf = @_;
78              
79 4         7 my $stderr = $plugin_conf{stderr};
80 4 100       11 $stderr = 1 unless defined $stderr;
81 4 100       13 my $handle = $stderr ? \*STDERR : \*STDOUT;
82 4         4 my $use_color = do {
83 4 100       17 if (defined $plugin_conf{use_color}) {
    50          
    50          
84 1         2 $plugin_conf{use_color};
85             } elsif (exists $ENV{NO_COLOR}) {
86 0         0 0;
87             } elsif (defined $ENV{COLOR}) {
88 0         0 $ENV{COLOR};
89             } else {
90 3 100       26 $stderr ? (-t STDERR) : (-t STDOUT);
91             }
92             };
93 4         8 my $color_depth = do {
94 4 100 0     16 if (defined $plugin_conf{color_depth}) {
    50 0        
    50          
    0          
    0          
95 1         1 $plugin_conf{color_depth};
96             } elsif (defined $ENV{COLOR_DEPTH}) {
97 0         0 $ENV{COLOR_DEPTH};
98             } elsif (!$use_color) {
99 3         6 0;
100             } elsif (defined $ENV{COLORTERM} && $ENV{COLORTERM} eq 'truecolor') {
101 0         0 16777216;
102             } elsif (defined $ENV{TERM} && $ENV{TERM} =~ /256color/) {
103 0         0 256;
104             } else {
105 0         0 16;
106             }
107             };
108 4         6 my $formatter = $plugin_conf{formatter};
109              
110             return {
111             create_outputter => [
112             __PACKAGE__, # key
113             50, # priority
114             sub { # hook
115 16     16   8059 my %hook_args = @_; # see Log::ger::Manual::Internals/"Arguments passed to hook"
116             my $outputter = sub {
117 7         8928 my ($per_target_conf, $msg, $per_msg_conf) = @_;
118 7 100       12 my $level; $level = $per_msg_conf->{level} if $per_msg_conf; $level = $hook_args{level} unless defined $level;
  7 100       45  
  7         30  
119 7 50       16 if ($formatter) {
120 0         0 $msg = $formatter->($msg);
121             }
122 7         24 hook_before_log({ _fh=>$handle }, $msg);
123 7 100       18 if ($use_color) {
124 1         3 print $handle _pick_color($level, $color_depth), $msg, "\e[0m";
125             } else {
126 6         167 print $handle $msg;
127             }
128 7         34 hook_after_log({ _fh=>$handle }, $msg);
129 16         50 };
130 16         38 [$outputter];
131 4         31 }],
132             };
133             }
134              
135             1;
136             # ABSTRACT: Output log to screen
137              
138             __END__