31

I am using Winston logging with my Node.js app and have defined a file transport. Throughout my code, I log using either logger.error, logger.warn, or logger.info.

My question is, how do I specify the log level? Is there a config file and value that I can set so that only the appropriate log messages are logged? For example, I'd like the log level to be "info" in my development environment but "error" in production.

Boann
  • 48,794
  • 16
  • 117
  • 146
Silent User
  • 2,657
  • 7
  • 29
  • 36

6 Answers6

37

If you are using the default logger, you can adjust the log levels like this:

const winston = require('winston');
// ...
winston.level = 'debug';

will set the log level to 'debug'. (Tested with winston 0.7.3, default logger is still around in 3.2.1).

However, the documentation recommends creating a new logger with the appropriate log levels and then using that logger:

const myLogger = winston.createLogger({
  level: 'debug'
});
myLogger.debug('hello world');

If you are already using the default logger in your code base this may require you to replace all usages with this new logger that you are using:

const winston = require('winston');
// default logger
winston.log('debug', 'default logger being used');

// custom logger
myLogger.log('debug', 'custom logger being used');
AndreasPizsa
  • 1,736
  • 19
  • 26
  • 2
    yep, this is the correct answer, the other ones require creating a new logger and don't adjust the settings of the existing default loggers created by winston. –  Aug 01 '14 at 03:06
  • 1
    This was the single hardest bit of info to find! Thanks @AndreasPizsa! – Adrian Lynch Mar 16 '18 at 13:44
  • 2
    @RudolfOlah The correct answer is what the docs recommend, which is creating a new logger. Changing the log level of the default logger (or of any other already created logging instance) dynamically has been discussed in winston's github issues countless times and the outcome is in most cases - while it might work with most or even recent/current versions - to not do it. Don't just call an answer "correct" just because it matches your personal preference better. However there are libraries wrapping around winston that provide this functionality. – Num Lock Feb 14 '20 at 07:50
  • 1
    Appreciated, thanks. Mind sharing a few links or search terms to such libraries? @RudolfOlah – AndreasPizsa Feb 14 '20 at 10:27
  • Oh, that’s funny - accidentally mentioned RudolfOlah when in fact I meant @Num Lock. Thank you both for your contributions and insight! – AndreasPizsa Feb 16 '20 at 15:17
25

Looks like there is a level option in the options passed covered here

From that doc:

var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)({ level: 'error' }),
    new (winston.transports.File)({ filename: 'somefile.log' })
  ]
});

Now, those examples show passing level in the option object to the console transport. When you use a file transport, I believe you would pass an options object that not only contains the filepath but also the level.

That should lead to something like:

var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.File)({ filename: 'somefile.log', level: 'error' })
  ]
});

Per that doc, note also that as of 2.0, it exposes a setLevel method to change at runtime. Look in the Using Log Levels section of that doc.

bryanmac
  • 38,941
  • 11
  • 91
  • 99
  • 1
    bryanmac, thanks for the reply but I am afreaid it still doesnt answer my question. Let me clarify. At my previous job, we were using a custom logging module which was very similar to winston featurewise. The module relied on an entry in a config file which set the log level. If we had to debug any issue, we would change the entry in the config file so as to increase the verbosity of the log. But during other times, we would set the level to its lowest level so as to log only errors. Is something like that possible with winston? – Silent User Mar 21 '13 at 02:33
  • 1
    The programmatic code above could read from a log file to set the initial logging level. Now, to change at runtime from the intial/default level, you could expose an API that turns around and calls the setLevel method I mentioned. That way you could have an admin page that reads the log level and a way to set it. – bryanmac Mar 21 '13 at 04:42
  • Bryan, I am going to accept your initial answer + your comment as the answer to my question. Thanks. – Silent User Mar 21 '13 at 18:10
  • Thanks - if you have any other feedback or thoughts on how you used it or it worked out, that's appreciated. I was in the process of going through the same thing right now :) – bryanmac Mar 21 '13 at 23:00
  • Bryan, I will certainly comeback and share my implementation details here. – Silent User Mar 22 '13 at 18:30
  • Bryan, I ended up using a solution based on this post (which is very similar to what your solution was): http://stackoverflow.com/questions/8332333/node-js-setting-up-environment-specific-configs-to-be-used-with-everyauth – Silent User Mar 23 '13 at 04:00
8

There are 6 default levels in winston: silly=0(lowest), debug=1, verbose=2, info=3, warn=4, error=5(highest)

While creating the logger transports, you can specify the log level like:

new (winston.transports.File)({ filename: 'somefile.log', level: 'warn' })

Above code will set log level to warn, which means silly, verbose and info will not be output to somefile.log, while warn, debug and error will.

You can also define your own levels:

var myCustomLevels = {
  levels: {
    foo: 0,
    bar: 1,
    baz: 2,
    foobar: 3
  }
};

var customLevelLogger = new (winston.Logger)({ levels: myCustomLevels.levels });
customLevelLogger.foobar('some foobar level-ed message');

Note that it's better to always include the 6 predefined levels in your own custom levels, in case somewhere used the predefined levels.

Chen
  • 1,654
  • 2
  • 13
  • 21
3

You can change the logging level in runtime by modifying the level property of the appropriate transport:

var log = new (winston.Logger)({
    transports: [
        new (winston.transports.Console)({ level : 'silly' })
    ]
});

...

// Only messages with level 'info' or higher will be logged after this.
log.transports.Console.level = 'info';

I guess, it works similarly for file but I haven't tried that.

Wyatt Barnett
  • 15,573
  • 3
  • 34
  • 53
weekens
  • 8,064
  • 6
  • 45
  • 62
0

If you want to change the log level on the fly. Like for when you need to trace production issue for short amount of time; then revert to error log level. You can use a dynamic logger provided you can expose a service on the web https://github.com/yannvr/Winston-dynamic-loglevel

Yann VR
  • 486
  • 5
  • 9
0

apart from this you can cleanly achieve this by imlplementing runtime-node-refresh follow this link for more.

  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/33007407) – L8R Oct 27 '22 at 17:31