Imported Upstream version 0.03
This commit is contained in:
165
lib/Log/Log4perl/Layout/GELF.pm
Normal file
165
lib/Log/Log4perl/Layout/GELF.pm
Normal file
@@ -0,0 +1,165 @@
|
||||
##################################################
|
||||
package Log::Log4perl::Layout::GELF;
|
||||
##################################################
|
||||
|
||||
use 5.006;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use JSON::XS;
|
||||
use IO::Compress::Gzip qw( gzip $GzipError );
|
||||
use Log::Log4perl;
|
||||
|
||||
use base qw(Log::Log4perl::Layout::PatternLayout);
|
||||
|
||||
# We need to define our own cspecs
|
||||
$Log::Log4perl::ALLOW_CODE_IN_CONFIG_FILE = 1;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Log::Log4perl::Layout::GELF - Log4perl for graylog2
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.03
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = '0.03';
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Log4perl implementation of GELF. When used with
|
||||
Log::Log4perl::Appender::Socket you can log directly
|
||||
to a graylog2 server.
|
||||
|
||||
=cut
|
||||
|
||||
=head1 What is graylog?
|
||||
|
||||
Graylog is log management server that can be used to run analytics,
|
||||
alerting, monitoring and perform powerful searches over your whole
|
||||
log base. Need to debug a failing request? Just run a quick filter
|
||||
search to find it and see what errors it produced. Want to see all
|
||||
messages a certain API consumer is consuming in real time? Create
|
||||
streams for every consumer and have them always only one click away.
|
||||
|
||||
=cut
|
||||
|
||||
=head1 Configuration Sample
|
||||
|
||||
Code snippet. Replace the ip with your graylog server.
|
||||
|
||||
use Log::Log4perl
|
||||
my $logger_conf = {
|
||||
'log4perl.logger.graylog' => "DEBUG, SERVER",
|
||||
'log4perl.appender.SERVER' => "Log::Log4perl::Appender::Socket",
|
||||
'log4perl.appender.SERVER.PeerAddr' => '10.211.1.94',
|
||||
'log4perl.appender.SERVER.PeerPort' => "12201",
|
||||
'log4perl.appender.SERVER.Proto' => "udp",
|
||||
'log4perl.appender.SERVER.layout' => "GELF"
|
||||
};
|
||||
Log::Log4perl->init( $logger_conf );
|
||||
my $LOGGER = Log::Log4perl->get_logger('graylog');
|
||||
$LOGGER->debug("Debug log");
|
||||
...
|
||||
=cut
|
||||
|
||||
=head1 SUBROUTINES/METHODS
|
||||
|
||||
=head2 new
|
||||
|
||||
Can take most of options that Log::Log4perl::Layout::PatternLayout can.
|
||||
|
||||
Additional Options:
|
||||
PlainText - outputs plaintext and not gzipped files.
|
||||
|
||||
=cut
|
||||
sub new {
|
||||
my $class = shift;
|
||||
$class = ref ($class) || $class;
|
||||
|
||||
my $options = ref $_[0] eq "HASH" ? shift : {};
|
||||
|
||||
# Creating object to make changes easier
|
||||
my $gelf_format = {
|
||||
"version" => "1.0",
|
||||
"host" => "%H",
|
||||
"short_message" => "%m{chomp}",
|
||||
"timestamp" => "%Z", # custom cspec
|
||||
"level"=> "%Y", # custom cspec
|
||||
"facility"=> "%M",
|
||||
"file"=> "%F",
|
||||
"line"=> "%L",
|
||||
"_pid" => "%P",
|
||||
};
|
||||
# make a JSON string
|
||||
my $conversion_pattern = encode_json($gelf_format);
|
||||
|
||||
$options->{ConversionPattern} = { value => $conversion_pattern } ;
|
||||
|
||||
# Since we are building on top of PatternLayout, we can define our own
|
||||
# own patterns using a "cspec".
|
||||
$options->{cspec} = {
|
||||
'Z' => { value => sub {return time } },
|
||||
'Y' => { value => \&_level_converter } ,
|
||||
};
|
||||
|
||||
my $self = $class->SUPER::new($options);
|
||||
|
||||
# to help with debugging. you can skip the bzipping.
|
||||
$self->{PlainText} = 0;
|
||||
if(defined $options->{PlainText}->{value} ){
|
||||
$self->{PlainText} = $options->{PlainText}->{value};
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
# Maps over the syslog levels from Log4perl levels.
|
||||
|
||||
# Syslog Levels for Reference
|
||||
# 0 Emergency: system is unusable
|
||||
# 1 Alert: action must be taken immediately
|
||||
# 2 Critical: critical conditions
|
||||
# 3 Error: error conditions
|
||||
# 4 Warning: warning conditions
|
||||
# 5 Notice: normal but significant condition
|
||||
# 6 Informational: informational messages
|
||||
# 7 Debug: debug-level messages
|
||||
sub _level_converter {
|
||||
my ($layout, $message, $category, $priority, $caller_level) = @_;
|
||||
# TODO Replace with a case statement
|
||||
my $levels = {
|
||||
"DEBUG" => 7,
|
||||
"INFO" => 6,
|
||||
"NOTICE"=> 5,
|
||||
"WARN" => 4,
|
||||
"ERROR" => 3,
|
||||
"FATAL" => 2
|
||||
};
|
||||
return $levels->{$priority};
|
||||
}
|
||||
|
||||
=head2 render
|
||||
|
||||
Wraps the Log::Log4perl::Layout::PatternLayout return value so we can
|
||||
gzip the JSON string.
|
||||
|
||||
=cut
|
||||
|
||||
sub render {
|
||||
my($self, $message, $category, $priority, $caller_level) = @_;
|
||||
my $encoded_message = $self->SUPER::render($message, $category, $priority, $caller_level);
|
||||
|
||||
# makes debugging easier
|
||||
if( defined $self->{PlainText} && $self->{PlainText} ){
|
||||
return $encoded_message;
|
||||
}
|
||||
|
||||
# Graylog2 servers require gzipped messesages.
|
||||
my $gzipped_message;
|
||||
gzip \$encoded_message => \$gzipped_message or die "gzip failed: $GzipError\n";
|
||||
return $gzipped_message;
|
||||
}
|
||||
1;
|
||||
Reference in New Issue
Block a user