⚙️ Expose Google Sheet KPIs as Prometheus metrics for Grafana

⚡ 22 views · ⚙️ DevOps & CI/CD

Description

Quick overview

This workflow exposes KPI values stored in a Google Sheet as a Prometheus text exposition endpoint via an n8n webhook, so Grafana can scrape and chart them, with caching, validation, and built-in exporter health metrics.

How it works

  1. Receives a Prometheus scrape request via an n8n webhook secured with header authentication.
  2. Checks an in-workflow cache and immediately returns the cached Prometheus exposition text if it is still within the configured TTL.
  3. If the cache is stale, reads metric rows from a specified Google Sheets document and tab.
  4. Validates and normalizes each row (metric name, type, numeric value, and labels), dropping malformed, duplicate, or over-limit series and tracking reasons as comments/metadata.
  5. Renders the valid rows into Prometheus 0.0.4 text format, saves the result back into the cache, and appends exporter self-metrics (including up status, cache hit/age, and row/series counts).
  6. Returns the final metrics body as plain text to Prometheus, optionally serving a stale cached body and/or a configurable HTTP status code if the sheet read fails.

Setup

  1. Add a Google Sheets credential and ensure the target spreadsheet has columns named metric_name, help, type, value, and labels.
  2. In the exporter configuration, set the Google Sheet ID and tab name (and adjust cache_ttl_seconds, max_series, exporter_prefix, and error behavior as needed).
  3. Configure webhook header authentication (Authorization: Bearer ) and change the webhook path from metrics-CHANGEME to an unguessable value.
  4. Activate the workflow, copy the production webhook URL, and add it as a scrape target in Prometheus (and then Grafana) using the same bearer token.

Requirements

Customization

Additional info

This is built for slow-moving values a person maintains, things like SLO targets, license counts, contracted headcount or a manually counted backlog, rather than for high-frequency telemetry, and the recommended scrape_interval is 60s rather than the usual 15s: a human-edited spreadsheet does not change faster than that, and at 15s the endpoint runs 5,760 executions a day, which on n8n Cloud consumes a plan’s monthly allowance in under a day and stops every other workflow on the account. Two behaviours are worth knowing before building dashboards on it. Prometheus renames any job or instance label coming from the sheet to exported_job and exported_instance under the default honor_labels setting, so the sheet can look correct while your PromQL matches nothing; the workflow flags this through sheet_exporter_warnings rather than rejecting the row. And keep high-cardinality values such as user IDs out of the labels column, since every distinct label set becomes its own series in Prometheus memory.

🔗 Nodes Used

Google Sheets, Webhook

📥 Import

Download workflow.json and import into n8n: Workflow menu → Import from File

📖 Importing guide · 🔑 Credential setup