diff --git a/.github/ISSUE_TEMPLATE/ask-for-help.md b/.github/ISSUE_TEMPLATE/ask-for-help.md index e5bcd5ccf..a89d94218 100644 --- a/.github/ISSUE_TEMPLATE/ask-for-help.md +++ b/.github/ISSUE_TEMPLATE/ask-for-help.md @@ -9,3 +9,9 @@ assignees: '' **Is it a duplicate question?** Please search in Issues without filters: https://github.com/louislam/uptime-kuma/issues?q= +**Info** +Uptime Kuma Version: +Using Docker?: Yes/No +OS: +Browser: + diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index f647520aa..da89d154b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -23,15 +23,16 @@ Steps to reproduce the behavior: **Expected behavior** A clear and concise description of what you expected to happen. + +**Info** +- Uptime Kuma Version: +- Using Docker?: Yes/No +- OS: +- Browser: + **Screenshots** If applicable, add screenshots to help explain your problem. -**Desktop (please complete the following information):** - - Uptime Kuma Version: - - Using Docker?: Yes/No - - OS: - - Browser: +**Error Log** +It is easier for us to find out the problem. - -**Additional context** -Add any other context about the problem here. diff --git a/.stylelintrc b/.stylelintrc index 4d3d9d1f8..b50448c14 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,3 +1,3 @@ { - "extends": "stylelint-config-recommended", + "extends": "stylelint-config-recommended" } diff --git a/README.md b/README.md index 8561b26d1..285f14708 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name upti Browse to http://localhost:3001 after started. -If you want to change port and volume, or need to browse via a reserve proxy, please read: https://github.com/louislam/uptime-kuma/wiki/Installation. +If you want to change **port** and **volume**, or need to browse via a reserve proxy, please read wiki. ### 💪🏻 Without Docker (Recommanded for x86/x64 only) @@ -55,7 +55,7 @@ pm2 start npm --name uptime-kuma -- run start-server Browse to http://localhost:3001 after started. -If you want to change port and hostname, or need to browse via a reserve proxy, please read: https://github.com/louislam/uptime-kuma/wiki/Installation. +If you want to change **port** and **hostname**, or need to browse via a reserve proxy, please read wiki. ## 🆙 How to Update @@ -79,7 +79,7 @@ PS: For every new release, it takes some time to build the docker image, please ```bash cd git fetch --all -git checkout 1.1.0 --force +git checkout 1.2.0 --force npm install npm run build pm2 restart uptime-kuma diff --git a/package.json b/package.json index 7fe438cc5..891806830 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uptime-kuma", - "version": "1.1.0", + "version": "1.2.0", "license": "MIT", "repository": { "type": "git", @@ -17,10 +17,10 @@ "update": "", "build": "vite build", "vite-preview-dist": "vite preview --host", - "build-docker": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma -t louislam/uptime-kuma:1 -t louislam/uptime-kuma:1.1.0 --target release . --push", + "build-docker": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma -t louislam/uptime-kuma:1 -t louislam/uptime-kuma:1.2.0 --target release . --push", "build-docker-nightly": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly --target nightly . --push", "build-docker-nightly-amd64": "docker buildx build --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push", - "setup": "git checkout 1.1.0 && npm install && npm run build", + "setup": "git checkout 1.2.0 && npm install && npm run build", "update-version": "node extra/update-version.js", "mark-as-nightly": "node extra/mark-as-nightly.js", "reset-password": "node extra/reset-password.js", diff --git a/server/database.js b/server/database.js index f10ec40cb..2c6ec7145 100644 --- a/server/database.js +++ b/server/database.js @@ -24,10 +24,15 @@ class Database { pool: { min: 1, max: 1, - idleTimeoutMillis: 30000, + acquireTimeoutMillis: 3600 * 1000, + idleTimeoutMillis: 3600 * 1000 } })); + 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 94b2f0d04..2b4839824 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/notification.js b/server/notification.js index ea065b2fa..924aa07c2 100644 --- a/server/notification.js +++ b/server/notification.js @@ -197,9 +197,9 @@ class Notification { try { let config = { headers: { - 'api-key': notification.octopushAPIKey, - 'api-login': notification.octopushLogin, - 'cache-control': 'no-cache' + "api-key": notification.octopushAPIKey, + "api-login": notification.octopushLogin, + "cache-control": "no-cache" } }; let data = { @@ -215,7 +215,7 @@ class Notification { "sender": notification.octopushSenderName }; - await axios.post(`https://api.octopush.com/v1/public/sms-campaign/send`, data, config) + await axios.post("https://api.octopush.com/v1/public/sms-campaign/send", data, config) return true; } catch (error) { console.log(error) @@ -356,30 +356,30 @@ class Notification { } else if (notification.type === "pushbullet") { try { - let pushbulletUrl = `https://api.pushbullet.com/v2/pushes`; + let pushbulletUrl = "https://api.pushbullet.com/v2/pushes"; let config = { headers: { - 'Access-Token': notification.pushbulletAccessToken, - 'Content-Type': 'application/json' + "Access-Token": notification.pushbulletAccessToken, + "Content-Type": "application/json" } }; if (heartbeatJSON == null) { let testdata = { - "type": "note", + "type": "note", "title": "Uptime Kuma Alert", "body": "Testing Successful.", } await axios.post(pushbulletUrl, testdata, config) } else if (heartbeatJSON["status"] == 0) { let downdata = { - "type": "note", + "type": "note", "title": "UptimeKuma Alert:" + monitorJSON["name"], "body": "[🔴 Down]" + heartbeatJSON["msg"] + "\nTime (UTC):" + heartbeatJSON["time"], } await axios.post(pushbulletUrl, downdata, config) } else if (heartbeatJSON["status"] == 1) { let updata = { - "type": "note", + "type": "note", "title": "UptimeKuma Alert:" + monitorJSON["name"], "body": "[✅ Up]" + heartbeatJSON["msg"] + "\nTime (UTC):" + heartbeatJSON["time"], } @@ -432,15 +432,21 @@ class Notification { static async smtp(notification, msg) { - let transporter = nodemailer.createTransport({ + const config = { host: notification.smtpHost, port: notification.smtpPort, secure: notification.smtpSecure, - auth: { + }; + + // Should fix the issue in https://github.com/louislam/uptime-kuma/issues/26#issuecomment-896373904 + if (notification.smtpUsername || notification.smtpPassword) { + config.auth = { user: notification.smtpUsername, pass: notification.smtpPassword, - }, - }); + }; + } + + let transporter = nodemailer.createTransport(config); // send mail with defined transport object await transporter.sendMail({ diff --git a/server/server.js b/server/server.js index 31de72823..6dabcf398 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 2b7141ceb..b1b7f7739 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 73a960b5f..bb55ee08b 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") + } + } +}