The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

MojoX::Logite - A simple Mojo::Log implementation which logs to an SQLite database

SYNOPSIS

  use MojoX::Logite;

  # Create a logging object that will log to STDERR by default
  my $logite = MojoX::Logite->new;

  # Customize the logite location and minimum log level
  my $logite = MojoX::Logite->new(
        path  => '/var/log/mojo.db',
        level => 'warn',
        package => 'MyApp::Logite',
    );

  $logite->log(debug => 'This should work');

  $logite->debug("Why isn't this working?");
  $logite->info("FYI: it happened again");
  $logite->warn("This might be a problem");
  $logite->error("Garden variety error");
  $logite->fatal("Boom!");

  # wipe the whole log file
  $logite->clear(0);

  # clear all messages older than 7 days
  $logite->clear(7);

  # ORLite root and table package methods (be careful!)

  my $package = $logite->package;

  my $handle = $package->dbh;

  my %whos = $package->selectall_hashref(
                'select who from Log where ...'
                );

  my $package_log = $logite->package.'::Log';

  $package_log->iterate( sub {
             print localtime($_->l_when)." ".$_->l_level." ".$_->l_who." [".$_->l_ctx."]: ".$_->l_what."\n";
         } );

  # clean completly the log
  MyApp::Logite::Log->truncate;

DESCRIPTION

MojoX::Logite is a simple Mojo::Log subclass implementation which logs to an SQLite database. A Mojolicious::Plugin::Logite plugin is also provided.

The module by default logs to a SQLite database file. The module levergaes basic ORLite library and methods to do basic searching and bookkeeping of log information.

By default the module uses 'log/mojo_log.db' as DB log file in the context/application directory. No directories are created apart the DB file itself.

ATTRIBUTES

MojoX::Logite inherits all attributes from Mojo::Log and implements the following new ones.

package

    my $package = $logite->package;

ORLite root package namespace. By default is set to be 'MojoX::Logite' itself and the there is only one log table defined named LogiteTable. See also package_table method and ORLite documentation.

prune

    my $prune = $logite->prune(1);

See ORLite documentation. In some situation, such as during test scripts, an application will only need the created SQLite database temporarily. In these situations, the "prune" option can be provided to instruct ORLite to delete the SQLite database when the program ends.

By default, the "prune" option is set to false.

user_version

    my $user_version = $logite->user_version(1);

Basic support for ORlite schema version-locking. See ORLite documentation. It will require PRAGMA user_version = <version_number> to work. It is genrally used with the cache attribute, see below.

cache

    my $cache = $logite->cache('cache/directory');

Cache ORLite auto-generated package structures. See ORLite documentation.

readonly

    my $readonly = $logite->readonly(1);

Not very useful, if not to just open log DB for statistics and no log operationas are required. See ORLite documentation.

app

    my $app = $logite->app;

If set it is a name or identifier for the application which is logging information. This might be useful for applications which need to track additional contextual information on a per-application base, in addition to track the default package, line, log level and process pid information. By default, no additional app context is set.

context_stack

    my $context_stack = $logite->context_stack;

    # peek
    my $value = $logite->context_stack->[-1];

    # pop
    my $value = pop @{$logite->context_stack};

    # likewise perl equivalents shift/unshift/slice etc...

    # push
    push @{$logite->context_stack}, $value;

    # clear any state
    $logite->context_stack( [] ); 

The Nested Diagnostic Context (NDC) to use to generate contextual logging information using the %x placeholder. See DIAGNOSTIC CONTEXTS below.

context_map

    my $context_map = $logite->context_map;

    my $state = $logite->context_map->{state};

    $logite->context_map->{new_state} = $new_value;

    # clear any state
    $logite->context_map( {} );

The Mapped Diagnostic Context (MDC) to use to generate contextual logging information using the %X{key} placeholder. See DIAGNOSTIC CONTEXTS below.

METHODS

MojoX::Logite inherits all methods from Mojo::Log and implements the following new ones.

log($level, @messages)

  $log = $log->log(debug => 'This should work');

This method simply overrides the default Mojo::Log one and logs information to the underling SQL table.

