File Coverage

blib/lib/Log/Pony.pm
Criterion Covered Total %
statement 101 102 99.0
branch 10 12 83.3
condition 4 5 80.0
subroutine 28 28 100.0
pod 13 15 86.6
total 156 162 96.3


line stmt bran cond sub pod time code
1             package Log::Pony;
2 6     6   149097 use strict;
  6         16  
  6         381  
3 6     6   30 use warnings;
  6         10  
  6         171  
4 6     6   1260 use utf8;
  6         22  
  6         55  
5 6     6   464 use 5.008005;
  6         21  
  6         487  
6             our $VERSION = '1.0.1';
7 6     6   30 use Carp ();
  6         16  
  6         101  
8 6     6   8191 use Term::ANSIColor ();
  6         66749  
  6         333  
9             use Class::Accessor::Lite (
10 6         45 ro => [qw/color log_level/],
11 6     6   6476 );
  6         6945  
12              
13             our $TRACE_LEVEL = 0;
14              
15             __PACKAGE__->set_levels(qw( debug info warn critical error));
16             __PACKAGE__->set_colors( 'red on_white', 'green', 'black on_yellow', 'black on_red', 'red on_black');
17              
18             sub new {
19 10     10 1 12810 my $class = shift;
20 10 50       63 my %args = @_ == 1 ? %{$_[0]} : @_;
  0         0  
21 10 50       50 my $log_level = delete $args{log_level}
22             or Carp::croak("Missing mandatory parameter: log_level");
23 10         25 $log_level = uc($log_level);
24 10   100     68 my $color = delete $args{color} || 0;
25 10         50 my $self = bless {
26             log_level => $log_level,
27             log_level_n => $class->level_to_number($log_level),
28             color => $color,
29             }, $class;
30 10         48 $self->init(%args);
31 10         27 return $self;
32             }
33              
34 10     10 1 15 sub init { }
35              
36             sub set_colors {
37 6     6 1 17 my ($class, @colors) = @_;
38 6     6   1559 no strict 'refs';
  6         13  
  6         4961  
39 6     4   17 *{"${class}::colors"} = sub { @colors };
  6         30  
  4         11  
40             }
41              
42             sub colorize {
43 4     4 1 5 my ($self, $level, $message) = @_;
44 4         7 my $n = $self->level_to_number($level);
45 4         8 my @colors = $self->colors();
46 4   66     13 my $color = $colors[$n] || $colors[-1];
47 4         14 return Term::ANSIColor::colored([$color], $message);
48             }
49              
50             sub log {
51 26     26 1 69 my ($self, $level, $format, @args) = @_;
52 26 100       54 return if $self->level_to_number($level) < $self->{log_level_n};
53 24         37 local $TRACE_LEVEL = $TRACE_LEVEL + 1;
54 24         173 $self->process($level, $self->sanitize(sprintf($format, @args)));
55             }
56              
57             sub trace_info {
58 10     10 1 32 my $self = shift;
59 10         81 my @caller = caller($TRACE_LEVEL+1);
60 10         51 return "at $caller[1] line $caller[2]";
61             }
62              
63             sub sanitize {
64 25     25 0 41 my ($self, $message) = @_;
65 25         63 $message =~ s/\x0a\z//g;
66 25         39 $message =~ s/\x0d/\\r/g;
67 25         39 $message =~ s/\x0a/\\n/g;
68 25         37 $message =~ s/\x09/\\t/g;
69 25         216 return $message;
70             }
71              
72             sub time {
73 6     6 1 569 my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time);
74 6         47 return sprintf( "%04d-%02d-%02dT%02d:%02d:%02d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec );
75             }
76              
77             sub process {
78 5     5 1 6 my ($self, $level, $message) = @_;
79 5         15 my $time = $self->time();
80 5         22 my $trace = $self->trace_info();
81 5 100       19 if ($self->color) {
82 4         31 $message = $self->colorize($level, $message);
83             }
84 5         402 print STDERR "$time [$level] $message $trace\n";
85             }
86              
87             sub info {
88 8     8 1 44 my $self = shift;
89 8         22 local $TRACE_LEVEL = $TRACE_LEVEL + 1;
90 8         40 $self->log(INFO => @_);
91             }
92              
93             sub warn {
94 5     5 1 53 my $self = shift;
95 5         16 local $TRACE_LEVEL = $TRACE_LEVEL + 1;
96 5         15 $self->log(WARN => @_);
97             }
98              
99             sub critical {
100 4     4 1 35 my $self = shift;
101 4         7 local $TRACE_LEVEL = $TRACE_LEVEL + 1;
102 4         13 $self->log(CRITICAL => @_);
103             }
104              
105             sub debug {
106 5     5 1 904 my $self = shift;
107 5         12 local $TRACE_LEVEL = $TRACE_LEVEL + 1;
108 5         86 $self->log(DEBUG => @_);
109             }
110              
111             sub set_levels {
112 7     7 1 42 my ($class, @levels) = @_;
113 7         13 my $i = 1;
114 7         18 my %levels = map { uc($_) => $i++ } @levels;
  35         107  
115 7         23 for my $level (@levels) {
116 35 100       250 unless ($class->can($level)) {
117 7         30 $class->mk_level_accessor($level);
118             }
119             }
120 6     6   34 no strict 'refs';
  6         10  
  6         880  
121 7         46 *{"${class}::level_to_number"} = sub {
122 40     40   170 my ($class, $level) = @_;
123 40 100       305 my $number = $levels{uc $level}
124             or Carp::croak("Unknown logging level: $level");
125 39         163 return $number;
126 7         30 };
127             }
128              
129             sub mk_level_accessor {
130 7     7 0 15 my ($class, $level) = @_;
131 7         19 my $LEVEL = uc($level);
132 7         23 $level = lc($level);
133 6     6   82 no strict 'refs';
  6         10  
  6         759  
134 7         51 *{"${class}::${level}"} = sub {
135 3     3   21 my $self = shift;
136 3         6 local $TRACE_LEVEL = $TRACE_LEVEL + 1;
137 3         15 $self->log($LEVEL => @_);
138 7         33 };
139             }
140              
141             1;
142             __END__