Before winston@3, the rewriter offered a possibility to mutate the metadata. @indexzero explained that the name comes from this possibility.
Mutating metadata is helpful for adding a request/correlation id to all logs of a given request without changing the logger statements.
I understand from the migration guide that rewriters are replaced by custom formats in winston@3.
We can write something like this:
import cls from 'cls-hooked';
import winston from 'winston';
import Koa from 'koa';
import Router from 'koa-router';
import uuid from 'uuid';
const addContext = winston.format.printf(info => {
const ns = cls.getNamespace('foobar');
const correlationId = ns.get('correlationId');
info.message = `${correlationId ? `cor=${correlationId} ` : ''}${info.message}`;
return info;
});
winston.configure({
transports: [new winston.transports.Console()],
format: winston.format.combine(
addContext,
winston.format.json(),
),
});
const app = new Koa();
const ns = cls.createNamespace('foobar');
app.use(async (ctx, next) => {
await ns.runAndReturn(async () => {
const correlationId = uuid.v4();
cls.getNamespace('foobar').set('correlationId', correlationId);
await next();
});
});
const router = new Router();
app.use(router.routes());
router.get('/', async ctx => {
winston.info('Hello World');
ctx.body = 'Hello World';
});
app.listen(3000);
The log displayed in the console is:
{"message":"cor=cfec0c42-3890-4c44-b5f9-00a1df7ed529 Hello World","level":"info"}
Before winston@3, with a rewriter it was possible to mutate the metadata to obtain this:
{"message":"Hello World","level":"info", "correlation_id": "cfec0c42-3890-4c44-b5f9-00a1df7ed529"}
With winston@3, the only way to achieve this seems to wrap the winston module for the level methods (info(), ...) and to add the metadata in parameter of those methods. Am I right ?
Is it an intentional decision of the winston@3 design to remove the possibility to mutate the metadata ?
+1 I was disappointed to see that this was removed and am considering downgrading to get that functionality back
@ThierryAbalea @shmendo info objects are considered mutable in [email protected]. Another way to look at it is that we _combined formatters and rewriters into a single, new concept:_ formats.
To get the behavior you are seeking simply set it as a property on the info object in the format. Consider the classic credit card masking example that's been in the README.md of winston for ages, but upgraded to [email protected].
/*
* Simple string mask. For example purposes only.
*/
function maskCardNumbers(num) {
const str = num.toString();
const { length } = str;
return Array.from(str, (n, i) => {
return i < length - 4 ? '*' : n;
}).join('');
}
// Define the format
const maskFormat = winston.format(info => {
// You can CHANGE existing property values
if (info.creditCard) {
info.creditCard = maskCardNumbers(info.creditCard);
}
// You can also ADD NEW properties if you wish
info.hasCreditCard = !!info.creditCard;
return info;
});
// Then combine the format with other formats and make a logger
const logger = winston.createLogger({
format: winston.format.combine(
//
// Order is important here, the formats are called in the
// order they are passed to combine.
//
maskFormat(),
winston.format.json()
),
transports: [
new winston.transports.Console()
]
});
logger.info('transaction ok', { creditCard: 123456789012345 });
Or in your code sample:
const addContext = winston.format.printf(info => {
const ns = cls.getNamespace('foobar');
const correlationId = ns.get('correlationId');
// Do not mutate the message
// info.message = `${correlationId ? `cor=${correlationId} ` : ''}${info.message}`;
// Just MUTATE the info by adding a correlationId property if it exists
if (correlationId) {
info.correlationId = correlationId;
}
return info;
});
Thank you for opening this issue. Mutability of info within formats is a core concept for winston@3. To help make upgrading easier and less frightening for long time users we committed to not releasing 3.0.0 out of RC until the Upgrad Guide was complete.
In triaging this issue I was able to make a final draft of the upgrade guide in https://github.com/winstonjs/winston/pull/1278. Any additional upgrade feedback you have would be awesome!
Most helpful comment
+1 I was disappointed to see that this was removed and am considering downgrading to get that functionality back