How does the Morgan Express Middleware Library work? Explored with examples of the code

by SkillAiNest

Moangan There is an Express Middleware Library that tests HTTP requests and logs out the application details to the output. It is one of the most famous Library of Express Middleware that has more than 8,000 gut hub stars and more than 9,000 NPM libraries depending on it. Gut Hub reports that Morgan is used by at least 3.6 million reserves.

This guide explains the Morgan Library code to help you understand how it works under the hood. If you have an Express experience and you are interested in understanding internal tasks that Morgan Log lines produce. The understanding of closures in the JavaScript is helpful for this guide but not necessary.

The table of content

What is Express Middleware?

According to Express DocumentsA middleware is a function that has access to application and response objects and next Express application cycle function. Their use is commonly used to carry out the side effects before or after handling the applications through its route handler.

A middleware can be used:

  • Make changes to the application and response objects: It can make changes to the application and response objects by connecting the features such as headers and cookies.

  • Eliminate the cycle of application response: It can terminate the application and send the application to the client before or after handling its route handler.

  • Perform the next middleware in the stack: This can then stimulate middleware hanging next Functional argument.

Called a function called next Usually a middleware is the third argument and its application is used to deliver the next middleware. Unless next The function is not implemented in any middleware and the request is not clearly removed by sending a response to the client, the application will be stopped to be hanged and the application will be prevented from handling the upcoming requests.

The middleware interface shown in the code pieces below:

function middleware(request, response, next) 

A middleware can stop and handle matters where middleware or route handlers throw unhealthy mistakes. These middleware are commonly called error handler middleware and accept four arguments as shown below:

function errorHandlerMiddleware(error, request, response, next) 

error The argument represents an incompetent error.

Some middleware such as Morgan and Cors There are high order functions. When they are subjected to the application, they accept the order arguments when returning the middleware function.

function initialise(...configArgs)  
  var fmt = morgan(name) 

A brief overview of how Morgan works

import morgan from "morgan"

morgan("tiny") 

Morgan has been launched by performing with her need format The argument and an optional options Proof format May argue:

  • Name of a descriptive Morgan format

  • A format string consisting of default token (a token set)

  • A custom format function that lootes the logout in the form of string

options The argument is optional. This is an item that has three features:

  • immediate (BOLIN): If trueLogin output requests will be prepared not to receive the response. This is pre -default false.

  • skip (Function): The function accepts the application and the response object as arguments and returns the price of bold on the basis of logic. If the price is returned trueLogline is not logged in for application. skip Default. false.

  • stream (Ritable Stream): Output stream to write a log line. This is pre -default process.stdout But this can be a file.

When Morgan is launched, it stores its initial arguments in the closure variables and returns the middleware function. When an application collides it, the function is hanged and it outscares the log line for request. This is determined by the initial arguments where the format and where the log -line is output.

What is Morgan tokens?

A Morgan Tok is a wire manufactured by a large intestine, according to a application or response items or user -made value property. For example, the application method is the token ':method' And is the retaliation status code token ':status'. A token can also accept an argument for customizing his behavior. For example, I ':date(format)'For, for, for,. format Can be replaced with clfFor, for, for,. iso Or web To fix the date that will be in the log line. The understanding of Morgan tokens is very important to understand how Morgan works.

You can create a new token using this morgan.token The function below makes a piece of code a new token called ':type' Which is equal to the reaction Content-Type Header:

morgan.token('type', function (req, res) 
  "use strict"
  return "" +
    (tokens("method")(req, res) )

Morgan nominated format (default format (tinyFor, for, for,. devFor, for, for,. shortFor, for, for,. combinedFor, for, for,. common) It has a specific token set and sequence in a token set and each designated format. Is the token seat for the smaller ':method :url :status :res(content-length) - :response-time ms'. Morgan can accept these designated formats as its value format Proof

In addition to accepting designated formats, Morgan can also accept a token set (eg ':method :url :status :res(content-length) - :response-time ms') As such format The type of the third argument that Morgan accepted format The argument is a format function. A format function accepts three arguments and returns a wire that creates a log line for each application. For example, the format function is described below:

morgan(function (tokens, req, res) {
    return `method: $ "-") + " - " +
    (tokens("response-time")(req, res) 
path: $
code: $ "-") + " - " +
    (tokens("response-time")(req, res) `
})

This will be the log -line output like:

method: get
path: /
code: 200

tokens.methodFor, for, for,. tokens.url And tokens.status There are examples of functions on this morgan The object that can create values ​​to log in. For example, the table below shows sample token methods, their token and sample production values.

The token methodTokenSample output
Method“:method”Get
URL“:url”).).
Prestige”:status”200

The next part of this article explains how Morgan works under the hood. To follow, open Morgan’s Index Dot JS File on Gut Hub.

What happens when Morgan begins?

