NAME
    Log::Any::App - A simple wrapper for Log::Any + Log::Log4perl for use in
    applications

VERSION
    version 0.10

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 logging with $log->debug(), $log->info(), $log->error(),
    etc. That's it. The task of initializing and configuring the logger
    rests on the shoulder of module users.

    It's less straightforward for module users though, especially for casual
    ones. You have to pick an adapter and connect it to another logging
    framework (like Log::Log4perl) and configure it. The typical incantation
    is like this:

     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 application authors and
    module users. 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 scripts and one-liners whenever there are
    Log::Any-using modules involved (like Data::Schema or Config::Tree).

USING
    Most of the time you just need to do this from command line:

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

    or from a script:

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

    this will send logs to screen as well as file (~/$NAME.log or
    /var/log/$NAME.log if running as root). One-liners by default do not log
    to file. $NAME will be taken from $0, but can be changed using:

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

    Default level is 'warn', but can be changed in several ways. From the
    code:

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

    or:

     use Log::Any::App '$log';
     BEGIN {
         $Log_Level = 'fatal'; # setting to fatal
         # $Quiet = 1;         # another way, setting to error
         # $Log_Level= 'warn'; # setting to warn, default
         # $Verbose = 1;       # another way, setting to info
         # $Debug = 1;         # another way, setting to debug
         # $Trace = 1;         # another way, setting to trace
     }

    or from environment variable:

     LOG_LEVEL=fatal yourprogram.pl;   # setting level to fatal
     QUIET=1 yourproogram.pl;          # another way, setting to error
     LOG_LEVEL=warn yourprogram.pl;    # setting level to warn, default
     VERBOSE=1 yourprogram.pl;         # another way, setting to info
     DEBUG=1 yourprogram.pl;           # another way, setting to debug
     TRACE=1 yourprogram.pl;           # another way, setting to trace

    or, from the command line options:

     yourprogram.pl --log-level debug
     yourprogram.pl --debug
     # and so on

    If you want to add a second file with a different level and category:

     use Log::Any::App '$log', -file => ['first.log',
                                         {path=>'second.log', level=>'debug',
                                          category=>'Some::Category'}];

    If you want to turn off screen logging:

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

    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 don't want syslog logging:

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

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

FUNCTIONS
  init(\@args)
    This is the actual function that implements the setup and configuration
    of logging. You normally need not call this function explicitly, 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']);

    Arguments to init can be one or more of:

    -init => BOOL
        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.

    -level => 'debug'|'warn'|...
        Specify log level for all outputs, e.g. "warn", "debug", etc. 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", "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.

        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", "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", "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).

    -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", "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?
    All of Log::Any and all of Log::Log4perl, as what Log::Any::App does is
    just combine those two (and add a thin wrapper). You still produce log
    with Log::Any so later should portions of your application code get
    refactored into modules, you don't need to change the logging part.

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

  Why Log4perl instead of Log::Dispatch?
    You can use Log::Dispatch::* output modules in Log4perl but (currently)
    not vice versa.

    You can configure Log4perl using a configuration file, so you can
    conveniently store your settings separate from the application.

    Feel free to fork Log::Any::App and use Log::Dispatch instead if you
    don't like Log4perl.

  Why not just use Log4perl then? Why bother with Log::Any at all? You're tied to Log4perl anyway.
    Yes, combining Log::Any with Log4perl (or some other adapter) is
    necessary to get output, but that's only in applications. Your
    Log::Any-using modules are still not tied to any adapter.

    The goal is to keep using Log::Any in your modules, and have a
    convenient way of displaying your logs in your applications, without a
    long incantation.

    Users of your modules can still use Log::Dispatch or some other adapter
    if they want to. You are not forcing your module users to use Log4perl.

    Btw, I'm actually fine with a Log4perl-only world. It's just that
    (currently) you need to explicitly initialize Log4perl so this might
    irritate my users if I use Log4perl in my modules. Log::Any's default is
    the nice 'null' logging so my users don't need to be aware of logging at
    all.

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

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

  How do I see the Log4perl configuration that gets used?
    Set environment LOGANYAPP_DEBUG to true, and Log::Any::App will dump the
    Log4perl configuration as well as additional messages to help you trace
    how it came up to be.

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

SEE ALSO
    Log::Any

    Log::Log4perl

AUTHOR
      Steven Haryanto <stevenharyanto@gmail.com>

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

