.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{
. if \nF \{
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "Log::Handler::Examples 3pm"
.TH Log::Handler::Examples 3pm "2014-10-24" "perl v5.20.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
Log::Handler::Examples \- Examples.
.SH "CREATE LOGGER"
.IX Header "CREATE LOGGER"
Quite simple
.PP
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\& $log\->add( screen => \e%options );
.Ve
.PP
Create a application wide logger
.PP
.Vb 2
\& my $log = Log::Handler\->create_logger("myapp");
\& $log\->add( screen => \e%options );
.Ve
.PP
Once created you can use the application logger in all
modules of your project:
.PP
.Vb 2
\& package MyApp;
\& use Log::Handler;
\&
\& my $log = Log::Handler\->create_logger("myapp");
\& $log\->add( screen => \e%options );
\&
\& package MyApp::Admin;
\& use Log::Handler;
\&
\& my $log = Log::Handler\->get_logger("myapp");
\& $log\->info("message");
.Ve
.SH "ADD OUTPUTS"
.IX Header "ADD OUTPUTS"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->add( dbi => \e%options );
\& $log\->add( email => \e%options );
\& $log\->add( file => \e%options );
\& $log\->add( forward => \e%options );
\& $log\->add( screen => \e%options );
\& $log\->add( socket => \e%options );
.Ve
.PP
This is the same like
.PP
.Vb 6
\& $log\->add( "Log::Handler::Output::DBI" => \e%options );
\& $log\->add( "Log::Handler::Output::Email" => \e%options );
\& $log\->add( "Log::Handler::Output::File" => \e%options );
\& $log\->add( "Log::Handler::Output::Forward" => \e%options );
\& $log\->add( "Log::Handler::Output::Screen" => \e%options );
\& $log\->add( "Log::Handler::Output::Socket" => \e%options );
.Ve
.SH "RELOAD THE LOGGER"
.IX Header "RELOAD THE LOGGER"
.SS "Quite simple"
.IX Subsection "Quite simple"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->config(config => "logger.conf");
\&
\& $log\->reload(config => "logger.conf");
.Ve
.SS "Reload on \s-1HUP\s0"
.IX Subsection "Reload on HUP"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->config(config => "logger.conf");
\&
\& $SIG{HUP} = sub {
\& unless ($log\->reload(config => "logger.conf")) {
\& warn "unable to reload configuration";
\& warn $log\->errstr;
\& }
\& };
.Ve
.SS "Validate first"
.IX Subsection "Validate first"
It's possible to make a configuration check before you reload:
.PP
.Vb 2
\& $log\->validate(config => "logger.conf")
\& or warn $log\->errstr;
.Ve
.SH "LOG VIA DBI"
.IX Header "LOG VIA DBI"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& dbi => {
\& database => "database",
\& driver => "mysql",
\& host => "127.0.0.1",
\& port => 3306,
\& user => "user",
\& password => "password",
\& table => "messages",
\& columns => [ qw/level ctime cdate pid hostname caller progname mtime message/ ],
\& values => [ qw/%level %time %date %pid %hostname %caller %progname %mtime %message/ ],
\& maxlevel => "error",
\& minlevel => "emergency"
\& newline => 0,
\& message_pattern => "%L %T %D %P %H %C %S %t %m",
\& }
\& );
\&
\& $log\->error("log an error");
.Ve
.PP
Or with \f(CW\*(C`dbname\*(C'\fR
.PP
.Vb 10
\& $log\->add(
\& dbi => {
\& dbname => "database",
\& driver => "Pg",
\& host => "127.0.0.1",
\& port => 5432,
\& user => "user",
\& password => "password",
\& table => "messages",
\& columns => [ qw/level ctime cdate pid hostname caller progname mtime message/ ],
\& values => [ qw/%level %time %date %pid %hostname %caller %progname %mtime %message/ ],
\& maxlevel => "error",
\& minlevel => "emergency"
\& newline => 0,
\& message_pattern => "%L %T %D %P %H %C %S %t %m",
\& }
\& );
.Ve
.PP
Or with \f(CW\*(C`data_source\*(C'\fR
.PP
.Vb 12
\& $log\->add(
\& dbi => {
\& data_source => "dbi:SQLite:dbname=database.sqlite",
\& table => "messages",
\& columns => [ qw/level ctime cdate pid hostname caller progname mtime message/ ],
\& values => [ qw/%level %time %date %pid %hostname %caller %progname %mtime %message/ ],
\& maxlevel => "error",
\& minlevel => "emergency"
\& newline => 0,
\& message_pattern => "%L %T %D %P %H %C %S %t %m",
\& }
\& );
.Ve
.SH "LOG VIA EMAIL"
.IX Header "LOG VIA EMAIL"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& email => {
\& host => "mx.bar.example",
\& hello => "EHLO my.domain.example",
\& timeout => 30,
\& from => "bar@foo.example",
\& to => "foo@bar.example",
\& subject => "your subject",
\& buffer => 0,
\& maxlevel => "emergency",
\& minlevel => "emergency",
\& message_pattern => \*(Aq%L\*(Aq,
\& }
\& );
\&
\& $log\->emergency("log an emergency issue");
.Ve
.SH "LOG VIA SENDMAIL"
.IX Header "LOG VIA SENDMAIL"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& sendmail => {
\& from => "bar@foo.example",
\& to => "foo@bar.example",
\& subject => "your subject",
\& maxlevel => "error",
\& minlevel => "error",
\& message_pattern => \*(Aq%L\*(Aq,
\& }
\& );
\&
\& $log\->emergency("message");
.Ve
.SH "LOG VIA FILE"
.IX Header "LOG VIA FILE"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& file => {
\& filename => "file1.log",
\& maxlevel => 7,
\& minlevel => 0
\& }
\& );
\&
\& $log\->error("log an error");
.Ve
.SH "LOG VIA FORWARD"
.IX Header "LOG VIA FORWARD"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& forward => {
\& forward_to => \e&my_func,
\& message_pattern => [ qw/%L %T %P %H %C %S %t/ ],
\& message_layout => "%m",
\& maxlevel => "info",
\& }
\& );
\&
\& $log\->info("log a information");
\&
\& sub my_func {
\& my $params = shift;
\& print Dumper($params);
\& }
.Ve
.SH "LOG VIA SCREEN"
.IX Header "LOG VIA SCREEN"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& screen => {
\& log_to => "STDERR",
\& maxlevel => "info",
\& }
\& );
\&
\& $log\->info("log to the screen");
.Ve
.SH "LOG VIA SOCKET"
.IX Header "LOG VIA SOCKET"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& socket => {
\& peeraddr => "127.0.0.1",
\& peerport => 44444,
\& maxlevel => "info",
\& die_on_errors => 0,
\& }
\& );
\&
\& while ( 1 ) {
\& $log\->info("test")
\& or warn "unable to send message: ", $log\->errstr;
\& sleep 1;
\& }
.Ve
.SS "\s-1SIMPLE SOCKET SERVER \s0(\s-1TCP\s0)"
.IX Subsection "SIMPLE SOCKET SERVER (TCP)"
.Vb 4
\& use strict;
\& use warnings;
\& use IO::Socket::INET;
\& use Log::Handler::Output::File;
\&
\& my $sock = IO::Socket::INET\->new(
\& LocalAddr => "127.0.0.1",
\& LocalPort => 44444,
\& Listen => 2,
\& ) or die $!;
\&
\& my $file = Log::Handler::Output::File\->new(
\& filename => "file.log",
\& fileopen => 1,
\& reopen => 1,
\& );
\&
\& while ( 1 ) {
\& $file\->log(message => "waiting for next connection\en");
\&
\& while (my $request = $sock\->accept) {
\& my $ipaddr = sprintf("%\-15s", $request\->peerhost);
\& while (my $message = <$request>) {
\& $file\->log(message => "$ipaddr \- $message");
\& }
\& }
\& }
.Ve
.SH "DIFFERENT OUTPUTS"
.IX Header "DIFFERENT OUTPUTS"
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& file => {
\& filename => "common.log",
\& maxlevel => 6,
\& minlevel => 5,
\& }
\& );
\&
\& $log\->add(
\& file => {
\& filename => "error.log",
\& maxlevel => 4,
\& minlevel => 0,
\& }
\& );
\&
\& $log\->add(
\& email => {
\& host => "mx.bar.example",
\& hello => "EHLO my.domain.example",
\& timeout => 120,
\& from => "bar@foo.example",
\& to => "foo@bar.example",
\& subject => "your subject",
\& buffer => 0,
\& maxlevel => 0,
\& }
\& );
\&
\& # log to common.log
\& $log\->info("this is a info message");
\&
\& # log to error.log
\& $log\->warning("this is a warning");
\&
\& # log to error.log and to foo@bar.example
\& $log\->emergency("this is a emergency message");
.Ve
.SH "FILTER MESSAGES"
.IX Header "FILTER MESSAGES"
.Vb 1
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& screen => {
\& maxlevel => 6,
\& filter_message => {
\& match1 => "foo",
\& match2 => "bar",
\& match3 => "baz",
\& condition => "(match1 && match2) && !match3"
\& }
\& }
\& );
\&
\& $log\->info("foo");
\& $log\->info("foo bar");
\& $log\->info("foo baz");
.Ve
.SS "\s-1FILTER CALLER\s0"
.IX Subsection "FILTER CALLER"
This example shows you how it's possilbe to debug messages
only from a special namespace.
.PP
.Vb 1
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& file => {
\& filename => "file1.log",
\& maxlevel => "warning",
\& }
\& );
\&
\& $log\->add(
\& screen => {
\& maxlevel => "debug",
\& message_layout => "message from %p \- %m",
\& filter_caller => qr/^Foo::Bar\ez/,
\& }
\& );
\&
\& $log\->warning("a warning here");
\&
\& package Foo::Bar;
\& $log\->info("an info here");
\& 1;
.Ve
.SS "\s-1ANOTHER FILTER\s0"
.IX Subsection "ANOTHER FILTER"
.Vb 1
\& filter_message => "as string"
\&
\& filter_message => qr/as regexp/
\&
\& filter_message => sub { shift\->{message} =~ /as code ref/ }
\&
\& # or with conditions
\&
\& filter_message => {
\& match1 => "as string",
\& match2 => qr/as regexp/,
\& condition => "match1 || match2",
\& }
\&
\& filter_caller => "as string"
\&
\& filter_caller => qr/as regexp/
.Ve
.SH "CONFIG"
.IX Header "CONFIG"
Examples:
.PP
.Vb 1
\& my $log = Log::Handler\->new( config => "logger.conf" );
\&
\& # or
\&
\& $log\->add( config => "logger.conf" );
\&
\& # or
\&
\& $log\->config( config => "logger.conf" );
.Ve
.PP
Example with Config::General.
.PP
Script:
.PP
.Vb 1
\& use Log::Handler;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->config( config => "logger.conf" );
.Ve
.PP
Config (logger.conf):
.PP
.Vb 6
\&
\& alias = common
\& filename = example.log
\& maxlevel = info
\& minlevel = warn
\&
\&
\&
\& alias = error
\& filename = example\-error.log
\& maxlevel = warn
\& minlevel = emergency
\&
\&
\&
\& alias = debug
\& filename = example\-debug.log
\& maxlevel = debug
\& minlevel = debug
\&
\&
\&
\& log_to = STDERR
\& dump = 1
\& maxlevel = debug
\& minlevel = debug
\&
.Ve
.SH "CHECK FOR ACTIVE LEVELS"
.IX Header "CHECK FOR ACTIVE LEVELS"
It can be very useful if you want to check if a level is active.
.PP
.Vb 2
\& use Log::Handler;
\& use Data::Dumper;
\&
\& my $log = Log::Handler\->new();
\&
\& $log\->add(
\& file => {
\& filename => "file1.log",
\& maxlevel => 4,
\& }
\& );
\&
\& my %hash = (foo => 1, bar => 2);
.Ve
.PP
Now you want to dump the hash, but not in any case.
.PP
.Vb 4
\& if ( $log\->is_debug ) {
\& my $dump = Dumper(\e%hash);
\& $log\->debug($dump);
\& }
.Ve
.PP
This would dump the hash only if the level debug is active.
.SH "AUTHOR"
.IX Header "AUTHOR"
Jonny Schulz .