Skip to content

Instantly share code, notes, and snippets.

@LitHaxor
Last active July 13, 2023 05:22
Show Gist options
  • Select an option

  • Save LitHaxor/213678e70b438132761091ff5b1c878f to your computer and use it in GitHub Desktop.

Select an option

Save LitHaxor/213678e70b438132761091ff5b1c878f to your computer and use it in GitHub Desktop.
PRODUCTION READY Request Response Logger NodeJS
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,
});
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