=head1 NAME

Log::Handler::Examples - Examples.

=head1 CREATE LOGGER

Quite simple

    use Log::Handler;

    my $log = Log::Handler->new();
    $log->add( screen => \%options );

Create a application logger and accessor LOG

    use Log::Handler myapp => 'LOG';

    LOG->add( screen => \%options );

Create a application logger without accessor

    use Log::Handler 'myapp';

    my $log = Log::Handler->get_logger('myapp');
    $log->add( screen => \%options );

Create application logger with C<create_logger()>

    use Log::Handler;

    my $log = Log::Handler->create_logger('myapp');
    $log->add( screen => \%options );

Another self-explanatory examples

    use Log::Handler l1 => 'LOG1', l2 => 'LOG2', l3 => 'LOG3';

    @logger = Log::Handler->create_logger(qw/l1 l2 l3/);

    @logger = Log::Handler->get_logger(qw/l1 l2 l3/);

Once created you can import a application logger into all
modules of your project:

    package MyApp;
    use Log::Handler myapp => 'LOG';
    LOG->add( screen => \%options );

    package MyApp::Foo;
    # Import it with an accessor
    use Log::Handler myapp => 'LOG';
    LOG->info('message');

    package MyApp::Bar;
    use Log::Handler;
    # Import it with get_logger()
    my $log = Log::Handler->get_logger('myapp');
    $log->info('message');

=head1 ADD OUTPUTS

    use Log::Handler;

    my $log = Log::Handler->new();

    $log->add( dbi     => \%options );
    $log->add( email   => \%options );
    $log->add( file    => \%options );
    $log->add( forward => \%options );
    $log->add( screen  => \%options );
    $log->add( socket  => \%options );

This is the same like

    $log->add( 'Log::Handler::Output::DBI'     => \%options );
    $log->add( 'Log::Handler::Output::Email'   => \%options );
    $log->add( 'Log::Handler::Output::File'    => \%options );
    $log->add( 'Log::Handler::Output::Forward' => \%options );
    $log->add( 'Log::Handler::Output::Screen'  => \%options );
    $log->add( 'Log::Handler::Output::Socket'  => \%options );

You can add output objects on this way as well:

    use Log::Handler;
    use Log::Handler::Output::File;

    my %file_options = (
        filename => 'file1.log',
        mode     => 'append'
    );

    my %handler_options = (
        maxlevel => 'info',
        newline  => 1
    );

    my $log  = Log::Handler->new();
    my $file = Log::Handler::Output::File->new( \%file_options );

    $log->add( $file => \%handler_options );

=head1 LOG VIA DBI

    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'
            message_pattern => '%L %T %D %P %H %C %S %t %m',
        }
    );

    $log->error('log an error');

Or with C<dbname>

    $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'
            message_pattern => '%L %T %D %P %H %C %S %t %m',
        }
    );

Or with C<data_source>

    $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'
            message_pattern => '%L %T %D %P %H %C %S %t %m',
        }
    );

=head1 LOG VIA EMAIL

    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',
        }
    );

    $log->emergency('log an emergency issue');

=head1 LOG VIA FILE

    use Log::Handler;

    my $log = Log::Handler->new();

    $log->add(
        file => {
            filename => 'file1.log',
            mode     => 'append',
            newline  => 1,
            maxlevel => 7,
            minlevel => 0
        }
    );

    $log->error('log an error');

=head1 LOG VIA FORWARD

    use Log::Handler;

    my $log = Log::Handler->new();

    $log->add(
        forward => {
            forward_to      => \&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);
    }

=head1 LOG VIA SCREEN

    use Log::Handler;

    my $log = Log::Handler->new();

    $log->add(
        screen => {
            log_to   => 'STDERR',
            newline  => 1,
            maxlevel => 'info',
        }
    );

    $log->info('log to the screen');

