improvement
This commit is contained in:
+1918
-18692
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,24 @@
|
|||||||
[
|
[
|
||||||
"cloudflare.com",
|
"cloudflare.com",
|
||||||
"postgresql.org",
|
"example.invalid",
|
||||||
"github.com",
|
|
||||||
"mozilla.org",
|
|
||||||
"amazon.com",
|
|
||||||
"google.com",
|
"google.com",
|
||||||
|
"myfakewebsite123.xyz",
|
||||||
|
"postgresql.org",
|
||||||
|
"notarealdomain.test",
|
||||||
|
"github.com",
|
||||||
"docker.com",
|
"docker.com",
|
||||||
"wikipedia.org",
|
"invalid-site-999.com",
|
||||||
"duckduckgo.com",
|
"mozilla.org",
|
||||||
"nodejs.org",
|
|
||||||
"amns.in",
|
|
||||||
"amazon.in",
|
"amazon.in",
|
||||||
"amdocs.com"
|
"thisdoesnotexistabc123.com",
|
||||||
|
"nodejs.org",
|
||||||
|
"amdocs.com",
|
||||||
|
"fake-company-domain.org",
|
||||||
|
"wikipedia.org",
|
||||||
|
"nonexistentdomain987654.net",
|
||||||
|
"duckduckgo.com",
|
||||||
|
"amazon.com",
|
||||||
|
"amns.in",
|
||||||
|
"missingwebsite.fake",
|
||||||
|
"randominvaliddomain12345.io"
|
||||||
]
|
]
|
||||||
@@ -4,6 +4,12 @@ const url_path = path.join(__dirname, "../database", "db.json");
|
|||||||
|
|
||||||
const StoreRecord = async (urlRecord) => {
|
const StoreRecord = async (urlRecord) => {
|
||||||
try {
|
try {
|
||||||
|
try {
|
||||||
|
await fs.access(url_path);
|
||||||
|
} catch {
|
||||||
|
await fs.writeFile(url_path, "[]");
|
||||||
|
}
|
||||||
|
|
||||||
const rawData = await fs.readFile(url_path, "utf8");
|
const rawData = await fs.readFile(url_path, "utf8");
|
||||||
const data = JSON.parse(rawData);
|
const data = JSON.parse(rawData);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ const { StoreRecord } = require("./models/db_store_controller");
|
|||||||
const { checkUrl } = require("./models/health_status_controller");
|
const { checkUrl } = require("./models/health_status_controller");
|
||||||
|
|
||||||
const { init, broadcast } = require("./utils/utils");
|
const { init, broadcast } = require("./utils/utils");
|
||||||
// const urlPath = "./database/urls.json";
|
|
||||||
const urlPath = path.join(__dirname, "database", "urls.json");
|
const urlPath = path.join(__dirname, "database", "urls.json");
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
@@ -35,11 +34,17 @@ const checkAllUrl = async (Store) => {
|
|||||||
async function setupWebSocket(wss) {
|
async function setupWebSocket(wss) {
|
||||||
init(wss);
|
init(wss);
|
||||||
let Store = [];
|
let Store = [];
|
||||||
checkAllUrl(Store);
|
wss.on("connection", (ws) => {
|
||||||
setInterval(async () => {
|
|
||||||
Store = [];
|
|
||||||
checkAllUrl(Store);
|
checkAllUrl(Store);
|
||||||
}, 2000);
|
});
|
||||||
|
|
||||||
|
setInterval(
|
||||||
|
async () => {
|
||||||
|
Store = [];
|
||||||
|
checkAllUrl(Store);
|
||||||
|
},
|
||||||
|
process.env.TIME || 60 * 1000,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { setupWebSocket };
|
module.exports = { setupWebSocket };
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
<h1>URL HEALTH MONITOR</h1>
|
<h1>URL HEALTH MONITOR</h1>
|
||||||
|
|
||||||
<h4>WebSocket: <span id="websocket_status">Connecting...</span></h4>
|
<h4>WebSocket: <span id="websocket_status">Connecting...</span></h4>
|
||||||
|
<h4>Page will fetch latest update every 60 second </h4>
|
||||||
|
|
||||||
<h4 id="status"></h4>
|
<h4 id="status"></h4>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+51
-54
@@ -1,23 +1,22 @@
|
|||||||
const tbody = document.getElementById("content-display");
|
const tbody = document.getElementById("content-display");
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/api/url");
|
const response = await fetch("/api/url");
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP ${response.status}`);
|
throw new Error(`HTTP ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const urls = await response.json();
|
const urls = await response.json();
|
||||||
|
|
||||||
urls.forEach((url) => {
|
urls.forEach((url) => {
|
||||||
|
const id = url.replace(/[^a-zA-Z0-9]/g, "_");
|
||||||
|
|
||||||
const id = url.replace(/[^a-zA-Z0-9]/g, "_");
|
const row = document.createElement("tr");
|
||||||
|
row.id = id;
|
||||||
|
|
||||||
const row = document.createElement("tr");
|
row.innerHTML = `
|
||||||
row.id = id;
|
|
||||||
|
|
||||||
row.innerHTML = `
|
|
||||||
<td>${url}</td>
|
<td>${url}</td>
|
||||||
<td class="status">Waiting...</td>
|
<td class="status">Waiting...</td>
|
||||||
<td class="statusCode">-</td>
|
<td class="statusCode">-</td>
|
||||||
@@ -25,12 +24,11 @@ async function init() {
|
|||||||
<td class="error">-</td>
|
<td class="error">-</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
tbody.appendChild(row);
|
tbody.appendChild(row);
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
} catch (err) {
|
console.error(err);
|
||||||
console.error(err);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", init);
|
document.addEventListener("DOMContentLoaded", init);
|
||||||
@@ -43,60 +41,59 @@ console.log(socket);
|
|||||||
const websocket_status = document.getElementById("websocket_status");
|
const websocket_status = document.getElementById("websocket_status");
|
||||||
|
|
||||||
socket.onopen = () => {
|
socket.onopen = () => {
|
||||||
websocket_status.textContent = "Connected";
|
websocket_status.textContent = "Connected";
|
||||||
};
|
};
|
||||||
let counter = 0
|
let counter = 0;
|
||||||
socket.onmessage = (event) => {
|
socket.onmessage = (event) => {
|
||||||
// console.log(counter)
|
// console.log(counter)
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.type === "checking") {
|
if (data.type === "checking") {
|
||||||
counter = counter + 1
|
counter = counter + 1;
|
||||||
console.log(counter)
|
document.getElementById("status").textContent =
|
||||||
document.getElementById("status").textContent = "Refreshed " + counter + " Times";
|
"Refreshed " + counter + " Times";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const id = data.url.replace(/[^a-zA-Z0-9]/g, "_");
|
||||||
|
const row = document.getElementById(id);
|
||||||
|
if (!row) return;
|
||||||
|
|
||||||
const id = data.url.replace(/[^a-zA-Z0-9]/g, "_");
|
row.querySelector(".status").textContent = data.status;
|
||||||
const row = document.getElementById(id);
|
row.querySelector(".statusCode").textContent = data.statusCode;
|
||||||
if (!row) return;
|
row.querySelector(".responseTime").textContent =
|
||||||
|
data.responseTime != null ? `${data.responseTime} ms` : "-";
|
||||||
row.querySelector(".status").textContent = data.status;
|
row.querySelector(".error").textContent = data.error || "-";
|
||||||
row.querySelector(".statusCode").textContent = data.statusCode;
|
|
||||||
row.querySelector(".responseTime").textContent = data.responseTime != null ? `${data.responseTime} ms` : "-";
|
|
||||||
row.querySelector(".error").textContent = data.error || "-";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
socket.onclose = () => {
|
socket.onclose = () => {
|
||||||
websocket_status.textContent = "Disconnected";
|
websocket_status.textContent = "Disconnected";
|
||||||
};
|
};
|
||||||
|
|
||||||
document.getElementById("addBtn").addEventListener("click", async () => {
|
document.getElementById("addBtn").addEventListener("click", async () => {
|
||||||
const url = document.getElementById("urlInput").value.trim();
|
const url = document.getElementById("urlInput").value.trim();
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
|
|
||||||
const response = await fetch("/api/url/register", {
|
const response = await fetch("/api/url/register", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ url })
|
body: JSON.stringify({ url }),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
document.getElementById("urlInput").value = "";
|
document.getElementById("urlInput").value = "";
|
||||||
|
|
||||||
const id = url.replace(/[^a-zA-Z0-9]/g, "_");
|
const id = url.replace(/[^a-zA-Z0-9]/g, "_");
|
||||||
if (!document.getElementById(id)) {
|
if (!document.getElementById(id)) {
|
||||||
const row = document.createElement("tr");
|
const row = document.createElement("tr");
|
||||||
row.id = id;
|
row.id = id;
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td>${url}</td>
|
<td>${url}</td>
|
||||||
<td class="status">Waiting...</td>
|
<td class="status">Waiting...</td>
|
||||||
<td class="statusCode">-</td>
|
<td class="statusCode">-</td>
|
||||||
<td class="responseTime">-</td>
|
<td class="responseTime">-</td>
|
||||||
<td class="error">-</td>
|
<td class="error">-</td>
|
||||||
`;
|
`;
|
||||||
tbody.appendChild(row);
|
tbody.appendChild(row);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
+2
-3
@@ -2,10 +2,9 @@
|
|||||||
"name": "uptime_monitor",
|
"name": "uptime_monitor",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "A lightweight **URL Health Monitoring** application built with **Node.js, Express, WebSocket, Axios, and Docker**. The application periodically checks the health of registered URLs and updates the frontend in real time using WebSockets.",
|
"description": "A lightweight **URL Health Monitoring** application built with **Node.js, Express, WebSocket, Axios, and Docker**. The application periodically checks the health of registered URLs and updates the frontend in real time using WebSockets.",
|
||||||
"main": "app.js",
|
"main": "./backend/app.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node backend/app.js",
|
"start": "node backend/app.js"
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Akshay Vadher",
|
"author": "Akshay Vadher",
|
||||||
|
|||||||
Reference in New Issue
Block a user