NAME
    Log::Any::App - An easy way to use Log::Any in applications

VERSION
    version 0.27

SYNOPSIS
        # in your script/application
        use Log::Any::App qw($log);

        # or, in command line
        % perl -MLog::Any::App -MModuleThatUsesLogAny -e ...

DESCRIPTION
    Log::Any makes life easy for module authors. All you need to do is:

     use Log::Any qw($log);

    and you're off producing logs with $log->debug(), $log->info(),
    $log->error(), etc. That's it. The task of consuming logs (setting up
    each output, deciding which messages gets to which output, etc) rests on
    the shoulder of module users.

    Life is not equally easy for the module users (or application authors)
    though. The typical incantation to consume logs (assuming we use the
    Log::Log4perl adapter) is:

     use Log::Any qw($log);
     use Log::Any::Adapter;
     use Log::Log4perl;
     my $log4perl_config = '
       some
       long
       multiline
       config...';
     Log::Log4perl->init(\$log4perl_config);
     Log::Any::Adapter->set('Log4perl');

    Frankly, I couldn't possibly remember all that (especially the details
    of Log4perl configuration), hence Log::Any::App. The goal of
    Log::Any::App is to make life equally easy for log consumers. All you
    need to do is:

     use Log::Any::App qw($log);

    or, from the command line:

     perl -MLog::Any::App='$log' -MModuleThatUsesLogAny -e ...

    and you can display the logs in screen, file(s), syslog, etc. You can
    also log using $log->debug(), etc as usual. Most of the time you don't
    need to configure anything as Log::Any::App will construct the most
    appropriate default Log4perl config for your application.

    I mostly use Log::Any;:App in oneliners and simple to medium scripts
    whenever I have to use Log::Any-using modules (for example: Data::Schema
    and Config::Tree).

