-
Notifications
You must be signed in to change notification settings - Fork 1
Logging Functions
Before you can use perj
to log content to JSON you need to create a logger using the Perj constructor.
import Perj from 'perj'
const log = new Perj()
Once you have a logger (I like to use the variable name 'log') you can use the logging functions. By default there are 6 logging functions being fatal
, error
, warn
, info
, debug
, and trace
. You don't have to stick with these functions. You can create your own using the levels option.
Each one of the logging function has a number associated with it. This number is used for filtering purposes.
Here is what the default levels object looks like with the names and numbers:
{
fatal: 60,
error: 50,
warn: 40,
info: 30,
debug: 20,
trace: 10
}
When you create the logger each of these log levels is created as a function. Here is an example using each of the functions and there output:
import Perj from 'perj'
const log = new Perj()
log.level = 'trace'
log.fatal('fatal')
log.error('error')
log.warn('warn')
log.info('info')
log.debug('debug')
log.trace('trace')
/*
Standard out will be:
{"level":"fatal","lvl":60,"time":1526272817616,"msg":"fatal","data":""}
{"level":"error","lvl":50,"time":1526272817620,"msg":"error","data":""}
{"level":"warn","lvl":40,"time":1526272817620,"msg":"warn","data":""}
{"level":"info","lvl":30,"time":1526272817621,"msg":"info","data":""}
{"level":"debug","lvl":20,"time":1526272817621,"msg":"debug","data":""}
{"level":"trace","lvl":10,"time":1526272817621,"msg":"trace","data":""}
*/
There are a couple of points on interest in the above example. Firstly, the log.level
was set to 'trace'. If this change was not made the debug
and trace
messages would not have been seen. Secondly you will see the output contains the 5 default keys being level
, lvl
, time
, msg
, and data
.
The log.level setting is important. If you set log.level = 'warn'
then you will only see fatal
, error
, and warn
log messages sent to the write function (process.stdout by default). This allows you to turn down the verbosity of the logging in production and likewise turn it up for development.
Throughout your code you can write log.info()
statements to help understand the flow of processing when debugging and help trace errors. Use the log.error()
to report exceptions and the other levels where you see fit.
I think one of the best features of perj
is the flexibility in the logging arguments. You can call each log function with any number of arguments of any type. Here is the logic behind where the log arguments get placed:
- The first
String
message will be assigned to themsg
JSON key. The firstString
message is defined as either aString
argument or the message on anError
object. - Extra
String
messages will be found attached to thedata
JSON key. - One or more
Object
arguments will be found attached to thedata
JSON key. - If there is more than one value attached to the
data
key the key will be anArray
.
Let's see how that works with some code. Here is calling the info
and error
logging functions with a number of different arguments and their associated output. Note that you can pass Error objects to any log function:
import Perj from 'perj'
const log = new Perj()
log.info('single string')
log.info('first string', 'second string')
log.info('first string', 'second string', 'third string')
log.info('first string', 'second string', 'third string', 'fourth string')
log.info({ first: 'object' })
log.info({ first: 'object' }, { second: 'object' })
log.info({ first: 'object' }, { second: 'object' }, { third: 'object' })
log.info('single string', { first: 'object' })
log.info({ first: 'object' }, 'single string')
log.info({ first: 'object' }, 'first string', 'second string')
log.info({ first: 'object' }, 'single string', { second: 'object' })
log.error(new Error('first error'))
log.error(new Error('first error'), 'custom message after error')
log.error('custom message before error', new Error('first error'))
log.error(new Error('first error'), new Error('second error'))
log.error(new Error('first error'), new Error('second error'), new Error('third error'))
The above code will produce the following output. Note that I have formatted the output to make it easier to read:
{
"level": "info",
"lvl": 30,
"time": 1526274419613,
"msg": "single string",
"data": ""
}
{
"level": "info",
"lvl": 30,
"time": 1526274419615,
"msg": "first string",
"data": "second string"
}
{
"level": "info",
"lvl": 30,
"time": 1526274419616,
"msg": "first string",
"data": [
"second string",
"third string"
]
}
{
"level": "info",
"lvl": 30,
"time": 1526274419616,
"msg": "first string",
"data": [
"second string",
"third string",
"fourth string"
]
}
{
"level": "info",
"lvl": 30,
"time": 1526274419616,
"msg": "",
"data": {
"first": "object"
}
}
{
"level": "info",
"lvl": 30,
"time": 1526274419617,
"msg": "",
"data": [
{
"first": "object"
},
{
"second": "object"
}
]
}
{
"level": "info",
"lvl": 30,
"time": 1526274419617,
"msg": "",
"data": [
{
"first": "object"
},
{
"second": "object"
},
{
"third": "object"
}
]
}
{
"level": "info",
"lvl": 30,
"time": 1526274419617,
"msg": "single string",
"data": {
"first": "object"
}
}
{
"level": "info",
"lvl": 30,
"time": 1526274419617,
"msg": "single string",
"data": {
"first": "object"
}
}
{
"level": "info",
"lvl": 30,
"time": 1526274419618,
"msg": "first string",
"data": [
{
"first": "object"
},
"second string"
]
}
{
"level": "info",
"lvl": 30,
"time": 1526274419618,
"msg": "single string",
"data": [
{
"first": "object"
},
{
"second": "object"
}
]
}
{
"level": "error",
"lvl": 50,
"time": 1526274419619,
"msg": "first error",
"data": {
"stack": "Error: first error\n at Object.<anonymous> (/home/grant/node-perj/quick.js:33:11)\n at Module._compile (internal/modules/cjs/loader.js:678:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)\n at Module.load (internal/modules/cjs/loader.js:589:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:528:12)\n at Function.Module._load (internal/modules/cjs/loader.js:520:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)\n at startup (internal/bootstrap/node.js:228:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)",
"message": "first error",
"name": "Error"
},
"error": true
}
{
"level": "error",
"lvl": 50,
"time": 1526274419620,
"msg": "first error",
"data": [
{
"stack": "Error: first error\n at Object.<anonymous> (/home/grant/node-perj/quick.js:34:11)\n at Module._compile (internal/modules/cjs/loader.js:678:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)\n at Module.load (internal/modules/cjs/loader.js:589:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:528:12)\n at Function.Module._load (internal/modules/cjs/loader.js:520:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)\n at startup (internal/bootstrap/node.js:228:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)",
"message": "first error",
"name": "Error"
},
"custom message after error"
],
"error": true
}
{
"level": "error",
"lvl": 50,
"time": 1526274419621,
"msg": "custom message before error",
"data": {
"stack": "Error: first error\n at Object.<anonymous> (/home/grant/node-perj/quick.js:35:43)\n at Module._compile (internal/modules/cjs/loader.js:678:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)\n at Module.load (internal/modules/cjs/loader.js:589:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:528:12)\n at Function.Module._load (internal/modules/cjs/loader.js:520:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)\n at startup (internal/bootstrap/node.js:228:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)",
"message": "first error",
"name": "Error"
},
"error": true
}
{
"level": "error",
"lvl": 50,
"time": 1526274419622,
"msg": "first error",
"data": [
{
"stack": "Error: first error\n at Object.<anonymous> (/home/grant/node-perj/quick.js:36:11)\n at Module._compile (internal/modules/cjs/loader.js:678:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)\n at Module.load (internal/modules/cjs/loader.js:589:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:528:12)\n at Function.Module._load (internal/modules/cjs/loader.js:520:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)\n at startup (internal/bootstrap/node.js:228:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)",
"message": "first error",
"name": "Error"
},
{
"stack": "Error: second error\n at Object.<anonymous> (/home/grant/node-perj/quick.js:36:37)\n at Module._compile (internal/modules/cjs/loader.js:678:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)\n at Module.load (internal/modules/cjs/loader.js:589:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:528:12)\n at Function.Module._load (internal/modules/cjs/loader.js:520:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)\n at startup (internal/bootstrap/node.js:228:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)",
"message": "second error",
"name": "Error"
}
],
"error": true
}
{
"level": "error",
"lvl": 50,
"time": 1526274419623,
"msg": "first error",
"data": [
{
"stack": "Error: first error\n at Object.<anonymous> (/home/grant/node-perj/quick.js:37:11)\n at Module._compile (internal/modules/cjs/loader.js:678:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)\n at Module.load (internal/modules/cjs/loader.js:589:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:528:12)\n at Function.Module._load (internal/modules/cjs/loader.js:520:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)\n at startup (internal/bootstrap/node.js:228:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)",
"message": "first error",
"name": "Error"
},
{
"stack": "Error: second error\n at Object.<anonymous> (/home/grant/node-perj/quick.js:37:37)\n at Module._compile (internal/modules/cjs/loader.js:678:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)\n at Module.load (internal/modules/cjs/loader.js:589:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:528:12)\n at Function.Module._load (internal/modules/cjs/loader.js:520:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)\n at startup (internal/bootstrap/node.js:228:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)",
"message": "second error",
"name": "Error"
},
{
"stack": "Error: third error\n at Object.<anonymous> (/home/grant/node-perj/quick.js:37:64)\n at Module._compile (internal/modules/cjs/loader.js:678:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)\n at Module.load (internal/modules/cjs/loader.js:589:32)\n at tryModuleLoad (internal/modules/cjs/loader.js:528:12)\n at Function.Module._load (internal/modules/cjs/loader.js:520:3)\n at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)\n at startup (internal/bootstrap/node.js:228:19)\n at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)",
"message": "third error",
"name": "Error"
}
],
"error": true
}