File Coverage

blib/lib/Log/Log4perl/Layout/LTSV.pm
Criterion Covered Total %
statement 45 46 97.8
branch 3 4 75.0
condition 1 3 33.3
subroutine 12 12 100.0
pod 2 2 100.0
total 63 67 94.0


line stmt bran cond sub pod time code
1             package Log::Log4perl::Layout::LTSV;
2              
3 2     2   124804 use 5.008_001;
  2         7  
4 2     2   12 use strict;
  2         4  
  2         50  
5 2     2   9 use warnings;
  2         8  
  2         75  
6 2     2   2000 use Encode;
  2         23151  
  2         250  
7 2     2   1248 use Log::Log4perl;
  2         52502  
  2         16  
8 2     2   1831 use POSIX qw(strftime);
  2         14774  
  2         15  
9 2     2   2906 use base qw(Log::Log4perl::Layout::PatternLayout);
  2         5  
  2         1249  
10              
11             $Log::Log4perl::ALLOW_CODE_IN_CONFIG_FILE = 1;
12              
13             =head1 NAME
14              
15             Log::Log4perl::Layout::LTSV - Log4perl for LTSV
16              
17             =head1 VERSION
18              
19             Version 1.0
20              
21             =cut
22              
23             our $VERSION = '1.0';
24              
25             =head1 SYNOPSIS
26              
27             Log4perl implementation of LTSV.
28              
29             =head1 CONFIGURATION SAMPLE
30              
31             use Log::Log4perl
32             my $logger_conf = {
33             'log4perl.logger.test' => 'DEBUG, SERVER',
34             'log4perl.appender.SERVER' => 'Log::Log4perl::Appender::Socket',
35             'log4perl.appender.SERVER.PeerAddr' => '10.1.2.3',
36             'log4perl.appender.SERVER.PeerPort' => '514',
37             'log4perl.appender.SERVER.Proto' => 'tcp',
38             'log4perl.appender.SERVER.layout' => 'LTSV',
39             'log4perl.appender.SERVER.layout.facility' => 'Custom facility'
40             };
41             Log::Log4perl->init($logger_conf);
42             my $LOGGER = Log::Log4perl->get_logger('test');
43             $LOGGER->debug('Debug log');
44             ...
45              
46             =cut
47              
48             =head1 SUBROUTINES/METHODS
49              
50             =head2 new
51              
52             Can take most of options that Log::Log4perl::Layout::PatternLayout can.
53              
54             =cut
55              
56             sub new {
57 2     2 1 3274 my $class = shift;
58 2   33     14 $class = ref($class) || $class;
59 2 100       10 my $options = ref $_[0] eq 'HASH' ? shift : {};
60 2         21 my $record = {
61             'time' => '%Z',
62             'host' => '%H',
63             'message' => '%m{chomp}',
64             'level' => '%Y',
65             'facility' => '%M',
66             'file' => '%F',
67             'line' => '%L',
68             'pid' => '%P',
69             };
70 2         7 while ( my ($key) = each %{ $options->{field} } ) {
  2         13  
71 0         0 $record->{$key} = $options->{field}->{$key}->{value};
72             }
73 2         11 my $conversion_pattern = _encode_ltsv($record);
74 2         9 $options->{ConversionPattern} = { value => $conversion_pattern };
75             $options->{cspec} = {
76             'Y' => { value => \&_level_converter },
77             'Z' => {
78             value => sub {
79 5     5   684 return strftime( '[%Y-%m-%dT%H:%M:%SZ]', gmtime( time() ) );
80             }
81             }
82 2         20 };
83 2         29 return $class->SUPER::new($options);
84             }
85              
86             sub _encode_ltsv {
87 2     2   5 my $hash = shift;
88 2         4 my @res;
89 2         12 while ( my ($key, $value) = each %$hash ) {
90 16         27 $value =~ s/[\r\n\t]/ /g;
91 16 50       61 if ( not Encode::is_utf8( $value, 1 ) ) {
92 16         58 $value = Encode::encode( 'UTF-8', $value, Encode::FB_CROAK );
93 16         870 Encode::_utf8_on($value);
94             }
95 16         78 push( @res, join( ':', $key, $value ) );
96             }
97 2         10 return join( "\t", @res );
98             }
99              
100             sub _level_converter {
101 5     5   160 my ( $layout, $message, $category, $priority, $caller_level ) = @_;
102 5         20 my $levels = {
103             'FATAL' => 2,
104             'ERROR' => 3,
105             'WARN' => 4,
106             'NOTICE' => 5,
107             'INFO' => 6,
108             'DEBUG' => 7
109             };
110 5         22 return $levels->{$priority};
111             }
112              
113             =head2 render
114              
115             Wraps the Log::Log4perl::Layout::PatternLayout return value
116              
117             =cut
118              
119             sub render {
120 5     5 1 1661 my ( $self, $message, $category, $priority, $caller_level ) = @_;
121 5         20 return $self->SUPER::render( $message, $category, $priority, $caller_level )
122             . "\n";
123             }
124             1;