USING AND EXAMPLES
    Using Log::Any::App is very easy. Most of the time you just need to do
    this from command line:

     % perl -MLog::Any::App -MModuleThatUsesLogAny -e ...

    or from a script:

     use ModuleThatUsesLogAny;
     use Log::Any::App '$log';

    This will send logs to screen as well as file (~/$SCRIPT_NAME.log or
    /var/log/$SCRIPT_NAME.log if running as root, command-line scripts by
    default do not log to file) with the default level of 'warn'. This means
    $log->error("foo") will display, while $log->info("bar") will not.

    The 'use Log::Any::App' statement can be issued before or after the
    modules that use Log::Any, it doesn't matter. Logging will be
    initialized in the INIT phase.

  Changing logging level
    Changing logging level can be done from the script or outside the
    script. From the script:

     use Log::Any::App '$log', -level => 'debug';

    but oftentimes what you want is changing level without modifying the
    script itself. So leave it to Log::Any::App to determine level:

     use Log::Any::App '$log';

    and then you can use environment variable:

     TRACE=1 script.pl;       # setting level to trace
     DEBUG=1 script.pl;       # setting level to debug
     VERBOSE=1 script.pl;     # setting level to info
     QUIET=1 script.pl;       # setting level to error
     LOG_LEVEL=... script.pl; # setting a specific log level

    or command-line options:

     script.pl --trace
     script.pl --debug
     script.pl --verbose
     script.pl --quiet
     script.pl --log_level=debug;   # '--log-level debug' will also do

    Log::Any::App won't interfere with command-line processing modules like
    Getopt::Long or App::Options.

  Changing default level
    The default log level is 'warn'. You can change this using:

     use Log::Any::App '$log';
     BEGIN { our $Log_Level = 'info' }

    and then you can still use environment or command-line options to
    override the setting.

  Changing per-output level
    Logging level can also be specified on a per-output level. For example,
    if you want your script to be chatty on the screen but still logs to
    file at the default 'warn' level:

     SCREEN_VERBOSE=1 script.pl
     SCREEN_DEBUG=1 script.pl
     SCREEN_TRACE=1 script.pl
     SCREEN_LOG_LEVEL=info script.pl

     script.pl --screen_verbose
     script.pl --screen-debug
     script.pl --screen-trace=1
     script.pl --screen-log-level=info
     # and so on

    Similarly, to set only file level, use FILE_VERBOSE, FILE_LOG_LEVEL,
    --file-trace, etc.

  Setting default per-output level
    As with setting default level, you can also set default level on a
    per-output basis:

     use Log::Any::App '$log';
     BEGIN {
         our $Screen_Log_Level = 'off';
         our $File_Quiet = 1; # setting level to 'error'
         # and so on
     }

    If a per-output level is not specifed, it will default to the general
    log level.

  Enabling/disabling output
    To disable a certain output, you can do this:

     use Log::Any::App '$log', -file => 0;

    or:

     use Log::Any::App '$log', -screen => {level=>'off'};

    and this won't allow it to be reenabled from outside the script. However
    if you do this:

     use Log::Any::App;
     BEGIN { our $Screen_Log_Level = 'off' }

    then you will be able to override the screen log level using environment
    or command-line options (SCREEN_DEBUG, --screen-verbose, and so on).

  Changing log file name/location
    By default Log::Any::App will use ~/$NAME.log (or /var/log/$NAME.log if
    script is running as root), where $NAME is taken from $0. But this can
    be changed using:

     use Log::Any::App '$log', -name => 'myprog';

    Or, using custom path:

     use Log::Any::App '$log', -file => '/path/to/file';

  Changing other output parameters
    Each output argument can accept a hashref to specify various options.
    For example:

     use Log::Any::App '$log',
         -screen => {color=>0},   # never use color
         -file   => {path=>'/var/log/foo',
                     rotate=>'10M',
                     histories=>10,
                    },

    For all the available options of each output, see the init() function.

  Logging to syslog
    Logging to syslog is enabled by default if your script looks like a
    daemon, e.g.:

     use Net::Daemon; # this indicate your program is a daemon
     use Log::Any::App; # syslog logging will be turned on by default

    but if you are certain you don't want syslog logging:

     use Log::Any::App -syslog => 0;

  Logging to directory
    This is done using Log::Dispatch::Dir where each log message is logged
    to a different file in a specified directory. By default logging to dir
    is not turned on, to turn it on:

     use Log::Any::App '$log', -dir => 1;

    For all the available options of directory output, see the init()
    function.

  Multiple outputs
    Each output argument can accept an arrayref to specify more than one
    output, example:

     use Log::Any::App '$log',
         -file => ["/var/log/log1",
                   {path=>"/var/log/debug_foo", category=>'Foo', level=>'debug'}];

  Changing level of a certain module
    Suppose you want to shut up Foo, Bar::Baz, and Qux's logging because
    they are too noisy:

     use Log::Any::App '$log',
         -category_level => { Foo => 'off', 'Bar::Baz' => 'off', Qux => 'off' };

    or (same thing):

     use Log::Any::App '$log',
         -category_alias => { -noisy => [qw/Foo Bar::Baz Qux/] },
         -category_level => { -noisy => 'off' };

    You can even specify this on a per-output basis. Suppose you only want
    to shut up the noisy modules on the screen, but not on the file:

     use Log::Any::App '$log',
        -category_alias => { -noisy => [qw/Foo Bar::Baz Qux/] },
        -screen => { category_level => { -noisy => 'off' } };

    Or perhaps, you want to shut up the noisy modules everywhere, except on
    the screen:

     use Log::Any::App '$log',
         -category_alias => { -noisy => [qw/Foo Bar::Baz Qux/] },
         -category_level => { -noisy => 'off' },
         -syslog => 1,
         -file   => "/var/log/foo",
         -screen => { category_level => {} }; # do not do per-category level

  Preventing logging level to be changed from outside the script
    Sometimes, for security/audit reasons, you don't want to allow script
    caller to change logging level. To do so, just specify the 'level'
    option in the script during 'use' statement:

  Debugging
    To see the Log4perl configuration that is generated by Log::Any::App and
    how it came to be, set environment LOGANYAPP_DEBUG to true.