When Morgan is launched, it makes a copy of the arguments provided to it. For the arguments that were not provided, Morgan sets the pre -determined values ​​for them. For example, if not format The Staring argument was provided, Morgan uses 'default' Then logs in the designated format and then the notice of deportation, after which you are then suggested an unbeaten method to start it.

After that Morgan set up formatLine Function – The function that creates and returns the log line for application at the time of process. How does it do?

First, Morgan checks if format There is a format function. If it is, the format function has been assigned formatLine And after that, Morgan sets the output stream. Unless format There is no function, it is approved as an argument getFormatFunction. getFormatFunction Accepts format And sees Morgan’s Object Store to check format Is:

If this is not either of the two, Morgan uses default Nominated format.

function getFormatFunction (name) { 
  var fmt = morgan(name) || name || morgan.default

  return typeof fmt !== 'function'
    ? compile(fmt)
    : fmt
}

If the designated format is equal to a format function after searching, Morgan returns the format function, which is then assigned formatLineOtherwise, it’s equal to the token seat. Morgan sets tokens in a compiled format function compile Function – The most important task in the Morgan package.

compile Ceremony

compile The function accepts a token set and returns a function that contains a format function interface. How does it do?

With JavaScript replace Method, this token seat uses all the tokens search for the token and replaces each event. If the token is set ':method :res(content-length) - :response-time ms' Regime replace The procedure replaces the token as described in the table below:

NameargThe string of change
‘Method’undefined`(Token (” Method “) (Req, RS)“-“) + ” +`
‘Race’’content-length’`(Token (” race “) (rack, race,” content length “))” -“) + ” -” + `
‘Response Time’Uncontrollable`(Token (” Response Time “) (Req, RS)“-“) +`

Regax space results have already been developed "use strict"\n return "" And ends the wire to prepare the bottom:

"use strict" 
    return "" +  
    (tokens("method")(req, res) || "-") + " " +   
    (tokens("res")(req, res, "content-length") || "-") + " - " + 
    (tokens("response-time")(req, res) || "-") + " ms"

Used to make format function using the aforementioned string Function Constructor And returned like:

function (tokens, req, res) {
  "use strict"
  return "" +
    (tokens("method")(req, res) || "-") + " " +
    (tokens("res")(req, res, "content-length") || "-") + " - " +
    (tokens("response-time")(req, res) || "-") + " ms"
}

Format Function is eventually stored formatLine.

While formatLine Is hanged with morgan As if tokens Argument, it will build a log line. In case of sample token set, it will create a log line that will look GET 20 1.233 ms.

After making formatLine Function, Morgan uses createBufferStream Function to configure the streaming of log lines produced in preferential output if configured options.stream. Unless options.stream Does not set, it uses process.stdout.

Morgan sets it up all so that he can quickly create log lines when he seize the application. It would be useless to do all this for every request.

What happens when Morgan received a request?

When Morgan occupies a request, it stores using client’s IP address getip The function next, it saves the time when the application mobilized it and linked it to the application object _startAt And _startTime Specialty.

  • _startAt Used to calculate the total time between the time between the application in the Morgan and when the reaction is over, in millions, the connection is written on the connection.

  • _startTime The reaction time is used to calculate – the time between the application obtained by Morgan and when the reaction headers are written.

Next, Morgan tries to prepare the log line for request and logs it by implementing it logRequest The function Morgan checks whether the log line should be out on application, and if it should be, Morgan executes logRequest And executes next Then to send a request to the next middleware.

if (immediate) {
  logRequest()
} else {
  onHeaders(res, recordStartTime)
  onFinished(res, logRequest)
}

next()

If the login output should be made on response, the Morgan Response Object Event enters two tasks on listeners.

  • Start writing on the header response object when running a function: When this listener becomes dynamic, it records the time when the header starts writing on the respondent objects like _startAt And startTime. These values ​​are used to calculate the time and the total time of application.

  • A function to drive when the application is closed, expire or errors: It processes logRequest When this happens.

In logRequestMorgan checks its value skip Option If this is a function, it is implemented and if it returns trueMorgan does not make log output for application and it exits.

function logRequest () {
  if (skip !== false && skip(req, res)) {
    debug('skip request')
    return
  }

  var line = formatLine(morgan, req, res)

  if (line == null) {
    debug('skip line')
    return
  }

  stream.write(line + '\n')
};

Unless skip Is false Or the implementation is reviewed falseMorgan develops a log line for application use formatLine. If the log line is nullMorgan comes out, otherwise it sends the log line to the output medium and exits.

Next steps

You have learned how Morgan Express does middleware output. Now you have the basic skills to take another middleware or node Dot JS Library you use and study how it works. Choose one, study it, write about it, and share it with others.

If you have any questions, you can contact me Linked. I will be happy to answer.

You may also like

Leave a Comment

At Skillainest, we believe the future belongs to those who embrace AI, upgrade their skills, and stay ahead of the curve.

Get latest news

Subscribe my Newsletter for new blog posts, tips & new photos. Let's stay updated!

@2025 Skillainest.Designed and Developed by Pro