Acrux

 view release on metacpan or  search on metacpan

eg/acrux_log.pl  view on Meta::CPAN

    level  => 'trace',
    #short  => 1,
    color  => 1,
    #format => sub {
    #    my ($time, $level, @lines) = @_;
    #    return "[$time] [$level] " . join (' ', @lines) . "\n";
    #}
);

$log->trace('Whatever');
$log->debug('You screwed up, but that is ok');
$log->info('You are bad, but you prolly know already');
$log->notice('Normal, but significant, condition...');
$log->warn('Dont do that Dave...');
$log->error('You really screwed up this time');
$log->fatal('Its over...');
$log->crit('Its over...');
$log->alert('Action must be taken immediately');
$log->emerg('System is unusable');

__END__

eg/acrux_test.pl  view on Meta::CPAN

### CODE:
    my ($self, $meta, @args) = @_;
    $self->test; # Call created method

    #print dumper(
    #        "App:"  => $self,
    #        "Meta:" => $meta,
    #        "Args:" => \@args,
    #    );

    $self->log->debug(sprintf('Config value "/deep/foo/bar/test": >%s<',
        $self->config->get("/deep/foo/bar/test")));

    # Test log
    #$self->log->trace('Whatever');
    #$self->log->debug('You screwed up, but that is ok');
    #$self->log->info('You are bad, but you prolly know already');
    #$self->log->notice('Normal, but significant, condition...');
    #$self->log->warn('Dont do that Dave...');
    #$self->log->error('You really screwed up this time');
    #$self->log->fatal('Its over...');
    #$self->log->crit('Its over...');
    #$self->log->alert('Action must be taken immediately');
    #$self->log->emerg('System is unusable');

    return 1;

eg/acrux_test.pl  view on Meta::CPAN

package main;

use Getopt::Long;
use IO::Handle;
use Acrux::Util qw/dumper color/;

# Get options from command line
Getopt::Long::Configure("bundling");
GetOptions(my $options = {},
    "verbose|v",            # Verbose mode
    "debug|d",              # Debug mode
    "test|t",               # Test mode

    # Application
    "noload|n",             # NoLoad config file
    "config|conf|c=s",      # Config file
    "datadir|dir|D=s",      # DataDir

) || die color("bright_red" => 'Incorrect options'), "\n";
my $command = shift(@ARGV) // 'default';
my @arguments = @ARGV ? @ARGV : ();

# Create
my $app = MyApp->new(
    project     => 'MyApp',
    preload     => [qw/Config Log/], # disable preloading all system plugins
    options     => $options,
    root        => '.',
    configfile  => $options->{config} // 't/test.conf',
    verbose     => $options->{verbose},
    debug       => $options->{debug},
    test        => $options->{test},

    #config_noload => 1,
    loghandle   => IO::Handle->new_from_fd(fileno(STDOUT), "w"),
    logcolorize => 1

    # ($options->{datadir} ? (datadir => $options->{datadir}) : ()),

);

eg/acrux_test.pl  view on Meta::CPAN


use parent 'Acme::Crux::Plugin';

use Acrux::Util qw/color/;

sub register {
    my ($self, $app, $args) = @_;
    print sprintf(color(bright_magenta => "Registered %s plugin"), $self->name), "\n";

    $app->register_method(test => sub { print color(red => "This test method created in plugin register"), "\n" });
    $app->log->debug(sprintf("Registered %s plugin", $self->name));

    return sprintf 'Ok! I am %s plugin!', $self->name;
}

1;

__END__

lib/Acme/Crux.pm  view on Meta::CPAN

        logdir      => '/var/log/myapp',
        logfile     => '/var/log/myapp/myapp.log',
        pidfile     => '/var/run/myapp/myapp.pid',
        root        => '/etc/myapp',
        rundir      => '/var/run/myapp',
        sharedir    => '/usr/share/myapp',
        spooldir    => '/var/spool/myapp',
        tempdir     => '/tmp/myapp',
        webdir      => '/var/www/myapp',

        debug       => 0,
        test        => 0,
        verbose     => 0,
    );

