added sqlserver monitor

This commit is contained in:
Christopher Pickering 2022-05-12 12:48:03 -05:00
parent 332b9ab248
commit 87f933df4f
No known key found for this signature in database
GPG key ID: E14DB3B0A0FACF84
9 changed files with 1796 additions and 42 deletions

View 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

File diff suppressed because it is too large Load diff

View file

@ -92,6 +92,7 @@
"jwt-decode": "^3.1.2",
"limiter": "^2.1.0",
"mqtt": "^4.2.8",
"mssql": "^8.1.0",
"node-cloudflared-tunnel": "~1.0.9",
"nodemailer": "~6.6.5",
"notp": "~2.0.3",

View file

@ -58,6 +58,7 @@ class Database {
"patch-monitor-expiry-notification.sql": true,
"patch-status-page-footer-css.sql": true,
"patch-added-mqtt-monitor.sql": true,
"patch-add-sqlserver-monitor.sql": true,
};
/**

View file

@ -7,7 +7,7 @@ dayjs.extend(timezone);
const axios = require("axios");
const { Prometheus } = require("../prometheus");
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 { BeanModel } = require("redbean-node/dist/bean-model");
const { Notification } = require("../notification");
@ -87,7 +87,9 @@ class Monitor extends BeanModel {
mqttUsername: this.mqttUsername,
mqttPassword: this.mqttPassword,
mqttTopic: this.mqttTopic,
mqttSuccessMessage: this.mqttSuccessMessage
mqttSuccessMessage: this.mqttSuccessMessage,
databaseConnectionString: this.databaseConnectionString,
databaseQuery: this.databaseQuery
};
if (includeSensitiveData) {
@ -435,6 +437,14 @@ class Monitor extends BeanModel {
interval: this.interval,
});
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 {
bean.msg = "Unknown Monitor Type";
bean.status = PENDING;

View file

@ -674,6 +674,8 @@ try {
bean.mqttPassword = monitor.mqttPassword;
bean.mqttTopic = monitor.mqttTopic;
bean.mqttSuccessMessage = monitor.mqttSuccessMessage;
bean.databaseConnectionString = monitor.databaseConnectionString;
bean.databaseQuery = monitor.databaseQuery;
await R.store(bean);

View file

@ -10,6 +10,7 @@ const chardet = require("chardet");
const mqtt = require("mqtt");
const chroma = require("chroma-js");
const { badgeConstants } = require("./config");
const sql = require("mssql");
// From ping-lite
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
* @param {string} key Key of setting to retrieve

View file

@ -464,4 +464,6 @@ export default {
"Domain Names": "Domain Names",
signedInDisp: "Signed in as {0}",
signedInDispDisabled: "Auth Disabled.",
"Connection String": "Connection String",
"Query": "Query",
};

View file

@ -35,6 +35,9 @@
<option value="mqtt">
MQTT
</option>
<option value="sqlserver">
SQL Server
</option>
</select>
</div>
@ -148,6 +151,18 @@
</div>
</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 -->
<div class="my-3">
<label for="interval" class="form-label">{{ $t("Heartbeat Interval") }} ({{ $t("checkEverySecond", [ monitor.interval ]) }})</label>