=head1 LOG VIA SOCKET

    use Log::Handler;

    my $log = Log::Handler->new();

    $log->add(
        socket => {
            peeraddr => '127.0.0.1',
            peerport => 44444,
            newline  => 1,
            maxlevel => 'info',
            die_on_errors => 0,
        }
    );

    while ( 1 ) {
        $log->info('test')
            or warn "unable to send message: ", $log->errstr;
        sleep 1;
    }

=head2 SIMPLE SOCKET SERVER (TCP)

    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',
        mode     => 'append',
        fileopen => 1,
        reopen   => 1,
    );

    while ( 1 ) {
        $file->log(message => "waiting for next connection\n");

        while (my $request = $sock->accept) {
            my $ipaddr = sprintf('%-15s', $request->peerhost);
            while (my $message = <$request>) {
                $file->log(message => "$ipaddr - $message");
            }
        }
    }

=head1 DIFFERENT OUTPUTS

    use Log::Handler;

    my $log = Log::Handler->new();

    $log->add(
        file => {
            filename => 'common.log',
            mode     => 'append',
            maxlevel => 6,
            minlevel => 5,
        }
    );

    $log->add(
        file => {
            filename => 'error.log',
            mode     => 'append',
            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");

=head1 FILTER MESSAGES

    my $log = Log::Handler->new();

    $log->add(
        screen => {
            newline  => 1,
            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');

=head2 FILTER CALLER

This example shows you how it's possilbe to debug messages
only from a special namespace.

    my $log = Log::Handler->new();

    $log->add(
        file => {
            filename => 'file1.log',
            mode     => 'append',
            newline  => 1,
            maxlevel => 'warning',
        }
    );

    $log->add(
        screen => {
            maxlevel => 'debug',
            newline  => 1,
            message_layout => 'message from %p - %m',
            filter_caller  => qr/^Foo::Bar\z/,
        }
    );

    $log->warning('a warning here');

    package Foo::Bar;
    $log->info('an info here');
    1;

=head2 ANOTHER FILTER

    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/

=head1 CONFIG

Examples with Config::General.

    <file>
        alias    = common
        filename = example.log
        maxlevel = info
        minlevel = warn
    </file>

    <file>
        alias    = error
        filename = example-error.log
        maxlevel = warn
        minlevel = emergency
    </file>

    <file>
        alias    = debug
        filename = example-debug.log
        maxlevel = debug
        minlevel = debug
    </file>

    <screen>
        log_to   = STDERR
        dump     = 1
        maxlevel = debug
        minlevel = debug
    </screen>

Or

    <file>
        <default>
            newline        = 1
            permissions    = 0640
            timeformat     = %b %d %H:%M:%S
            fileopen       = 1
            reopen         = 1
            mode           = append
            debug_mode     = 2
            message_layout = %T %H[%P] [%L] %S: %m
        </default>

        <common>
            filename = example.log
            maxlevel = info
            minlevel = warn
        </common>

        <error>
            filename = example-error.log
            maxlevel = warn
            minlevel = emergency
        </error>

        <debug>
            filename = example-debug.log
            maxlevel = debug
            minlevel = debug
        </debug>
    </file>

    <screen>
        <foo>
            log_to   = STDERR
            dump     = 1
            maxlevel = debug
            minlevel = debug
        </foo>
    </screen>

Script:

    use Log::Handler;

    my $log = Log::Handler->new();

    $log->config(config => 'file.conf');

=head1 CHECK FOR ACTIVE LEVELS

It can be very useful if you want to check if a level is active.

    use Log::Handler;
    use Data::Dumper;

    my $log = Log::Handler->new();

    $log->add(
        file => {
            filename   => 'file1.log',
            mode       => 'append',
            maxlevel   => 4,
        }
    );

    my %hash = (foo => 1, bar => 2);

Now you want to dump the hash, but not in any case.

    if ( $log->is_debug ) {
        my $dump = Dumper(\%hash);
        $log->debug($dump);
    }

This would dump the hash only if the level debug is active.

=head1 AUTHOR

Jonny Schulz <jschulz.cpan(at)bloonix.de>.

=cut
