What is Winston?
Winston is a simple and universal logging library.
Why use a logging library?
When developing an application, sometimes we need to get information about how the application is running. We can use functions like console.log
, console.error
, console.warn
to accomplish this. A logging library, such as Winston, allows us to output similar types of data except it can send this data (log data) to locations other than just the console. For example, an external file.
The basic idea of logging
Basically, you have a logger that writes to an arbitrary amount of transports. A transport is essentially a storage device for your logs. Some common transports include:
- stdout (console)
- file
- HTTP
- Datadog (log aggregator)
Log levels
Log levels allow us to categorize the entries in a log file by urgency. The higher up it is, the more severe it is. As you can see, fatal
is the most severe.
These are npm log levels:
{
fatal: 0,
error: 0,
info: 0,
http: 0,
verbose: 0,
debug: 0,
}
Setting up a simple logger in Winston
The recommended way to use winston
is to create your own logger. The simplest way to do this is using winston.createLogger
.
Install Winston in project
npm install winston
In a new file, create a logger with winston.createLogger
const winston = require('winston');
const logger = winston.createLogger({
});
module.exports = logger;
Add custom properties to logger
const winston = require('winston');
const logger = winston.createLogger({
format: winston.format.simple(),
transports: [new winston.transports.Console()],
});
module.exports = logger;
The format
property controls how the logs are displayed visually.
transports
is an array of the places (transports) to send the log data to. In the above example, our only transport is the console.
Use the logger
const logger = require('./logger') // access the file you created earlier
logger.info('text info');
logger.warn('text warn');
logger.error('text error');
logger.debug('text debug');
The output should look something like this:

Why is the debug log not showing up? The default log level for a Winston logger is info. This means that Winston will only log the info level and all levels ABOVE it (warn, error, etc.)
Creating custom log format in Winston
Destructure Winston import
This is just for our own ease of use. No change to the logic.
const { createLogger, format, transports } = require('winston');
const { timestamp, combine, printf } = format;
const logger = createLogger({
format: format.simple(),
transports: [new transports.Console()]
});
Create custom format
const myFormat = printf(({ level, message, timestamp }) => {
return `${timestamp} ${level}: ${message}`;
});
Add the format to your logger
const logger = createLogger({
format: combine(timestamp(), myFormat),
transports: [new transports.Console()]
});
Final code
const { createLogger, format, transports } = require('winston');
const myFormat = printf(({ level, message, timestamp }) => {
return `${timestamp} ${level}: ${message}`;
});
const logger = createLogger({
format: combine(timestamp(), myFormat),
transports: [new transports.Console()]
});
Here is another custom log format
const logger = createLogger({
format: combine(
format.colorize(),
timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
myFormat
),
transports: [new transports.Console()]
});
