Exception logging in nodejs using winston

Ujjwal Gupta
fortjs
Published in
4 min readJul 15, 2019

Exception is the undesired part of any application & we can’t get rid of it. Some of the common cases of exceptions are - database issue , operating system issue, IO issue , memory issue, null variable issue etc .

And it is very important to log these exception, so that we can know the exception information & fixed it.

In this article - i am going to show you how we can use winston to create a logger and log information.

Winston is a famous nodejs library for logging. It provides so many customisation and is easy to use.

I am going to use the framework fortjs with es6 syntax, but you can use any framework. If you want to know more about fortjs, take a look at fortjs get started page http://fortjs.info/tutorial/get-started/

Let’s Code

You can download/view the code for this article here - https://github.com/ujjwalguptaofficial/fortjs/tree/master/example/winston

Project setup

We are going to use fort-creator - a cli tool to help with fortjs development.

Perform the below steps sequentially -

  • Install the fort creator globally - run the command npm i fort-creator -g
  • Create new project — fort-creator new my-app. Here “my-app” is the name of app, you can choose any.
  • Enter into the project directory — cd my-app
  • Start the dev server — fort-creator start
  • Open the url — “http://localhost:4000/

You should see something like this in the browser -

fortjs start page

Let’s throw an exception

Open the file default_controller.js located inside controllers folder and inside the method index replace everything by below code

try {
if (this.query.error == 'true') {
throw new Error("Exception occured");
} else {
return textResult('Runing Ok');
}
} catch (ex) {
const result = textResult(`Our server is busy right now. Please try later.`);
return result;
}

In the above code

  • We are creating an exception when query string has value error true.
  • handling the exception and showing user a good message “Our server is busy right now. Please try later.”

Let’s test the above changes

Refresh the page - http://localhost:4000/ and you will see the result “Runing Ok”. Now try appending the query string “error=true” i.e http://localhost:4000/?error=true and you will see the exception message.

Right now, we dont have any information to exception occured because we are not logging the exception. The easiest way is to log using console.log which will print the log to current stdout. But in production you must be runing your app as a background service and in this case you dont have access to console and there can be other situation where getting console logs can be very hard.

So the best solution is to log the information inside a file when the app is runing in production.

The above functionality can be achieved very easily using winston.

Winston Setup

Perform the below steps -

  • Install the winston using command -npm i winston
  • Create a file logger.js inside root of project and write below code
import * as winston from "winston";
export const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
defaultMeta: {
service: 'user-service'
},
transports: [
//
// - Write to all logs with level `debug` and below to `all.log`
// - Write all logs error (and below) to `error.log`.
//
new winston.transports.File({
filename: 'logs/error.log',
level: 'error'
}),
new winston.transports.File({
filename: 'logs/all.log',
level: 'debug'
})
]
});
// If we're not in production then log to the `console`if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}

let’s use this logger to log the exception. open the default_controller.js file and inside the catch block write the below code -

logger.error(`message - ${ex.message}, stack trace - ${ex.stack}`);

So the code index.js method looks like this -

try {
if (this.query.error == 'true') {
throw new Error("Exception occured");
} else {
return textResult('Runing Ok');
}
}
catch (ex) {
logger.error(`message - ${ex.message}, stack trace - ${ex.stack}`);
const result = textResult(`Our server is busy right now. Please try later.`);
return result;
}

Let’s test the logger. Refresh the page - http://localhost:4000/?error=true

and you will see the error message in console as well message saved inside logs folder in files - error.log & all.log.

So our logger is working awesome but there is a big problem here.

All messages are being saved inside a single file i.e all error inside error.log & all message inside all.log, and with time it will become very huge. For finding an error which happened today we will have to navigate through all message.

So the solution is to create new file every day. This process is known as rotating file.

Winston provides a seperate npm package “winston-daily-rotate-file” for this. Let’s install this package and configure it -

Install the package using command - npm i winston-daily-rotate-file

Replace the logger.js code by below code -

import * as winston from "winston";
import "winston-daily-rotate-file";
export const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
defaultMeta: {
service: 'user-service'
},
transports: [
// - Write to all logs with level `debug` and below to `all.log`
// - Write all logs error (and below) to `error.log`.

new winston.transports.DailyRotateFile({
datePattern: 'DD-MM-YYYY',
filename: `logs/error.log`,
level: 'error'
}),
new winston.transports.DailyRotateFile({
datePattern: 'DD-MM-YYYY',
filename: `logs/all.log`,
level: 'debug'
})
]
});
// If we're not in production then log to the `console`
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}

the above code uses the new transports to rotate file on daily basis. You can configure the way you want.

Let’s test this, open the url - http://localhost:4000/?error=true

and you will see files with date stamp is created and exception are being logged into those files.

The full code of this article is available here — https://github.com/ujjwalguptaofficial/fortjs-examples/tree/master/winston

This is the end of the article 😬. Hope you have liked it. Don’t forget to hit the clap button. Thanks !

References

--

--

Ujjwal Gupta
fortjs
Editor for

Frontend lead Polygon | Creator of jsstore, mahaljs | sqlweb, fortjs | opensource creator | we3, blockchain, solidity | javascript