diff --git a/.do/deploy.template.yaml b/.do/deploy.template.yaml
deleted file mode 100644
index 1023e85..0000000
--- a/.do/deploy.template.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-spec:
- name: uptime-kuma
- services:
- - dockerfile_path: Dockerfile
- git:
- branch: main
- repo_clone_url: https://github.com/philippdormann/uptime-kuma.git
- name: uptime-kuma
\ No newline at end of file
diff --git a/.dockerignore b/.dockerignore
index 618d711..df1f46a 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -17,6 +17,8 @@ README.md
/.github
package-lock.json
app.json
+CODE_OF_CONDUCT.md
+CONTRIBUTING.md
### .gitignore content (commented rules are duplicated)
diff --git a/.eslintrc.js b/.eslintrc.js
index 41ad54b..fde74f6 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -16,6 +16,9 @@ module.exports = {
requireConfigFile: false,
},
rules: {
+ "camelcase": ["warn", {
+ "properties": "never"
+ }],
// override/add rules settings here, such as:
// 'vue/no-unused-vars': 'error'
"no-unused-vars": "warn",
@@ -36,6 +39,11 @@ module.exports = {
"no-multi-spaces": ["error", {
ignoreEOLComments: true,
}],
+ "space-before-function-paren": ["error", {
+ "anonymous": "always",
+ "named": "never",
+ "asyncArrow": "always"
+ }],
"curly": "error",
"object-curly-spacing": ["error", "always"],
"object-curly-newline": "off",
@@ -62,12 +70,13 @@ module.exports = {
exceptAfterSingleLine: true,
}],
"no-unneeded-ternary": "error",
- "no-else-return": ["error", {
- "allowElseIf": false,
- }],
"array-bracket-newline": ["error", "consistent"],
"eol-last": ["error", "always"],
//'prefer-template': 'error',
"comma-dangle": ["warn", "only-multiline"],
+ "no-empty": ["error", {
+ "allowEmptyCatch": true
+ }],
+ "no-control-regex": "off"
},
}
diff --git a/.github/ISSUE_TEMPLATE/ask-for-help.md b/.github/ISSUE_TEMPLATE/ask-for-help.md
index c365726..a89d942 100644
--- a/.github/ISSUE_TEMPLATE/ask-for-help.md
+++ b/.github/ISSUE_TEMPLATE/ask-for-help.md
@@ -6,5 +6,12 @@ labels: help
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 cea1fc1..da89d15 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -7,6 +7,9 @@ assignees: ''
---
+**Is it a duplicate question?**
+Please search in Issues without filters: https://github.com/louislam/uptime-kuma/issues?q=
+
**Describe the bug**
A clear and concise description of what the bug is.
@@ -20,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/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 11fc491..9141130 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -6,6 +6,8 @@ labels: enhancement
assignees: ''
---
+**Is it a duplicate question?**
+Please search in Issues without filters: https://github.com/louislam/uptime-kuma/issues?q=
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
diff --git a/.stylelintrc b/.stylelintrc
index 4d3d9d1..d981fe7 100644
--- a/.stylelintrc
+++ b/.stylelintrc
@@ -1,3 +1,10 @@
{
- "extends": "stylelint-config-recommended",
+ "extends": "stylelint-config-standard",
+ "rules": {
+ "indentation": 4,
+ "no-descending-specificity": null,
+ "selector-list-comma-newline-after": null,
+ "declaration-empty-line-before": null,
+ "no-duplicate-selectors": null
+ }
}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b3308df..5bbf343 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -6,7 +6,38 @@ The project was created with vite.js (vue3). Then I created a sub-directory call
The frontend code build into "dist" directory. The server uses "dist" as root. This is how production is working.
-Your IDE should follow the config in ".editorconfig". The most special thing is I set it to 4 spaces indentation. I know 2 spaces indentation became a kind of standard nowadays for js, but my eyes is not so comfortable for this. In my opinion, there is no callback-hell nowadays, it is good to go back 4 spaces world again.
+# Can I create a pull request for Uptime Kuma?
+
+Generally, if the pull request is working fine and it do not affect any existing logic, workflow and perfomance, I will merge to the master branch once it is tested.
+
+If you are not sure, feel free to create an empty pull request draft first.
+
+## Pull Request Examples
+
+### ✅ High - Medium Priority
+
+- Add a new notification
+- Add a chart
+- Fix a bug
+
+### *️⃣ Requires one more reviewer
+
+I do not have such knowledge to test it
+
+- Add k8s supports
+
+### *️⃣ Low Priority
+
+It chnaged my current workflow and require further studies.
+
+- Change my release approach
+
+### ❌ Won't Merge
+
+- Duplicated pull request
+- Buggy
+- Existing logic is completely modified or deleted
+- A function that is completely out of scope
# Project Styles
@@ -19,16 +50,27 @@ For example, recently, because I am not a python expert, I spent a 2 hours to re
- All settings in frontend.
- Easy to use
+# Coding Styles
+
+- Follow .editorconfig
+- Follow eslint
+
+## Name convention
+
+- Javascript/Typescript: camelCaseType
+- SQLite: underscore_type
+- CSS/SCSS: dash-type
+
# Tools
- Node.js >= 14
- Git
-- IDE that supports .editorconfig (I am using Intellji Idea)
+- IDE that supports .editorconfig and eslint (I am using Intellji Idea)
- A SQLite tool (I am using SQLite Expert Personal)
-# Prepare the dev
+# Install dependencies
```bash
-npm install
+npm install --dev
```
# Backend Dev
@@ -39,7 +81,6 @@ npm run start-server
# Or
node server/server.js
-
```
It binds to 0.0.0.0:3001 by default.
@@ -92,7 +133,8 @@ The data and socket logic in "src/mixins/socket.js"
# Database Migration
-TODO
+1. create `patch{num}.sql` in `./db/`
+1. update `latestVersion` in `./server/database.js`
# Unit Test
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..47f0786
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,14 @@
+# Security Policy
+
+## Supported Versions
+
+Use this section to tell people about which versions of your project are
+currently being supported with security updates.
+
+| Version | Supported |
+| ------- | ------------------ |
+| 1.x.x | :white_check_mark: |
+
+## Reporting a Vulnerability
+
+https://github.com/louislam/uptime-kuma/issues
diff --git a/app.json b/app.json
deleted file mode 100644
index ab64321..0000000
--- a/app.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "Uptime Kuma",
- "description": "A fancy self-hosted monitoring tool",
- "repository": "https://github.com/louislam/uptime-kuma",
- "logo": "https://raw.githubusercontent.com/louislam/uptime-kuma/master/public/icon.png",
- "keywords": ["node", "express", "socket-io", "uptime-kuma", "uptime"]
-}
diff --git a/db/patch5.sql b/db/patch5.sql
new file mode 100644
index 0000000..5730b2d
--- /dev/null
+++ b/db/patch5.sql
@@ -0,0 +1,70 @@
+-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
+PRAGMA foreign_keys = off;
+
+BEGIN TRANSACTION;
+
+create table monitor_dg_tmp (
+ id INTEGER not null primary key autoincrement,
+ name VARCHAR(150),
+ active BOOLEAN default 1 not null,
+ user_id INTEGER references user on update cascade on delete
+ set
+ null,
+ interval INTEGER default 20 not null,
+ url TEXT,
+ type VARCHAR(20),
+ weight INTEGER default 2000,
+ hostname VARCHAR(255),
+ port INTEGER,
+ created_date DATETIME default (DATETIME('now')) not null,
+ keyword VARCHAR(255),
+ maxretries INTEGER NOT NULL DEFAULT 0,
+ ignore_tls BOOLEAN default 0 not null,
+ upside_down BOOLEAN default 0 not null
+);
+
+insert into
+ monitor_dg_tmp(
+ id,
+ name,
+ active,
+ user_id,
+ interval,
+ url,
+ type,
+ weight,
+ hostname,
+ port,
+ keyword,
+ maxretries,
+ ignore_tls,
+ upside_down
+ )
+select
+ id,
+ name,
+ active,
+ user_id,
+ interval,
+ url,
+ type,
+ weight,
+ hostname,
+ port,
+ keyword,
+ maxretries,
+ ignore_tls,
+ upside_down
+from
+ monitor;
+
+drop table monitor;
+
+alter table
+ monitor_dg_tmp rename to monitor;
+
+create index user_id on monitor (user_id);
+
+COMMIT;
+
+PRAGMA foreign_keys = on;
diff --git a/db/patch6.sql b/db/patch6.sql
new file mode 100644
index 0000000..4f539a2
--- /dev/null
+++ b/db/patch6.sql
@@ -0,0 +1,74 @@
+-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
+PRAGMA foreign_keys = off;
+
+BEGIN TRANSACTION;
+
+create table monitor_dg_tmp (
+ id INTEGER not null primary key autoincrement,
+ name VARCHAR(150),
+ active BOOLEAN default 1 not null,
+ user_id INTEGER references user on update cascade on delete
+ set
+ null,
+ interval INTEGER default 20 not null,
+ url TEXT,
+ type VARCHAR(20),
+ weight INTEGER default 2000,
+ hostname VARCHAR(255),
+ port INTEGER,
+ created_date DATETIME default (DATETIME('now')) not null,
+ keyword VARCHAR(255),
+ maxretries INTEGER NOT NULL DEFAULT 0,
+ ignore_tls BOOLEAN default 0 not null,
+ upside_down BOOLEAN default 0 not null,
+ maxredirects INTEGER default 10 not null,
+ accepted_statuscodes_json TEXT default '["200-299"]' not null
+);
+
+insert into
+ monitor_dg_tmp(
+ id,
+ name,
+ active,
+ user_id,
+ interval,
+ url,
+ type,
+ weight,
+ hostname,
+ port,
+ created_date,
+ keyword,
+ maxretries,
+ ignore_tls,
+ upside_down
+ )
+select
+ id,
+ name,
+ active,
+ user_id,
+ interval,
+ url,
+ type,
+ weight,
+ hostname,
+ port,
+ created_date,
+ keyword,
+ maxretries,
+ ignore_tls,
+ upside_down
+from
+ monitor;
+
+drop table monitor;
+
+alter table
+ monitor_dg_tmp rename to monitor;
+
+create index user_id on monitor (user_id);
+
+COMMIT;
+
+PRAGMA foreign_keys = on;
diff --git a/extra/compile-install-script.ps1 b/extra/compile-install-script.ps1
new file mode 100644
index 0000000..dd44798
--- /dev/null
+++ b/extra/compile-install-script.ps1
@@ -0,0 +1,2 @@
+# Must enable File Sharing in Docker Desktop
+docker run -it --rm -v ${pwd}:/app louislam/batsh /usr/bin/batsh bash --output ./install.sh ./extra/install.batsh
diff --git a/extra/healthcheck.js b/extra/healthcheck.js
index b547fbc..c0b33b6 100644
--- a/extra/healthcheck.js
+++ b/extra/healthcheck.js
@@ -1,19 +1,19 @@
-var http = require("http");
-var options = {
- host: "localhost",
- port: "3001",
- timeout: 2000,
+let http = require("http");
+let options = {
+ host: "localhost",
+ port: "3001",
+ timeout: 2000,
};
-var request = http.request(options, (res) => {
- console.log(`STATUS: ${res.statusCode}`);
- if (res.statusCode == 200) {
- process.exit(0);
- } else {
- process.exit(1);
- }
+let request = http.request(options, (res) => {
+ console.log(`STATUS: ${res.statusCode}`);
+ if (res.statusCode == 200) {
+ process.exit(0);
+ } else {
+ process.exit(1);
+ }
});
request.on("error", function (err) {
- console.log("ERROR");
- process.exit(1);
+ console.log("ERROR");
+ process.exit(1);
});
request.end();
diff --git a/extra/install.batsh b/extra/install.batsh
new file mode 100644
index 0000000..cf14d0a
--- /dev/null
+++ b/extra/install.batsh
@@ -0,0 +1,245 @@
+// install.sh is generated by ./extra/install.batsh, do not modify it directly.
+// "npm run compile-install-script" to compile install.sh
+// The command is working on Windows PowerShell and Docker for Windows only.
+
+
+// curl -o kuma_install.sh https://raw.githubusercontent.com/louislam/uptime-kuma/master/install.sh && sudo bash kuma_install.sh
+println("=====================");
+println("Uptime Kuma Installer");
+println("=====================");
+println("Supported OS: CentOS 7/8, Ubuntu >= 16.04 and Debian");
+println("---------------------------------------");
+println("This script is designed for Linux and basic usage.");
+println("For advanced usage, please go to https://github.com/louislam/uptime-kuma/wiki/Installation");
+println("---------------------------------------");
+println("");
+println("Local - Install Uptime Kuma in your current machine with git, Node.js 14 and pm2");
+println("Docker - Install Uptime Kuma Docker container");
+println("");
+
+if ("$1" != "") {
+ type = "$1";
+} else {
+ call("read", "-p", "Which installation method do you prefer? [DOCKER/local]: ", "type");
+}
+
+defaultPort = "3001";
+
+function checkNode() {
+ bash("nodeVersion=$(node -e 'console.log(process.versions.node.split(`.`)[0])')");
+ println("Node Version: " ++ nodeVersion);
+
+ if (nodeVersion < "12") {
+ println("Error: Required Node.js 14");
+ call("exit", "1");
+ }
+
+ if (nodeVersion == "12") {
+ println("Warning: NodeJS " ++ nodeVersion ++ " is not tested.");
+ }
+}
+
+function deb() {
+ bash("nodeCheck=$(node -v)");
+ bash("apt --yes update");
+
+ if (nodeCheck != "") {
+ checkNode();
+ } else {
+
+ // Old nodejs binary name is "nodejs"
+ bash("check=$(nodejs --version)");
+ if (check != "") {
+ println("Error: 'node' command is not found, but 'nodejs' command is found. Your NodeJS should be too old.");
+ bash("exit 1");
+ }
+
+ bash("curlCheck=$(curl --version)");
+ if (curlCheck == "") {
+ println("Installing Curl");
+ bash("apt --yes install curl");
+ }
+
+ println("Installing Node.js 14");
+ bash("curl -sL https://deb.nodesource.com/setup_14.x | bash - > log.txt");
+ bash("apt --yes install nodejs");
+ bash("node -v");
+
+ bash("nodeCheckAgain=$(node -v)");
+
+ if (nodeCheckAgain == "") {
+ println("Error during Node.js installation");
+ bash("exit 1");
+ }
+ }
+
+ bash("check=$(git --version)");
+ if (check == "") {
+ println("Installing Git");
+ bash("apt --yes install git");
+ }
+}
+
+if (type == "local") {
+ defaultInstallPath = "/opt/uptime-kuma";
+
+ if (exists("/etc/redhat-release")) {
+ os = call("cat", "/etc/redhat-release");
+ distribution = "rhel";
+
+ } else if (exists("/etc/issue")) {
+ bash("os=$(head -n1 /etc/issue | cut -f 1 -d ' ')");
+ if (os == "Ubuntu") {
+ distribution = "ubuntu";
+ }
+ if (os == "Debian") {
+ distribution = "debian";
+ }
+ }
+
+ bash("arch=$(uname -i)");
+
+ println("Your OS: " ++ os);
+ println("Distribution: " ++ distribution);
+ println("Arch: " ++ arch);
+
+ if ("$3" != "") {
+ port = "$3";
+ } else {
+ call("read", "-p", "Listening Port [$defaultPort]: ", "port");
+
+ if (port == "") {
+ port = defaultPort;
+ }
+ }
+
+ if ("$2" != "") {
+ installPath = "$2";
+ } else {
+ call("read", "-p", "Installation Path [$defaultInstallPath]: ", "installPath");
+
+ if (installPath == "") {
+ installPath = defaultInstallPath;
+ }
+ }
+
+ // CentOS
+ if (distribution == "rhel") {
+ bash("nodeCheck=$(node -v)");
+
+ if (nodeCheck != "") {
+ checkNode();
+ } else {
+
+ bash("curlCheck=$(curl --version)");
+ if (curlCheck == "") {
+ println("Installing Curl");
+ bash("yum -y -q install curl");
+ }
+
+ println("Installing Node.js 14");
+ bash("curl -sL https://rpm.nodesource.com/setup_14.x | bash - > log.txt");
+ bash("yum install -y -q nodejs");
+ bash("node -v");
+
+ bash("nodeCheckAgain=$(node -v)");
+
+ if (nodeCheckAgain == "") {
+ println("Error during Node.js installation");
+ bash("exit 1");
+ }
+ }
+
+ bash("check=$(git --version)");
+ if (check == "") {
+ println("Installing Git");
+ bash("yum -y -q install git");
+ }
+
+ // Ubuntu
+ } else if (distribution == "ubuntu") {
+ deb();
+
+ // Debian
+ } else if (distribution == "debian") {
+ deb();
+
+ } else {
+ // Unknown distribution
+ error = 0;
+
+ bash("check=$(git --version)");
+ if (check == "") {
+ error = 1;
+ println("Error: git is missing");
+ }
+
+ bash("check=$(node -v)");
+ if (check == "") {
+ error = 1;
+ println("Error: node is missing");
+ }
+
+ if (error > 0) {
+ println("Please install above missing software");
+ bash("exit 1");
+ }
+ }
+
+ bash("check=$(pm2 --version)");
+ if (check == "") {
+ println("Installing PM2");
+ bash("npm install pm2 -g");
+ bash("pm2 startup");
+ }
+
+ bash("mkdir -p $installPath");
+ bash("cd $installPath");
+ bash("git clone https://github.com/louislam/uptime-kuma.git .");
+ bash("npm run setup");
+
+ bash("pm2 start npm --name uptime-kuma -- run start-server -- --port=$port");
+
+} else {
+ defaultVolume = "uptime-kuma";
+
+ bash("check=$(docker -v)");
+ if (check == "") {
+ println("Error: docker is not found!");
+ bash("exit 1");
+ }
+
+ bash("check=$(docker info)");
+
+ bash("if [[ \"$check\" == *\"Is the docker daemon running\"* ]]; then
+ echo \"Error: docker is not running\"
+ exit 1
+ fi");
+
+ if ("$3" != "") {
+ port = "$3";
+ } else {
+ call("read", "-p", "Expose Port [$defaultPort]: ", "port");
+
+ if (port == "") {
+ port = defaultPort;
+ }
+ }
+
+ if ("$2" != "") {
+ volume = "$2";
+ } else {
+ call("read", "-p", "Volume Name [$defaultVolume]: ", "volume");
+
+ if (volume == "") {
+ volume = defaultVolume;
+ }
+ }
+
+ println("Port: $port");
+ println("Volume: $volume");
+ bash("docker volume create $volume");
+ bash("docker run -d --restart=always -p $port:3001 -v $volume:/app/data --name uptime-kuma louislam/uptime-kuma:1");
+}
+
+println("http://localhost:$port");
diff --git a/extra/mark-as-nightly.js b/extra/mark-as-nightly.js
index 2849651..0316596 100644
--- a/extra/mark-as-nightly.js
+++ b/extra/mark-as-nightly.js
@@ -1,25 +1,9 @@
-/**
- * String.prototype.replaceAll() polyfill
- * https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/
- * @author Chris Ferdinandi
- * @license MIT
- */
-if (!String.prototype.replaceAll) {
- String.prototype.replaceAll = function(str, newStr){
-
- // If a regex pattern
- if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
- return this.replace(str, newStr);
- }
+const pkg = require("../package.json");
+const fs = require("fs");
+const util = require("../src/util");
- // If a string
- return this.replace(new RegExp(str, 'g'), newStr);
+util.polyfill();
- };
-}
-
-const pkg = require('../package.json');
-const fs = require("fs");
const oldVersion = pkg.version
const newVersion = oldVersion + "-nightly"
@@ -35,6 +19,6 @@ if (newVersion) {
// Process README.md
if (fs.existsSync("README.md")) {
- fs.writeFileSync("README.md", fs.readFileSync("README.md", 'utf8').replaceAll(oldVersion, newVersion))
+ fs.writeFileSync("README.md", fs.readFileSync("README.md", "utf8").replaceAll(oldVersion, newVersion))
}
}
diff --git a/extra/reset-password.js b/extra/reset-password.js
new file mode 100644
index 0000000..b849848
--- /dev/null
+++ b/extra/reset-password.js
@@ -0,0 +1,59 @@
+console.log("== Uptime Kuma Reset Password Tool ==");
+
+console.log("Loading the database");
+
+const Database = require("../server/database");
+const { R } = require("redbean-node");
+const readline = require("readline");
+const { initJWTSecret } = require("../server/util-server");
+const rl = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout
+});
+
+(async () => {
+ await Database.connect();
+
+ try {
+ const user = await R.findOne("user");
+
+ if (! user) {
+ throw new Error("user not found, have you installed?");
+ }
+
+ console.log("Found user: " + user.username);
+
+ while (true) {
+ let password = await question("New Password: ");
+ let confirmPassword = await question("Confirm New Password: ");
+
+ if (password === confirmPassword) {
+ await user.resetPassword(password);
+
+ // Reset all sessions by reset jwt secret
+ await initJWTSecret();
+
+ rl.close();
+ break;
+ } else {
+ console.log("Passwords do not match, please try again.");
+ }
+ }
+
+ console.log("Password reset successfully.");
+ } catch (e) {
+ console.error("Error: " + e.message);
+ }
+
+ await Database.close();
+
+ console.log("Finished. You should restart the Uptime Kuma server.")
+})();
+
+function question(question) {
+ return new Promise((resolve) => {
+ rl.question(question, (answer) => {
+ resolve(answer);
+ })
+ });
+}
diff --git a/extra/update-version.js b/extra/update-version.js
new file mode 100644
index 0000000..697a640
--- /dev/null
+++ b/extra/update-version.js
@@ -0,0 +1,59 @@
+const pkg = require("../package.json");
+const fs = require("fs");
+const child_process = require("child_process");
+const util = require("../src/util");
+
+util.polyfill();
+
+const oldVersion = pkg.version;
+const newVersion = process.argv[2];
+
+console.log("Old Version: " + oldVersion);
+console.log("New Version: " + newVersion);
+
+if (! newVersion) {
+ console.error("invalid version");
+ process.exit(1);
+}
+
+const exists = tagExists(newVersion);
+
+if (! exists) {
+ // Process package.json
+ pkg.version = newVersion;
+ pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion);
+ pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion);
+ fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n");
+
+ commit(newVersion);
+ tag(newVersion);
+} else {
+ console.log("version exists")
+}
+
+function commit(version) {
+ let msg = "update to " + version;
+
+ let res = child_process.spawnSync("git", ["commit", "-m", msg, "-a"]);
+ let stdout = res.stdout.toString().trim();
+ console.log(stdout)
+
+ if (stdout.includes("no changes added to commit")) {
+ throw new Error("commit error")
+ }
+}
+
+function tag(version) {
+ let res = child_process.spawnSync("git", ["tag", version]);
+ console.log(res.stdout.toString().trim())
+}
+
+function tagExists(version) {
+ if (! version) {
+ throw new Error("invalid version");
+ }
+
+ let res = child_process.spawnSync("git", ["tag", "-l", version]);
+
+ return res.stdout.toString().trim() === version;
+}
diff --git a/extra/version-global-replace.js b/extra/version-global-replace.js
deleted file mode 100644
index bf91865..0000000
--- a/extra/version-global-replace.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * String.prototype.replaceAll() polyfill
- * https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/
- * @author Chris Ferdinandi
- * @license MIT
- */
-if (!String.prototype.replaceAll) {
- String.prototype.replaceAll = function(str, newStr){
-
- // If a regex pattern
- if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
- return this.replace(str, newStr);
- }
-
- // If a string
- return this.replace(new RegExp(str, 'g'), newStr);
-
- };
-}
-
-const pkg = require('../package.json');
-const fs = require("fs");
-const oldVersion = pkg.version
-const newVersion = process.argv[2]
-
-console.log("Old Version: " + oldVersion)
-console.log("New Version: " + newVersion)
-
-if (newVersion) {
- // Process package.json
- pkg.version = newVersion
- pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion)
- pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion)
- fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n")
-
- // Process README.md
- fs.writeFileSync("README.md", fs.readFileSync("README.md", 'utf8').replaceAll(oldVersion, newVersion))
-}
-
diff --git a/index.html b/index.html
index 66d58c1..61d0f42 100644
--- a/index.html
+++ b/index.html
@@ -1,16 +1,16 @@
-
+
-
-
-
+
+
+
Uptime Kuma
-
-
-
-
-
+
+
+
+
+
diff --git a/install.sh b/install.sh
new file mode 100644
index 0000000..a840bb2
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,203 @@
+# install.sh is generated by ./extra/install.batsh, do not modify it directly.
+# "npm run compile-install-script" to compile install.sh
+# The command is working on Windows PowerShell and Docker for Windows only.
+# curl -o kuma_install.sh https://raw.githubusercontent.com/louislam/uptime-kuma/master/install.sh && sudo bash kuma_install.sh
+"echo" "-e" "====================="
+"echo" "-e" "Uptime Kuma Installer"
+"echo" "-e" "====================="
+"echo" "-e" "Supported OS: CentOS 7/8, Ubuntu >= 16.04 and Debian"
+"echo" "-e" "---------------------------------------"
+"echo" "-e" "This script is designed for Linux and basic usage."
+"echo" "-e" "For advanced usage, please go to https://github.com/louislam/uptime-kuma/wiki/Installation"
+"echo" "-e" "---------------------------------------"
+"echo" "-e" ""
+"echo" "-e" "Local - Install Uptime Kuma in your current machine with git, Node.js 14 and pm2"
+"echo" "-e" "Docker - Install Uptime Kuma Docker container"
+"echo" "-e" ""
+if [ "$1" != "" ]; then
+ type="$1"
+else
+ "read" "-p" "Which installation method do you prefer? [DOCKER/local]: " "type"
+fi
+defaultPort="3001"
+function checkNode {
+ local _0
+ nodeVersion=$(node -e 'console.log(process.versions.node.split(`.`)[0])')
+ "echo" "-e" "Node Version: ""$nodeVersion"
+ _0="12"
+ if [ $(($nodeVersion < $_0)) == 1 ]; then
+ "echo" "-e" "Error: Required Node.js 14"
+ "exit" "1"
+fi
+ if [ "$nodeVersion" == "12" ]; then
+ "echo" "-e" "Warning: NodeJS ""$nodeVersion"" is not tested."
+fi
+}
+function deb {
+ nodeCheck=$(node -v)
+ apt --yes update
+ if [ "$nodeCheck" != "" ]; then
+ "checkNode"
+ else
+ # Old nodejs binary name is "nodejs"
+ check=$(nodejs --version)
+ if [ "$check" != "" ]; then
+ "echo" "-e" "Error: 'node' command is not found, but 'nodejs' command is found. Your NodeJS should be too old."
+ exit 1
+fi
+ curlCheck=$(curl --version)
+ if [ "$curlCheck" == "" ]; then
+ "echo" "-e" "Installing Curl"
+ apt --yes install curl
+fi
+ "echo" "-e" "Installing Node.js 14"
+ curl -sL https://deb.nodesource.com/setup_14.x | bash - > log.txt
+ apt --yes install nodejs
+ node -v
+ nodeCheckAgain=$(node -v)
+ if [ "$nodeCheckAgain" == "" ]; then
+ "echo" "-e" "Error during Node.js installation"
+ exit 1
+fi
+ fi
+ check=$(git --version)
+ if [ "$check" == "" ]; then
+ "echo" "-e" "Installing Git"
+ apt --yes install git
+fi
+}
+if [ "$type" == "local" ]; then
+ defaultInstallPath="/opt/uptime-kuma"
+ if [ -e "/etc/redhat-release" ]; then
+ os=$("cat" "/etc/redhat-release")
+ distribution="rhel"
+ else
+ if [ -e "/etc/issue" ]; then
+ os=$(head -n1 /etc/issue | cut -f 1 -d ' ')
+ if [ "$os" == "Ubuntu" ]; then
+ distribution="ubuntu"
+fi
+ if [ "$os" == "Debian" ]; then
+ distribution="debian"
+fi
+fi
+ fi
+ arch=$(uname -i)
+ "echo" "-e" "Your OS: ""$os"
+ "echo" "-e" "Distribution: ""$distribution"
+ "echo" "-e" "Arch: ""$arch"
+ if [ "$3" != "" ]; then
+ port="$3"
+ else
+ "read" "-p" "Listening Port [$defaultPort]: " "port"
+ if [ "$port" == "" ]; then
+ port="$defaultPort"
+fi
+ fi
+ if [ "$2" != "" ]; then
+ installPath="$2"
+ else
+ "read" "-p" "Installation Path [$defaultInstallPath]: " "installPath"
+ if [ "$installPath" == "" ]; then
+ installPath="$defaultInstallPath"
+fi
+ fi
+ # CentOS
+ if [ "$distribution" == "rhel" ]; then
+ nodeCheck=$(node -v)
+ if [ "$nodeCheck" != "" ]; then
+ "checkNode"
+ else
+ curlCheck=$(curl --version)
+ if [ "$curlCheck" == "" ]; then
+ "echo" "-e" "Installing Curl"
+ yum -y -q install curl
+fi
+ "echo" "-e" "Installing Node.js 14"
+ curl -sL https://rpm.nodesource.com/setup_14.x | bash - > log.txt
+ yum install -y -q nodejs
+ node -v
+ nodeCheckAgain=$(node -v)
+ if [ "$nodeCheckAgain" == "" ]; then
+ "echo" "-e" "Error during Node.js installation"
+ exit 1
+fi
+ fi
+ check=$(git --version)
+ if [ "$check" == "" ]; then
+ "echo" "-e" "Installing Git"
+ yum -y -q install git
+fi
+ # Ubuntu
+ else
+ if [ "$distribution" == "ubuntu" ]; then
+ "deb"
+ # Debian
+ else
+ if [ "$distribution" == "debian" ]; then
+ "deb"
+ else
+ # Unknown distribution
+ error=$((0))
+ check=$(git --version)
+ if [ "$check" == "" ]; then
+ error=$((1))
+ "echo" "-e" "Error: git is missing"
+fi
+ check=$(node -v)
+ if [ "$check" == "" ]; then
+ error=$((1))
+ "echo" "-e" "Error: node is missing"
+fi
+ if [ $(($error > 0)) == 1 ]; then
+ "echo" "-e" "Please install above missing software"
+ exit 1
+fi
+ fi
+ fi
+ fi
+ check=$(pm2 --version)
+ if [ "$check" == "" ]; then
+ "echo" "-e" "Installing PM2"
+ npm install pm2 -g
+ pm2 startup
+fi
+ mkdir -p $installPath
+ cd $installPath
+ git clone https://github.com/louislam/uptime-kuma.git .
+ npm run setup
+ pm2 start npm --name uptime-kuma -- run start-server -- --port=$port
+else
+ defaultVolume="uptime-kuma"
+ check=$(docker -v)
+ if [ "$check" == "" ]; then
+ "echo" "-e" "Error: docker is not found!"
+ exit 1
+fi
+ check=$(docker info)
+ if [[ "$check" == *"Is the docker daemon running"* ]]; then
+ echo "Error: docker is not running"
+ exit 1
+ fi
+ if [ "$3" != "" ]; then
+ port="$3"
+ else
+ "read" "-p" "Expose Port [$defaultPort]: " "port"
+ if [ "$port" == "" ]; then
+ port="$defaultPort"
+fi
+ fi
+ if [ "$2" != "" ]; then
+ volume="$2"
+ else
+ "read" "-p" "Volume Name [$defaultVolume]: " "volume"
+ if [ "$volume" == "" ]; then
+ volume="$defaultVolume"
+fi
+ fi
+ "echo" "-e" "Port: $port"
+ "echo" "-e" "Volume: $volume"
+ docker volume create $volume
+ docker run -d --restart=always -p $port:3001 -v $volume:/app/data --name uptime-kuma louislam/uptime-kuma:1
+fi
+"echo" "-e" "http://localhost:$port"
diff --git a/kubernetes/README.md b/kubernetes/README.md
new file mode 100644
index 0000000..26ab2f6
--- /dev/null
+++ b/kubernetes/README.md
@@ -0,0 +1,28 @@
+# Uptime-Kuma K8s Deployment
+## How does it work?
+
+Kustomize is a tool which builds a complete deployment file for all config elements.
+You can edit the files in the ```uptime-kuma``` folder except the ```kustomization.yml``` until you know what you're doing.
+If you want to choose another namespace you can edit the ```kustomization.yml``` in the ```kubernetes```-Folder and change the ```namespace: uptime-kuma``` to something you like.
+
+It creates a certificate with the specified Issuer and creates the Ingress for the Uptime-Kuma ClusterIP-Service
+
+## What do i have to edit?
+You have to edit the ```ingressroute.yml``` to your needs.
+This ingressroute.yml is for the [nginx-ingress-controller](https://kubernetes.github.io/ingress-nginx/) in combination with the [cert-manager](https://cert-manager.io/).
+
+- host
+- secrets and secret names
+- (Cluster)Issuer (optional)
+- the Version in the Deployment-File
+ - update:
+ - change to newer version and run the above commands, it will update the pods one after another
+
+## How To use:
+
+- install [kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/)
+- Edit files mentioned above to your needs
+- run ```kustomize build > apply.yml```
+- run ```kubectl apply -f apply.yml```
+
+Now you should see some k8s magic and Uptime-Kuma should be available at the specified address.
\ No newline at end of file
diff --git a/kubernetes/kustomization.yml b/kubernetes/kustomization.yml
new file mode 100644
index 0000000..0daf10f
--- /dev/null
+++ b/kubernetes/kustomization.yml
@@ -0,0 +1,10 @@
+namespace: uptime-kuma
+namePrefix: uptime-kuma-
+
+commonLabels:
+ app: uptime-kuma
+
+bases:
+ - uptime-kuma
+
+
diff --git a/kubernetes/uptime-kuma/deployment.yml b/kubernetes/uptime-kuma/deployment.yml
new file mode 100644
index 0000000..a122509
--- /dev/null
+++ b/kubernetes/uptime-kuma/deployment.yml
@@ -0,0 +1,42 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ component: uptime-kuma
+ name: deployment
+spec:
+ selector:
+ matchLabels:
+ component: uptime-kuma
+ replicas: 1
+ strategy:
+ type: Recreate
+
+ template:
+ metadata:
+ labels:
+ component: uptime-kuma
+ spec:
+ containers:
+ - name: app
+ image: louislam/uptime-kuma:1
+ ports:
+ - containerPort: 3001
+ volumeMounts:
+ - mountPath: /app/data
+ name: storage
+ livenessProbe:
+ exec:
+ command:
+ - node
+ - extra/healthcheck.js
+ readinessProbe:
+ httpGet:
+ path: /
+ port: 3001
+ scheme: HTTP
+
+ volumes:
+ - name: storage
+ persistentVolumeClaim:
+ claimName: pvc
diff --git a/kubernetes/uptime-kuma/ingressroute.yml b/kubernetes/uptime-kuma/ingressroute.yml
new file mode 100644
index 0000000..71f7027
--- /dev/null
+++ b/kubernetes/uptime-kuma/ingressroute.yml
@@ -0,0 +1,39 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: nginx
+ cert-manager.io/cluster-issuer: letsencrypt-prod
+ nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
+ nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
+ nginx.ingress.kubernetes.io/server-snippets: |
+ location / {
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_http_version 1.1;
+ proxy_set_header X-Forwarded-Host $http_host;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_set_header Host $host;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_cache_bypass $http_upgrade;
+ }
+ name: ingress
+spec:
+ tls:
+ - hosts:
+ - example.com
+ secretName: example-com-tls
+ rules:
+ - host: example.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: service
+ port:
+ number: 3001
diff --git a/kubernetes/uptime-kuma/kustomization.yml b/kubernetes/uptime-kuma/kustomization.yml
new file mode 100644
index 0000000..638a2ab
--- /dev/null
+++ b/kubernetes/uptime-kuma/kustomization.yml
@@ -0,0 +1,5 @@
+resources:
+ - deployment.yml
+ - service.yml
+ - ingressroute.yml
+ - pvc.yml
\ No newline at end of file
diff --git a/kubernetes/uptime-kuma/pvc.yml b/kubernetes/uptime-kuma/pvc.yml
new file mode 100644
index 0000000..eda3b8b
--- /dev/null
+++ b/kubernetes/uptime-kuma/pvc.yml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: pvc
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 4Gi
diff --git a/kubernetes/uptime-kuma/service.yml b/kubernetes/uptime-kuma/service.yml
new file mode 100644
index 0000000..5fa812e
--- /dev/null
+++ b/kubernetes/uptime-kuma/service.yml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: service
+spec:
+ selector:
+ component: uptime-kuma
+ type: ClusterIP
+ ports:
+ - name: http
+ port: 3001
+ targetPort: 3001
+ protocol: TCP
diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png
new file mode 100644
index 0000000..8dae0df
Binary files /dev/null and b/public/apple-touch-icon-precomposed.png differ
diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png
index 0e9c109..f3c5854 100644
Binary files a/public/apple-touch-icon.png and b/public/apple-touch-icon.png differ
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..dedf0cd
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/robots.txt b/public/robots.txt
deleted file mode 100644
index e9e57dc..0000000
--- a/public/robots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# https://www.robotstxt.org/robotstxt.html
-User-agent: *
-Disallow:
diff --git a/server/check-version.js b/server/check-version.js
new file mode 100644
index 0000000..96e8aec
--- /dev/null
+++ b/server/check-version.js
@@ -0,0 +1,44 @@
+const { setSetting } = require("./util-server");
+const axios = require("axios");
+const { isDev } = require("../src/util");
+
+exports.version = require("../package.json").version;
+exports.latestVersion = null;
+
+let interval;
+
+exports.startInterval = () => {
+ let check = async () => {
+ try {
+ const res = await axios.get("https://raw.githubusercontent.com/louislam/uptime-kuma/master/package.json");
+
+ if (typeof res.data === "string") {
+ res.data = JSON.parse(res.data);
+ }
+
+ // For debug
+ if (process.env.TEST_CHECK_VERSION === "1") {
+ res.data.version = "1000.0.0"
+ }
+
+ exports.latestVersion = res.data.version;
+ console.log("Latest Version: " + exports.latestVersion);
+ } catch (_) { }
+
+ };
+
+ check();
+ interval = setInterval(check, 3600 * 1000 * 48);
+};
+
+exports.enableCheckUpdate = async (value) => {
+ await setSetting("checkUpdate", value);
+
+ clearInterval(interval);
+
+ if (value) {
+ exports.startInterval();
+ }
+};
+
+exports.socket = null;
diff --git a/server/database.js b/server/database.js
index 04f764e..9b83fe7 100644
--- a/server/database.js
+++ b/server/database.js
@@ -1,16 +1,45 @@
const fs = require("fs");
-const { sleep } = require("../src/util");
const { R } = require("redbean-node");
-const {
- setSetting, setting,
-} = require("./util-server");
+const { setSetting, setting } = require("./util-server");
class Database {
static templatePath = "./db/kuma.db"
static path = "./data/kuma.db";
- static latestVersion = 4;
+ static latestVersion = 6;
static noReject = true;
+ static sqliteInstance = null;
+
+ static async connect() {
+ const acquireConnectionTimeout = 120 * 1000;
+
+ R.useBetterSQLite3 = true;
+ R.betterSQLite3Options.timeout = acquireConnectionTimeout;
+
+ R.setup("sqlite", {
+ filename: Database.path,
+ useNullAsDefault: true,
+ acquireConnectionTimeout: acquireConnectionTimeout,
+ }, {
+ min: 1,
+ max: 1,
+ idleTimeoutMillis: 120 * 1000,
+ propagateCreateError: false,
+ acquireTimeoutMillis: acquireConnectionTimeout,
+ });
+
+ 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");
+
+ // Change to WAL
+ await R.exec("PRAGMA journal_mode = WAL");
+ console.log(await R.getAll("PRAGMA journal_mode"));
+ }
static async patch() {
let version = parseInt(await setting("database_version"));
@@ -24,6 +53,8 @@ class Database {
if (version === this.latestVersion) {
console.info("Database no need to patch");
+ } else if (version > this.latestVersion) {
+ console.info("Warning: Database version is newer than expected");
} else {
console.info("Database patch is needed")
@@ -31,6 +62,16 @@ class Database {
const backupPath = "./data/kuma.db.bak" + version;
fs.copyFileSync(Database.path, backupPath);
+ const shmPath = Database.path + "-shm";
+ if (fs.existsSync(shmPath)) {
+ fs.copyFileSync(shmPath, shmPath + ".bak" + version);
+ }
+
+ const walPath = Database.path + "-wal";
+ if (fs.existsSync(walPath)) {
+ fs.copyFileSync(walPath, walPath + ".bak" + version);
+ }
+
// Try catch anything here, if gone wrong, restore the backup
try {
for (let i = version + 1; i <= this.latestVersion; i++) {
@@ -83,37 +124,27 @@ class Database {
return statement !== "";
})
+ // Use better-sqlite3 to run, prevent "This statement does not return data. Use run() instead"
+ const db = await this.getBetterSQLite3Database();
+
for (let statement of statements) {
- await R.exec(statement);
+ db.prepare(statement).run();
}
}
+ static getBetterSQLite3Database() {
+ return R.knex.client.acquireConnection();
+ }
+
/**
* Special handle, because tarn.js throw a promise reject that cannot be caught
* @returns {Promise}
*/
static async close() {
- const listener = (reason, p) => {
- Database.noReject = false;
- };
- process.addListener("unhandledRejection", listener);
-
- console.log("Closing DB")
-
- while (true) {
- Database.noReject = true;
- await R.close()
- await sleep(2000)
-
- if (Database.noReject) {
- break;
- } else {
- console.log("Waiting to close the db")
- }
+ if (this.sqliteInstance) {
+ this.sqliteInstance.close();
}
- console.log("SQLite closed")
-
- process.removeListener("unhandledRejection", listener);
+ console.log("Stopped database");
}
}
diff --git a/server/model/monitor.js b/server/model/monitor.js
index 49fcfb3..17ab277 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -6,11 +6,12 @@ dayjs.extend(utc)
dayjs.extend(timezone)
const axios = require("axios");
const { Prometheus } = require("../prometheus");
-const { debug, UP, DOWN, PENDING, flipStatus } = require("../../src/util");
-const { tcping, ping, checkCertificate } = require("../util-server");
+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");
const { Notification } = require("../notification")
+const version = require("../../package.json").version;
/**
* status:
@@ -45,6 +46,8 @@ class Monitor extends BeanModel {
keyword: this.keyword,
ignoreTls: this.getIgnoreTls(),
upsideDown: this.isUpsideDown(),
+ maxredirects: this.maxredirects,
+ accepted_statuscodes: this.getAcceptedStatuscodes(),
notificationIDList,
};
}
@@ -65,6 +68,10 @@ class Monitor extends BeanModel {
return Boolean(this.upsideDown);
}
+ getAcceptedStatuscodes() {
+ return JSON.parse(this.accepted_statuscodes_json);
+ }
+
start(io) {
let previousBeat = null;
let retries = 0;
@@ -73,6 +80,10 @@ class Monitor extends BeanModel {
const beat = async () => {
+ // Expose here for prometheus update
+ // undefined if not https
+ let tlsInfo = undefined;
+
if (! previousBeat) {
previousBeat = await R.findOne("heartbeat", " monitor_id = ? ORDER BY time DESC", [
this.id,
@@ -99,30 +110,36 @@ class Monitor extends BeanModel {
try {
if (this.type === "http" || this.type === "keyword") {
+ // Do not do any queries/high loading things before the "bean.ping"
let startTime = dayjs().valueOf();
- // Use Custom agent to disable session reuse
- // https://github.com/nodejs/node/issues/3940
let res = await axios.get(this.url, {
+ timeout: this.interval * 1000 * 0.8,
headers: {
- "User-Agent": "Uptime-Kuma",
+ "Accept": "*/*",
+ "User-Agent": "Uptime-Kuma/" + version,
},
httpsAgent: new https.Agent({
- maxCachedSessions: 0,
+ maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
rejectUnauthorized: ! this.getIgnoreTls(),
}),
+ maxRedirects: this.maxredirects,
+ validateStatus: (status) => {
+ return checkStatusCode(status, this.getAcceptedStatuscodes());
+ },
});
bean.msg = `${res.status} - ${res.statusText}`
bean.ping = dayjs().valueOf() - startTime;
// Check certificate if https is used
-
let certInfoStartTime = dayjs().valueOf();
if (this.getUrl()?.protocol === "https:") {
try {
- await this.updateTlsInfo(checkCertificate(res));
+ tlsInfo = await this.updateTlsInfo(checkCertificate(res));
} catch (e) {
- console.error(e.message)
+ if (e.message !== "No TLS certificate in response") {
+ console.error(e.message)
+ }
}
}
@@ -223,7 +240,8 @@ class Monitor extends BeanModel {
try {
await Notification.send(JSON.parse(notification.config), msg, await this.toJSON(), bean.toJSON())
} catch (e) {
- console.error("Cannot send notification to " + notification.name)
+ console.error("Cannot send notification to " + notification.name);
+ console.log(e);
}
}
}
@@ -240,22 +258,22 @@ class Monitor extends BeanModel {
console.warn(`Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Type: ${this.type}`)
}
- prometheus.update(bean)
-
io.to(this.user_id).emit("heartbeat", bean.toJSON());
-
- await R.store(bean)
Monitor.sendStats(io, this.id, this.user_id)
+ await R.store(bean);
+ prometheus.update(bean, tlsInfo);
+
previousBeat = bean;
+
+ this.heartbeatInterval = setTimeout(beat, this.interval * 1000);
}
beat();
- this.heartbeatInterval = setInterval(beat, this.interval * 1000);
}
stop() {
- clearInterval(this.heartbeatInterval)
+ clearTimeout(this.heartbeatInterval);
}
/**
@@ -275,7 +293,7 @@ class Monitor extends BeanModel {
/**
* Store TLS info to database
* @param checkCertificateResult
- * @returns {Promise}
+ * @returns {Promise