loggin
v3.0.2
Published
Flexible and tiny logging system
Downloads
633
Readme
loggin
Flexible and tiny logging system for nodejs platform
##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 stuffDEBUG
recommended to use it for debugging applicationsNOTE
development verbose information (default)INFO
minor informationLOG
significant messagesWARNING
really important stuffERROR
application business logic error conditionFATAL
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:
String context
- logger contextString level
- record log levelFunction caller
- function, that was called in program to make lo entry, e.g.logger.log
.Arguments args
- the arguments passed tocaller
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
- producesdate
,context
,message
andlevel
variables.loggin/core/records/verbose
- inherits fromregular
. Also producesmodule
,filename
,line
andcolumn
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 contextString level
- record log levelDate date
- record creation dateArray message
- all the arguments passed to log function
verbose
- more rich record thanregular
provides the fields:String context
- logger contextString level
- record log levelDate date
- record creation dateArray message
- all the arguments passed to log functionNumber line
- log calling line numberNumber column
- log calling column numberString filename
- log caller absolute filenameString module
- log caller filename relative from main module dirname
###Layouts
cleanRegular
- the layout, ideal for logging regular messages into filecleanVerbose
- may be pretty to log warnings and errors into file, including caller datacolorRegular
- ideal for logging regular messages to terminalcolorVerbose
- good for logging errors and warnings to terminal, including caller data
###Handlers
stdoutColorRegular
- writes colored compact entries which level less thenWARNING
to standard output (dev)stderrColorRegular
- writes colored compact entries which level isWARNING
to standard error output (dev)stderrColorVerbose
- writes colored verbose entries which level higher thenLOG
to standard error output (dev)stdoutCleanRegular
- writes all the entries to standard output in pretty compact layout (prod)stderrCleanRegular
- writesWARNING
entries to standard error output in pretty compact layout (prod)stderrCleanVerbose
- writesWARNING
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