Grafana Dashboard Extractor avatar

Grafana Dashboard Extractor

Pricing

from $0.35 / 1,000 records

Go to Apify Store
Grafana Dashboard Extractor

Grafana Dashboard Extractor

Point at any Grafana instance and extract its dashboard + folder inventory, version and health via the open HTTP API. One row per dashboard/folder with title, uid, tags, folder; plus health and discovery modes. No per-host scraper.

Pricing

from $0.35 / 1,000 records

Rating

0.0

(0)

Developer

Datamule

Datamule

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

a month ago

Last modified

Categories

Share

A GENERIC "point at any Grafana instance" Apify actor — the dashboard-inventory sibling of the netdata / gatus / uptime-kuma observability runners, over a different, far larger platform population. Grafana (grafana/grafana, ~66k★) is THE self-hosted dashboarding / observability platform, on virtually every observability stack, and a large fraction of instances leaves the HTTP API anonymous-readable — so ONE actor spans every instance, no per-host scraper and no host enumeration.

Input

FieldModeMeaning
sources (required)allOne or more Grafana base URLs — https://play.grafana.org, https://grafana.wikimedia.org, or any self-hosted instance. The /api/... path is appended for you.
mode—search (default), health, or discovery.
querysearchCase-insensitive substring matched against dashboard/folder titles.
typesearchdash-db (dashboards) or dash-folder (folders). Empty = both.
tagsearchOne or more tags (AND-ed by Grafana).
maxRecordsallGlobal cap across every source (one row = one billable event).
bearerallOptional API key / service-account token (Authorization: Bearer). Never logged.
extraHeadersallOptional extra request headers (JSON).

Modes

  • search (default) — paginated /api/search → one flat row per dashboard/folder: id, uid, title, kind (dashboard/folder/other), type, url, tags, isStarred, folderId/folderUid/folderTitle, plus the instance _version / _grafanaBuildCommit (best-effort from a cheap health probe) and a lossless _raw.
  • health — /api/health (+ best-effort /api/frontend/settings) → one row per instance: database, version, commit, edition, and the non-secret auth fingerprint (disableLoginForm, samlEnabled, ldapEnabled, oauthProviders [names only], featureToggleCount).
  • discovery — health + settings + a bounded search count → one summary row per instance: version, edition, dashboardCount, and authDisabled (did anonymous /api/search return 200?). A cheap way to fingerprint many instances at once.

Behaviour

  • Every field is read by key presence (dict.get) — Grafana's /api/search + /api/health shapes drift across the 8→13 major versions and instances populate different optional fields, so an entry omitting folderTitle / tags / sortMeta yields null / [] for that column, never a crash. Unknown fields survive in _raw.
  • Many instances gate /api/search (401/403) but leave /api/health open. In search mode, such a source falls back to a discovery row (the instance fingerprint) instead of yielding nothing.
  • A source behind an anti-bot interstitial (a non-JSON HTTP 200), unreachable (Cloudflare 52x), or returning a non-Grafana body is a clean skip-with-warning — the runner continues with the other sources. The run only fails fast (exit 91) when every source was skipped, so nothing broken ships and the cloud smoke gate stays honest.
  • A valid instance with 0 matching dashboards → 0 records and a clean exit 0. Unpopular is fine; the actor never fabricates rows.

Pricing

Pay-per-event: one record charge per emitted dataset row.

Each row is charged as it is saved, within the maximum cost you set for the run. The Actor stops before it requests a search page or an instance your budget cannot pay for, so you never receive rows you did not pay for. If an instance fails after some rows were delivered, those rows stay in your dataset and the run is marked failed, so a partial export never looks complete.

Development

python3.12 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python tests_logic.py # pure-logic tests (no network)
apify validate-schema
apify run # local run (set storage/key_value_stores/default/INPUT.json)