Norway Porridge Makers

    loggin

    3.0.2 • Public • Published

    loggin Build Status

    Flexible and tiny logging system for nodejs platform

    Easiest usage example

    Features

    • Pretty default settings
    • Context logging
    • Easy messages templating (sprintf)
    • Incremental configuration

    Installation

    $ npm install loggin
    

    Easiest usage

    var logging = require('loggin');
     
    logging.log('Hello, World!');

    Philosophy

    The idea is to create lightweight logging system, with low understanding threshold, but with high customization level. Every data you log turns to record object, then that will be formatted with layout and then will be handled by handler.

    Handler is an object that have a behaviour to store data somewhere. It can be just stdout or file, even database. The function of handler - just store log messages. Handler storing place can require some data type or format, therefore handler have layout.

    Layout is an object that takes some structure, describing the log message and turns it to handler required format. Also layout can manage just message representation. The same types of handlers can have different layouts. Totally, layout is a micro templating system. Layout template can require some data format. Because of that layout have own record factory.

    Record factory is special object that takes incoming data like caller, arguments passed to caller, log level, logging context, etc. that constructs a log message model for layout.

    Context appending

    Sometimes log messages need to be bound to some execution context. E.g. request id.

    console.log('%s - %s', request.id, 'Some happened');

    You should add request id to your any log message to then find some information about this request later. With loggin you should not. You can create a logger that context is bound to request id.

    var rootLogger = logging.getLogger();
     
    ***
     
    //  bind request context
    var logger = rootLogger.bind(request.id);
     
    logger.log('The data, bound to request id');

    Your record factory has access to logging context, and layout can represent it in messages. Logger instances is lightweight, and you can create context loggers as mush as you want.

    API

    logging

    Logging logging.getLogger([name="default"])

    Creates a new root logger

    var logger = logging.getLogger();

    logging will memorize getLogger calls by name argument.

    assert.strictEqual(logging.getLogger('foo'), logging.getLogger('foo'));

    It would also be useful to know that loggin package exporting object is an instance of Logging with name "default". It is default root logger.

    var logging = require('loggin');
     
    assert.strictEqual(logging, logging.getLogger());   // done

    String logging.logLevel

    Sets logging level

    Available log levels:

    • INTERNAL use it for logging calls and other internal stuff
    • DEBUG recommended to use it for debugging applications
    • NOTE development verbose information (default)
    • INFO minor information
    • LOG significant messages
    • WARNING really important stuff
    • ERROR application business logic error condition
    • FATAL system error condition
    logging.logLevel = 'LOG'; // production case

    Set any unknown level to disable any records

    Logger

    logger is an object returned from logging.getLogger()

    logger.log(String message[, * arg...])

    Logs a message

    logger.log('Hello %s', 'world');

    internal, debug, note, info, warn, error, fatal methods also available

    logger.bind(String context)

    Creates new context lightweight logger

    var rootLogger = logging.getLogger('<e.g. application name>');
    var contextLogger = rootLogger.bind('<some context>');

    logger.setup(Object some)

    Setups logger to <some> object

    logger.setup(console);
    console.log('Start initialization');

    Advanced customization

    The true way to customize your logging is using logging.conf

    logging.conf(configs)

    Incrementaly confugures logging

    logging.conf({
        logLevel: 'WARNING'
    });

    This call adds a logLevel to the existing configuration.

    How to create my own log handler?

    Handler class is an object that must implement handler.handle method and layout property that should be a layout. handler.handle will be called with value, returned from handler's layout.

    Create your own handler or use bundled StreamHandler handler.

    //  Using stream-handler
    logging.conf({
        handlers: {
            // handler instance or descriptor
            console: {
                //  path to handler class or direct link to class
                Class: 'loggin/core/handlers/stream-handler',
                //  Link to handler's layout, layout instance will be passed to handler constructor as first argument
                layout: 'colorVerbose',
                //  handlers keyword arguments, will be passed to handler constructor as second argument
                kwargs: {
                    stream: process.stdout,
                }
            }
        }
    });

    How to create my own layout?

    Layout class must implement layout.format method and record property. layout.format will be called before record handled.

    record property should be an object that implements create method, that will be called before layout.format called.

    record.create will be called with positional arguments:

    1. String context - logger context
    2. String level - record log level
    3. Function caller - function, that was called in program to make lo entry, e.g. logger.log.
    4. Arguments args - the arguments passed to caller

    record.create should return an object which will be passed to layout.format.

    Create your own layout class, or configure bundled classes.

    //  Using builtin layout class
    logging.conf({
        layouts: {
            // layout instance or configuration
            spec: {
                //  Path to layout class or direct link to constructor
                Class: 'loggin/core/layouts/layout',
                //  Link to config.records.regular, should be passed in Layout constructor as first argument
                record: 'regular',
                //  layout-specific arguments, will be passed to Layout constructor as second argument
                kwargs: {
                    template: '%(date)s %(level)s %(message)s\n'
                    dateFormat: '%H:%M:%S'
                }
            }
        }
    });

    layout.format should return any data for its handler.

    Record factories

    There are some built-in Record classes

    • loggin/core/records/regular - produces date, context, message and level variables.
    • loggin/core/records/verbose - inherits from regular. Also produces module, filename, line and column variables.

    You can create your own record class and specify it in config.

    logging.conf({
        records: {
            //  record descriptor or instance
            recordName: {
                // path to record class or direct link to class
                Class: 'path/to/class',
                //  this object will be passed to record constructor
                kwargs: {}
            }
        }
    });

    Ok, how to use MY handler???

    You can enable one or more handlers:

    logging.conf({
        enabled: ['console'/**, more */]
    });

    Handler log levels

    You can support handler.minLevel and handler.maxLevel properties in your handlers which can be used to enable your handlers in some record level ranges

    logging.conf({
        enabled: ['foo', 'bar']
        handlers: {
            foo: {
                Class: 'loggin/core/handlers/stream-handler',
                layout: 'colorRegular',
                kwargs: {
                    maxLevel: 'LOG',
                    stream: process.stdout
                }
            },
            bar: {
                Class: 'loggin/core/handlers/stream-handler',
                layout: 'colorVerbose',
                kwargs: {
                    minLevel: 'WARNING',
                    stream: process.stderr
                }
            }
        }
    });

    Configuration like this let you to write LOG and less records to stdout and WARNING and higher records to stderr.

    Default configuration

    loggin gives you rich and pretty default configuration. There are some handlers, layouts and two record instances.

    Records

    • regular - regular record provides fields:

      • String context - logger context
      • String level - record log level
      • Date date - record creation date
      • Array message - all the arguments passed to log function
    • verbose - more rich record than regular provides the fields:

      • String context - logger context
      • String level - record log level
      • Date date - record creation date
      • Array message - all the arguments passed to log function
      • Number line - log calling line number
      • Number column - log calling column number
      • String filename - log caller absolute filename
      • String module - log caller filename relative from main module dirname

    Layouts

    • cleanRegular - the layout, ideal for logging regular messages into file
    • cleanVerbose - may be pretty to log warnings and errors into file, including caller data
    • colorRegular - ideal for logging regular messages to terminal
    • colorVerbose - good for logging errors and warnings to terminal, including caller data

    Handlers

    • stdoutColorRegular - writes colored compact entries which level less then WARNING to standard output (dev)
    • stderrColorRegular - writes colored compact entries which level is WARNING to standard error output (dev)
    • stderrColorVerbose - writes colored verbose entries which level higher then LOG to standard error output (dev)
    • stdoutCleanRegular - writes all the entries to standard output in pretty compact layout (prod)
    • stderrCleanRegular - writes WARNING entries to standard error output in pretty compact layout (prod)
    • stderrCleanVerbose - writes WARNING and higher entries to standard error output in super verbose layout (prod)

    Default setup

    By default stdoutColorRegular and stderrColorVerbose handlers are enabled and NOTE log level is enabled. In this case you can see really important data in pretty form in your terminal output. It is development setup. In production case you can set higher logLevel and enable stdoutCleanRegular and stderrCleanVerbose handlers to see clean logs in the files, written by you application starting daemon for example.

    var loggin = require('loggin');
     
    if (process.env.NODE_ENV !== 'development') {
        loggin.conf({
            logLevel: 'LOG',
            enabled: ['stdoutCleanRegular', 'stdoutCleanVerbose']
        });
    }

    Complete configuration example

    See loggin's default configuration as example


    LICENSE MIT

    Install

    npm i loggin

    DownloadsWeekly Downloads

    56

    Version

    3.0.2

    License

    MIT

    Unpacked Size

    85.3 kB

    Total Files

    29

    Last publish

    Collaborators

    • golyshevd
    • mkg20001