Skip to content

Commit

Permalink
Revert "Extend Prometheus Labels to include tags (requires restart fo…
Browse files Browse the repository at this point in the history
…r NEW labels on the monitor to be visible)" (#5174)
  • Loading branch information
louislam authored Oct 8, 2024
1 parent 59e70cb commit 4829ad8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 110 deletions.
4 changes: 2 additions & 2 deletions server/model/monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ class Monitor extends BeanModel {
let previousBeat = null;
let retries = 0;

this.prometheus = await Prometheus.createAndInitMetrics(this);
this.prometheus = new Prometheus(this);

const beat = async () => {

Expand Down Expand Up @@ -978,7 +978,7 @@ class Monitor extends BeanModel {
await R.store(bean);

log.debug("monitor", `[${this.name}] prometheus.update`);
await this.prometheus?.update(bean, tlsInfo);
this.prometheus?.update(bean, tlsInfo);

previousBeat = bean;

Expand Down
144 changes: 36 additions & 108 deletions server/prometheus.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const { R } = require("redbean-node");
const PrometheusClient = require("prom-client");
const { log } = require("../src/util");

Expand All @@ -10,115 +9,43 @@ const commonLabels = [
"monitor_port",
];

class Prometheus {

/**
* Metric: monitor_cert_days_remaining
* @type {PrometheusClient.Gauge<string> | null}
*/
static monitorCertDaysRemaining = null;

/**
* Metric: monitor_cert_is_valid
* @type {PrometheusClient.Gauge<string> | null}
*/
static monitorCertIsValid = null;

/**
* Metric: monitor_response_time
* @type {PrometheusClient.Gauge<string> | null}
*/
static monitorResponseTime = null;

/**
* Metric: monitor_status
* @type {PrometheusClient.Gauge<string> | null}
*/
static monitorStatus = null;

/**
* All registered metric labels.
* @type {string[] | null}
*/
static monitorLabelNames = null;

/**
* Monitor labels/values combination.
* @type {{}}
*/
monitorLabelValues;
const monitorCertDaysRemaining = new PrometheusClient.Gauge({
name: "monitor_cert_days_remaining",
help: "The number of days remaining until the certificate expires",
labelNames: commonLabels
});

const monitorCertIsValid = new PrometheusClient.Gauge({
name: "monitor_cert_is_valid",
help: "Is the certificate still valid? (1 = Yes, 0= No)",
labelNames: commonLabels
});
const monitorResponseTime = new PrometheusClient.Gauge({
name: "monitor_response_time",
help: "Monitor Response Time (ms)",
labelNames: commonLabels
});

const monitorStatus = new PrometheusClient.Gauge({
name: "monitor_status",
help: "Monitor Status (1 = UP, 0= DOWN, 2= PENDING, 3= MAINTENANCE)",
labelNames: commonLabels
});

/**
* Initialize metrics and get all label names the first time called.
* @returns {void}
*/
static async initMetrics() {
if (!this.monitorLabelNames) {
let labelNames = await R.getCol("SELECT name FROM tag");
this.monitorLabelNames = [ ...commonLabels, ...labelNames ];
}
if (!this.monitorCertDaysRemaining) {
this.monitorCertDaysRemaining = new PrometheusClient.Gauge({
name: "monitor_cert_days_remaining",
help: "The number of days remaining until the certificate expires",
labelNames: this.monitorLabelNames
});
}
if (!this.monitorCertIsValid) {
this.monitorCertIsValid = new PrometheusClient.Gauge({
name: "monitor_cert_is_valid",
help: "Is the certificate still valid? (1 = Yes, 0 = No)",
labelNames: this.monitorLabelNames
});
}
if (!this.monitorResponseTime) {
this.monitorResponseTime = new PrometheusClient.Gauge({
name: "monitor_response_time",
help: "Monitor Response Time (ms)",
labelNames: this.monitorLabelNames
});
}
if (!this.monitorStatus) {
this.monitorStatus = new PrometheusClient.Gauge({
name: "monitor_status",
help: "Monitor Status (1 = UP, 0 = DOWN, 2 = PENDING, 3 = MAINTENANCE)",
labelNames: this.monitorLabelNames
});
}
}

/**
* Wrapper to create a `Prometheus` instance and ensure metrics are initialized.
* @param {Monitor} monitor Monitor object to monitor
* @returns {Promise<Prometheus>} `Prometheus` instance
*/
static async createAndInitMetrics(monitor) {
await Prometheus.initMetrics();
let tags = await monitor.getTags();
return new Prometheus(monitor, tags);
}
class Prometheus {
monitorLabelValues = {};

/**
* Creates a prometheus metric instance.
*
* Note: Make sure to call `Prometheus.initMetrics()` once prior creating Prometheus instances.
* @param {Monitor} monitor Monitor object to monitor
* @param {Promise<LooseObject<any>[]>} tags Tags of the monitor
* @param {object} monitor Monitor object to monitor
*/
constructor(monitor, tags) {
constructor(monitor) {
this.monitorLabelValues = {
monitor_name: monitor.name,
monitor_type: monitor.type,
monitor_url: monitor.url,
monitor_hostname: monitor.hostname,
monitor_port: monitor.port
};
Object.values(tags)
// only label names that were known at first metric creation.
.filter(tag => Prometheus.monitorLabelNames.includes(tag.name))
.forEach(tag => {
this.monitorLabelValues[tag.name] = tag.value;
});
}

/**
Expand All @@ -128,6 +55,7 @@ class Prometheus {
* @returns {void}
*/
update(heartbeat, tlsInfo) {

if (typeof tlsInfo !== "undefined") {
try {
let isValid;
Expand All @@ -136,15 +64,15 @@ class Prometheus {
} else {
isValid = 0;
}
Prometheus.monitorCertIsValid.set(this.monitorLabelValues, isValid);
monitorCertIsValid.set(this.monitorLabelValues, isValid);
} catch (e) {
log.error("prometheus", "Caught error");
log.error("prometheus", e);
}

try {
if (tlsInfo.certInfo != null) {
Prometheus.monitorCertDaysRemaining.set(this.monitorLabelValues, tlsInfo.certInfo.daysRemaining);
monitorCertDaysRemaining.set(this.monitorLabelValues, tlsInfo.certInfo.daysRemaining);
}
} catch (e) {
log.error("prometheus", "Caught error");
Expand All @@ -154,18 +82,18 @@ class Prometheus {

if (heartbeat) {
try {
Prometheus.monitorStatus.set(this.monitorLabelValues, heartbeat.status);
monitorStatus.set(this.monitorLabelValues, heartbeat.status);
} catch (e) {
log.error("prometheus", "Caught error");
log.error("prometheus", e);
}

try {
if (typeof heartbeat.ping === "number") {
Prometheus.monitorResponseTime.set(this.monitorLabelValues, heartbeat.ping);
monitorResponseTime.set(this.monitorLabelValues, heartbeat.ping);
} else {
// Is it good?
Prometheus.monitorResponseTime.set(this.monitorLabelValues, -1);
monitorResponseTime.set(this.monitorLabelValues, -1);
}
} catch (e) {
log.error("prometheus", "Caught error");
Expand All @@ -180,10 +108,10 @@ class Prometheus {
*/
remove() {
try {
Prometheus.monitorCertDaysRemaining?.remove(this.monitorLabelValues);
Prometheus.monitorCertIsValid?.remove(this.monitorLabelValues);
Prometheus.monitorResponseTime?.remove(this.monitorLabelValues);
Prometheus.monitorStatus?.remove(this.monitorLabelValues);
monitorCertDaysRemaining.remove(this.monitorLabelValues);
monitorCertIsValid.remove(this.monitorLabelValues);
monitorResponseTime.remove(this.monitorLabelValues);
monitorStatus.remove(this.monitorLabelValues);
} catch (e) {
console.error(e);
}
Expand Down

0 comments on commit 4829ad8

Please sign in to comment.