Skip to content

Instantly share code, notes, and snippets.

@cyberinferno
Created September 22, 2022 04:58
Show Gist options
  • Save cyberinferno/cbadd779a15330607d999c95ef48a6df to your computer and use it in GitHub Desktop.
Save cyberinferno/cbadd779a15330607d999c95ef48a6df to your computer and use it in GitHub Desktop.
A simple JSON log server
const http = require("http");
const fs = require("fs");
const { networkInterfaces } = require("os");
const path = require("path");
const PORT = process.argv.length > 2 ? process.argv[2] : 8081;
const LOG_PATH = process.argv.length > 3 ? process.argv[3] : "logs";
if (!fs.existsSync(LOG_PATH)) {
fs.mkdirSync(LOG_PATH);
}
const currentDate = new Date();
const currentSessionLogFile = `${LOG_PATH}${
path.sep
}${currentDate.getFullYear()}-${currentDate.getMonth()}-${currentDate.getDate()}.log`;
const logFileStream = fs.createWriteStream(currentSessionLogFile, {
flags: "a",
});
const networks = networkInterfaces();
const handleLog = (data, type) => {
if (Array.isArray(data) && data.length === 0) {
// Ignore empty data if it is an array
return;
}
let myTypeString;
switch (type.toString().toLowerCase()) {
case "debug":
myTypeString = "[DEBUG]";
Array.isArray(data) ? console.debug(...data) : console.debug(data);
break;
case "error":
myTypeString = "[ERROR]";
Array.isArray(data) ? console.error(...data) : console.error(data);
break;
case "info":
myTypeString = "[INFO]";
Array.isArray(data) ? console.info(...data) : console.info(data);
break;
case "warn":
myTypeString = "[WARN]";
Array.isArray(data) ? console.warn(...data) : console.warn(data);
break;
default:
myTypeString = "[LOG]";
Array.isArray(data) ? console.log(...data) : console.log(data);
break;
}
if (
(Array.isArray(data) && data.length === 1) ||
typeof data !== "object"
) {
logFileStream.write(`${myTypeString} ${data}\n`);
return;
}
logFileStream.write(`${myTypeString} ${JSON.stringify(data)}\n`);
};
const listener = (req, res) => {
// CORS headers
const headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS, POST, GET",
"Access-Control-Max-Age": 2592000,
"Access-Control-Allow-Headers": "Content-Type, x-requested-with",
};
if (req.method === "OPTIONS") {
res.writeHead(204, headers);
res.end();
return;
}
let body = "";
req.on("data", (data) => {
body += data.toString();
});
req.on("end", () => {
res.writeHead(200, { ...headers, "Content-Type": "application/json" });
res.end(JSON.stringify({ status: 200, message: "ok" }));
if (body.toString().trim() === "") {
// Ignore empty body requests
return;
}
try {
const logData = JSON.parse(body);
const { data, type } = logData;
if (!data || !type) {
// Some random JSON hence just print
handleLog(logData, "log");
return;
}
handleLog(data, type);
} catch {
// Probably not JSON data hence just print
handleLog(body, "log");
}
});
};
const server = http.createServer(listener);
console.log(`Starting remote console log server on port ${PORT}...`);
server.listen(PORT);
console.log(`Logs are being saved into the file ${currentSessionLogFile}`);
console.log("Remote log server addresses are as follows:");
console.log(`http://127.0.0.1:${PORT}`);
console.log(`http://localhost:${PORT}`);
for (let i = 0; i < Object.keys(networks).length; i += 1) {
const key = Object.keys(networks)[i];
const currentNetworks = networks[key];
currentNetworks.forEach((network) => {
const networkFamilyIPv4 =
typeof network.family === "string" ? "IPv4" : 4;
if (network.family === networkFamilyIPv4 && !network.internal) {
console.log(`http://${network.address}:${PORT}`);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment