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