mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-01-13 06:48:02 -08:00
added sqlserver monitor
This commit is contained in:
parent
332b9ab248
commit
87f933df4f
10
db/patch-add-sqlserver-monitor.sql
Normal file
10
db/patch-add-sqlserver-monitor.sql
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
ALTER TABLE monitor
|
||||||
|
ADD database_connection_string VARCHAR(2000);
|
||||||
|
|
||||||
|
ALTER TABLE monitor
|
||||||
|
ADD database_query TEXT;
|
||||||
|
|
||||||
|
|
||||||
|
COMMIT
|
1768
package-lock.json
generated
1768
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -92,6 +92,7 @@
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"limiter": "^2.1.0",
|
"limiter": "^2.1.0",
|
||||||
"mqtt": "^4.2.8",
|
"mqtt": "^4.2.8",
|
||||||
|
"mssql": "^8.1.0",
|
||||||
"node-cloudflared-tunnel": "~1.0.9",
|
"node-cloudflared-tunnel": "~1.0.9",
|
||||||
"nodemailer": "~6.6.5",
|
"nodemailer": "~6.6.5",
|
||||||
"notp": "~2.0.3",
|
"notp": "~2.0.3",
|
||||||
|
|
|
@ -58,6 +58,7 @@ class Database {
|
||||||
"patch-monitor-expiry-notification.sql": true,
|
"patch-monitor-expiry-notification.sql": true,
|
||||||
"patch-status-page-footer-css.sql": true,
|
"patch-status-page-footer-css.sql": true,
|
||||||
"patch-added-mqtt-monitor.sql": true,
|
"patch-added-mqtt-monitor.sql": true,
|
||||||
|
"patch-add-sqlserver-monitor.sql": true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,7 +7,7 @@ dayjs.extend(timezone);
|
||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
const { Prometheus } = require("../prometheus");
|
const { Prometheus } = require("../prometheus");
|
||||||
const { log, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/util");
|
const { log, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/util");
|
||||||
const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mqttAsync } = require("../util-server");
|
const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, sqlserver, mqttAsync } = require("../util-server");
|
||||||
const { R } = require("redbean-node");
|
const { R } = require("redbean-node");
|
||||||
const { BeanModel } = require("redbean-node/dist/bean-model");
|
const { BeanModel } = require("redbean-node/dist/bean-model");
|
||||||
const { Notification } = require("../notification");
|
const { Notification } = require("../notification");
|
||||||
|
@ -87,7 +87,9 @@ class Monitor extends BeanModel {
|
||||||
mqttUsername: this.mqttUsername,
|
mqttUsername: this.mqttUsername,
|
||||||
mqttPassword: this.mqttPassword,
|
mqttPassword: this.mqttPassword,
|
||||||
mqttTopic: this.mqttTopic,
|
mqttTopic: this.mqttTopic,
|
||||||
mqttSuccessMessage: this.mqttSuccessMessage
|
mqttSuccessMessage: this.mqttSuccessMessage,
|
||||||
|
databaseConnectionString: this.databaseConnectionString,
|
||||||
|
databaseQuery: this.databaseQuery
|
||||||
};
|
};
|
||||||
|
|
||||||
if (includeSensitiveData) {
|
if (includeSensitiveData) {
|
||||||
|
@ -435,6 +437,14 @@ class Monitor extends BeanModel {
|
||||||
interval: this.interval,
|
interval: this.interval,
|
||||||
});
|
});
|
||||||
bean.status = UP;
|
bean.status = UP;
|
||||||
|
} else if (this.type === "sqlserver") {
|
||||||
|
let startTime = dayjs().valueOf();
|
||||||
|
|
||||||
|
await sqlserver(this.databaseConnectionString, this.databaseQuery);
|
||||||
|
|
||||||
|
bean.msg = "";
|
||||||
|
bean.status = UP;
|
||||||
|
bean.ping = dayjs().valueOf() - startTime;
|
||||||
} else {
|
} else {
|
||||||
bean.msg = "Unknown Monitor Type";
|
bean.msg = "Unknown Monitor Type";
|
||||||
bean.status = PENDING;
|
bean.status = PENDING;
|
||||||
|
|
|
@ -674,6 +674,8 @@ try {
|
||||||
bean.mqttPassword = monitor.mqttPassword;
|
bean.mqttPassword = monitor.mqttPassword;
|
||||||
bean.mqttTopic = monitor.mqttTopic;
|
bean.mqttTopic = monitor.mqttTopic;
|
||||||
bean.mqttSuccessMessage = monitor.mqttSuccessMessage;
|
bean.mqttSuccessMessage = monitor.mqttSuccessMessage;
|
||||||
|
bean.databaseConnectionString = monitor.databaseConnectionString;
|
||||||
|
bean.databaseQuery = monitor.databaseQuery;
|
||||||
|
|
||||||
await R.store(bean);
|
await R.store(bean);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ const chardet = require("chardet");
|
||||||
const mqtt = require("mqtt");
|
const mqtt = require("mqtt");
|
||||||
const chroma = require("chroma-js");
|
const chroma = require("chroma-js");
|
||||||
const { badgeConstants } = require("./config");
|
const { badgeConstants } = require("./config");
|
||||||
|
const sql = require("mssql");
|
||||||
|
|
||||||
// From ping-lite
|
// From ping-lite
|
||||||
exports.WIN = /^win/.test(process.platform);
|
exports.WIN = /^win/.test(process.platform);
|
||||||
|
@ -203,6 +204,30 @@ exports.dnsResolve = function (hostname, resolverServer, rrtype) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a query on SQL Server
|
||||||
|
* @param {string} connectionString The database connection string
|
||||||
|
* @param {string} query The query to validate the database with
|
||||||
|
* @returns {Promise<(string[]|Object[]|Object)>}
|
||||||
|
*/
|
||||||
|
exports.sqlserver = function (connectionString, query) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
sql.on("error", err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
sql.connect(connectionString).then(pool => {
|
||||||
|
|
||||||
|
return pool.request()
|
||||||
|
.query(query);
|
||||||
|
}).then(result => {
|
||||||
|
resolve(result);
|
||||||
|
}).catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve value of setting based on key
|
* Retrieve value of setting based on key
|
||||||
* @param {string} key Key of setting to retrieve
|
* @param {string} key Key of setting to retrieve
|
||||||
|
|
|
@ -464,4 +464,6 @@ export default {
|
||||||
"Domain Names": "Domain Names",
|
"Domain Names": "Domain Names",
|
||||||
signedInDisp: "Signed in as {0}",
|
signedInDisp: "Signed in as {0}",
|
||||||
signedInDispDisabled: "Auth Disabled.",
|
signedInDispDisabled: "Auth Disabled.",
|
||||||
|
"Connection String": "Connection String",
|
||||||
|
"Query": "Query",
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
<option value="mqtt">
|
<option value="mqtt">
|
||||||
MQTT
|
MQTT
|
||||||
</option>
|
</option>
|
||||||
|
<option value="sqlserver">
|
||||||
|
SQL Server
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -148,6 +151,18 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- SQL Server -->
|
||||||
|
<template v-if="monitor.type === 'sqlserver'">
|
||||||
|
<div class="my-3">
|
||||||
|
<label for="sqlserverConnectionString" class="form-label">SQL Server {{ $t("Connection String") }}</label>
|
||||||
|
<input id="sqlserverConnectionString" v-model="monitor.databaseConnectionString" type="text" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="my-3">
|
||||||
|
<label for="sqlserverQuery" class="form-label">SQL Server {{ $t("Query") }}</label>
|
||||||
|
<textarea id="sqlserverQuery" v-model="monitor.databaseQuery" class="form-control" placeholder="Example: select getdate()"></textarea>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- Interval -->
|
<!-- Interval -->
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
<label for="interval" class="form-label">{{ $t("Heartbeat Interval") }} ({{ $t("checkEverySecond", [ monitor.interval ]) }})</label>
|
<label for="interval" class="form-label">{{ $t("Heartbeat Interval") }} ({{ $t("checkEverySecond", [ monitor.interval ]) }})</label>
|
||||||
|
|
Loading…
Reference in a new issue