pino-pretty
pino-pretty copied to clipboard
Ability to format log string before message is appended
This tool is exactly what I'm after, but I was hoping that it would be a little easier to format the log that's output before the message is appended. I've built a solution and am hoping that it can be adopted into the project. I see room here to provide configuration logic that can allow specifying what keys and delimiters should be rendered.
Rather than make a separate transport, I took a stab at adding a feature that would provide this the flexibility I was looking for. This issue is going to be followed by a PR for review.
My specific use case, was to bind the module and method to each log entry and have them show in a format that's easy to digest. I found a lot of modules that wrap pino and leverage CallSite, but that doesn't help with my minified code. So I went with this approach:
// logger/LoggerFactory.ts
/**
* @module logger
*/
import * as pino from 'pino';
import * as pkg from '../package.json';
process.env.LOG_LEVEL = (process.env.LOG_LEVEL)? process.env.LOG_LEVEL : 'info';
/**
* Factory class which will create a pino logger for each class to use.
*/
export default class LoggerFactory {
/**
* Pino Logger instance to be shared by all modules in this application
*
* log level defaults to `info` and can be overridden with `$LOG_LEVEL` env variable
*/
private static logger = pino({
level: process.env.LOG_LEVEL,
redact: { paths: ['hostname'], remove: true },
prettyPrint: {
translateTime: true,
format: [
{ delimiter: '[', requiresAll: ['time'] },
{ key: 'time' },
{ delimiter: '] ', requiresAll: ['time'] },
{ key: 'level' },
{ delimiter: ' (' },
{ key: 'pid' },
{ delimiter: ') [' },
{ key: 'app' },
{ delimiter: '] [' },
{ key: 'class' },
{ delimiter: '] ' },
{ delimiter: '[', requiresAll: ['fn'] },
{ key: 'fn' },
{ delimiter: '] ', requiresAll: ['fn'] }
]
}
});
/**
* The module/class path where the logger will be used
*
* @param classPath
*/
public static getLogger(classPath:string):pino.Logger {
return LoggerFactory.logger.child({
app: pkg.logCode,
class: classPath
});
}
}
// api/mqtt/Client.js
/**
* @module api/mqtt
*/
import LoggerFactory from '../../logger/LoggerFactory'
const logger = LoggerFactory.getLogger('api/http/Client');
export default class Client {
constructor() {
let flog = logger.child({fn: 'constructor'});
flog.info('Client Created');
}
public connect() {
let flog = logger.child({fn: 'connect'});
flog.trace('start');
// Client connection logic
flog.trace('end');
}
}
// server.js
/**
* @module server
*/
import LoggerFactory from './logger/LoggerFactory';
import Client from './api/mqtt/Client';
const logger = LoggerFactory.getLogger('server');
logger.debug('Start the Application');
let client = new Client();
client.connect
process.on('SIGINT', () => {
logger.info('SIGINT received, closing process');
process.exit()
});
I will then take it upon myself and the team to manually bind fn
when logging within the context of a specific function. Now I get logs that look like this:
[2019-03-02 13:43:35.942 +0000] DEBUG (61924) [app] [server] Start the Application [2019-03-02 13:43:35.946 +0000] TRACE (61924) [app] [api/mqtt/Client] [constructor] Client Created [2019-03-02 13:43:35.947 +0000] TRACE (61924) [app] [api/mqtt/Client] [connect] start [2019-03-02 13:43:35.947 +0000] TRACE (61924) [app] [api/mqtt/Client] [connect] end [2019-03-02 13:44:20.324 +0000] INFO (61924) [app] [server] SIGINT received, closing process
This is exactly what I'm looking for. Any info on this?
I have this working as advertised here: https://github.com/rayvincent-bsd/pino-pretty/tree/v2.6.1-rc.1
Though, this PR hasn't been approved and has lost momentum. And since then, the code has been refactored which would require further updates to allow the PR to be considered again. https://github.com/pinojs/pino-pretty/pull/55
Thanks! I'll take a look at this when I'll go back to my project.