@noveo/logger

1.3.2 • Public • Published

logger

Lightweight, customizable and flexible logger module. 🚀

How to use

npm install @noveo/logger --save
const logger = require('@noveo/logger');

logger.configure({
    transport: 'native',
    level: 'debug',
    useTimezone: true,
    applicationId: 'app-name',
    format: '{datetime} {pid} {ctx.requestId} [{level}] [{full-tag}] {message} {meta}',
    dateFormat: 'DD.MM.YYYY HH:mm:ss.SSS'
});

const log = logger.getLogger('logger-name');


log.info('Some fun message', { meta: 'object' });
// => 16.06.2018 21:00:22.521 3457 0 [info] [app-name:logger-name] Some fun message { "meta": "object" }

Context of execute

Its object contains the executing environment, such as request ID, user data, request source object and other.

API

logger.configure(options)

Configure logger. Can be executed once on start system. Config options have different fields for different transports.

const logger = require('@noveo/logger');
logger.configure({
    transport: 'native',
    level: 'debug',
    useTimezone: true,
    applicationId: 'app-name',
    format: '{datetime} {pid} {ctx.requestId} [{level}] [{full-tag}] {message} {meta}',
    dateFormat: 'DD.MM.YYYY HH:mm:ss.SSS'
})

logger.getLogger(name)

Create logger instance by base config and with the custom name. Return instance of Logger class

Logger

log.(message, [meta])

Create message with default context and write him to output stream with level "LEVEL"

log.info('Info message');
// => 31.01.2017 16:44:55.599 3457 0 [INFO] [app-name::my-module-name] Info message
log.warn('Warning message', {
    userName: 'Cool'
});
// => 31.01.2017 16:44:55.599 3457 0 [WARN] [app-name::my-module-name] Warning message {"userName": "Cool"}

log.LEVEL(ctx, message, [meta])

Create message with context and write him to output stream with level "LEVEL"

log.info({requestId: 45}, 'Info message');
// => 31.01.2017 16:44:55.599 3457 45 [INFO] [app-name::my-module-name] Info message
log.warn({requestId: 48}, 'Warning message', {
    userName: 'Cool'
});
// => 31.01.2017 16:44:55.599 3457 48 [WARN] [app-name::my-module-name] Warning message {"userName": "Cool"}

log.child(tag, [ctx])

Create child logger instance with extra context and predifined tag.

const log = logger.getLogger('tag-name');
const childLog = log.child('child-tag');
log.info('I am child!');
// => 16.02.2017 09:59:27.821 3457 0 [info] [module-name:tag-name.child-tag] I am child!
const log = logger.getLogger('tag-name');
const childLog = log.child('child-tag', {
    requestId: 75
});
log.info('I am child!');
// => 16.02.2017 09:59:27.821 3457 75 [info] [module-name:tag-name.child-tag] I am child!

log.startProfiling([tag])

Create Profile instance.

const log = logger.getLogger('tag-name');
const profile = log.startProfiling('mainController');
// => 16.02.2017 09:59:27.821 3457 0 [debug] [module-name:tag-name.profile] Profiling "mainController" start
log.info(`Current value of profile ${profile}ms`);
// => 16.02.2017 09:59:27.821 3457 0 [info] [module-name:tag-name.profile] Current value of profile 34ms
profile.stop();
// => 16.02.2017 09:59:39.821 3457 0 [debug] [module-name:tag-name.profile] Profiling "mainController" finished in 12045ms
// ... some time later
log.info(`Profile value don\`t increase - ${profile}ms`);
// => 16.02.2017 09:59:49.023 3457 0 [info] [module-name:tag-name.profile] Profile value don`t increase - 12045ms
Profile

API for render profiling messages by logger instance

new Profile(log, [tag])

Create new instance

profile.valueOf() ⇒ Profile

Get current value of profile

profile.toString() ⇒ String

Convert current value to string

profile.stop() ⇒ Profile

Stop time counting

Transports

native

Logging to STDOUT stream in one line format by template string. Settings:

  • metaSerializer {String|Function} - meta serialization function or module name (by default fast-safe-stringify)
  • format {String} - format of output message
const logger = require('@noveo/logger');
logger.configure({
    transport: 'native',
    format: '${datetime} ${ctx.requestId} [${level}] [${full-tag}] ${message} ${meta}'
})
const logger = require('@noveo/logger');
logger.configure({
    transport: 'native',
    metaSerializer: 'json-stringify-safe',
    format: '{datetime} {pid} {ctx.requestId} [{level}] [{full-tag}] {message} {meta}'
})

Parameters available for formatter string:

  • pid - process ID
  • ctx - execution context object
  • tags - list of tags
  • applicationId - Application ID (set on init logger)
  • name - logger instance name (see getLogger)
  • host - host name
  • level - logging level name
  • datetime - Datetime if format, what was set in format propertyDatetime in the format, what was set in format property
  • message - Message
  • full-tag - Artificial parameter what rendered from applicationId (if set), logger name and list of tags

