npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

loggin

v3.0.2

Published

Flexible and tiny logging system

Downloads

633

Readme

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