Winston: String interpolation causes inconsistent behaviour

Created on 1 Feb 2018  路  2Comments  路  Source: winstonjs/winston

This api uses string interpolation:
logger.log('info', 'test message %s', 'my string'); // info: test message my string

And this uses meta data:
logger.info(`npm version patch -m "Upgrade to %s"`, {status: 'OK'}) // info: npm version patch -m "Upgrade to [object Object]"

Both rely on value of the 2nd argument.
In 2nd case we are using metadata feature to pass status = OK, as well as we are using npm's interpolation for making a new git commit with new upgraded version.

There is no conflict between npm's interpolation and winston... however 2nd argument to info() will be treated as string to interpolate and metadata will receive empty object. This is a very inconsistent behaviour, especially if you are using your own custom formatter relying on metadata.

Is there a way to bypass this besides sanitising strings before calling log methods?

Disabling string interpolation would be a half measure, ideally api should be more cohesive so that this problem would be avoided all together.

docs

Most helpful comment

@mrt123 this is not a winston bug, but I am going to leave it open so that we can better document how splats work within winston.

Under the covers the splat format from logform uses the core util.format method in Node.js. This method is behaving as expected for %s:

node -pe 'util.format(`npm version patch -m "Upgrade to %s"`, {status: "OK"})'
npm version patch -m "Upgrade to [object Object]"

What you want to use is %j:

node -pe 'util.format(`npm version patch -m "Upgrade to %j"`, {status: "OK"})'
npm version patch -m "Upgrade to {"status":"OK"}"

See the util.format docs for more details. I have confirmed this with this example:

const { createLogger, format, transports } = winston;

const logger = winston.createLogger({
  format: format.combine(
    format.splat(),
    format.simple()
  ),
  transports :[
    new winston.transports.Console()
  ]
})

logger.info(`npm version patch -m "Upgrade to %j"`, { status: 'OK' })

All 2 comments

I am also facing a similar issue. Any suggestions for this?

@mrt123 this is not a winston bug, but I am going to leave it open so that we can better document how splats work within winston.

Under the covers the splat format from logform uses the core util.format method in Node.js. This method is behaving as expected for %s:

node -pe 'util.format(`npm version patch -m "Upgrade to %s"`, {status: "OK"})'
npm version patch -m "Upgrade to [object Object]"

What you want to use is %j:

node -pe 'util.format(`npm version patch -m "Upgrade to %j"`, {status: "OK"})'
npm version patch -m "Upgrade to {"status":"OK"}"

See the util.format docs for more details. I have confirmed this with this example:

const { createLogger, format, transports } = winston;

const logger = winston.createLogger({
  format: format.combine(
    format.splat(),
    format.simple()
  ),
  transports :[
    new winston.transports.Console()
  ]
})

logger.info(`npm version patch -m "Upgrade to %j"`, { status: 'OK' })
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Buzut picture Buzut  路  3Comments

xungwoo picture xungwoo  路  3Comments

greenhat616 picture greenhat616  路  3Comments

pocesar picture pocesar  路  3Comments

exortech picture exortech  路  3Comments