diff --git a/server/database.js b/server/database.js index 3f2f6df0..2c6ec714 100644 --- a/server/database.js +++ b/server/database.js @@ -29,6 +29,10 @@ class Database { } })); + if (process.env.SQL_LOG === "1") { + R.debug(true); + } + // Auto map the model to a bean object R.freeze(true) await R.autoloadModels("./server/model"); diff --git a/server/model/monitor.js b/server/model/monitor.js index 94b2f0d0..2b483982 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -6,7 +6,7 @@ dayjs.extend(utc) dayjs.extend(timezone) const axios = require("axios"); const { Prometheus } = require("../prometheus"); -const { debug, UP, DOWN, PENDING, flipStatus } = require("../../src/util"); +const { debug, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/util"); const { tcping, ping, checkCertificate, checkStatusCode } = require("../util-server"); const { R } = require("redbean-node"); const { BeanModel } = require("redbean-node/dist/bean-model"); @@ -133,7 +133,6 @@ class Monitor extends BeanModel { bean.ping = dayjs().valueOf() - startTime; // Check certificate if https is used - let certInfoStartTime = dayjs().valueOf(); if (this.getUrl()?.protocol === "https:") { try { @@ -311,10 +310,10 @@ class Monitor extends BeanModel { } static async sendStats(io, monitorID, userID) { - Monitor.sendAvgPing(24, io, monitorID, userID); - Monitor.sendUptime(24, io, monitorID, userID); - Monitor.sendUptime(24 * 30, io, monitorID, userID); - Monitor.sendCertInfo(io, monitorID, userID); + await Monitor.sendAvgPing(24, io, monitorID, userID); + await Monitor.sendUptime(24, io, monitorID, userID); + await Monitor.sendUptime(24 * 30, io, monitorID, userID); + await Monitor.sendCertInfo(io, monitorID, userID); } /** @@ -322,6 +321,8 @@ class Monitor extends BeanModel { * @param duration : int Hours */ static async sendAvgPing(duration, io, monitorID, userID) { + const timeLogger = new TimeLogger(); + let avgPing = parseInt(await R.getCell(` SELECT AVG(ping) FROM heartbeat @@ -332,6 +333,8 @@ class Monitor extends BeanModel { monitorID, ])); + timeLogger.print(`[Monitor: ${monitorID}] avgPing`); + io.to(userID).emit("avgPing", monitorID, avgPing); } @@ -351,6 +354,8 @@ class Monitor extends BeanModel { * @param duration : int Hours */ static async sendUptime(duration, io, monitorID, userID) { + const timeLogger = new TimeLogger(); + let sec = duration * 3600; let heartbeatList = await R.getAll(` @@ -362,6 +367,8 @@ class Monitor extends BeanModel { monitorID, ]); + timeLogger.print(`[Monitor: ${monitorID}][${duration}] sendUptime`); + let downtime = 0; let total = 0; let uptime; diff --git a/server/server.js b/server/server.js index 31de7282..6dabcf39 100644 --- a/server/server.js +++ b/server/server.js @@ -1,7 +1,7 @@ console.log("Welcome to Uptime Kuma"); console.log("Node Env: " + process.env.NODE_ENV); -const { sleep, debug } = require("../src/util"); +const { sleep, debug, TimeLogger } = require("../src/util"); console.log("Importing Node libraries") const fs = require("fs"); @@ -644,11 +644,11 @@ async function afterLogin(socket, user) { // Delay a bit, so that it let the main page to query the data first, since SQLite can process one sql at the same time only. // For example, query the edit data first. - setTimeout(() => { + setTimeout(async () => { for (let monitorID in monitorList) { - sendHeartbeatList(socket, monitorID); - sendImportantHeartbeatList(socket, monitorID); - Monitor.sendStats(io, monitorID, user.id) + await sendHeartbeatList(socket, monitorID); + await sendImportantHeartbeatList(socket, monitorID); + await Monitor.sendStats(io, monitorID, user.id) } }, 500); } @@ -764,6 +764,8 @@ async function startMonitors() { * Send Heartbeat History list to socket */ async function sendHeartbeatList(socket, monitorID) { + const timeLogger = new TimeLogger(); + let list = await R.find("heartbeat", ` monitor_id = ? ORDER BY time DESC @@ -782,6 +784,8 @@ async function sendHeartbeatList(socket, monitorID) { } async function sendImportantHeartbeatList(socket, monitorID) { + const timeLogger = new TimeLogger(); + let list = await R.find("heartbeat", ` monitor_id = ? AND important = 1 @@ -791,6 +795,8 @@ async function sendImportantHeartbeatList(socket, monitorID) { monitorID, ]) + timeLogger.print(`[Monitor: ${monitorID}] sendImportantHeartbeatList`); + socket.emit("importantHeartbeatList", monitorID, list) } diff --git a/src/util.js b/src/util.js index 2b7141ce..b1b7f773 100644 --- a/src/util.js +++ b/src/util.js @@ -1,6 +1,8 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.PENDING = exports.UP = exports.DOWN = exports.appName = void 0; +exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; +const dayjs = require("dayjs"); +exports.isDev = process.env.NODE_ENV === "development"; exports.appName = "Uptime Kuma"; exports.DOWN = 0; exports.UP = 1; @@ -28,7 +30,7 @@ function ucfirst(str) { } exports.ucfirst = ucfirst; function debug(msg) { - if (process.env.NODE_ENV === "development") { + if (exports.isDev) { console.log(msg); } } @@ -44,3 +46,14 @@ function polyfill() { } } exports.polyfill = polyfill; +class TimeLogger { + constructor() { + this.startTime = dayjs().valueOf(); + } + print(name) { + if (exports.isDev) { + console.log(name + ": " + (dayjs().valueOf() - this.startTime) + "ms"); + } + } +} +exports.TimeLogger = TimeLogger; diff --git a/src/util.ts b/src/util.ts index 73a960b5..bb55ee08 100644 --- a/src/util.ts +++ b/src/util.ts @@ -4,6 +4,9 @@ // Frontend uses util.ts // Need to run "tsc" to compile if there are any changes. +import * as dayjs from "dayjs"; + +export const isDev = process.env.NODE_ENV === "development"; export const appName = "Uptime Kuma"; export const DOWN = 0; export const UP = 1; @@ -39,7 +42,7 @@ export function ucfirst(str) { } export function debug(msg) { - if (process.env.NODE_ENV === "development") { + if (isDev) { console.log(msg); } } @@ -52,7 +55,7 @@ export function polyfill() { * @license MIT */ if (!String.prototype.replaceAll) { - String.prototype.replaceAll = function(str, newStr) { + String.prototype.replaceAll = function (str, newStr) { // If a regex pattern if (Object.prototype.toString.call(str).toLowerCase() === "[object regexp]") { @@ -65,3 +68,15 @@ export function polyfill() { }; } } + +export class TimeLogger { + constructor() { + this.startTime = dayjs().valueOf(); + } + + print(name) { + if (isDev) { + console.log(name + ": " + (dayjs().valueOf() - this.startTime) + "ms") + } + } +}