DEV Community

Cover image for Track user behavior & resource demand with ‘mongoose-morgan’
Diego Gallovich
Diego Gallovich

Posted on

Track user behavior & resource demand with ‘mongoose-morgan’

Hello and welcome to this weeks’s article. Today, we will discuss three npm packages. Two will be explained very briefly ( mongoose and morgan ), and the third one is the one we will focus on ( mongoose-morgan ).

Mongoose is a MongoDB modeling tool for node.js applications. With it, we use object-oriented JavaScript programming to create MongoDB schemas and models. It also allows us to interact and query the database right from the backend of our node.js application. In the example below, we create a schema, then use the schema to create a model and finally export it to be used across our app’s code.

const MONGOOSE = require('mongoose');
const SCHEMA = MONGOOSE.Schema; 
// create User Schema
const USER_SCHEMA = new SCHEMA({  
   name: {    
       type: String,    
       required: true  
   },  
   email: {    
       type: String,   
       required: true,    
       unique: true  
   },  
   password: {    
       type: String,    
       required: true  
   },  
   avatar: {    
       type: String  
   },  
   date: {    
       type: Date,    
       default: Date.now()  
   }
}); 

// Define Model
const USER_MODEL = MONGOOSE.model('user', USER_SCHEMA);
// Export model
module.exports = USER_MODEL;
Enter fullscreen mode Exit fullscreen mode

So, let’s talk about morgan before we derail this any further. Morgan is an HTTP request logger for node.js applications. It works as middleware in the request cycle of the ‘request-response’ life-cycle of your application. Meaning that it plays a roadblock role in your applications HTTP requests. Each time a request is made to your server, morgan will log it to the console in the format of your choice. Morgan has many formats available but, I use ‘tiny’ format, which just logs the URL the request was made to, the status code of the response and the time it took to respond. Here’s a simple example:

// Require morgan in your server.js or index.js after npm install
const MORGAN = require('morgan');

// Whatever code you have...

// Right before your router and routes initialization, use morgan.
MORGAN('dev');

// Example route, router initialization
APP.use('/api/profiles/', require('./routes/api/profiles'));
APP.listen (PORT, () => console.log('Working...'));
Enter fullscreen mode Exit fullscreen mode

With the example above, morgan would log something like this to the console each time a request is made:

POST /api/users 200 195 - 720.322 ms

So it gives us the method of the request, the resource the request was made to, its status code and the time it took to send a response. There is a format called ‘dev’ which also gives you the date. And other formats allow you to extract the remote address the request was made from as well.

Now… the underdog of the day… mongoose-morgan!!!

I think that by now you have a pretty good guess of what this package does. This ingenious package, grants you the easiest way to track all requests made to your application by not only logging them but also saving them to your desired database. The way I use this package for example is to check which are the most demanded resources on my site without using any heavy analytics tools. Not only that, I can also see which resources take longer to load or tend to crash more. Here’s an example of it in my code:

// This is file is logger.js
const MONGOOSE_MORGAN = require('mongoose-morgan');
const CONFIG = require('config');

// Mongoose-morgan
const DB = CONFIG.get('mongoURI');
const MORGAN = MONGOOSE_MORGAN(  
      // DB object with connection string and target collection
      {   
       collection: 'request-logs',    
       connectionString: DB  
      },
      // Options object. Custom preferences
      {},
      // Logging format
      'tiny'
); 

// Export Middleware
module.exports = MONGO_MORGAN;
Enter fullscreen mode Exit fullscreen mode

Easy… We require mongoose-morgan and then config to retrieve the desired configuration variables (you could use dot-env too). We proceed to retrieve the Database URI for all requests to be saved, then we initialize a variable containing the mongoose-morgan call. MONGOOSE_MORGAN takes in three areguments:

  • An object defining database collection and connectionString.

  • After this object, we pass another one with any custom preferences, more of that in mongoose-morgan@npm.

  • Finally pass in the logging format you desire and close the call.

Finish up by exporting the middleware and import it in your server like we did with the morgan package:

// Server.js

// import
const MONGO_MORGAN = require('./middleware/logger.js');

// Call before router, route instance
APP.use(MONGO_MORGAN);

// Routes and APP.listen below.
Enter fullscreen mode Exit fullscreen mode

After that, you will see the collection you defined added to your database and all of your server requests logged to it. Giving you heavy impact data more lightly than ever before.

This is a powerful tool that gives you both marketing and performance related data about your application and saves it as you please.

Fun facts:

  • Mongoose has 800,000+ downloads a week
  • Morgan has 2,000,000+ downloads a week
  • Mongoose-morgan only has 200–400 downloads a week.

I hope you take advantage of this information and use it strategically. That was all folks!

Make sure to share this with your coworkers and fellow devs.

See you next week and stay safe!

Top comments (7)

Collapse
 
nempet profile image
Nemanja Petrovic

Thank you for saying so many kind words about my package! I hope it helps you to save your time. :)

Collapse
 
diegotech profile image
Diego Gallovich

Hello Nemanja! It really has helped me. Loved it since day 1!

Collapse
 
tharindurewatha profile image
Tharindu Rewatha

Hey how can I avoid logging GET requests from Morgan. What if I want to log POST,PUT and DELETE requests.

Collapse
 
nempet profile image
Nemanja Petrovic

Hi @tharindurewatha ,

you can achieve this by specifying skip function:

// EXAMPLE: only log error responses
morgan('combined', {
  skip: function (req, res) { return res.statusCode < 400 }
})
Enter fullscreen mode Exit fullscreen mode

and in this function you just check:

req.method
Enter fullscreen mode Exit fullscreen mode

property to satisfy your condition.

Collapse
 
diegotech profile image
Diego Gallovich • Edited

@nempet thanks for replying to this comment. I am barely getting back to articles.

I also found a similar example with a bit more specificity from your own docs:

app.use(morgan({
    collection: 'error_logger',
    connectionString: 'mongodb://localhost:27017/logs-db',
    user: 'admin',
    pass: 'test12345'
   },
   {
    skip: function (req, res) {
        return res.statusCode < 400;
    }
   },
   'dev'
));
Enter fullscreen mode Exit fullscreen mode
Collapse
 
yamlakkassahun profile image
yamlak

I was trying to implement this with typescript but am having errors

Collapse
 
diegotech profile image
Diego Gallovich

Could you be more specific about the errors? I would love to help you. Feel free to write directly to my email dieguiviti@gmail.com. Mongoose-morgan typescript declarations defined in the project, you should be doing alright. Please let me know