Skip to content

fix(metrics): sanitize metric label names in OpenMetrics output#59255

Merged
Altahrim merged 1 commit intonextcloud:masterfrom
moktamd:fix/metrics-escape-label-names
Apr 7, 2026
Merged

fix(metrics): sanitize metric label names in OpenMetrics output#59255
Altahrim merged 1 commit intonextcloud:masterfrom
moktamd:fix/metrics-escape-label-names

Conversation

@moktamd
Copy link
Copy Markdown
Contributor

@moktamd moktamd commented Mar 27, 2026

Fixes #59247

Apps with hyphens in their name (e.g. hide-photos) produce invalid OpenMetrics label names, causing Prometheus to reject the entire scrape. Label names must match [a-zA-Z_][a-zA-Z0-9_]* per the spec.

Sanitizes label names in formatLabels() by replacing non-alphanumeric characters with underscores, so hide-photos becomes hide_photos.

@moktamd moktamd requested a review from a team as a code owner March 27, 2026 14:17
@moktamd moktamd requested review from ArtificialOwl, come-nc, leftybournes and salmart-dev and removed request for a team March 27, 2026 14:18
@joshtrichards
Copy link
Copy Markdown
Member

Hi @moktamd -

Thanks for looking into this.

I didn't think we allowed - (dash) in app ids:

https://nextcloudappstore.readthedocs.io/en/latest/developer.html#info-xml

I wonder where it's getting through for this app. I don't see it in the app store.

@joshtrichards joshtrichards added bug 3. to review Waiting for reviews labels Mar 28, 2026
@joshtrichards joshtrichards added this to the Nextcloud 34 milestone Mar 28, 2026
@joshtrichards joshtrichards changed the title fix(metrics): sanitize label names in OpenMetrics output fix(metrics): sanitize metric label names in OpenMetrics output Mar 29, 2026
@joshtrichards joshtrichards requested a review from Altahrim March 29, 2026 14:35
@ainola
Copy link
Copy Markdown

ainola commented Mar 31, 2026

I believe I had installed it manually from https://github.com/matiasdelellis/hide-photos/

@Altahrim
Copy link
Copy Markdown
Collaborator

Hello @moktamd,

Thank you for your PR :)

I have the feeling it mainly hides the issue. I would prefer to ensure labels are always valid.
What do you think of something like that?

In lib/public/OpenMetrics/Metric.php ensure labels are always valid:

@@ -19,9 +19,18 @@ final readonly class Metric {
 		public array $labels = [],
 		public int|float|null $timestamp = null,
 	) {
+		$this->validateLabels();
 	}

 	public function label(string $name): ?string {
 		return $this->labels[$name] ?? null;
 	}
+
+	private function validateLabels(): void {
+		foreach ($this->labels as $label => $_value) {
+			if (preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $label) === false) {
+				throw new \Exception('Invalid label "' . $label . '"');
+			}
+		}
+	}
 }

In lib/private/OpenMetrics/Exporters/AppsInfo.php, fix the actual issue:

@@ -47,10 +47,11 @@ class AppsInfo implements IMetricFamily {

 	#[Override]
 	public function metrics(): Generator {
-		yield new Metric(
-			1,
-			$this->appManager->getAppInstalledVersions(true),
-			time()
-		);
+		$apps = $this->appManager->getAppInstalledVersions(true);
+		foreach ($apps as $label => $_version) {
+			// Some custom apps use - instead of _ as separator
+			$label = str_replace('-', '_', $label);
+		}
+		yield new Metric(1, $apps, time());
 	}
 }

@moktamd
Copy link
Copy Markdown
Contributor Author

moktamd commented Mar 31, 2026

Thanks @Altahrim — good call, moved the fix per your suggestion:

  • Metric.php: Added validateLabels() in the constructor that throws InvalidArgumentException for invalid label names
  • AppsInfo.php: Sanitize app IDs at the source by replacing hyphens with underscores before creating the Metric
  • Controller: Reverted the render-time sanitization — labels are now guaranteed valid at construction
  • Updated tests accordingly
  • Added Signed-off-by for DCO

Add validation in the Metric constructor that rejects invalid
OpenMetrics label names with InvalidArgumentException. Sanitize
app IDs at the source in AppsInfo by replacing hyphens with
underscores before creating the Metric.

Fixes nextcloud#59247

Signed-off-by: moktamd <moktamd@users.noreply.github.com>
@moktamd moktamd force-pushed the fix/metrics-escape-label-names branch from 7162cc4 to 1c33307 Compare March 31, 2026 11:20
@Altahrim Altahrim merged commit 83e464c into nextcloud:master Apr 7, 2026
167 of 172 checks passed
@welcome
Copy link
Copy Markdown

welcome Bot commented Apr 7, 2026

Thanks for your first pull request and welcome to the community! Feel free to keep them coming! If you are looking for issues to tackle then have a look at this selection: https://github.com/nextcloud/server/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22

@github-actions
Copy link
Copy Markdown
Contributor

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: /metrics endpoint does not escape hyphens

5 participants