=head1 ATTRIBUTES

This class implements the following attributes

=head2 cachedir

lib/Acme/Crux.pm  view on Meta::CPAN


    datadir => '/var/lib/myapp'

Data dir of project

    $app = $app->datadir( "/path/to/data/dir" );
    my $datadir = $app->datadir;

Default: /var/lib/<MONIKER>

=head2 debug

    debug => 1
    debug => 'on'
    debug => 'yes'

Debug mode

Default: 0

=head2 docdir

    docdir => '/usr/share/doc/myapp'

Doc dir for project documentation

lib/Acme/Crux.pm  view on Meta::CPAN

B<NOTE:> Please use only in your subclasses!

    sub startup {
        my $self = shift;

        . . .

        return $self; # REQUIRED!
    }

=head2 debugmode

    $app->debugmode;

Returns debug flag. 1 - on, 0 - off

=head2 begin

    my $timing_begin = $app->begin;

This method sets timestamp for L</elapsed>

    my $timing_begin = $app->begin;
    # ... long operations ...
    my $elapsed = $app->elapsed( $timing_begin );

lib/Acme/Crux.pm  view on Meta::CPAN


    my $elapsed = $app->elapsed;

    my $timing_begin = [gettimeofday];
    # ... long operations ...
    my $elapsed = $app->elapsed( $timing_begin );

Return fractional amount of time in seconds since unnamed timstamp has been created while start application

    my $elapsed = $app->elapsed;
    $app->log->debug("Database stuff took $elapsed seconds");

For formatted output:

    $app->log->debug(sprintf("%+.*f sec", 4, $app->elapsed));

=head2 error

    my $error = $app->error;

Returns error string if occurred any errors while working with application

    $app = $app->error( "error text" );

Sets new error message and returns object

lib/Acme/Crux.pm  view on Meta::CPAN

use Acrux::RefUtil qw/
        as_hash_ref is_hash_ref
        as_array_ref is_array_ref
        is_value is_code_ref is_true_flag
    /;
use Acrux::Const qw/:dir IS_ROOT/;
use Acrux::Util qw/load_class trim words/;

use constant {
    WIN             => !!($^O =~ /mswin/i),
    ALOWED_MODES    => [qw/debug test verbose/],
    PRELOAD_PLUGINS => [qw/Config Log/], # Order is very important!
    DEFAULT_PLUGINS => {
        Config  => "Acme::Crux::Plugin::Config",
        Log     => "Acme::Crux::Plugin::Log",
    },
};

sub new {
    my $class = shift;
    my $args = @_ ? @_ > 1 ? {@_} : {%{$_[0]}} : {};

lib/Acme/Crux.pm  view on Meta::CPAN


        # General
        orig        => {%$args},
        created     => Time::HiRes::time,
        hitime      => [gettimeofday],
        options     => as_hash_ref($args->{options}), # Options of command line
        plugins     => {},
        preload_plugins => $args->{preload} || $args->{preload_plugins} || PRELOAD_PLUGINS,

        # Modes (defaults)
        debugmode   => 0,
        testmode    => 0,
        verbosemode => 0,

        # Dirs
        pwd         => $pwd,
        exedir      => $RealBin, # Script dir
        root        => $args->{root}, # Root dir of project. Default: /etc/moniker
        tempdir     => $args->{tempdir}, # Temp dir of project. Default: /tmp/moniker
        datadir     => $args->{datadir}, # Data dir of project. Defaut: /var/lib/moniker
        logdir      => $args->{logdir}, # Log dir of project. Default: /var/log/moniker

lib/Acme/Crux.pm  view on Meta::CPAN

    my $self = shift;
    if (scalar(@_) >= 1) {
        $self->{pidfile} = shift;
        return $self;
    }
    return $self->{pidfile};
}

