Winston is the versatile and popular logging library for Node.js, It is widely used due to its flexibility and powerful features. It allows the developers to log information to various sources (e.g., console, files, databases) and provides robust tools for creating custom logs, handling exceptions, and formatting the output.
The Winston is designed to be simple yet extensible. At its core, it operates using the "transports" which determine where your logs are sent. You can log into the files, databases, or even the external logging services. Winston also supports multiple logging levels, custom formats, and stream handling.
These are the following topics that we are going to discuss:
Installation of npm winston
To install Winston, use the npm format below:
npm install winston
Basic Setup:
- Once installed, you can configure the Winston in your application. Below is an example showing how to set up basic logging with Winston.
inside logs, app.log will be createdUsage of npm winston
Once installed, The Winston can be required in your application and used to log the messages:
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'combined.log' })
]
});
logger.info('Information message');
logger.error('Error message');
In above example, The Winston is configured to log at the info level and send logs to both console and a file.
Logging of npm winston
Logging in the Winston is achieved by calling methods like logger.info, logger.error, logger.warn, etc., which correspond to different log levels. These methods automatically format log message and pass it to appropriate transports.
logger.warn('Warning message');
This logs a warning message depending on level set in logger configuration.
Common logging levels:
- error
- warn
- info
- http
- verbose
- debug
- silly
Creating Your Logger
To create the logger, use winston.createLogger(). This method takes an object where you define log level, transports and any additional settings:
const logger = winston.createLogger({
level: 'debug',
transports: [
new winston.transports.Console(),
]
});
Streams, objectMode, and info Objects
The Winston is stream-based and each transport can write to the different streams. The info object is passed around internally which includes the metadata like timestamp, level and the message. You can also run the Winston in objectMode if you need to handle the streams of objects instead of strings.
The Winston allows you to customize format of your logs. You can apply different formatting using the winston.format. A few common formats are:
- json() for JSON logs
- simple() for plain text logs
- timestamp() to add the timestamp to each log
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.simple()
),
transports: [
new winston.transports.Console()
]
});
You can combine the multiple formats using winston.format.combine(). This allows you to stack formats on top of each other by enhancing the flexibility of log output.
const customFormat = winston.format.combine(
winston.format.timestamp(),
winston.format.printf(({ timestamp, level, message }) => {
return `${timestamp} [${level}]: ${message}`;
})
);
String Interpolation
Winston supports the string interpolation for inserting the dynamic data into log messages using %s placeholders.
logger.info('User %s has logged in', username);
Filtering Info Objects
You can filter info objects using custom formats or by defining the filters within transports.
const filterOnlyErrors = winston.format((info) => {
return info.level === 'error' ? info : false;
});
const logger = winston.createLogger({
format: filterOnlyErrors(),
transports: [new winston.transports.Console()]
});
The Winston allows you to create your custom formats using a format function:
const myFormat = winston.format((info) => {
info.message = info.message.toUpperCase();
return info;
});
Logging Levels of npm winston
The Winston supports several built-in log levels such as error, warn, info, verbose, debug and silly. These levels are all numeric means lower levels are more critical and the higher levels are more verbose.
Using Logging Levels
The logger outputs logs that match or exceed a set level. If the level is set to warn then it will log warnings and the errors but not info or debug messages.
const logger = winston.createLogger({
level: 'warn',
transports: [
new winston.transports.Console()
]
});
Using the Custom Logging Levels
You can define the custom logging levels in Winston:
const customLevels = {
levels: {
critical: 0,
error: 1,
warn: 2,
info: 3
}
};
const logger = winston.createLogger({
levels: customLevels.levels,
transports: [new winston.transports.Console()]
});
Transports of npm winston
The Transports in Winston determine where log messages go. The Common transports include:
Console: Logs to console.
File: Writes logs to the file.
Http: Sends logs over the HTTP.
Multiple Transports of Same Type
The Winston allows using multiple transports of same type such as logging to the multiple files or consoles:
const logger = winston.createLogger({
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
Adding the Custom Transports
You can create custom transports by extending the winston.Transport. The Custom transports give you more control over where and how the logs are stored.
Common Transport Options
The Transports have options like level, silent and the handleExceptions which allow you to fine-tune their behavior.
filename: File path for log file.
level: Logging level for transport.
handleExceptions: Set to true to handle uncaught exceptions.
Exceptions of npm winston
The Winston can capture uncaught exceptions and log them. This is useful in the production environments to track the unexpected errors.
Handling Uncaught Exceptions with the Winston
To capture the uncaught exceptions, use handleExceptions option:
const logger = winston.createLogger({
transports: [
new winston.transports.Console({ handleExceptions: true })
]
});
To Exit or Not to Exit
By the default, Winston exits a process after an uncaught exception. You can change this behavior:
logger.exitOnError = false;
Rejections in npm winston
Handling Uncaught Promise Rejections with winston
const logger = winston.createLogger({
rejectionHandlers: [
new winston.transports.Console()
]
});
Profiling of npm winston
By calling the logger.profile(label), Winston starts tracking time. When you call it again with same label it logs duration between start and the stop points. This is useful for the performance monitoring and identifying slow parts of your code. Profiling logs include the message indicating how long operation took, making it easier to identify the bottlenecks in system.
Streaming Logs of npm winston
Streaming logs in the Winston allows you to pipe log output to writable streams such as files or the network connections. This is useful when you want to process or analyze the log data in real-time or store it externally. The Winston supports both object-mode and traditional streaming modes that ensuring compatibility with various stream consumers. You can use logger.stream() method to hook into Winston logs and continuously feed them into any writable stream for further manipulation or the storage.
Querying Logs
Querying logs in the Winston enables you to retrieve specific log entries based on defined criteria such as time range or log level. By using logger.query() method you can filter the logs and control number of results returned. This feature is particularly useful for analyzing the historical logs or monitoring application behavior over time. The Query results can be processed or displayed in different formats which allows for easy integration with reporting tools or the dashboards. This functionality enhances the log management and helps with troubleshooting and performance the analysis.
Further Reading
Using Default Logger
The Winston includes default logger so that you do not need to create one explicitly:
winston.info('This is a default log');
For more on using Winston default logger check Winston default logger documentation. This covers how to configure and customize default logger and explains its limitations and some common use cases.
Awaiting Logs to Be Written in the Winston
You can await logs to ensure they are written before continuing:
await logger.log('info', 'Message to log');
Winston supports an asynchronous logging. For more details on how to ensure the logs are fully written before proceeding refer to Winston logging flow documentation. This explains how the Winston handles I/O with different transports and how to handle logging in an asynchronous contexts.
Routing Console Transport Messages to Console Instead of stdout and stderr
By default, The Winston sends logs to stdout or stderr. You can route them to console directly if needed. The Winston allows you to control which levels go to stdout or the stderr. For further reading you can explore to Winston Console transport documentation which explains how to modify stderrLevels to route specific log levels to different outputs.
Run Tests
To run the Winston tests, use:
npm test
Example: Once the Winston is installed you can start using it in your application. Below is how to set up the basic logging with Winston:
- setup with Create app.js
- In C:\my-app directory, create the file named app.js. This file will contain the code to log messages using Winston.
- path follows as:
C:\my-app\app.js:
JavaScript
const winston = require('winston');
const path = require('path');
// Create a logger
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
// Log to the console
new winston.transports.Console(),
// Log to a file in the 'logs' folder
new winston.transports.File({ filename: path.join(__dirname, 'logs', 'app.log') })
]
});
// Use the logger
logger.info('This is an info message');
logger.error('This is an error message');
Output:
Here, In this example:
- You can execute above example by following steps of this article.
- The directory setup of this example is same as above Basic setup steps in this article.
- We created the logger using winston.createLogger().
- We specified log level (set to "info") to control importance of messages being logged.
- We used transports to tell the Winston where to log messages. Here, we are logging both to the console and to file named logger.js.
Conclusion
Winston is highly versatile and the powerful logging library that caters to wide range of logging needs in the Node.js applications. With support for multiple transports, customizable logging levels and formats, Winston can be easily tailored to meet requirements of any application whether it is logging to the file, database or external services. The library is ability to handle an uncaught exceptions and promise rejections makes it invaluable for the production environments for ensuring critical errors and issues are captured for analysis.
Similar Reads
Setup Numpy on PyCharm Numpy is a Python library used for scientific calculations. You can work on linear algebra, Fourier transforms, statistical operations, random simulation, and matrices using this library. Apart from that, this library has many more functions to support fast and lengthy calculations. You can use this
2 min read
How to Install NuPIC on Linux? NuPIC (short for "Numenta Platform for Intelligent Computing") is an open-source platform for machine learning and artificial intelligence. It was developed by Numenta, a company founded by Jeff Hawkins, the creator of the PalmPilot and the co-founder of Handspring. NuPIC is based on the theory of t
4 min read
How to Create More Options in ReactJS ? More Options in React JS is a common feature that every application has to show the user some extra functionality on clicking on that button. Material UI for React has this component available for us and it is very easy to integrate. Prerequisites:NPM & Node.jsReact JSReact Material UIApproach:T
2 min read
NPM React Bootstrap NPM react-bootstrap is a package that provides Bootstrap components as React components. It allows developers to easily integrate Bootstrap's styling and functionality into their React applications making the UI development process easier and building responsive design for the web application. Prere
3 min read
React Suite Icons Component React Suite is a popular front-end library with a set of React components that are designed for the middle platform and back-end products. Icon Component allows the user to add icons to your application. Icons are commonly used in every application for UI purposes. We can use the following approach
3 min read
How to Install and Creating First Nuxt.js App ? What is NuxtJS? NuxtJS is a framework of VueJS for creating web apps. It makes development more fast, easy, and organized. NuxtJS is similar to Next.js, which is a framework of React.js. The main features of NuxtJS are: Great folder structure: Nuxt App comes with a great folder structure that makes
2 min read