By Thanos - @thanpolas
Node.js
Having a log at the right place, with the right kind of information can save your 🥓🥓🥓.
Why Logging is Important
Why Logging is Important
Why Logging is Important
Why Logging is Important
What and How to Log
[2021-04-10T13:05:32.712Z] ▶ notice /app/services.boot.js - Booting Services...
{"level":"notice","severity":5,"dt":"2021-04-10T13:04:03.215Z","message":"Booting Services...","context":{"runtime":{"application":"skgbot"},"source":{"file_name":"/app/services.boot.js"},"system":{"hostname":"192.168.1.74","pid":49862,"process_name":"/Users/thanpolas/.nvm/versions/node/v14.15.5/bin/node"}},"event":{}}
Pretty Print
JSON
What and How to Log
What and How to Log
What and How to Log
In a JSON logger, you should be able to add certain [boolean] flags so you can later easily query and filter for them.
Example Flags:
security: true
audit: true
bogus: true
Logality is a versatile and extensible logger for Node.JS
Logality Features
{
"severity": 6,
"level": "info",
"dt": "2018-05-18T16:25:57.815Z",
"message": "hello world",
"event": {},
"context": {
"runtime": {
"application": "testLogality"
},
"source": {
"file_name": "/test/spec/surface.test.js"
},
"system": {
"hostname": "localhost",
"pid": 36255,
"process_name": "node ."
}
}
}
Automatic Detection
Logality Features
Logality Uses the Syslog Severity Levels (RFC 5424)
Logality Features
Serialisers are triggered by defined keys in the context object.
Each serialiser is configured to listen to a specific key.
log.info('User Logged in', {
user: udo,
});
Logality Features
User Serialiser
log.info('User Logged in', { user: user })
Error Serialiser
log.error('User Logged in', { error: exception })
Express Request Serialiser
function index (req, res) {
log.info('Index request', { req });
}
Logality Features
You can define your own serialisers
const mySerialisers = {
order: function (order) {
return {
path: 'context.order',
value: {
order_id: order.id,
sku_id: order.sku,
total_price: order.item_price * order.quantity,
quantity: order.quantity,
},
};
},
};
log.info('New order', {order: orderItem})
Logality Features
You can overwrite built-in serialisers
const mySerialisers = {
user: function (user) {
return {
path: 'context.user',
value: {
id: user.id,
email: user.email,
first_name: user.first_name,
last_name: user.last_name,
},
};
},
};
log.info('User Logged In', {user: req.user})
Logality Features
Middleware are invoked after serialisers
logality.use((context) => {
delete context.user;
});
The "context" object is a JS Native Object, representing the entire log message.
Logality Features
You can configure Logality for asynchronous operation
logality.use(async (context) => {
await db.write(context);
});
Consequently, all logging commands need async invocation:
await log.info('Something happened');
Logality Features
You can fully manipulate the master output:
const Logality = require('logality');
const logality = Logality({
appName: 'service-something',
prettyPrint: false,
async: false,
output: (logContext) => {
const logMessage = JSON.stringify(logContext);
process.stdout.write(logMessage);
},
});
The "logContext" object is a JS Native Object, representing the entire log message.
Logality Features
Logality can safely be used in libraries!
const thirdPartyLib = require('thirdPartyLibrary');
/** ... */
const myLogality = Logality();
myLogality.pipe(thirdPartyLib.logality);
Logality | Winston | Bunyan | Pino | |
---|---|---|---|---|
JSON Output | ✅ | ✅ | ✅ | ✅ |
Pretty Print | ✅ | ✅ | ❌ | ✅ |
Custom Log Levels | ❌ | ✅ | ❌ | ✅ |
Serialisers | ✅ | ❌ | ✅ | ✅ |
Middleware | ✅ | ✅ | ❌ | ✅ |
Mutate JSON Schema | ✅ | ✅ | ❌ | ❌ |
Logality | Winston | Bunyan | Pino | |
---|---|---|---|---|
Output Destination | ✅ | ✅ | ✅ | ✅ |
Mutate Output | ✅ | ✅ | ❌ | ❌ |
Async Operation | ✅ | ❌ | ❌ | ❌ |
Filename Detection | ✅ | ❌ | ❌ | ❌ |
Speed Optimised | ❌ | ❌ | ❌ | ✅ |
Used in Libraries | ✅ | ❌ | ❌ | ❌ |
Thank you
Questions?