In addition, diagnostic context information the following placeholders can be used in the log messages passed to the method:

    %x The topmost NDC (see C<context_stack> attribute above)
    %X{key} The entry 'key' of the MDC ( see C<context_map> attribute above)

NDC and MDC are explained in DIAGNOSTIC CONTEXTS below.

For example using NDC the following:

  push @{$logite->context_stack}, "193.123.45.67";

  $log = $log->log(debug => '[%x] This should work');

Should store into the SQL table a log message like

  "[193.123.45.67] This should work"

Or using MDC instead:

  $log->context_map->{ip} = "193.123.45.67";
  
  $log = $log->log(debug => '[%X{ip}] This should work');

Should generate the same message.

package_table

Helper function. It returns the fully qualified package name of the underlying SQLite table used for logging.

clear([NUMDAYS])

Clean the log DB. A mandatory unsigned integer NUMDAYS parameter must specified, to indicate that only messages older than NUMDAYS will be removed.

    $logite->clear(1);

Clear all messages older than yesterday (yesterday messages are left intact).

If NUMDAYS is set to 0 the whole log is cleaned up.

schema

Read-only helper function. It returns the SQLite schema used for logging. This might be useful for applications willing to pre-create the tabled into an existing SQLite database, so that MojoX::Logite can then work on its logging table/s on an existing database.

We note that by default ORLite does not allow to create a table on a existing database (obviously), but sometimes we might want to maintain one single DB file for the whole application, including logging information.

ROOT AND TABLE PACKAGE METHODS

The MojoX::Logite package method provides access via the defined package namesapce (default 'MojoX::Logite::ORLite') to the ORLite root packages methods and the table specific methods via the MojoX::Logite::ORLite::Log package. If differently specified the name of the package can be retrieved with the package attribute and package_table method respectively.

BE CAREFUL IF YOU DO NOT KNOW WHAT YOU ARE DOING!

READ carefully the ORLite module documentation first trying anything, you could corrupt or wipe you log DB files without notice

DIAGNOSTIC CONTEXTS

MojoX::Logite allows loggers to maintain common contextual data, called the Nested Diagnostic Context (NDC) and Mapped Diagnostic Context (MDC).

The concept of diagnostic logging context is described in Neil Harrison "Patterns for Logging Diagnostic Messages" article, and it is already implemented into other logging APIs such as Log::Log4perl::MDC.

An MDC is a simple hash table which can be associated to a logger in order to preserve context between different logging operations. An application can stuff values under certain keys and retrieve them later via the "%X{key}" placeholder as part of the message/s passed to the MojoX::Logite log method. This has the benefit to allow to pass a state between different logging operations then more contextual information can be extracted from the log. See the context_map attribute above.

In some other cases, at some point the application might decide to push a piece of data onto the NDC stack, which other parts of the application might want to reuse. For example, at the beginning of a web request in a server, the application might decide to push the IP address of the client onto the stack to provide it for other loggers down the road without having to pass the data from function to function.

MojoX::Logite provides the %x placeholder which is replaced by a string which is a blank-separated concatenation of the elements currently on the context stack. See the context_stack attribute above.

A diagnostic logging context come in handy when users have lots of logs to go through. For example when diagnosing weird bugs on a production system with interleaving outputs. Having more contexts gives you way to filter the output or not outputting unneeded logs.

Once an MDC is tied to a logger any log() operation will automatically refer and use the MDC hash information when referred into output log messages with placeholders. See MojoX::Logite.

MojoX::Logite will automatically replace any %X{key} with the correspoding MDC hash value.

SEE ALSO

 Mojolicious::Plugin::Logite
 Mojolicious::Plugin::Logite::MDC
 Mojolicious::Plugin::Logite::NDC
 Mojo::Log
 Mojolicious
 ORLite

 "Patterns for Logging Diagnostic Messages" from Neil Harrison

REPOSITORY

http://github.com/areggiori/MojoX-Logite

AUTHOR

Alberto Attilio Reggiori, <areggiori@cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2011 by Alberto Reggiori

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.0 or, at your option, any later version of Perl 5 you may have available.