FUNCTIONS
  init(\@args)
    This is the actual function that implements the setup and configuration
    of logging. You normally need not call this function explicitly (but see
    below), it will be called once in an INIT block. In fact, when you do:

     use Log::Any::App 'a', 'b', 'c';

    it is actually passed as:

     init(['a', 'b', 'c']);

    You will need to call init() manually if you require Log::Any::App at
    runtime, in which case it is too late to run INIT block. If you want to
    run Log::Any::App in runtime phase, do this:

     require Log::Any::App;
     Log::Any::App::init(['a', 'b', 'c']);

    Arguments to init can be one or more of:

    -init => BOOL
        Whether to call Log::Log4perl->init() after setting up the Log4perl
        configuration. Default is true. You can set this to false, and you
        can initialize Log4perl yourself (but then there's not much point in
        using this module, right?)

    -name => STRING
        Change the program name. Default is taken from $0.

    -category_alias => {ALIAS=>CATEGORY, ...}
        Create category aliases so the ALIAS can be used in place of real
        categories in each output's category specification. For example,
        instead of doing this:

         init(
             -file   => [category=>[qw/Foo Bar Baz/], ...],
             -screen => [category=>[qw/Foo Bar Baz/]],
         );

        you can do this instead:

         init(
             -category_alias => {_fbb => [qw/Foo Bar Baz/]},
             -file   => [category=>'-fbb', ...],
             -screen => [category=>'-fbb', ...],
         );

    -category_level => {CATEGORY=>LEVEL, ...}
        Specify per-category level. Categories not mentioned on this will
        use the general level (-level). This can be used to increase or
        decrease logging on certain categories/modules.

    -level => 'trace'|'debug'|'info'|'warn'|'error'|'fatal'|'off'
        Specify log level for all outputs. Each output can override this
        value. The default log level is determined as follow:

        If App::Options is present, these keys are checked in %App::options:
        log_level, trace (if true then level is "trace"), debug (if true
        then level is "debug"), verbose (if true then level is "info"),
        quiet (if true then level is "error").

        Otherwise, it will try to scrape @ARGV for the presence of
        --log-level, --trace, --debug, --verbose, or --quiet (this usually
        works because Log::Any::App does this in the INIT phase, before you
        call Getopt::Long's GetOptions() or the like).

        Otherwise, it will look for environment variables: LOG_LEVEL, QUIET.
        VERBOSE, DEBUG, TRACE.

        Otherwise, it will try to search for package variables in the "main"
        namespace with names like $Log_Level or $LOG_LEVEL or $log_level,
        $Quiet or $QUIET or $quiet, $Verbose or $VERBOSE or $verbose, $Trace
        or $TRACE or $trace, $Debug or $DEBUG or $debug.

        If everything fails, it defaults to 'warn'.

    -file => 0 | 1|yes|true | PATH | {opts} | [{opts}, ...]
        Specify output to one or more files, using
        Log::Dispatch::FileRotate.

        If the argument is a false boolean value, file logging will be
        turned off. If argument is a true value that matches
        /^(1|yes|true)$/i, file logging will be turned on with default path,
        etc. If the argument is another scalar value then it is assumed to
        be a path. If the argument is a hashref, then the keys of the
        hashref must be one of: "level", "path", "max_size" (maximum size
        before rotating, in bytes, 0 means unlimited or never rotate),
        "histories" (number of old files to keep, excluding the current
        file), "category" (a string of ref to array of strings),
        "category_level" (a hashref, similar to -category_level),
        "pattern_style" (see "PATTERN STYLES"), "pattern" (Log4perl
        pattern).

        If the argument is an arrayref, it is assumed to be specifying
        multiple files, with each element of the array as a hashref.

        How Log::Any::App determines defaults for file logging:

        If program is a one-liner script specified using "perl -e", the
        default is no file logging. Otherwise file logging is turned on.

        If the program runs as root, the default path is
        "/var/log/$NAME.log", where $NAME is taken from $0 (or "-name").
        Otherwise the default path is ~/$NAME.log. Intermediate directories
        will be made with File::Path.

        If specified "path" ends with a slash (e.g. "/my/log/"), it is
        assumed to be a directory and the final file path is directory
        appended with $NAME.log.

        Default rotating behaviour is no rotate (max_size = 0).

        Default level for file is the same as the global level set by
        -level. But App::options, command line, environment, and package
        variables in main are also searched first (for FILE_LOG_LEVEL,
        FILE_TRACE, FILE_DEBUG, FILE_VERBOSE, FILE_QUIET, and the similars).

    -dir => 0 | 1|yes|true | PATH | {opts} | [{opts}, ...]
        Log messages using Log::Dispatch::Dir. Each message is logged into
        separate files in the directory. Useful for dumping content (e.g.
        HTML, network dumps, or temporary results).

        If the argument is a false boolean value, dir logging will be turned
        off. If argument is a true value that matches /^(1|yes|true)$/i, dir
        logging will be turned on with defaults path, etc. If the argument
        is another scalar value then it is assumed to be a directory path.
        If the argument is a hashref, then the keys of the hashref must be
        one of: "level", "path", "max_size" (maximum total size of files
        before deleting older files, in bytes, 0 means unlimited), "max_age"
        (maximum age of files to keep, in seconds, undef means unlimited).
        "histories" (number of old files to keep, excluding the current
        file), "category", "category_level" (a hashref, similar to
        -category_level), "pattern_style" (see "PATTERN STYLES"), "pattern"
        (Log4perl pattern), "filename_pattern" (pattern of file name).

        If the argument is an arrayref, it is assumed to be specifying
        multiple directories, with each element of the array as a hashref.

        How Log::Any::App determines defaults for dir logging:

        Directory logging is by default turned off. You have to explicitly
        turn it on.

        If the program runs as root, the default path is "/var/log/$NAME/",
        where $NAME is taken from $0. Otherwise the default path is
        ~/log/$NAME/. Intermediate directories will be created with
        File::Path. Program name can be changed using "-name".

        Default rotating parameters are: histories=1000, max_size=0,
        max_age=undef.

        Default level for dir logging is the same as the global level set by
        -level. But App::options, command line, environment, and package
        variables in main are also searched first (for DIR_LOG_LEVEL,
        DIR_TRACE, DIR_DEBUG, DIR_VERBOSE, DIR_QUIET, and the similars).

    -screen => 0 | 1|yes|true | {opts}
        Log messages using Log::Log4perl::Appender::ScreenColoredLevels.

        If the argument is a false boolean value, screen logging will be
        turned off. If argument is a true value that matches
        /^(1|yes|true)$/i, screen logging will be turned on with default
        settings. If the argument is a hashref, then the keys of the hashref
        must be one of: "color" (default is true, set to 0 to turn off
        color), "stderr" (default is true, set to 0 to log to stdout
        instead), "level", "category", "category_level" (a hashref, similar
        to -category_level), "pattern_style" (see "PATTERN STYLE"),
        "pattern" (Log4perl string pattern).

        How Log::Any::App determines defaults for screen logging:

        Screen logging is turned on by default.

        Default level for screen logging is the same as the global level set
        by -level. But App::options, command line, environment, and package
        variables in main are also searched first (for SCREEN_LOG_LEVEL,
        SCREEN_TRACE, SCREEN_DEBUG, SCREEN_VERBOSE, SCREEN_QUIET, and the
        similars).

        Color can also be turned on/off using environment variable COLOR (if
        color argument is not set).

    -syslog => 0 | 1|yes|true | {opts}
        Log messages using Log::Dispatch::Syslog.

        If the argument is a false boolean value, syslog logging will be
        turned off. If argument is a true value that matches
        /^(1|yes|true)$/i, syslog logging will be turned on with default
        level, ident, etc. If the argument is a hashref, then the keys of
        the hashref must be one of: "level", "ident", "facility",
        "category", "category_level" (a hashref, similar to
        -category_level), "pattern_style" (see "PATTERN STYLES"), "pattern"
        (Log4perl pattern).

        How Log::Any::App determines defaults for syslog logging:

        If a program is a daemon (determined by detecting modules like
        Net::Server or Proc::PID::File) then syslog logging is turned on by
        default and facility is set to "daemon", otherwise the default is
        off.

        Ident is program's name by default ($0, or "-name").

        Default level for syslog logging is the same as the global level set
        by -level. But App::options, command line, environment, and package
        variables in main are also searched first (for SYSLOG_LOG_LEVEL,
        SYSLOG_TRACE, SYSLOG_DEBUG, SYSLOG_VERBOSE, SYSLOG_QUIET, and the
        similars).

    -dump => BOOL
        If set to true then Log::Any::App will dump the generated Log4perl
        config. Useful for debugging the logging.

PATTERN STYLES
    Log::Any::App provides some styles for Log4perl patterns. You can
    specify "pattern_style" instead of directly specifying "pattern".
    example:

     use Log::Any::App -screen => {pattern_style=>"script_long"};

     Name           Description                        Example output
     ----           -----------                        --------------
     plain          The message, the whole message,    Message
                    and nothing but the message.
                    Used by dir logging.

                    Equivalent to pattern: '%m'

     script_short   For scripts that run for a short   [234] Message
                    time (a few seconds). Shows just
                    the number of milliseconds. This
                    is the default for screen.

                    Equivalent to pattern:
                    '[%r] %m%n'

     script_long    Scripts that will run for a        [2010-04-22 18:01:02] Message
                    while (more than a few seconds).
                    Shows date/time.

                    Equivalent to pattern:
                    '[%d] %m%n'

     daemon         For typical daemons. Shows PID     [pid 1234] [2010-04-22 18:01:02] Message
                    and date/time. This is the
                    default for file logging.

                    Equivalent to pattern:
                    '[pid %P] [%d] %m%n'

     syslog         Style suitable for syslog          [pid 1234] Message
                    logging.

                    Equivalent to pattern:
                    '[pid %p] %m'

    If you have a favorite pattern style, please do share them.

FAQ
  What's the benefit of using Log::Any::App?
    You get all the benefits of Log::Any, as what Log::Any::App does is just
    wrap Log::Any and Log::Log4perl with some nice defaults. It provides you
    with an easy way to consume Log::Any logs and customize level/some other
    options via various ways.

    You still produce logs with Log::Any so later should portions of your
    application code get refactored into modules, you don't need to change
    the logging part. And if your application becomes more complex and
    Log::Any::App doesn't suffice your custom logging needs anymore, you can
    just replace 'use Log::Any::App' line with something more adequate.

  And what's the benefit of using Log::Any?
    This is better described in the Log::Any documentation itself, but in
    short: Log::Any frees your module users to use whatever logging
    framework they want. It increases the reusability of your modules.

  Do I need Log::Any::App if I am writing modules?
    No, if you write modules just use Log::Any.

  Why use Log4perl?
    Log::Any::App uses the Log4perl adapter to display the logs because it
    is mature, flexible, featureful. The other alternative adapter is
    Log::Dispatch, but you can use Log::Dispatch::* output modules in
    Log4perl and (currently) not vice versa.

    Other adapters might be considered in the future, for now I'm fairly
    satisfied with Log4perl.

    Note that producing logs are still done with Log::Any as usual and not
    tied to Log4perl in any way.

  How do I create extra logger objects?
    The usual way as with Log::Any:

     my $other_log = Log::Any->get_logger(category => $category);

  My needs are not met by the simple configuration system of Log::Any::App!
    You can use Log4perl adapter directly and write your own Log4perl
    configuration (or even other adapters). Log::Any::App is meant for quick
    and simple logging output needs anyway (but do tell me if your logging
    output needs are reasonably simple and should be supported by
    Log::Any::App).

BUGS/TODOS
    Need to provide appropriate defaults for Windows/other OS.

    Probably: SCREEN0_DEBUG, --file1-log-level, etc.

SEE ALSO
    Log::Any

    Log::Log4perl

AUTHOR
    Steven Haryanto <stevenharyanto@gmail.com>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2011 by Steven Haryanto.

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

