NAME

Log::ger::Manual::Tutorial::490_WritingAnOutputPlugin - Writing an output plugin

VERSION

version 0.040.000

DESCRIPTION

A lot of output plugins have been written. Search CPAN for Log::ger::Output::* modules. If none suits your needs, there's still Log::ger::Output::LogDispatchOutput which can use a Log::Dispatch output module (of which there are many), or Log::ger::Output::Callback which lets you supply just a coderef to do the logging.

If you really want to write your own Log::ger output plugin, the following will show you how. Let's say we want to log to some logging server using a client library called Lancard. Create Log::ger::Output::Lancard as follows:

# in lib/Log/ger/Output/Lancard.pm
package Log::ger::Output::Lancard;

use 5.010;
use strict;
use warnings;

sub meta { +{
    v => 2,
} }

sub get_hooks {
    require Lancard::Client;
    my %plugin_conf = @_;

    $plugin_conf{host} or die "Please specify host";

    my $lancard = Lancard::Client->connect(
        host => $plugin_conf{host},
        port => $plugin_conf{port} // 12345,
    );

    return {
        create_outputter => [
            __PACKAGE__, # key
            50,          # priority
            sub {        # hook
                my %hook_args = @_;
                my $outputter = sub {
                    my ($ctx, $msg) = @_;
                    $lancard->log($msg);
                };
                [$outputter];
            }
        },
    };
}

1;

First of all, the plugin needs to define meta() that returns a hashref where the required key is v set to 2. This is a way to do API versioning so Log::ger can reject plugins with incompatible API version.

The only subroutine you have to provide is get_hooks to return the hooks that this plugin wants to add. For output plugin, usually this is hook in the create_outputter. Our get_hooks should return a hashref with phase names as keys and hook records as values. Hook record is [$key, $priority, $hook] where $key is usually __PACKAGE__, and $priority is usually 50 unless you want to do something tricky or advanced.

At this point, it will really help if you understand how hooks work by reading Log::ger::Manual::Internals. But, without reading the said documentation, it's still possible to write an output plugin so let's continue right away if you want to skip reading the internals documentation.

The actual hook coderef ($hook) should return an outputter routine, which is another coderef ($outputter in the above code). Outputter will receive ($per_target_conf, $msg, $per_msg_conf) as argument where $msg is the already-formatted message. You typically just need to send $msg (which is almost always a string) to some output. In our example, we send the log message string to the logging server via the client object $lancard.

Note that a separate logger routine will be created for each logging level (and for each target package that uses logging!), so you'd want to keep $outputter small, like avoid instantiating your Lancard client $lancard inside $outputter as there will be multiple clients instantiated.

To use your newly written output plugin, do the usual:

use Log::ger::Output Lancard => (host => '192.168.0.22');

or:

use Log::ger::Output;
Log::ger::Output->set(Lancard => (host => '192.168.0.22'));

SEE ALSO

AUTHOR

perlancar <perlancar@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2022, 2020, 2019, 2018, 2017 by perlancar <perlancar@cpan.org>.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.