NAME
    Log::ger - A lightweight, flexible logging framework

VERSION
    version 0.041

SYNOPSIS
  Producing logs
    In your module (producer):

     package MyModule;

     # this will install some logger routines. by default: log_trace, log_debug,
     # log_info, log_warn, log_error, and log_fatal. level checker routines are also
     # installed: log_is_trace, log_is_debug, and so on.
     use Log::ger;

     sub foo {
         ...
         # produce some logs. no need to configure output or level. by default
         # output goes nowhere.
         log_error "an error occured: %03d - %s", $errcode, $errmsg;
         ...

         # the logging routines (log_*) can automatically dump data structures
         log_debug "http response: %s", $http;

         # log_fatal does not die by default, if you want to then die() explicitly.
         # but there are plugins that let you do this or provide log_die etc.
         if (blah) { log_fatal "..."; die }

         # use the level checker routines (log_is_*) to avoid doing unnecessary
         # heavy calculation
         if (log_is_trace) {
             my $res = some_heavy_calculation();
             log_trace "The result is %s", $res;
         }

     }
     1;

  Consuming logs
   Choosing an output
    In your application (consumer/listener):

     use MyModule;
     use Log::ger::Output 'Screen'; # configure output
     # level is by default 'warn'
     foo(); # the error message is shown, but debug/trace messages are not.

   Choosing multiple outputs
    Instead of screen, you can output to multiple outputs (including
    multiple files):

     use Log::ger::Output 'Composite' => (
         outputs => {
             Screen => {},
             File   => [
                 {conf=>{path=>'/path/to/app.log'}},
                 ...
             ],
             ...
         },
     );

    See Log::ger::Manual::Tutorial::481_Output_Composite for more examples.

    There is also Log::ger::App that wraps this in a simple interface so you
    just need to do:

     # In your application or script:
     use Log::ger::App;
     use MyModule;

   Choosing level
    One way to set level:

     use Log::ger::Util;
     Log::ger::Util::set_level('debug'); # be more verbose
     foo(); # the error message as well as debug message are now shown, but the trace is not

    There are better ways, e.g. letting users configure log level via
    configuration file or command-line option. See
    Log::ger::Manual::Tutorial::300_Level for more details.

DESCRIPTION
    Log::ger is yet another logging framework with the following features:

    *   Separation of producers and consumers/listeners

        Like Log::Any, this offers a very easy way for modules to produce
        some logs without having to configure anything. Configuring output,
        level, etc can be done in the application as log
        consumers/listeners. To read more about this, see the documentation
        of Log::Any or Log::ger::Manual (but nevertheless see
        Log::ger::Manual on why you might prefer Log::ger to Log::Any).

    *   Lightweight and fast

        Slim distribution. No non-core dependencies, extra functionalities
        are provided in separate distributions to be pulled as needed.

        Low startup overhead. Only ~0.5-1ms. For comparison, strict
        ~0.2-0.5ms, warnings ~2ms, Log::Any (v0.15) ~2-3ms, Log::Any
        (v1.049) ~8-10ms, Log::Log4perl ~35ms. This is measured on a
        2014-2015 PC and before doing any output configuration. I strive to
        make "use Log::ger;" statement to be roughly as light as "use
        strict;" or "use warnings;" so the impact of adding the statement is
        really minimal and you can just add logging without much thought to
        most of your modules. This is important to me because I want logging
        to be pervasive.

        To test for yourself, try e.g. with bencher-code:

         % bencher-code 'use Log::ger' 'use Log::Any' --startup

        Fast. Low null-/stealth-logging overhead, about 1.5x faster than
        Log::Any, 3x faster than Log4perl, 5x faster than Log::Fast, ~40x
        faster than Log::Contextual, and ~100x faster than Log::Dispatch.

        For more benchmarks, see Bencher::Scenarios::Log::ger.

        Conditional compilation. There is a plugin to optimize away unneeded
        logging statements, like assertion/conditional compilation, so they
        have zero runtime performance cost. See Log::ger::Plugin::OptAway.

        Being lightweight means the module can be used more universally,
        from CLI to long-running daemons to inside routines with tight
        loops.

    *   Flexible

        Customizable levels and routine/method names. Can be used in a
        procedural or OO style. Log::ger can mimic the interface of
        Log::Any, Log::Contextual, Log::Log4perl, or some other popular
        logging frameworks, to ease migration or adjust with your personal
        style.

        Per-package settings. Each importer package can use its own
        format/layout, output. For example, a module that is migrated from
        Log::Any uses Log::Any-style logging, while another uses native
        Log::ger style, and yet some other uses block formatting like
        Log::Contextual. This eases code migration and teamwork. Each module
        author can preserve her own logging style, if wanted, and all the
        modules still use the same framework.

        Dynamic. Outputs and levels can be changed anytime during run-time
        and logger routines will be updated automatically. This is useful in
        situation like a long-running server application: you can turn on
        tracing logs temporarily to debug problems, then turn them off
        again, without restarting your server.

        Interoperability. There are modules to interop with Log::Any, either
        consume Log::Any logs (see Log::Any::Adapter::LogGer) or produce
        logs to be consumed by Log::Any (see Log::ger::Output::LogAny).

        Many output modules and plugins. See "Log::ger::Output::*",
        "Log::ger::Format::*", "Log::ger::Layout::*", "Log::ger::Plugin::*".
        Writing an output module in Log::ger is easier than writing a
        Log::Any::Adapter::*.

    For more documentation, start with Log::ger::Manual.

SEE ALSO
    Some other popular logging frameworks: Log::Any, Log::Contextual,
    Log::Log4perl, Log::Dispatch, Log::Dispatchouli.

    If you still prefer debugging using the good old print(), there's
    Debug::Print.

AUTHOR
    perlancar <perlancar@cpan.org>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2023, 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.