From 331027c89628181f770c6e9f85f2d9991c7662a0 Mon Sep 17 00:00:00 2001 From: Rick van Drongelen Date: Mon, 19 May 2025 12:11:16 +0200 Subject: [PATCH 1/4] feat #680: Add tags to prometheus labels From ed1b696d5bd15150dc2aa93b0b43f2d9e1c3755f Mon Sep 17 00:00:00 2001 From: Rick van Drongelen Date: Mon, 19 May 2025 12:34:30 +0200 Subject: [PATCH 2/4] Added monitor_tags to the prometheus metrics. --- server/model/monitor.js | 2 +- server/prometheus.js | 40 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/server/model/monitor.js b/server/model/monitor.js index 85293bbdc..1a066d162 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -328,7 +328,7 @@ class Monitor extends BeanModel { let previousBeat = null; let retries = 0; - this.prometheus = new Prometheus(this); + this.prometheus = new Prometheus(this, await this.getTags()); const beat = async () => { diff --git a/server/prometheus.js b/server/prometheus.js index f26125d2c..ad93bd634 100644 --- a/server/prometheus.js +++ b/server/prometheus.js @@ -7,6 +7,7 @@ const commonLabels = [ "monitor_url", "monitor_hostname", "monitor_port", + "monitor_tags" ]; const monitorCertDaysRemaining = new PrometheusClient.Gauge({ @@ -37,17 +38,51 @@ class Prometheus { /** * @param {object} monitor Monitor object to monitor + * @param {Array} tags Tags to add to the monitor */ - constructor(monitor) { + constructor(monitor, tags) { + let sanitizedTags = this.sanitizeTags(tags); + + if (sanitizedTags.length <= 0) { + sanitizedTags = "null"; + } + this.monitorLabelValues = { monitor_name: monitor.name, monitor_type: monitor.type, monitor_url: monitor.url, monitor_hostname: monitor.hostname, - monitor_port: monitor.port + monitor_port: monitor.port, + monitor_tags: sanitizedTags }; } + /** + * Sanitize tags to remove non-ASCII characters + * See https://github.com/louislam/uptime-kuma/pull/4704#issuecomment-2366524692 + * @param {Array} tags The tags to sanitize + * @returns {*[]} The sanitized tags + */ + sanitizeTags(tags) { + const nonAsciiRegex = /[^\x00-\x7F]/g; + const sanitizedTags = []; + tags.forEach((tag) => { + if (tag.name.match(nonAsciiRegex) || tag.value.match(nonAsciiRegex)) { + // If the tag name or value contains non-ASCII characters, skip it + return; + } + + if (tag.value !== "") { + sanitizedTags.push(tag.name + ":" + tag.value); + return; + } + + sanitizedTags.push(tag.name); + }); + + return sanitizedTags; + } + /** * Update the metrics page * @param {object} heartbeat Heartbeat details @@ -55,7 +90,6 @@ class Prometheus { * @returns {void} */ update(heartbeat, tlsInfo) { - if (typeof tlsInfo !== "undefined") { try { let isValid; From 536621234786940acd5195940943b98a91c84295 Mon Sep 17 00:00:00 2001 From: Rick van Drongelen Date: Wed, 21 May 2025 12:43:47 +0200 Subject: [PATCH 3/4] Reworked non-ascii tag filtering for prometheus metrics --- server/prometheus.js | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/server/prometheus.js b/server/prometheus.js index ad93bd634..34646d6c7 100644 --- a/server/prometheus.js +++ b/server/prometheus.js @@ -41,10 +41,10 @@ class Prometheus { * @param {Array} tags Tags to add to the monitor */ constructor(monitor, tags) { - let sanitizedTags = this.sanitizeTags(tags); + let filteredValidAsciiTags = this.filterValidAsciiTags(tags); - if (sanitizedTags.length <= 0) { - sanitizedTags = "null"; + if (filteredValidAsciiTags.length <= 0) { + filteredValidAsciiTags = "null"; } this.monitorLabelValues = { @@ -53,34 +53,28 @@ class Prometheus { monitor_url: monitor.url, monitor_hostname: monitor.hostname, monitor_port: monitor.port, - monitor_tags: sanitizedTags + monitor_tags: filteredValidAsciiTags }; } /** - * Sanitize tags to remove non-ASCII characters + * Filter tags to remove the ones that contain non-ASCII characters * See https://github.com/louislam/uptime-kuma/pull/4704#issuecomment-2366524692 - * @param {Array} tags The tags to sanitize - * @returns {*[]} The sanitized tags + * @param {Array<{name: string, value:string}>} tags The tags to filter + * @returns {string[]} The filtered tags */ - sanitizeTags(tags) { - const nonAsciiRegex = /[^\x00-\x7F]/g; - const sanitizedTags = []; - tags.forEach((tag) => { - if (tag.name.match(nonAsciiRegex) || tag.value.match(nonAsciiRegex)) { - // If the tag name or value contains non-ASCII characters, skip it - return; + filterValidAsciiTags(tags) { + const asciiRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/; + return tags.reduce((filteredTags, tag) => { + if (asciiRegex.test(tag.name)) { + if (tag.value !== "" && asciiRegex.test(tag.value)) { + filteredTags.push(`${tag.name}:${tag.value}`); + } else { + filteredTags.push(tag.name); + } } - - if (tag.value !== "") { - sanitizedTags.push(tag.name + ":" + tag.value); - return; - } - - sanitizedTags.push(tag.name); - }); - - return sanitizedTags; + return filteredTags; + }, []); } /** From 4a5fe2145c9170c63c28e5277b17596422451cf6 Mon Sep 17 00:00:00 2001 From: Rick van Drongelen Date: Wed, 21 May 2025 13:09:02 +0200 Subject: [PATCH 4/4] Fixed jsdoc type --- server/prometheus.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/prometheus.js b/server/prometheus.js index 34646d6c7..d81e5d0ab 100644 --- a/server/prometheus.js +++ b/server/prometheus.js @@ -38,7 +38,7 @@ class Prometheus { /** * @param {object} monitor Monitor object to monitor - * @param {Array} tags Tags to add to the monitor + * @param {Array<{name:string,value:?string}>} tags Tags to add to the monitor */ constructor(monitor, tags) { let filteredValidAsciiTags = this.filterValidAsciiTags(tags); @@ -60,7 +60,7 @@ class Prometheus { /** * Filter tags to remove the ones that contain non-ASCII characters * See https://github.com/louislam/uptime-kuma/pull/4704#issuecomment-2366524692 - * @param {Array<{name: string, value:string}>} tags The tags to filter + * @param {Array<{name: string, value:?string}>} tags The tags to filter * @returns {string[]} The filtered tags */ filterValidAsciiTags(tags) {