# Modes (methods)
sub testmode    { !! shift->{testmode} }
sub debugmode   { !! shift->{debugmode} }
sub verbosemode { !! shift->{verbosemode} }
sub silentmode  { ! shift->{verbosemode} }

# Methods
sub error {
    my $self = shift;
    if (scalar(@_) >= 1) {
        $self->{error} = shift;
        return $self;
    }

lib/Acme/Crux/Plugin/Config.pm  view on Meta::CPAN

    # Create instance
    my $config = Acrux::Config->new(
        file        => $file,
        options     => $options,
        noload      => $noload,
        defaults    => $defaults,
        root        => $root,
        dirs        => $dirs,
    );
    if (my $err = $config->error) {
        if ($app->debugmode) {
            $app->verbosemode
              ? warn qq{Can't load configuration file "$file"\n$err\n}
              : warn qq{Can't load configuration file "$file"\n};
        }
    }

    # Set conf and config helpers (methods)
    $app->register_method(config => sub { $config });
    $app->register_method(conf => sub { $config });

lib/Acme/Crux/Plugin/Log.pm  view on Meta::CPAN

Acme::Crux::Plugin::Log - The Acme::Crux plugin for logging in your application

=head1 SYNOPSIS

    # In startup
    $app->plugin('Log');
    $app->plugin('Log', undef, { ... options ... });

    # In application
    $app->log->trace('Whatever');
    $app->log->debug('You screwed up, but that is ok');
    $app->log->info('You are bad, but you prolly know already');
    $app->log->notice('Normal, but significant, condition...');
    $app->log->warn('Dont do that Dave...');
    $app->log->error('You really screwed up this time');
    $app->log->fatal('Its over...');
    $app->log->crit('Its over...');
    $app->log->alert('Action must be taken immediately');
    $app->log->emerg('System is unusable');

=head1 DESCRIPTION

lib/Acme/Crux/Plugin/Log.pm  view on Meta::CPAN


    $app->plugin(Log => undef, {ident => 'myapp'});

The B<ident> is prepended to every B<syslog> message

Default: C<logident> command line option or C<logident> application argument
or C<LogIdent> configuration value or script name C<basename($0)> otherwise

=head2 level

    $app->plugin(Log => undef, {level => 'debug'});

This option sets log level

Predefined log levels: C<fatal>, C<error>, C<warn>, C<info>, C<debug>, and C<trace> (in descending priority).
The syslog supports followed additional log levels: C<emerg>, C<alert>, C<crit'> and C<notice> (in descending priority).
But we recommend not using them to maintain compatibility.

See also L<Acrux::Log/level>

Default: C<loglevel> command line option or C<loglevel> application argument
or C<LogLevel> configuration value or C<debug> otherwise

=head2 logger

    $app->plugin(Log => undef, {logger => Mojo::Log->new()});

This option sets predefined logger, eg. Mojo::Log

Default: C<logger> application argument or C<undef> otherwise

=head2 logopt

lib/Acrux/Log.pm  view on Meta::CPAN

    my $log = Acrux::Log->new(
            handle => IO::Handle->new_from_fd(fileno(STDOUT), "w")
        );
    $log->error("My test error message to STDOUT")

    # Customize minimum log level
    my $log = Acrux::Log->new(level => 'warn');

    # Log messages
    $log->trace('Doing stuff');
    $log->debug('Not sure what is happening here');
    $log->info('FYI: it happened again');
    $log->notice('Normal, but significant, condition...');
    $log->warn('This might be a problem');
    $log->error('Garden variety error');
    $log->fatal('Boom');
    $log->crit('Its over...');
    $log->alert('Action must be taken immediately');
    $log->emerg('System is unusable');

=head1 DESCRIPTION

Acrux::Log is a simple logger for Acrux logging

=head2 new

    my $log = Acrux::Log->new(
        logopt      => 'ndelay,pid',
        facility    => 'user',
        level       => 'debug',
        ident       => 'test.pl',
        autoclean   => 1,
        logopt      => 'ndelay,pid',
    );

With default attributes

    use Mojo::Log;
    my $log = Acrux::Log->new( logger => Mojo::Log->new );
    $log->error("Test error message");

lib/Acrux/Log.pm  view on Meta::CPAN

=head2 ident

    ident => 'myapp'

The B<ident> is prepended to every B<syslog> message

Default: script name C<basename($0)>

=head2 level

    level => 'debug'

There are six predefined log levels: C<fatal>, C<error>, C<warn>, C<info>, C<debug>, and C<trace> (in descending priority).
The syslog supports followed additional log levels: C<emerg>, C<alert>, C<crit'> and C<notice> (in descending priority).
But we recommend not using them to maintain compatibility.
Your configured logging level has to at least match the priority of the logging message.

If your configured logging level is C<warn>, then messages logged with info(), debug(), and trace()
will be suppressed; fatal(), error() and warn() will make their way through, because their
priority is higher or equal than the configured setting.

Default: C<debug>

See also L<Sys::Syslog/Levels>

=head2 logger

    logger => Mojo::Log->new()

This attribute perfoms to set predefined logger, eg. Mojo::Log

Default: C<undef>

lib/Acrux/Log.pm  view on Meta::CPAN


Log C<alert> message

=head2 crit

    $log->crit('Its over...');
    $log->crit('Bye', 'bye');

Log C<crit> message (See L</fatal> method)

=head2 debug

    $log->debug('You screwed up, but that is ok');
    $log->debug('All', 'cool');

Log C<debug> message

=head2 emerg

    $log->emerg('System is unusable');
    $log->emerg('To', 'die');

Log C<emerg> message

=head2 error

lib/Acrux/Log.pm  view on Meta::CPAN

=head2 info

    $log->info('You are bad, but you prolly know already');
    $log->info('Ok', 'then');

Log C<info> message

=head2 level

    my $level = $log->level;
    $log      = $log->level('debug');

Active log level, defaults to debug.
Available log levels are C<trace>, C<debug>, C<info>, C<notice>, C<warn>, C<error>,
C<fatal> (C<crit>), C<alert> and C<emerg>, in that order

=head2 logger

    my $logger = $log->logger;

This method returns the logger object or undef if not exists

=head2 notice

lib/Acrux/Log.pm  view on Meta::CPAN

use Encode qw/find_encoding/;
use Time::HiRes qw/time/;
use Acrux::Util qw/color/;

use constant {
    LOGOPTS         => 'ndelay,pid', # For Sys::Syslog
    SEPARATOR       => ' ',
    LOGFORMAT       => '%s',
};
my %LOGLEVELS = (
    'trace'     => Sys::Syslog::LOG_DEBUG,    # 7 debug-level message
    'debug'     => Sys::Syslog::LOG_DEBUG,    # 7 debug-level message
    'info'      => Sys::Syslog::LOG_INFO,     # 6 informational message
    'notice'    => Sys::Syslog::LOG_NOTICE,   # 5 normal, but significant, condition
    'warn'      => Sys::Syslog::LOG_WARNING,  # 4 warning conditions
    'error'     => Sys::Syslog::LOG_ERR,      # 3 error conditions
    'fatal'     => Sys::Syslog::LOG_CRIT,     # 2 critical conditions
    'crit'      => Sys::Syslog::LOG_CRIT,     # 2 critical conditions
    'alert'     => Sys::Syslog::LOG_ALERT,    # 1 action must be taken immediately
    'emerg'     => Sys::Syslog::LOG_EMERG,    # 0 system is unusable
);
my %MAGIC = (
    'trace'     => 8,
    'debug'     => 7,
    'info'      => 6,
    'notice'    => 5,
    'warn'      => 4,
    'error'     => 3,
    'fatal'     => 2, 'crit' => 2,
    'alert'     => 1,
    'emerg'     => 0,
);
my %COLORS = (
    'trace'     => 'white',
    'debug'     => 'bright_white',
    'info'      => 'cyan',
    'notice'    => 'green',
    'warn'      => 'yellow',
    'error'     => 'red',
    'fatal'     => 'bright_red', 'crit' => 'bright_magenta',
    'alert'     => 'white on_red',
    'emerg'     => 'bright_white on_red',
);
my %SHORT = ( # Log::Log4perl::Level notation
    0 => 'fatal', 1 => 'fatal', 2 => 'fatal',
    3 => 'error',
    4 => 'warn',
    5 => 'info', 6 => 'info',
    7 => 'debug',
    8 => 'trace',
);

my $ENCODING = find_encoding('UTF-8') or croak qq/Encoding "UTF-8" not found/;

sub new {
    my $class = shift;
    my $args = @_ ? @_ > 1 ? {@_} : {%{$_[0]}} : {};
    $args->{facility}   ||= Sys::Syslog::LOG_USER;
    $args->{ident}      ||= basename($0);
    $args->{logopt}     ||= LOGOPTS;
    $args->{logger}     ||= undef;
    $args->{level}      ||= 'debug';
    $args->{file}       ||= undef;
    $args->{handle}     ||= undef;
    $args->{provider}   = 'unknown';
    $args->{autoclean}  ||= 0;
    $args->{prefix}     ||= '';
    $args->{format}     ||= undef;
    $args->{color}      ||= 0;

    # Check level
    $args->{level} = lc($args->{level});
    unless (exists $MAGIC{$args->{level}}) {
        carp "Incorrect log level specified. Well be used debug log level by default";
        $args->{level} = 'debug';
    }

    # Instance
    my $self = bless {%$args}, $class;

    # Set formatter
    $self->{format} ||= $self->{short} ? \&_short : $self->{color} ? \&_color : \&_default;

    # Open sys log socket
    if ($args->{logger}) {

lib/Acrux/Log.pm  view on Meta::CPAN

        $self->{level} = shift;
        return $self;
    }
    return $self->{level};
}
sub logger { shift->{logger} }
sub handle { shift->{handle} }
sub provider { shift->{provider} }

sub trace { shift->_log('trace', @_) }
sub debug { shift->_log('debug', @_) }
sub info { shift->_log('info', @_) }
sub notice { shift->_log('notice', @_) }
sub warn { shift->_log('warn', @_) }
sub error { shift->_log('error', @_) }
sub fatal { shift->_log('fatal', @_) }
sub crit { shift->_log('crit', @_) }
sub alert { shift->_log('alert', @_) }
sub emerg { shift->_log('emerg', @_) }

sub _log {

t/09-log.t  view on Meta::CPAN

# This is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.
#
#########################################################################
use strict;
use utf8;
use Test::More;

use_ok qw/Acrux::Log/;

# Error message with debug loglevel
{
    my $log = Acrux::Log->new();
    is $log->level, 'debug', "Debug LogLevel";
    ok $log->error("My test error message"), 'Error message to syslog';
}

# Info and fatal message with eror loglevel
{
    my $log = Acrux::Log->new(level => 'error');
    is $log->level, 'error', "Error LogLevel";
    ok !$log->info("My test info message"), 'Info message not allowed';
    ok $log->fatal("My test fatal message"), 'Fatal message to syslog';
    #note explain $log;
}

# Fake Logger
{
    my $fake = FakeLogger->new;
    my $log = Acrux::Log->new(logger => $fake);
    $log->error("Test error message") and ok 1, "Test error message to STDOUT via FakeLogger";
    #ok $log->debug("Test debug message");
    $log->info("Test info message") and ok 1, "Test info message to STDOUT via FakeLogger";
    #note explain $log;
}

# File
{
    my $log = Acrux::Log->new(file => 'log.tmp');
    $log->error("Test error message") and ok 1, "Test error message to file";
    $log->warn("Тестовое сообщение") and ok 1, "Test error message to file (RU)";
    $log->info("Test info message") and ok 1, "Test info message to file";



( run in 1.599 second using v1.01-cache-2.11-cpan-49f99fa48dc )