confusedWarrior
confusedWarrior

Reputation: 1350

winston Unknown logger level: undefined

I am using winston to log errors, on production it logs to file, on development it logs to console. There are other logging transport I have setup i.e. A custom transport to send errors to slack.

Below is my logger.js

const expressWinston = require('express-winston');
const { createLogger, format, transports } = require('winston');
const SlackAPIAccessDevTransport = require('./winston-slack');

const accessLogger = expressWinston.logger({
  transports: [
    new SlackAPIAccessDevTransport(),
  ],
  format: format.combine(
    format.colorize(),
    format.json(),
  ),
});

const logToFile = createLogger({
  transports: [
    new transports.File({
      json: true,
      maxFiles: 5,
      level: 'error',
      colorize: false,
      filename: 'logs/error.log',
      maxsize: 5242880, // 5MB
    }),
  ],
});

const logToConsole = createLogger({
  level: 'info',
  transports: [
    new transports.Console({
      format: format.combine(
        format.colorize(),
        format.simple(),
      ),
    }),
  ],
});
module.exports = {
  logToFile,
  logToConsole,
  accessLogger,
};

Logging to file works fine, but for Console transport I am getting level undefined

This is my error middleware.

const Logger = require('../utils/logger');

module.exports = async (err, req, res, next) => {
  // log any kind of error
  console.log(err);
  const errorData = {
    date: new Date().toISOString(),
    env: process.env.NODE_ENV,
    level: 'error',
    name: err.name,
    message: err.message,
    api: req.url,
    method: req.method,
    stack: err.stack,
    body: req.body,
    client: req.connection.remoteAddress,
  };
  if (process.env.NODE_ENV === 'production') {
    Logger.logToFile.log(errorData);
  } else {
    Logger.logToConsole.log(err);
  }
return res.status(500).send('Something went wrong!');
}

Upvotes: 4

Views: 9210

Answers (1)

Lin Du
Lin Du

Reputation: 102257

You need to use format.errors.

The errors format allows you to pass in an instance of a JavaScript Error directly to the logger. It allows you to specify whether not to include the stack-trace.

Besides, it's better to add your custom format for error logs.

E.g.

import { createLogger, format, transports } from 'winston';

const logFormatter = format.printf((info) => {
  let { timestamp, level, stack, message } = info;
  message = stack || message;
  return `${timestamp} ${level}: ${message}`;
});

const logToConsole = createLogger({
  level: 'info',
  format: format.errors({ stack: true }),
  transports: [
    new transports.Console({
      format: format.combine(format.colorize(), format.simple(), format.timestamp(), logFormatter),
    }),
  ],
});

const err = new Error('network');
logToConsole.error(err);
// or
logToConsole.log('error', err);

Result:

2021-01-22T06:46:07.088Z error: Error: network
    at Object.<anonymous> (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/src/stackoverflow/65822479/index.ts:19:13)
    at Module._compile (internal/modules/cjs/loader.js:1158:30)
    at Module.m._compile (/Users/ldu020/workspace/github.com/mrdulin/mongoose5.x-lab/node_modules/ts-node/src/index.ts:530:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/ldu020/workspace/github.com/mrdulin/mongoose5.x-lab/node_modules/ts-node/src/index.ts:533:12)
    at Module.load (internal/modules/cjs/loader.js:1002:32)
    at Function.Module._load (internal/modules/cjs/loader.js:901:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
    at main (/Users/ldu020/workspace/github.com/mrdulin/mongoose5.x-lab/node_modules/ts-node/src/bin.ts:212:14)
    at Object.<anonymous> (/Users/ldu020/workspace/github.com/mrdulin/mongoose5.x-lab/node_modules/ts-node/src/bin.ts:470:3)
2021-01-22T06:46:07.089Z error: Error: network
    at Object.<anonymous> (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/src/stackoverflow/65822479/index.ts:19:13)
    at Module._compile (internal/modules/cjs/loader.js:1158:30)
    at Module.m._compile (/Users/ldu020/workspace/github.com/mrdulin/mongoose5.x-lab/node_modules/ts-node/src/index.ts:530:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/ldu020/workspace/github.com/mrdulin/mongoose5.x-lab/node_modules/ts-node/src/index.ts:533:12)
    at Module.load (internal/modules/cjs/loader.js:1002:32)
    at Function.Module._load (internal/modules/cjs/loader.js:901:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
    at main (/Users/ldu020/workspace/github.com/mrdulin/mongoose5.x-lab/node_modules/ts-node/src/bin.ts:212:14)
    at Object.<anonymous> (/Users/ldu020/workspace/github.com/mrdulin/mongoose5.x-lab/node_modules/ts-node/src/bin.ts:470:3)

Upvotes: 3

Related Questions