logstash

Logging to STDOUT stream in logstash format. Settings:

  • prettyPrint {Boolean} - flag to print json in pretty format
  • outputStream {stream.Writable|String} - Definition of output stream. Can be a string, if so, it'll use the string as a filename to append logs to it
const logger = require('./app/components/logger');
logger.configure({
    transport: 'logstash',
    prettyPrint: true
})

native-colorized (use only for development mode)

Logging to STDOUT stream in one line format by template string. Settings:

  • metaSerializer {String|Function} - meta serialization function or module name (by default JSON.stringify)
  • format {String} - format of output message
  • colors {Object} - list of levels with color values
  • matches {Object} - list of colors with regexp
const logger = require('@noveo/logger');
logger.configure({
    transport: 'native-colorized',
    level: 'silly',
    useTimezone: true,
    applicationId: 'app-name',
    format: '{datetime} {pid} {ctx.requestId} [{level}] [{full-tag}] {message} {meta}',
    dateFormat: 'DD.MM.YYYY HH:mm:ss.SSS',
    colors: {
        error: 'red',
        warn: 'yellow',
        silly: 'magenta'
    },
    matches: {
        green: 'request:',
        bgRed: /auth/i
    }
});

const log = logger.getLogger('colorized');


log.info('Info');
log.warn('Warning');
log.error('Error');
log.debug('Debug');
log.silly('Silly');
log.info('Start request: /user/login');
log.error('Some problem with AUTH man!');

Colored screenshort

mongo

Logging to mongodb collection. Settings:

  • db {String|Object} - MongoDB connection uri or preconnected db object (optional, dafaults to localhost:27017)
  • options {Object} - MongoDB connection parameters (optional, defaults to {poolSize: 2, autoReconnect: true})
  • collection {String} - The name of the collection you want to store log messages in (optional, defaults to logs)
  • capped {Boolean} - In case this property is true, try to create new log collection as capped
  • cappedSize {Number} - Size of logs capped collection in bytes (optional, defaults to 10000000)
  • cappedMax {Number} - Size of logs capped collection in number of documents (optional)
  • expireAfterSeconds {Number} - Seconds before the entry is removed. Do not use if capped is set
const logger = require('@noveo/logger');
logger.configure({
    transport: 'mongo',
    format: '{datetime} {pid} {ctx.requestId} [{level}] [{full-tag}] {message} {meta}',
    expireAfterSeconds: 5
})

Benchmark

winston x 4,410 ops/sec ±3.48% (75 runs sampled)
bunyan x 4,090 ops/sec ±1.96% (77 runs sampled)
noveo x 4,684 ops/sec ±2.00% (61 runs sampled)
pino x 4,044 ops/sec ±7.33% (55 runs sampled)
Benchmark: ""noveo"" is the fastest.

Convetions

logger-1 and logger-2

The repo contains two special examples ./examples/logger-1 and ./examples/logger-2. The ./examples/logger-1 contains sources example of noveo-logger usage approach based on Andrey Dergaev's opinion. The ./examples/logger-2 contains sources example of noveo-logger usage approach based on my (Alexander Dobrodiy) opinion.

Run ./examples/logger-1

node ./examples/logger-1

Run ./examples/logger-2

node ./examples/logger-2

As Andrey is a tech lead, please, use his approach, not my! =) Maybe anytime we would try my approach in any microservice.

Log levels

Please use such log levels

  • error
  • warning
  • info
  • debug

How to log

Error level

  • Log any error when you have catched it and don't throw it on the next code layer

Warning level

  • When you deprecated a method, put warning on method usage
  • So prefer you have an edge case that causes sending not trivial response to the user or requires any special processing way. Prefer you understand operations team want to catch such cases and big amount of this cases follows new tasks to reduce them. So that is to log it on warning level!

Info level

  • Starting a server
  • Starting a process
  • Starting a controller
  • etc TODO Add points to the list

Debug level

  • If you are implementing a complicated algorithm you may log some values
  • So prefer you had a lot of fluent bugs of a feature. You need to catch it on any server. That is to log on debug level.
  • If you want to log something, but you understand it would generate a sheet of logs on every request, that is to log on debug level

Libraries

If you are developing a library, think it is better to use debug module or not?

What to log

  • It is necessary to log requestId (but we still don't have it).
  • Anything else?

Package Sidebar

Install

npm i @noveo/logger

Weekly Downloads

1

Version

1.3.2

License

MIT

Unpacked Size

35.9 kB

Total Files

12

Last publish

Collaborators

  • adergaev
  • noveo-adobrodiy
  • agsh
  • noveogroup
  • noobikz0r
  • zlblden
  • koluch