Last active
July 13, 2023 05:22
-
-
Save LitHaxor/213678e70b438132761091ff5b1c878f to your computer and use it in GitHub Desktop.
PRODUCTION READY Request Response Logger NodeJS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let logData = {}; | |
| let headersFound = 0; | |
| const handleStream = (message) => { | |
| try { | |
| const ipRegex = /IP: ([\w.:]+)/; | |
| const ipMatch = message.match(ipRegex); | |
| if (ipMatch) { | |
| logData.request = { ...logData.request, ip: ipMatch[1] }; | |
| } | |
| const pathRegex = /Request: ([A-Z]+) ([^\s]+) /; | |
| const pathMatch = message.match(pathRegex); | |
| if (pathMatch) { | |
| logData.request = { | |
| ...logData.request, | |
| path: pathMatch[2], | |
| }; | |
| } | |
| if (pathMatch?.[2].includes('?')) { | |
| const queryRegex = /Request: ([A-Z]+) ([^\s]+)\?([^\s]+) /; | |
| const queryMatch = message.match(queryRegex); | |
| if (queryMatch) { | |
| logData.request = { | |
| ...logData.request, | |
| path: queryMatch[2], | |
| query: JSON.parse( | |
| `{"${decodeURI(queryMatch[3]) | |
| .replace(/"/g, '\\"') | |
| .replace(/&/g, '","') | |
| .replace(/=/g, '":"')}"}`, | |
| ), | |
| }; | |
| } | |
| } | |
| const methodRegex = /Request: ([A-Z]+) /; | |
| const methodMatch = message.match(methodRegex); | |
| if (methodMatch) { | |
| logData.request = { | |
| ...logData.request, | |
| method: methodMatch?.[1], | |
| }; | |
| } | |
| const userAgentRegex = /User Agent: ([^,]+)/; | |
| const userAgentMatch = message.match(userAgentRegex); | |
| if (userAgentMatch) { | |
| logData.request = { | |
| ...logData.request, | |
| userAgent: userAgentMatch[1], | |
| }; | |
| } | |
| const headersRegex = /headers\[([^\]]+)\]/; | |
| const headersMatch = message.match(headersRegex); | |
| if (headersMatch) { | |
| const headers = headersMatch[1].split(';'); | |
| const headersObj = {}; | |
| headers.forEach((header) => { | |
| const [key, value] = header.split('='); | |
| headersObj[key] = value; | |
| }); | |
| if (headersFound === 0) { | |
| logData.request = { | |
| ...logData.request, | |
| headers: headersObj, | |
| }; | |
| } else if (headersFound === 1) { | |
| logData.response = { | |
| ...logData.response, | |
| headers: headersObj, | |
| }; | |
| } | |
| headersFound++; | |
| } | |
| const requestBodyRegex = /Request Body: (.*)/; | |
| const requestBodyMatch = message.match(requestBodyRegex); | |
| if (requestBodyMatch) { | |
| try { | |
| logData.request = { | |
| ...logData.request, | |
| body: JSON.parse(requestBodyMatch[1]), | |
| }; | |
| } catch (error) { | |
| console.warn('Error parsing Request Body:', error); | |
| } | |
| } | |
| const responseBodyRegex = /Response Body: (.*)/; | |
| const responseBodyMatch = message.match(responseBodyRegex); | |
| if (responseBodyMatch) { | |
| try { | |
| logData.response = { | |
| ...logData.response, | |
| body: JSON.parse(responseBodyMatch?.[1]), | |
| }; | |
| } catch (error) { | |
| // trucate response body if it is too long | |
| logData.response = { | |
| ...logData.response, | |
| body: responseBodyMatch?.[1].substring(0, 100) | |
| }; | |
| } | |
| } | |
| const responseTimeRegex = /Response: (\d+.\d+) ms/; | |
| const responseTimeMatch = message.match(responseTimeRegex); | |
| if (responseTimeMatch) { | |
| logData.response = { | |
| ...logData.response, | |
| time: `${responseTimeMatch[1]} ms`, | |
| }; | |
| } | |
| const responseStatusRegex = /Response: (\d+)/; | |
| const responseStatusMatch = message.match(responseStatusRegex); | |
| if (responseStatusMatch) { | |
| logData.response = { | |
| ...logData.response, | |
| status: parseInt(responseStatusMatch[1]), | |
| }; | |
| } | |
| if (logData.request && logData.response && headersFound === 2) { | |
| logData.timestamp = new Date().toISOString(); | |
| logData.time = new Date().toLocaleString(); | |
| if (logData.response.status >= 400) { | |
| console.error(JSON.stringify(logData)); | |
| } else { | |
| console.log(JSON.stringify(logData)); | |
| } | |
| logData = {}; | |
| headersFound = 0; | |
| } | |
| return true; | |
| } catch (error) { | |
| console.warn(error); | |
| return true; | |
| } | |
| }; | |
| // in express | |
| const express = require("express"); | |
| const morganBody = require("morganBody"); | |
| const app = express(); | |
| morganBody(app, { | |
| write: handleStream, | |
| }); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import express, { Request, Response } from "express"; | |
| import morganBody from "morgan-body"; | |
| async function bootstrap() { | |
| const app = express(); | |
| // Middlewares | |
| app.use(express.json()); | |
| let logData: { | |
| request?: { | |
| ip?: string; | |
| userAgent?: string; | |
| body?: any; | |
| method?: string; | |
| }; | |
| response?: { | |
| body?: any; | |
| time?: string; | |
| status?: number; | |
| }; | |
| timestamp?: string; | |
| time?: string; | |
| } = {}; // Store partial log data | |
| morganBody(app, { | |
| noColors: true, | |
| prettify: false, | |
| stream: { | |
| write: (message: string) => { | |
| // Extract IP address | |
| const ipRegex = /IP: ([\w.:]+)/; | |
| const ipMatch = message.match(ipRegex); | |
| if (ipMatch) { | |
| logData.request = { ...logData.request, ip: ipMatch[1] }; | |
| } | |
| // example message = Request: POST / at Fri Jul 07 2023 22:46:34 GMT+0600, IP: ::1, User Agent: PostmanRuntime/7.32.3 | |
| const methodRegex = /Request: ([A-Z]+) /; | |
| const methodMatch = message.match(methodRegex); | |
| if (methodMatch) { | |
| logData.request = { | |
| ...logData.request, | |
| method: methodMatch?.[1], | |
| }; | |
| } | |
| // Extract User Agent | |
| const userAgentRegex = /User Agent: ([^,]+)/; | |
| const userAgentMatch = message.match(userAgentRegex); | |
| if (userAgentMatch) { | |
| logData.request = { | |
| ...logData.request, | |
| userAgent: userAgentMatch[1], | |
| }; | |
| } | |
| // Extract Request Body | |
| const requestBodyRegex = /Request Body: (.*)/; | |
| const requestBodyMatch = message.match(requestBodyRegex); | |
| if (requestBodyMatch) { | |
| try { | |
| logData.request = { | |
| ...logData.request, | |
| body: JSON.parse(requestBodyMatch[1]), | |
| }; | |
| } catch (error) { | |
| console.error("Error parsing Request Body:", error); | |
| } | |
| } | |
| // Extract Response Body | |
| const responseBodyRegex = /Response Body: (.*)/; | |
| const responseBodyMatch = message.match(responseBodyRegex); | |
| if (responseBodyMatch) { | |
| try { | |
| logData.response = { | |
| ...logData.response, | |
| body: JSON.parse(responseBodyMatch[1]), | |
| }; | |
| } catch (error) { | |
| console.error("Error parsing Response Body:", error); | |
| } | |
| } | |
| // Extract Response Time | |
| const responseTimeRegex = /Response: (\d+.\d+) ms/; | |
| const responseTimeMatch = message.match(responseTimeRegex); | |
| if (responseTimeMatch) { | |
| logData.response = { | |
| ...logData.response, | |
| time: `${responseTimeMatch[1]} ms`, | |
| }; | |
| } | |
| // Extract Response Status | |
| const responseStatusRegex = /Response: (\d+)/; | |
| const responseStatusMatch = message.match(responseStatusRegex); | |
| if (responseStatusMatch) { | |
| logData.response = { | |
| ...logData.response, | |
| status: parseInt(responseStatusMatch[1]), | |
| }; | |
| } | |
| if (logData.request && logData.response) { | |
| logData.timestamp = new Date().toISOString(); | |
| logData.time = new Date().toLocaleString(); | |
| console.log(JSON.stringify(logData)); | |
| logData = {}; // Clear the stored log data | |
| } | |
| // return message; | |
| return true; | |
| }, | |
| }, | |
| }); | |
| const port = 3000; | |
| app.post("/", (req: Request, res: Response) => { | |
| const data = { | |
| name: "Rakibul Islam", | |
| age: 25, | |
| email: "", | |
| body: req.body, | |
| }; | |
| res.send(data); | |
| }); | |
| app.listen(port, () => { | |
| console.log(`Server started on port http://localhost:${port}`); | |
| }); | |
| } | |
| bootstrap(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment